#![allow(dead_code)]
#![cfg_attr(not(feature = "std"), no_std)]
use core::convert::Infallible;
use std::fmt::Display;
pub trait UnwrapInfallible {
type Ok;
fn unwrap_infallible(self) -> Self::Ok;
}
impl<T> UnwrapInfallible for Result<T, Infallible> {
type Ok = T;
fn unwrap_infallible(self) -> T {
self.unwrap_or_else(|never| match never {})
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
pub struct MoreInputExpected {
}
impl std::error::Error for MoreInputExpected {
}
impl Display for MoreInputExpected {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "MoreInputExpected")
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct EncodingError {
pub line_nr: u32,
}
impl EncodingError {
#[track_caller]
pub fn new() -> Self {
let location = core::panic::Location::caller();
Self {
line_nr: location.line(),
}
}
}
impl std::error::Error for EncodingError {
}
impl Display for EncodingError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "EncodingError at line {}", self.line_nr)
}
}
impl From<MoreInputExpected> for EncodingError {
#[track_caller]
fn from(_: MoreInputExpected) -> Self {
let location = core::panic::Location::caller();
Self {
line_nr: location.line(),
}
}
}
fn raw_read_bytes(reader: &[u8], size: usize) -> Result<(&[u8], &[u8]), MoreInputExpected> {
if reader.len() < size {
return Err(MoreInputExpected::default());
}
let value = &reader[0..size];
Ok((value, &reader[size..]))
}
fn raw_read_f32(reader: &[u8]) -> Result<(f32, &[u8]), MoreInputExpected> {
if reader.len() < 4 {
return Err(MoreInputExpected::default());
}
let mut array : [u8; 4] = reader[0..4]
.try_into()
.expect("not enough bytes for 4-byte float");
array.reverse();
let f = f32::from_le_bytes(array);
Ok((f, &reader[4..]))
}
fn raw_read_f64(reader: &[u8]) -> Result<(f64, &[u8]), MoreInputExpected> {
if reader.len() < 8 {
return Err(MoreInputExpected::default());
}
let mut array : [u8; 8] = reader[0..8]
.try_into()
.expect("not enough bytes for 8-byte float");
array.reverse();
let f = f64::from_le_bytes(array);
Ok((f, &reader[8..]))
}
fn raw_read_u8(reader: &[u8]) -> Result<(u8, &[u8]), MoreInputExpected> {
if reader.is_empty() {
return Err(MoreInputExpected::default());
}
let value = reader[0];
Ok((value, &reader[1..]))
}
pub fn remaining_length_of_var_int(first: u8) -> usize {
if (first & 0b10000000) == 0 {
return 0;
}
if (first & 0b11000000) == 0b10000000 {
return 1;
}
if (first & 0b11100000) == 0b11000000 {
return 2;
}
if (first & 0b11110000) == 0b11100000 {
return 3;
}
if (first & 0b11111000) == 0b11110000 {
return 4;
}
if (first & 0b11111100) == 0b11111000 {
return 5;
}
if (first & 0b11111110) == 0b11111100 {
return 6;
}
if first == 0b11111110 {
return 7;
}
8
}
pub fn raw_read_var_u64(reader: &[u8]) -> Result<(u64,&[u8]), MoreInputExpected> {
let first = if let Some(first) = reader.first() {
*first as u64
} else {
return Err(MoreInputExpected::default());
};
if (first & 0b10000000) == 0 {
return Ok((first,&reader[1..]));
}
if (first & 0b11000000) == 0b10000000 {
if reader.len() < 2 {
return Err(MoreInputExpected::default());
}
let value = ((first & 0b00111111) << 8) | reader[1] as u64;
return Ok((value,&reader[2..]));
}
if (first & 0b11100000) == 0b11000000 {
if reader.len() < 3 {
return Err(MoreInputExpected::default());
}
let value = ((first & 0b00011111) << 16) | (reader[1] as u64) << 8 | (reader[2] as u64);
return Ok((value,&reader[3..]));
}
if (first & 0b11110000) == 0b11100000 {
if reader.len() < 4 {
return Err(MoreInputExpected::default());
}
let value = ((first & 0b00001111) << 24)
| (reader[1] as u64) << 16
| (reader[2] as u64) << 8
| (reader[3] as u64);
return Ok((value,&reader[4..]));
}
if (first & 0b11111000) == 0b11110000 {
if reader.len() < 5 {
return Err(MoreInputExpected::default());
}
let value = ((first & 0b00000111) << 32)
| (reader[1] as u64) << 24
| (reader[2] as u64) << 16
| (reader[3] as u64) << 8
| (reader[4] as u64);
return Ok((value,&reader[5..]));
}
if (first & 0b11111100) == 0b11111000 {
if reader.len() < 6 {
return Err(MoreInputExpected::default());
}
let value = ((first & 0b00000011) << 40)
| (reader[1] as u64) << 32
| (reader[2] as u64) << 24
| (reader[3] as u64) << 16
| (reader[4] as u64) << 8
| (reader[5] as u64);
return Ok((value,&reader[6..]));
}
if (first & 0b11111110) == 0b11111100 {
if reader.len() < 7 {
return Err(MoreInputExpected::default());
}
let value = ((first & 0b00000001) << 48)
| (reader[1] as u64) << 40
| (reader[2] as u64) << 32
| (reader[3] as u64) << 24
| (reader[4] as u64) << 16
| (reader[5] as u64) << 8
| (reader[6] as u64);
return Ok((value,&reader[7..]));
}
if first == 0b11111110 {
if reader.len() < 8 {
return Err(MoreInputExpected::default());
}
let value = (reader[1] as u64) << 48
| (reader[2] as u64) << 40
| (reader[3] as u64) << 32
| (reader[4] as u64) << 24
| (reader[5] as u64) << 16
| (reader[6] as u64) << 8
| (reader[7] as u64);
return Ok((value,&reader[8..]));
}
if reader.len() < 9 {
return Err(MoreInputExpected::default());
}
let value = u64::from_be_bytes(reader[1..9].try_into().unwrap());
Ok((value,&reader[9..]))
}
fn raw_read_u64(reader: &[u8], size: usize) -> Result<(u64,&[u8]), MoreInputExpected> {
if size > 8 || reader.len() < size {
return Err(MoreInputExpected::default());
}
let mut copy = [0u8; 8];
let offset = 8 - size;
copy[offset..8].copy_from_slice(&reader[0..size]);
let value = u64::from_be_bytes(copy);
Ok((value,&reader[size..]))
}
fn sign_extend(x: i64, nbits: u32) -> i64 {
debug_assert!(nbits <= 64);
let notherbits = core::mem::size_of_val(&x) as u32 * 8 - nbits;
x.wrapping_shl(notherbits).wrapping_shr(notherbits)
}
fn raw_read_i64(reader: &[u8], size: usize) -> Result<(i64,&[u8]), MoreInputExpected> {
if size > 8 || reader.len() < size {
return Err(MoreInputExpected::default());
}
let mut copy = [0u8; 8];
let offset = 8 - size;
copy[offset..8].copy_from_slice(&reader[0..size]);
let value = i64::from_be_bytes(copy);
Ok((sign_extend(value, (size as u32) * 8),&reader[size..]))
}
fn raw_read_var_i64(reader: &[u8]) -> Result<(i64, &[u8]), MoreInputExpected> {
let first = reader[0] as u64;
let (v,reader) = raw_read_var_u64(reader)?;
let bits = if (first & 0b10000000) == 0 {
7
} else if (first & 0b11000000) == 0b10000000 {
14
} else if (first & 0b11100000) == 0b11000000 {
21
} else if (first & 0b11110000) == 0b11100000 {
28
} else if (first & 0b11111000) == 0b11110000 {
35
} else if (first & 0b11111100) == 0b11111000 {
42
} else if (first & 0b11111110) == 0b11111100 {
49
} else if (first & 0b11111111) == 0b11111110 {
56
} else {
64
};
Ok((sign_extend(v as i64, bits),reader))
}
#[derive(Eq, PartialEq, Copy, Clone)]
pub struct RawReader<'a> {
data: &'a [u8],
}
impl<'a> RawReader<'a> {
pub fn with<'b>(data: &'b [u8]) -> Self where 'b: 'a {
Self { data, }
}
pub fn read_u8(&mut self) -> Result<u8,MoreInputExpected> {
let (v,r) = raw_read_u8(self.data)?;
self.data = r;
Ok(v)
}
pub fn read_u64(&mut self, len: usize) -> Result<u64,MoreInputExpected> {
let (v,r) = raw_read_u64(self.data, len)?;
self.data = r;
Ok(v)
}
pub fn read_i64(&mut self, len: usize) -> Result<i64,MoreInputExpected> {
let (v,r) = raw_read_i64(self.data, len)?;
self.data = r;
Ok(v)
}
pub fn read_var_u64(&mut self) -> Result<u64,MoreInputExpected> {
let (v,r) = raw_read_var_u64(self.data)?;
self.data = r;
Ok(v)
}
pub fn read_var_i64(&mut self) -> Result<i64,MoreInputExpected> {
let (v,r) = raw_read_var_i64(self.data)?;
self.data = r;
Ok(v)
}
pub fn read_bytes(&mut self, len: usize) -> Result<&'a [u8],MoreInputExpected> {
let (v,r) = raw_read_bytes(self.data, len)?;
self.data = r;
Ok(v)
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn read_f32(&mut self) -> Result<f32,MoreInputExpected> {
let (v,r) = raw_read_f32(self.data)?;
self.data = r;
Ok(v)
}
pub fn read_f64(&mut self) -> Result<f64,MoreInputExpected> {
let (v,r) = raw_read_f64(self.data)?;
self.data = r;
Ok(v)
}
pub fn read_var_bytes(&mut self) -> Result<&'a [u8],MoreInputExpected> {
let length = self.read_var_u64()?;
self.read_bytes(length as usize)
}
pub fn skip(&mut self, length: usize) -> Result<(), MoreInputExpected> {
if length > self.data.len() {
return Err(MoreInputExpected::default());
}
self.data = &self.data[length..];
Ok(())
}
pub fn data(&self) -> &'a [u8] {
self.data
}
pub fn truncate(&mut self, max: usize) {
if self.data.len() > max {
self.data = &self.data[0..max];
}
}
}
pub const fn size_of_i64(i: i64) -> usize {
if -0x80 <= i && i <= 0x7F {
return 1;
}
if -0x8000 <= i && i <= 0x7FFF {
return 2;
}
if -0x800000 <= i && i <= 0x7FFFFF {
return 3;
}
if -0x80000000 <= i && i <= 0x7FFFFFFF {
return 4;
}
if -0x8000000000 <= i && i <= 0x7FFFFFFFFF {
return 5;
}
if -0x800000000000 <= i && i <= 0x7FFFFFFFFFFF {
return 6;
}
if -0x80000000000000 <= i && i <= 0x7FFFFFFFFFFFFF {
return 7;
}
8
}
pub const fn size_of_var_i64(i: i64) -> usize {
if -0x40 <= i && i <= 0x3F {
return 1;
}
if -0x2000 <= i && i <= 0x1FFF {
return 2;
}
if -0x100000 <= i && i <= 0x0FFFFF {
return 3;
}
if -0x08000000 <= i && i <= 0x07FFFFFF {
return 4;
}
if -0x0400000000 <= i && i <= 0x03FFFFFFFF {
return 5;
}
if -0x020000000000 <= i && i <= 0x01FFFFFFFFFF {
return 6;
}
if -0x01000000000000 <= i && i <= 0x00FFFFFFFFFFFF {
return 7;
}
if -0x0080000000000000 <= i && i <= 0x007FFFFFFFFFFFFF {
return 8;
}
9
}
pub const fn size_of_var_u64(i: u64) -> usize {
if i <= 0x7F {
return 1;
}
if i <= 0x3FFF {
return 2;
}
if i <= 0x1FFFFF {
return 3;
}
if i <= 0x0FFFFFFF {
return 4;
}
if i <= 0x07FFFFFFFF {
return 5;
}
if i <= 0x03FFFFFFFFFF {
return 6;
}
if i <= 0x01FFFFFFFFFFFF {
return 7;
}
if i <= 0x00FFFFFFFFFFFFFF {
return 8;
}
9
}
pub fn size_of_var_bytes(s: &[u8]) -> usize {
size_of_var_u64(s.len() as u64) + s.len()
}
fn write_var_u64(data: &mut [u8], i: u64) {
let len = data.len();
match len {
1 => {
data[0] = i as u8;
return;
},
2 => {
data[0] = (i >> 8) as u8 | 0b10000000;
},
3 => {
data[0] = (i >> 16) as u8 | 0b11000000;
},
4 => {
data[0] = (i >> 24) as u8 | 0b11100000;
},
5 => {
data[0] = (i >> 32) as u8 | 0b11110000;
},
6 => {
data[0] = (i >> 40) as u8 | 0b11111000;
},
7 => {
data[0] = (i >> 48) as u8 | 0b11111100;
},
8 => {
data[0] = (i >> 56) as u8 | 0b11111110;
},
9 => {
data[0] = 0xFF;
},
_ => {
panic!("write_var_u64() should always be called with 1 <= len <= 9");
},
}
data[1..len].copy_from_slice(&i.to_be_bytes()[9-len..8]);
}
pub struct ToRawUnsignedVar {
data: [u8; 9],
len: u8,
}
impl ToRawUnsignedVar {
pub fn with(number: u64) -> Self {
let mut data = [0; 9];
let len = size_of_var_u64(number);
write_var_u64(&mut data[0..len], number);
Self { data, len: len as u8 }
}
}
impl core::ops::Deref for ToRawUnsignedVar {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.data[0..self.len as usize]
}
}
pub trait RawOutput<E> {
fn write_u8(&mut self, n: u8) -> Result<(),E>;
fn write_i64(&mut self, n: i64, size: usize) -> Result<(),E>;
fn write_u64(&mut self, i: u64, size: usize) -> Result<(),E>;
fn write_var_i64(&mut self, i: i64) -> Result<(),E>;
fn write_var_u64(&mut self, i: u64) -> Result<(),E>;
fn write_f32(&mut self, f: f32) -> Result<(),E>;
fn write_f64(&mut self, f: f64) -> Result<(),E>;
fn write_bytes(&mut self, s: &[u8]) -> Result<(),E>;
fn write_var_bytes(&mut self, s: &[u8]) -> Result<(),E>;
fn swap_range(&mut self, a: usize, b: usize) -> Result<(),E>;
fn pos(&self) -> usize;
}
pub fn write_with_header<T,E,E2,Output,Header,Body>(writer: &mut Output, header: Header, body: Body) -> Result<T,E2>
where
Output: RawOutput<E>,
Header: FnOnce(&mut Output, u64) -> Result<(),E>,
Body: FnOnce(&mut Output) -> Result<T,E2>,
E2: std::convert::From<E>,
{
let start = writer.pos();
let retval = body(writer)?;
let end = writer.pos();
let length = end - start;
header(writer, length as u64)?;
writer.swap_range(start, end)?;
Ok(retval)
}
pub struct RawWriterLength {
len: usize,
}
impl RawWriterLength {
pub const fn new() -> Self { Self { len: 0 } }
pub const fn length(&self) -> usize {
self.len
}
}
impl Default for RawWriterLength {
fn default() -> Self {
Self::new()
}
}
impl RawOutput<Infallible> for RawWriterLength {
fn write_u8(&mut self, _: u8) -> Result<(),Infallible> {
self.len += 1;
Ok(())
}
fn write_i64(&mut self, _: i64, size: usize) -> Result<(),Infallible> {
self.len += size;
Ok(())
}
fn write_u64(&mut self, _: u64, size: usize) -> Result<(),Infallible> {
self.len += size;
Ok(())
}
fn write_var_i64(&mut self, i: i64) -> Result<(),Infallible> {
self.len += size_of_var_i64(i);
Ok(())
}
fn write_var_u64(&mut self, i: u64) -> Result<(),Infallible> {
self.len += size_of_var_u64(i);
Ok(())
}
fn write_f32(&mut self, _: f32) -> Result<(),Infallible> {
self.len += 4;
Ok(())
}
fn write_f64(&mut self, _: f64) -> Result<(),Infallible> {
self.len += 8;
Ok(())
}
fn write_bytes(&mut self, s: &[u8]) -> Result<(),Infallible> {
self.len += s.len();
Ok(())
}
fn write_var_bytes(&mut self, s: &[u8]) -> Result<(),Infallible> {
self.len += size_of_var_u64(s.len() as u64) + s.len();
Ok(())
}
fn swap_range(&mut self, _a: usize, _b: usize) -> Result<(),Infallible> {
Ok(())
}
fn pos(&self) -> usize {
self.len
}
}
pub struct RawWriter<'a> {
data: &'a mut [u8],
pos: usize,
}
impl<'a> RawOutput<EncodingError> for RawWriter<'a> {
fn write_u8(&mut self, n: u8) -> Result<(),EncodingError> {
self.check(1)?;
self.data[self.pos] = n;
self.skip(1)
}
fn write_i64(&mut self, i: i64, size: usize) -> Result<(),EncodingError> {
self.check(size)?;
let i = i.to_be_bytes();
let offset = 8 - size;
for p in 0 .. size {
self.data[self.pos + p] = i[offset + p];
}
self.skip(size)
}
fn write_u64(&mut self, i: u64, size: usize) -> Result<(),EncodingError> {
self.check(size)?;
self.data[self.pos .. self.pos + size].copy_from_slice(&i.to_be_bytes()[8-size..8]);
self.skip(size)
}
fn write_var_i64(&mut self, i: i64) -> Result<(),EncodingError> {
if (-0x40..=0x3F).contains(&i) { return self.write_u8((i as u8) & 0x7F);
}
if (-0x2000..=0x1FFF).contains(&i) { return self.write_u64(((i as u64) & 0x3FFF) | (0b10000000 << 8), 2);
}
if (-0x100000..=0x0FFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x1FFFFF) | (0b11000000 << 16), 3);
}
if (-0x08000000..=0x07FFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x0FFFFFFF) | (0b11100000 << 24), 4);
}
if (-0x0400000000..=0x03FFFFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x07FFFFFFFF) | (0b11110000 << 32), 5);
}
if (-0x020000000000..=0x01FFFFFFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x03FFFFFFFFFF) | (0b11111000 << 40), 6);
}
if (-0x01000000000000..=0x00FFFFFFFFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x01FFFFFFFFFFFF) | (0b11111100 << 48), 7);
}
if (-0x0080000000000000..=0x007FFFFFFFFFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x00FFFFFFFFFFFFFF) | (0b11111110 << 56), 8);
}
self.check(9)?;
self.data[self.pos] = 0xFF;
self.data[self.pos + 1..self.pos + 9].copy_from_slice(&i.to_be_bytes());
self.skip(9)
}
fn write_var_u64(&mut self, i: u64) -> Result<(),EncodingError> {
let len = size_of_var_u64(i);
self.check(len)?;
write_var_u64(&mut self.data[self.pos..self.pos + len], i);
self.skip(len)
}
fn write_f32(&mut self, f: f32) -> Result<(),EncodingError> {
self.check(4)?;
let mut f = f.to_le_bytes();
f.reverse();
self.data[self.pos..self.pos + 4].copy_from_slice(&f);
self.skip(4)
}
fn write_f64(&mut self, f: f64) -> Result<(),EncodingError> {
self.check(8)?;
let mut f = f.to_le_bytes();
f.reverse();
self.data[self.pos..self.pos + 8].copy_from_slice(&f);
self.skip(8)
}
fn write_bytes(&mut self, s: &[u8]) -> Result<(),EncodingError> {
self.check(s.len())?;
self.data[self.pos..self.pos + s.len()].copy_from_slice(s);
self.skip(s.len())
}
fn write_var_bytes(&mut self, s: &[u8]) -> Result<(),EncodingError> {
self.write_var_u64(s.len() as u64)?;
self.write_bytes(s)
}
fn swap_range(&mut self, a: usize, b: usize) -> Result<(),EncodingError> {
if a >= self.pos || b >= self.pos || a > b {
return Err(EncodingError{ line_nr: line!(), });
}
self.data[a..self.pos].rotate_left(b - a);
Ok(())
}
fn pos(&self) -> usize {
self.pos
}
}
impl<'a> RawWriter<'a> {
pub fn with_uninit(data: &'a mut [std::mem::MaybeUninit<u8>]) -> Self {
unsafe {
Self { data: crate::memorypool::MemoryScope::slice_assume_init_mut(data), pos: 0, }
}
}
pub fn with(data: &'a mut [u8]) -> Self {
Self { data, pos: 0, }
}
pub fn check(&mut self, len: usize) -> Result<(),EncodingError> {
if self.pos + len <= self.data.len() {
Ok(())
} else {
Err(EncodingError { line_nr: line!()})
}
}
pub fn left(&self) -> usize {
self.data.len() - self.pos
}
fn skip(&mut self, n: usize) -> Result<(), EncodingError> {
self.pos += n;
Ok(())
}
pub fn build(self) -> &'a mut [u8] {
&mut self.data[0..self.pos]
}
}
pub struct RawScopedArrayBuilder<'a,'c> {
pub data: crate::memorypool::ScopedArrayBuilder<'a,'c,u8>,
pos: usize,
}
impl<'a,'c> RawOutput<Infallible> for RawScopedArrayBuilder<'a,'c> {
fn write_u8(&mut self, n: u8) -> Result<(),Infallible> {
self.extend(1);
self.data.as_mut_slice()[self.pos] = n;
self.skip(1)
}
fn write_i64(&mut self, i: i64, size: usize) -> Result<(),Infallible> {
self.extend(size);
let i = i.to_be_bytes();
let offset = 8 - size;
for p in 0 .. size {
self.data.as_mut_slice()[self.pos + p] = i[offset + p];
}
self.skip(size)
}
fn write_u64(&mut self, i: u64, size: usize) -> Result<(),Infallible> {
self.extend(size);
self.data.as_mut_slice()[self.pos .. self.pos + size].copy_from_slice(&i.to_be_bytes()[8-size..8]);
self.skip(size)
}
fn write_var_i64(&mut self, i: i64) -> Result<(),Infallible> {
if (-0x40..=0x3F).contains(&i) { return self.write_u8((i as u8) & 0x7F);
}
if (-0x2000..=0x1FFF).contains(&i) { return self.write_u64(((i as u64) & 0x3FFF) | (0b10000000 << 8), 2);
}
if (-0x100000..=0x0FFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x1FFFFF) | (0b11000000 << 16), 3);
}
if (-0x08000000..=0x07FFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x0FFFFFFF) | (0b11100000 << 24), 4);
}
if (-0x0400000000..=0x03FFFFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x07FFFFFFFF) | (0b11110000 << 32), 5);
}
if (-0x020000000000..=0x01FFFFFFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x03FFFFFFFFFF) | (0b11111000 << 40), 6);
}
if (-0x01000000000000..=0x00FFFFFFFFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x01FFFFFFFFFFFF) | (0b11111100 << 48), 7);
}
if (-0x0080000000000000..=0x007FFFFFFFFFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x00FFFFFFFFFFFFFF) | (0b11111110 << 56), 8);
}
self.extend(9);
self.data.as_mut_slice()[self.pos] = 0xFF;
self.data.as_mut_slice()[self.pos + 1..self.pos + 9].copy_from_slice(&i.to_be_bytes());
self.skip(9)
}
fn write_var_u64(&mut self, i: u64) -> Result<(),Infallible> {
let len = size_of_var_u64(i);
self.extend(len);
write_var_u64(&mut self.data.as_mut_slice()[self.pos..self.pos + len], i);
self.skip(len)
}
fn write_f32(&mut self, f: f32) -> Result<(),Infallible> {
self.extend(4);
let mut f = f.to_le_bytes();
f.reverse();
self.data.as_mut_slice()[self.pos..self.pos + 4].copy_from_slice(&f);
self.skip(4)
}
fn write_f64(&mut self, f: f64) -> Result<(),Infallible> {
self.extend(8);
let mut f = f.to_le_bytes();
f.reverse();
self.data.as_mut_slice()[self.pos..self.pos + 8].copy_from_slice(&f);
self.skip(8)
}
fn write_bytes(&mut self, s: &[u8]) -> Result<(),Infallible> {
self.extend(s.len());
self.data.as_mut_slice()[self.pos..self.pos + s.len()].copy_from_slice(s);
self.skip(s.len())
}
fn write_var_bytes(&mut self, s: &[u8]) -> Result<(),Infallible> {
self.write_var_u64(s.len() as u64)?;
self.write_bytes(s)
}
fn swap_range(&mut self, a: usize, b: usize) -> Result<(),Infallible> {
self.data.as_mut_slice()[a..self.pos].rotate_left(b - a);
Ok(())
}
fn pos(&self) -> usize {
self.pos
}
}
impl<'a,'c> RawScopedArrayBuilder<'a,'c> {
pub fn new(scope: &'a mut crate::memorypool::MemoryScope<'c>) -> Self {
Self { data: crate::memorypool::ScopedArrayBuilder::new(scope), pos: 0 }
}
pub fn with_capacity(scope: &'a mut crate::memorypool::MemoryScope<'c>, capacity: usize) -> Self {
Self { data: crate::memorypool::ScopedArrayBuilder::with_capacity(scope, capacity), pos: 0 }
}
pub fn extend(&mut self, len: usize) {
self.data.extend(len, 0u8);
}
fn skip(&mut self, n: usize) -> Result<(),Infallible> {
self.pos += n;
Ok(())
}
pub fn build(self) -> &'c mut [u8] {
self.data.build()
}
pub fn len(&self) -> usize {
self.pos
}
pub fn is_empty(&self) -> bool {
self.pos == 0
}
pub fn as_slice(&self) -> &[u8] {
&self.data.as_slice()[..self.pos]
}
}
#[derive(Clone,Debug)]
pub struct RawString {
pub data: Vec<u8>,
}
impl RawOutput<Infallible> for RawString {
fn write_u8(&mut self, n: u8) -> Result<(),Infallible> {
self.data.push(n);
Ok(())
}
fn write_i64(&mut self, i: i64, size: usize) -> Result<(),Infallible> {
let i = i.to_be_bytes();
let offset = 8 - size;
self.data.extend_from_slice(&i[offset..8]);
Ok(())
}
fn write_u64(&mut self, i: u64, size: usize) -> Result<(),Infallible> {
self.data.extend_from_slice(&i.to_be_bytes()[8-size..8]);
Ok(())
}
fn write_var_i64(&mut self, i: i64) -> Result<(),Infallible> {
if (-0x40..=0x3F).contains(&i) { return self.write_u8((i as u8) & 0x7F);
}
if (-0x2000..=0x1FFF).contains(&i) { return self.write_u64(((i as u64) & 0x3FFF) | (0b10000000 << 8), 2);
}
if (-0x100000..=0x0FFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x1FFFFF) | (0b11000000 << 16), 3);
}
if (-0x08000000..=0x07FFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x0FFFFFFF) | (0b11100000 << 24), 4);
}
if (-0x0400000000..=0x03FFFFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x07FFFFFFFF) | (0b11110000 << 32), 5);
}
if (-0x020000000000..=0x01FFFFFFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x03FFFFFFFFFF) | (0b11111000 << 40), 6);
}
if (-0x01000000000000..=0x00FFFFFFFFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x01FFFFFFFFFFFF) | (0b11111100 << 48), 7);
}
if (-0x0080000000000000..=0x007FFFFFFFFFFFFF).contains(&i) { return self.write_u64(((i as u64) & 0x00FFFFFFFFFFFFFF) | (0b11111110 << 56), 8);
}
self.data.push(0xFF);
self.data.extend_from_slice(&i.to_be_bytes());
Ok(())
}
fn write_var_u64(&mut self, i: u64) -> Result<(),Infallible> {
let len = size_of_var_u64(i);
let pos = self.data.len();
self.data.resize_with(self.data.len() + len, || 0u8);
write_var_u64(&mut self.data.as_mut_slice()[pos..pos + len], i);
Ok(())
}
fn write_f32(&mut self, f: f32) -> Result<(),Infallible> {
let mut f = f.to_le_bytes();
f.reverse();
self.data.extend_from_slice(&f);
Ok(())
}
fn write_f64(&mut self, f: f64) -> Result<(),Infallible> {
let mut f = f.to_le_bytes();
f.reverse();
self.data.extend_from_slice(&f);
Ok(())
}
fn write_bytes(&mut self, s: &[u8]) -> Result<(),Infallible> {
self.data.extend_from_slice(s);
Ok(())
}
fn write_var_bytes(&mut self, s: &[u8]) -> Result<(),Infallible> {
self.write_var_u64(s.len() as u64)?;
self.write_bytes(s)
}
fn swap_range(&mut self, a: usize, b: usize) -> Result<(),Infallible> {
let len = self.data.len();
self.data[a..len].rotate_left(b - a);
Ok(())
}
fn pos(&self) -> usize {
self.data.len()
}
}
impl RawString {
pub fn new() -> Self {
Self { data: Vec::new(), }
}
pub fn with_capacity(capacity: usize) -> Self {
Self { data: Vec::with_capacity(capacity), }
}
pub fn shrink_to_fit(&mut self) {
self.data.shrink_to_fit();
}
pub fn build(self) -> Vec<u8> {
self.data
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn as_slice(&self) -> &[u8] {
&self.data.as_slice()[..self.len()]
}
pub fn truncate(&mut self, len: usize) {
self.data.truncate(len);
}
pub fn clear(&mut self) {
self.data.clear()
}
}
impl Default for RawString {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use crate::*;
#[test]
fn fixed_signed_int_test() {
let mut buffer = [0u8; 9];
for i in -16384..=16384 {
println!("testing {}", i);
let mut writer = RawWriter::with(&mut buffer[..]);
writer.write_i64(i, 2).unwrap();
let writer_len = writer.left();
let mut reader = RawReader::with(&buffer[..]);
let r = reader.read_i64(2).unwrap();
assert_eq!(i, r);
assert_eq!(writer_len, reader.len());
}
let i : i64 = 36028797018963968;
println!("leading zeros of {} = {}", i, i.leading_zeros());
let size = size_of_i64(i);
println!("testing {} with size {}", i, size);
let mut writer = RawWriter::with(&mut buffer[..]);
writer.write_i64(i, size).unwrap();
let writer_len = writer.left();
let mut reader = RawReader::with(&buffer[..]);
let r = reader.read_i64(size).unwrap();
assert_eq!(i, r);
assert_eq!(writer_len, reader.len());
}
#[quickcheck]
fn quickcheck_fixed_signed(v: i64) -> bool {
let mut buffer = [0u8; 9];
let size = size_of_i64(v);
let mut writer = RawWriter::with(&mut buffer[..]);
writer.write_i64(v, size).unwrap();
let writer_len = writer.left();
let mut reader = RawReader::with(&buffer[..]);
let r = reader.read_i64(size).unwrap();
r == v && writer_len == reader.len()
}
#[test]
fn var_signed_int_test() {
let mut buffer = [0u8; 9];
for i in -65536..=65536 {
let mut writer = RawWriter::with(&mut buffer[..]);
writer.write_var_i64(i).unwrap();
let writer_left = writer.left();
let mut reader = RawReader::with(&buffer[..]);
let r = reader.read_var_i64().unwrap();
println!("checking {}: {:?}", i, r);
assert_eq!(writer_left, reader.len());
assert_eq!(i, r);
}
for i in [2199023255552_i64, 1048576_i64] {
println!("testing {}", i);
let expected_len = size_of_var_i64(i);
let mut writer = RawWriter::with(&mut buffer[..]);
writer.write_var_i64(i).unwrap();
let writer_left = writer.left();
assert_eq!(expected_len, buffer.len() - writer_left);
let mut reader = RawReader::with(&buffer[..]);
let r = reader.read_var_i64().unwrap();
println!("buffer: {:x?}", &buffer[0..expected_len]);
assert_eq!(reader.len(), writer_left);
assert_eq!(i, r);
}
}
#[quickcheck]
fn quickcheck_i64_var(v: i64) -> bool {
let mut buffer = [0u8; 9];
let expected_len = size_of_var_i64(v);
let mut writer = RawWriter::with(&mut buffer[..]);
writer.write_var_i64(v).unwrap();
let writer_left = writer.left();
let mut reader = RawReader::with(&buffer[..]);
let r = reader.read_var_i64().unwrap();
expected_len == buffer.len() - writer_left && reader.len() == writer_left && r == v
}
#[test]
fn var_unsigned_int_test() {
let mut buffer = [0u8; 9];
for i in 0..=0x0FFFF {
let mut writer = RawWriter::with(&mut buffer[..]);
writer.write_var_u64(i).unwrap();
let writer_left = writer.left();
let mut reader = RawReader::with(&buffer[..]);
let r = reader.read_var_u64().unwrap();
assert_eq!(writer_left, reader.len());
assert_eq!(r, i);
}
}
#[quickcheck]
fn quickcheck_u64_var(v: u64) -> bool {
let mut buffer = [0u8; 9];
let mut writer = RawWriter::with(&mut buffer[..]);
writer.write_var_u64(v).unwrap();
let writer_left = writer.left();
let mut reader = RawReader::with(&buffer[..]);
let r = reader.read_var_u64().unwrap();
writer_left == reader.len() && r == v
}
}