expry 0.3.0

Execute an expression on an encoded (binary) value, yielding another binary value (either in decoded or encoded form). Supports custom functions. Supports parsing the expression and converting the expression to bytecode.
Documentation
#![allow(dead_code)]
#![cfg_attr(not(feature = "std"), no_std)]

use core::convert::Infallible;
use std::fmt::Display;

// from https://github.com/mzabaluev/unwrap-infallible/blob/master/src/lib.rs
/// Unwrapping an infallible result into its success value.
pub trait UnwrapInfallible {
    /// Type of the `Ok` variant of the result.
    type Ok;

    /// Unwraps a result, returning the content of an `Ok`.
    ///
    /// Unlike `Result::unwrap`, this method is known to never panic
    /// on the result types it is implemented for. Therefore, it can be used
    /// instead of `unwrap` as a maintainability safeguard that will fail
    /// to compile if the error type of the `Result` is later changed
    /// to an error that can actually occur.
    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)]
pub struct EncodingError {
    pub line_nr: u32,
}

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)
    }
}

fn raw_read_bytes(reader: &[u8], size: usize) -> Result<(&[u8], &[u8]), EncodingError> {
    if reader.len() < size {
        return Err(EncodingError { line_nr: line!()});
    }
    let value = &reader[0..size];
    Ok((value, &reader[size..]))
}
fn raw_read_f32(reader: &[u8]) -> Result<(f32, &[u8]), EncodingError> {
    if reader.len() < 4 {
        return Err(EncodingError { line_nr: line!()});
    }
    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]), EncodingError> {
    if reader.len() < 8 {
        return Err(EncodingError { line_nr: line!()});
    }
    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]), EncodingError> {
    if reader.is_empty() {
        return Err(EncodingError { line_nr: line!()});
    }
    let value = reader[0];
    Ok((value, &reader[1..]))
}
fn raw_read_var_u64(reader: &[u8]) -> Result<(u64,&[u8]), EncodingError> {
    // optimize common cases
    // if reader.len() >= 4 {
    //     let first = reader[0] as u64;
    //     if (first & 0b10000000) == 0 {
    //         return Ok((first, &reader[1..]));
    //     }
    //     if (first & 0b11000000) == 0b10000000 {
    //         return Ok((((first & 0b00111111) << 8) | reader[1] as u64, &reader[2..]));
    //     }
    //     if (first & 0b11100000) == 0b11000000 {
    //         return Ok((
    //             ((first & 0b00011111) << 16) | (reader[1] as u64) << 8 | (reader[2] as u64),
    //             &reader[3..],
    //         ));
    //     }
    //     if (first & 0b11110000) == 0b11100000 {
    //         return Ok((
    //             ((first & 0b00001111) << 24)
    //                 | (reader[1] as u64) << 16
    //                 | (reader[2] as u64) << 8
    //                 | (reader[3] as u64),
    //             &reader[4..],
    //         ));
    //     }
    // }
    let first = if let Some(first) = reader.first() {
        *first as u64
    } else {
        return Err(EncodingError { line_nr: line!()});
    };
    // inspired by unicode. First bits indicate the length:
    // if first bit is 0 -> length is 1 byte
    // if first two bits are 10 -> length is 2 bytes
    // if first three bits are 110 -> length is 3 bytes
    // ...
    // if all 8 bytes are 1's -> length is 9 bytes (so 64-bits int fits)
    if (first & 0b10000000) == 0 {
        return Ok((first,&reader[1..]));
    }
    // if size_of::<T>() < 2 {
    //     return Err(EncodingError {});
    // }
    if (first & 0b11000000) == 0b10000000 {
        if reader.len() < 2 {
            return Err(EncodingError { line_nr: line!()});
        }
        let value = ((first & 0b00111111) << 8) | reader[1] as u64;
        return Ok((value,&reader[2..]));
    }
    // if size_of::<T>() < 4 {
    //     return Err(EncodingError {});
    // }
    if (first & 0b11100000) == 0b11000000 {
        if reader.len() < 3 {
            return Err(EncodingError { line_nr: line!()});
        }
        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(EncodingError { line_nr: line!()});
        }
        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 size_of::<T>() < 8 {
    //     return Err(EncodingError{});
    // }
    if (first & 0b11111000) == 0b11110000 {
        if reader.len() < 5 {
            return Err(EncodingError { line_nr: line!()});
        }
        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(EncodingError { line_nr: line!()});
        }
        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(EncodingError { line_nr: line!()});
        }
        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(EncodingError { line_nr: line!()});
        }
        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(EncodingError { line_nr: line!()});
    }
    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]), EncodingError> {
    if size > 8 || reader.len() < size {
        return Err(EncodingError{ line_nr: line!() });
    }
    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]), EncodingError> {
    if size > 8 || reader.len() < size {
        return Err(EncodingError{ line_nr: line!() });
    }
    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]), EncodingError> {
    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))
}

/// Helper to easily read binary values from an u8-slice, triggering EncodingError on
/// out-of-bounds errors.
#[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,EncodingError> {
        let (v,r) = raw_read_u8(self.data)?;
        self.data = r;
        Ok(v)
    }

    pub fn read_u64(&mut self, len: usize) -> Result<u64,EncodingError> {
        let (v,r) = raw_read_u64(self.data, len)?;
        self.data = r;
        Ok(v)
    }
    pub fn read_i64(&mut self, len: usize) -> Result<i64,EncodingError> {
        let (v,r) = raw_read_i64(self.data, len)?;
        self.data = r;
        Ok(v)
    }
    pub fn read_var_u64(&mut self) -> Result<u64,EncodingError> {
        let (v,r) = raw_read_var_u64(self.data)?;
        self.data = r;
        Ok(v)
    }

    pub fn read_var_i64(&mut self) -> Result<i64,EncodingError> {
        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],EncodingError> {
        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,EncodingError> {
        let (v,r) = raw_read_f32(self.data)?;
        self.data = r;
        Ok(v)
    }

    pub fn read_f64(&mut self) -> Result<f64,EncodingError> {
        let (v,r) = raw_read_f64(self.data)?;
        self.data = r;
        Ok(v)
    }

    pub fn read_var_string(&mut self) -> Result<&'a [u8],EncodingError> {
        let length = self.read_var_u64()?;
        self.read_bytes(length as usize)
    }

    pub fn skip(&mut self, length: usize) -> Result<(), EncodingError> {
        if length > self.data.len() {
            return Err(EncodingError { line_nr: line!()});
        }
        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,Output,Header,Body>(writer: &mut Output, header: Header, body: Body) -> Result<T,E>
where
    Output: RawOutput<E>,
    Header: FnOnce(&mut Output, u64) -> Result<(),E>,
    Body: FnOnce(&mut Output) -> Result<T,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
    }
}


/// Helper to easily write binary values to a mut u8-slice, triggering EncodingError on
/// out-of-bounds errors.
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) { // 1 byte
            return self.write_u8((i as u8) & 0x7F);
        }
        if (-0x2000..=0x1FFF).contains(&i) { // 2 bytes
            return self.write_u64(((i as u64) & 0x3FFF) | (0b10000000 << 8), 2);
        }
        if (-0x100000..=0x0FFFFF).contains(&i) { // 3 bytes
            return self.write_u64(((i as u64) & 0x1FFFFF) | (0b11000000 << 16), 3);
        }
        if (-0x08000000..=0x07FFFFFF).contains(&i) { // 4 bytes
            return self.write_u64(((i as u64) & 0x0FFFFFFF) | (0b11100000 << 24), 4);
        }
        if (-0x0400000000..=0x03FFFFFFFF).contains(&i) { // 5 bytes
            return self.write_u64(((i as u64) & 0x07FFFFFFFF) | (0b11110000 << 32), 5);
        }
        if (-0x020000000000..=0x01FFFFFFFFFF).contains(&i) { // 6 bytes
            return self.write_u64(((i as u64) & 0x03FFFFFFFFFF) | (0b11111000 << 40), 6);
        }
        if (-0x01000000000000..=0x00FFFFFFFFFFFF).contains(&i) { // 7 bytes
            return self.write_u64(((i as u64) & 0x01FFFFFFFFFFFF) | (0b11111100 << 48), 7);
        }
        if (-0x0080000000000000..=0x007FFFFFFFFFFFFF).contains(&i) { // 8 bytes
            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) { // 1 byte
            return self.write_u8((i as u8) & 0x7F);
        }
        if (-0x2000..=0x1FFF).contains(&i) { // 2 bytes
            return self.write_u64(((i as u64) & 0x3FFF) | (0b10000000 << 8), 2);
        }
        if (-0x100000..=0x0FFFFF).contains(&i) { // 3 bytes
            return self.write_u64(((i as u64) & 0x1FFFFF) | (0b11000000 << 16), 3);
        }
        if (-0x08000000..=0x07FFFFFF).contains(&i) { // 4 bytes
            return self.write_u64(((i as u64) & 0x0FFFFFFF) | (0b11100000 << 24), 4);
        }
        if (-0x0400000000..=0x03FFFFFFFF).contains(&i) { // 5 bytes
            return self.write_u64(((i as u64) & 0x07FFFFFFFF) | (0b11110000 << 32), 5);
        }
        if (-0x020000000000..=0x01FFFFFFFFFF).contains(&i) { // 6 bytes
            return self.write_u64(((i as u64) & 0x03FFFFFFFFFF) | (0b11111000 << 40), 6);
        }
        if (-0x01000000000000..=0x00FFFFFFFFFFFF).contains(&i) { // 7 bytes
            return self.write_u64(((i as u64) & 0x01FFFFFFFFFFFF) | (0b11111100 << 48), 7);
        }
        if (-0x0080000000000000..=0x007FFFFFFFFFFFFF).contains(&i) { // 8 bytes
            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> {
        // if a >= self.pos || b >= self.pos || a > b {
        //     return Err(EncodingError{ line_nr: line!(), });
        // }
        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()
    }
}
#[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) { // 1 byte
            return self.write_u8((i as u8) & 0x7F);
        }
        if (-0x2000..=0x1FFF).contains(&i) { // 2 bytes
            return self.write_u64(((i as u64) & 0x3FFF) | (0b10000000 << 8), 2);
        }
        if (-0x100000..=0x0FFFFF).contains(&i) { // 3 bytes
            return self.write_u64(((i as u64) & 0x1FFFFF) | (0b11000000 << 16), 3);
        }
        if (-0x08000000..=0x07FFFFFF).contains(&i) { // 4 bytes
            return self.write_u64(((i as u64) & 0x0FFFFFFF) | (0b11100000 << 24), 4);
        }
        if (-0x0400000000..=0x03FFFFFFFF).contains(&i) { // 5 bytes
            return self.write_u64(((i as u64) & 0x07FFFFFFFF) | (0b11110000 << 32), 5);
        }
        if (-0x020000000000..=0x01FFFFFFFFFF).contains(&i) { // 6 bytes
            return self.write_u64(((i as u64) & 0x03FFFFFFFFFF) | (0b11111000 << 40), 6);
        }
        if (-0x01000000000000..=0x00FFFFFFFFFFFF).contains(&i) { // 7 bytes
            return self.write_u64(((i as u64) & 0x01FFFFFFFFFFFF) | (0b11111100 << 48), 7);
        }
        if (-0x0080000000000000..=0x007FFFFFFFFFFFFF).contains(&i) { // 8 bytes
            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> {
        // if a >= self.pos || b >= self.pos || a > b {
        //     return Err(EncodingError{ line_nr: line!(), });
        // }
        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 truncate(&mut self, len: usize) {
        self.data.truncate(len);
    }
}

impl Default for RawString {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use crate::*;
    use crate::raw_utils::{RawWriter, RawReader};

    #[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
    }

}