1use crate::{DeserializationError, SerializationError, SerializerConfig};
2
3pub fn encoded_size(nr: u128) -> usize {
8 let mut res = 0;
9 let mut nr = nr;
10 while nr > 0 {
11 nr /= 128;
12 res += 1;
13 }
14 res
15}
16
17pub fn encode(nr: u128) -> Vec<u8> {
22 let mut res = Vec::new();
23 let mut nr = nr;
24 while nr > 0 {
25 let mut encoded = nr % 128;
26 nr /= 128;
27 if nr > 0 {
28 encoded |= 128;
29 }
30 res.push(encoded as u8);
31 }
32 res
33}
34
35pub fn decode(data: &[u8]) -> u128 {
40 let mut num = 0;
41 let mut multiplier = 1;
42 for byte in data {
43 num += (*byte as u128 & 127) * multiplier;
44 multiplier *= 128;
45 }
46 num
47}
48
49pub fn read_from_slice(data: &[u8]) -> Result<(u128, usize), DeserializationError> {
57 let mut idx = 0;
58 loop {
59 if idx > data.len() - 1 {
60 break Err(DeserializationError::NotEnoughBytes(1));
61 }
62
63 if (data[idx] & 1 << 7) == 0 {
64 break Ok((decode(&data[..=idx]), idx + 1));
65 }
66
67 idx += 1;
68 }
69}
70
71pub fn read_dynint<T : Clone>(
72 bytes: &[u8],
73 config: &mut SerializerConfig<T>
74) -> Result<u128, DeserializationError> {
75 config.reset_bits(true);
76 let (value, read_bytes) = read_from_slice(&bytes[config.pos..])?;
77 config.pos += read_bytes;
78 Ok(value)
79}
80
81pub fn write_dynint<T : Clone>(
82 val: u128,
83 bytes: &mut Vec<u8>,
84 config: &mut SerializerConfig<T>
85) -> Result<(), SerializationError> {
86 config.reset_bits(false);
87 let data = encode(val);
88 bytes.extend_from_slice(&data);
89 config.pos += data.len();
90 Ok(())
91}
92
93
94#[cfg(test)]
95mod test {
96 use super::*;
97
98 #[test]
99 fn can_encode_decode_number() {
100 let number = 1234567890;
101 let encoded = encode(number);
102 let decoded = decode(&encoded);
103 assert_eq!(number, decoded);
104 assert_eq!(5, encoded.len()); }
106
107 #[test]
108 fn can_decode_number() {
109 let nr = &[216u8, 4];
110 let res = decode(nr);
111 assert_eq!(600, res);
112 }
113
114 #[test]
115 fn can_decode_number_from_larger_slice() {
116 let nr = &[216u8, 4, 234, 19, 74];
117 let res = read_from_slice(nr).unwrap();
118 assert_eq!((600, 2), res);
119 }
120
121 #[test]
122 fn can_decode_number_in_4_bytes() {
123 let max_nr = 268435455; let encoded = encode(max_nr);
125 assert_eq!(4, encoded.len());
126 }
127
128 #[test]
129 fn cant_decode_bignr_in_4_bytes() {
130 let max_nr = 268435456;
131 let encoded = encode(max_nr);
132 assert_ne!(4, encoded.len());
133 }
134
135 #[test]
136 fn cant_decode_slice_that_lies() {
137 let slice = &[0b10111110]; let decoded = read_from_slice(slice);
139 assert!(decoded.is_err());
140 }
141
142 #[test]
143 fn can_encode_nr_lt_128_in_1_byte() {
144 let encoded = encode(127);
145 assert_eq!(1, encoded.len());
146 }
147
148 #[test]
149 fn can_guess_encoded_size() {
150 let one_byte = 127;
151 assert_eq!(1, encoded_size(one_byte));
152
153 let two_bytes = 128;
154 assert_eq!(2, encoded_size(two_bytes));
155
156 let four_bytes = 268435455;
157 assert_eq!(4, encoded_size(four_bytes));
158 }
159}