parquet2/encoding/
uleb128.rs

1use crate::error::Error;
2
3pub fn decode(values: &[u8]) -> Result<(u64, usize), Error> {
4    let mut result = 0;
5    let mut shift = 0;
6
7    let mut consumed = 0;
8    for byte in values {
9        consumed += 1;
10        if shift == 63 && *byte > 1 {
11            panic!()
12        };
13
14        result |= u64::from(byte & 0b01111111) << shift;
15
16        if byte & 0b10000000 == 0 {
17            break;
18        }
19
20        shift += 7;
21    }
22    Ok((result, consumed))
23}
24
25/// Encodes `value` in ULEB128 into `container`. The exact number of bytes written
26/// depends on `value`, and cannot be determined upfront. The maximum number of bytes
27/// required are 10.
28/// # Panic
29/// This function may panic if `container.len() < 10` and `value` requires more bytes.
30pub fn encode(mut value: u64, container: &mut [u8]) -> usize {
31    let mut consumed = 0;
32    let mut iter = container.iter_mut();
33    loop {
34        let mut byte = (value as u8) & !128;
35        value >>= 7;
36        if value != 0 {
37            byte |= 128;
38        }
39        *iter.next().unwrap() = byte;
40        consumed += 1;
41        if value == 0 {
42            break;
43        }
44    }
45    consumed
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn decode_1() {
54        let data = vec![0xe5, 0x8e, 0x26, 0xDE, 0xAD, 0xBE, 0xEF];
55        let (value, len) = decode(&data).unwrap();
56        assert_eq!(value, 624_485);
57        assert_eq!(len, 3);
58    }
59
60    #[test]
61    fn decode_2() {
62        let data = vec![0b00010000, 0b00000001, 0b00000011, 0b00000011];
63        let (value, len) = decode(&data).unwrap();
64        assert_eq!(value, 16);
65        assert_eq!(len, 1);
66    }
67
68    #[test]
69    fn round_trip() {
70        let original = 123124234u64;
71        let mut container = [0u8; 10];
72        let encoded_len = encode(original, &mut container);
73        let (value, len) = decode(&container).unwrap();
74        assert_eq!(value, original);
75        assert_eq!(len, encoded_len);
76    }
77
78    #[test]
79    fn min_value() {
80        let original = u64::MIN;
81        let mut container = [0u8; 10];
82        let encoded_len = encode(original, &mut container);
83        let (value, len) = decode(&container).unwrap();
84        assert_eq!(value, original);
85        assert_eq!(len, encoded_len);
86    }
87
88    #[test]
89    fn max_value() {
90        let original = u64::MAX;
91        let mut container = [0u8; 10];
92        let encoded_len = encode(original, &mut container);
93        let (value, len) = decode(&container).unwrap();
94        assert_eq!(value, original);
95        assert_eq!(len, encoded_len);
96    }
97}