pub(crate) fn encode_u32(mut value: u32, buf: &mut Vec<u8>) {
loop {
let mut byte = (value & 0x7f) as u8;
value >>= 7;
if value != 0 {
byte |= 0x80;
}
buf.push(byte);
if value == 0 {
break;
}
}
}
pub(crate) fn encode_u64(mut value: u64, buf: &mut Vec<u8>) {
loop {
let mut byte = (value & 0x7f) as u8;
value >>= 7;
if value != 0 {
byte |= 0x80;
}
buf.push(byte);
if value == 0 {
break;
}
}
}
pub(crate) fn decode_u32(buf: &[u8]) -> Option<(u32, usize)> {
let mut result: u32 = 0;
let mut shift = 0;
let mut bytes_read = 0;
for &byte in buf {
bytes_read += 1;
let lower_7_bits = (byte & 0x7f) as u32;
result |= lower_7_bits << shift;
if byte & 0x80 == 0 {
return Some((result, bytes_read));
}
shift += 7;
if shift >= 35 {
return None; }
}
None
}
pub(crate) fn decode_u64(buf: &[u8]) -> Option<(u64, usize)> {
let mut result: u64 = 0;
let mut shift = 0;
let mut bytes_read = 0;
for &byte in buf {
bytes_read += 1;
let lower_7_bits = (byte & 0x7f) as u64;
result |= lower_7_bits << shift;
if byte & 0x80 == 0 {
return Some((result, bytes_read));
}
shift += 7;
if shift >= 70 {
return None; }
}
None
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_varint_encode_decode() {
let mut buf = Vec::new();
let values = vec![0, 1, 127, 128, 255, 300, 16383, 16384, u32::MAX];
for &val in &values {
buf.clear();
encode_u32(val, &mut buf);
if val < 128 {
assert_eq!(buf.len(), 1);
} else if val < 16384 {
assert_eq!(buf.len(), 2);
}
let (decoded, len) = decode_u32(&buf).unwrap();
assert_eq!(decoded, val);
assert_eq!(len, buf.len());
}
}
}