binverse/
varint.rs

1use std::io::{Read, Write};
2use crate::error::{BinverseResult, BinverseError};
3
4/// The maximum length in bytes of a varint (u64)
5pub const MAX_LEN: usize = 10;
6
7/// Reads an unsigned 64-bit varint number from a Reader
8pub fn read<R: Read>(r: &mut R) -> BinverseResult<u64> {
9    let mut x: u64 = 0;
10    let mut s = 0;
11    let mut b = [0_u8; 1];
12    for i in 0..MAX_LEN {
13        r.read_exact(&mut b)?;
14        let b = b[0];
15        if b < 0x80 {
16            if i == MAX_LEN-1 && b > 1 {
17                return Err(BinverseError::VarIntOverflow)
18            }
19            return Ok(x | (b as u64) << s)
20        }
21        x |= ((b&0x7f) as u64) << s;
22        s += 7;
23    }
24    // varint was too long and can be considered invalid
25    Err(BinverseError::VarIntOverflow)
26}
27
28/// Writes an unsigned 64-bit varint number to a Writer
29pub fn write<W: Write>(mut x: u64, w: &mut W) -> Result<(), BinverseError> {
30    while x >= 0x80 {
31        w.write_all(&[x as u8 | 0x80])?;
32        x >>= 7;
33    }
34    w.write_all(&[x as u8])?;
35    Ok(())
36}