1#![deny(missing_docs)]
2pub fn read_varint(bytes: &[u8]) -> (i64, usize) {
18 let mut varint: i64 = 0;
19 let mut bytes_read: usize = 0;
20 for (i, byte) in bytes.iter().enumerate().take(9) {
21 bytes_read += 1;
22 if i == 8 {
23 varint = (varint << 8) | *byte as i64;
24 break;
25 } else {
26 varint = (varint << 7) | (*byte & 0b0111_1111) as i64;
27 if *byte < 0b1000_0000 {
28 break;
29 }
30 }
31 }
32 (varint, bytes_read)
33}
34
35pub fn read_varint_byte_length(bytes: &[u8]) -> usize {
48 for (i, byte) in bytes.iter().enumerate().take(9) {
49 if *byte < 0b1000_0000 {
50 return i + 1;
51 }
52 }
53 9
54}
55
56pub fn serialize_to_varint(input: i64) -> Vec<u8> {
66 use std::collections::VecDeque;
67
68 let mut result: VecDeque<u8> = VecDeque::new();
69 let mut shifted_input = input;
70
71 if input as u64 > 0x00ff_ffff_ffff_ffff {
72 result.push_front((shifted_input & 0b1111_1111) as u8);
74 shifted_input >>= 8;
75 }
76 for _ in 0..8 {
77 result.push_front((shifted_input & 0b0111_1111) as u8);
78
79 shifted_input >>= 7;
80 if result.len() > 1 {
81 let p = result.front_mut().unwrap();
82 *p |= 0b1000_0000;
83 }
84 if shifted_input == 0 {
85 break;
87 }
88 }
89
90 result.into_iter().collect()
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96 #[test]
97 fn read_single_byte_varint() {
98 assert_eq!((1, 1), read_varint(&vec![0b00000001]));
99 assert_eq!((3, 1), read_varint(&vec![0b00000011]));
100 assert_eq!((7, 1), read_varint(&vec![0b00000111]));
101 assert_eq!((15, 1), read_varint(&vec![0b00001111]));
102 }
103
104 #[test]
105 fn read_two_byte_varint() {
106 assert_eq!((128, 2), read_varint(&vec![0b10000001, 0b00000000]));
107 assert_eq!((129, 2), read_varint(&vec![0b10000001, 0b00000001]));
108 assert_eq!((255, 2), read_varint(&vec![0b10000001, 0b01111111]));
109 }
110
111 #[test]
112 fn read_nine_byte_varint() {
113 assert_eq!((-1, 9), read_varint(&vec![0xff; 9]));
114 }
115
116 #[test]
117 fn read_varint_in_longer_bytes() {
118 assert_eq!((1, 1), read_varint(&vec![0x01; 10]));
119 assert_eq!((-1, 9), read_varint(&vec![0xff; 10]));
120 }
121
122 #[test]
123 fn serialize_simple_varints() {
124 assert_eq!(vec![0b00000001], serialize_to_varint(1));
125 assert_eq!(vec![0b00000011], serialize_to_varint(3));
126 }
127
128 #[test]
129 fn serialize_medium_length_varints() {
130 assert_eq!(
131 vec![0b10000010, 0b00000001],
132 serialize_to_varint(0b100000001)
133 )
134 }
135
136 #[test]
137 fn serialize_negative_varints() {
138 assert_eq!(vec![0xff; 9], serialize_to_varint(-1));
139 }
140
141 #[test]
142 fn read_varint_lengths() {
143 let bytes_vec: Vec<Vec<u8>> = vec![
144 vec![0x0f],
145 vec![0xff, 0x0f],
146 vec![0xff, 0xff, 0x0f],
147 vec![0xff, 0xff, 0xff, 0x0f],
148 vec![0xff, 0xff, 0xff, 0xff, 0x0f],
149 vec![0xff, 0xff, 0xff, 0xff, 0xff, 0x0f],
150 vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f],
151 vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f],
152 vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f],
153 vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f],
155 vec![
156 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f,
157 ],
158 ];
159
160 let expected_lengths = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9];
161
162 for i in 0..bytes_vec.len() {
163 assert_eq!(expected_lengths[i], read_varint_byte_length(&bytes_vec[i]));
164 }
165 }
166
167 #[test]
168 fn test_noop() {
169 let inputs: Vec<i64> = vec![
171 0x01,
172 0x1ff,
173 0x123456,
174 0x11223344,
175 0x1122334455,
176 0x112233445566,
177 0x11223344556677,
178 0x1928374655647382,
179 ];
180 for input in inputs {
181 assert_eq!(input, read_varint(&serialize_to_varint(input)).0);
182 }
183 }
184}