plabble_codec/codec/common/
dyn_int.rs1use crate::abstractions::SerializationError;
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), SerializationError> {
54 let mut idx = 0;
55 loop {
56 if idx > data.len() - 1 {
57 break Err(SerializationError::TooFewBytes(1));
58 }
59
60 if (data[idx] & 1 << 7) == 0 {
61 break Ok((decode(&data[..=idx]), idx + 1));
62 }
63
64 idx += 1;
65 }
66}
67
68#[cfg(test)]
69mod test {
70 use super::*;
71
72 #[test]
73 fn can_encode_decode_number() {
74 let number = 1234567890;
75 let encoded = encode(number);
76 let decoded = decode(&encoded);
77 assert_eq!(number, decoded);
78 assert_eq!(5, encoded.len()); }
80
81 #[test]
82 fn can_decode_number() {
83 let nr = &[216u8, 4];
84 let res = decode(nr);
85 assert_eq!(600, res);
86 }
87
88 #[test]
89 fn can_decode_number_from_larger_slice() {
90 let nr = &[216u8, 4, 234, 19, 74];
91 let res = read_from_slice(nr).unwrap();
92 assert_eq!((600, 2), res);
93 }
94
95 #[test]
96 fn can_decode_number_in_4_bytes() {
97 let max_nr = 268435455; let encoded = encode(max_nr);
99 assert_eq!(4, encoded.len());
100 }
101
102 #[test]
103 fn cant_decode_bignr_in_4_bytes() {
104 let max_nr = 268435456;
105 let encoded = encode(max_nr);
106 assert_ne!(4, encoded.len());
107 }
108
109 #[test]
110 fn cant_decode_slice_that_lies() {
111 let slice = &[0b10111110]; let decoded = read_from_slice(slice);
113 assert!(decoded.is_err());
114 }
115
116 #[test]
117 fn can_encode_nr_lt_128_in_1_byte() {
118 let encoded = encode(127);
119 assert_eq!(1, encoded.len());
120 }
121
122 #[test]
123 fn can_guess_encoded_size() {
124 let one_byte = 127;
125 assert_eq!(1, encoded_size(one_byte));
126
127 let two_bytes = 128;
128 assert_eq!(2, encoded_size(two_bytes));
129
130 let four_bytes = 268435455;
131 assert_eq!(4, encoded_size(four_bytes));
132 }
133}