extern crate alloc;
use alloc::vec::Vec;
use crate::error::Error;
pub(crate) fn encode_int(out: &mut Vec<u8>, value: usize, n: u32, flags: u8) {
debug_assert!((1..=8).contains(&n));
let max_prefix = (1usize << n) - 1;
if value < max_prefix {
out.push(flags | value as u8);
return;
}
out.push(flags | max_prefix as u8);
let mut v = value - max_prefix;
while v >= 128 {
out.push((v & 0x7f) as u8 | 0x80);
v >>= 7;
}
out.push(v as u8);
}
pub(crate) fn decode_int(buf: &[u8], pos: usize, n: u32) -> Result<(usize, usize), Error> {
debug_assert!((1..=8).contains(&n));
let max_prefix = (1usize << n) - 1;
let first = *buf.get(pos).ok_or(Error::UnexpectedEnd)? as usize;
let value = first & max_prefix;
let mut p = pos + 1;
if value < max_prefix {
return Ok((value, p));
}
let mut value = value;
let mut shift = 0u32;
loop {
let b = *buf.get(p).ok_or(Error::UnexpectedEnd)? as usize;
p += 1;
if shift >= usize::BITS {
return Err(Error::Corrupt);
}
let add = (b & 0x7f).checked_shl(shift).ok_or(Error::Corrupt)?;
value = value.checked_add(add).ok_or(Error::Corrupt)?;
if b & 0x80 == 0 {
break;
}
shift += 7;
}
Ok((value, p))
}