1use serde::{Deserialize, Serialize};
2
3use crate::serializer::{Encoder, Packer};
4
5#[derive(Copy, Clone, Eq, PartialEq, Default, Debug, Serialize, Deserialize)]
6pub struct VarUint32 {
7 pub n: u32,
9}
10
11impl VarUint32 {
12 pub fn new(n: u32) -> Self {
14 Self { n }
15 }
16
17 pub fn value(&self) -> u32 {
19 self.n
20 }
21}
22
23impl Packer for VarUint32 {
24 fn size(&self) -> usize {
26 let mut size: usize = 0;
27 let mut val = self.n;
28 if val == 0 {
29 return 1;
30 }
31
32 while val > 0 {
33 val >>= 7;
34 size += 1;
35 }
36 size
37 }
38
39 fn pack(&self, enc: &mut Encoder) -> usize {
41 let mut val = self.n;
42 if val == 0 {
43 return 0u8.pack(enc);
44 }
45
46 let mut size = 0usize;
47
48 while val > 0 {
49 let mut b: u32 = val & 0x7f;
50 val >>= 7;
51 if val > 0 {
52 b |= 1 << 7;
53 }
54 let data = enc.alloc(1);
55 data[0] = b as u8;
56 size += 1;
57 }
58 size
59 }
60
61 fn unpack(&mut self, data: &[u8]) -> usize {
63 let mut by: u32 = 0;
64 let mut value: u32 = 0;
65 let mut length: usize = 0;
66 for b in data {
67 value |= (*b as u32 & 0x7f) << by;
68 by += 7;
69 length += 1;
70 if (*b & 0x80) == 0 {
71 break;
72 }
73 assert!(by < 32, "malformed varuint32 data");
74 }
75 self.n = value;
76 length
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83 use crate::chain::Encoder;
84
85 #[test]
86 fn test_varuint32_pack_unpack() {
87 let values = vec![
88 0,
89 1,
90 127,
91 128,
92 255,
93 256,
94 16383,
95 16384,
96 2097151,
97 2097152,
98 268435455,
99 268435456,
100 u32::MAX,
101 ];
102
103 for value in values {
104 let varuint32 = VarUint32::new(value);
105 let mut encoder = Encoder::new(varuint32.size());
106 varuint32.pack(&mut encoder);
107
108 let mut unpacked_varuint32 = VarUint32::default();
109 let _ = unpacked_varuint32.unpack(encoder.get_bytes());
110
111 assert_eq!(varuint32, unpacked_varuint32);
112 }
113 }
114}