use crate::buffer::Reader;
use crate::error::DecodeError;
use anyhow::Result;
pub const MAX_VARINT_LENGTH: usize = 10;
#[inline]
pub fn write_uvarint(mut x: u64, buf: &mut Vec<u8>) {
while x >= 0x80 {
buf.push(x as u8 | 0x80);
x >>= 7;
}
buf.push(x as u8);
}
#[inline]
pub fn write_varint(x: i64, buf: &mut Vec<u8>) {
let mut ux = (x as u64) << 1;
if x < 0 {
ux = !ux;
}
write_uvarint(ux, buf);
}
#[inline]
pub fn encode_uvarint(x: u64) -> Vec<u8> {
let mut buf = Vec::with_capacity(MAX_VARINT_LENGTH);
write_uvarint(x, &mut buf);
buf
}
#[inline]
pub fn encode_varint(x: i64) -> Vec<u8> {
let mut buf = Vec::with_capacity(MAX_VARINT_LENGTH);
write_varint(x, &mut buf);
buf
}
#[inline]
pub fn read_uvarint<T>(buf: &mut Reader<T>) -> Result<u64>
where
T: AsRef<[u8]>,
{
let mut x: u64 = 0;
let mut shift = 0;
if buf.is_end() {
return Err(DecodeError::EOF.into());
}
loop {
match buf.read_byte() {
Ok(v) => {
let b = v as u64;
x |= (b & 0x7F) << shift;
shift += 7;
if (b & 0x80) == 0 {
return Ok(x);
}
if shift >= 64 {
return Err(DecodeError::OverFlow64Bit.into());
}
}
Err(_) => {
return Err(DecodeError::UnexpectedEof.into());
}
}
}
}
#[inline]
pub fn read_varint<T>(buf: &mut Reader<T>) -> Result<i64>
where
T: AsRef<[u8]>,
{
let ux = read_uvarint(buf)?;
let mut x = (ux as i64) >> 1;
if ux & 1 != 0 {
x = !x;
}
Ok(x)
}