antelope/chain/
varint.rs

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    /// The unsigned integer value.
8    pub n: u32,
9}
10
11impl VarUint32 {
12    /// Create a new VarUint32 instance with the given value.
13    pub fn new(n: u32) -> Self {
14        Self { n }
15    }
16
17    /// Get the value of the VarUint32 instance.
18    pub fn value(&self) -> u32 {
19        self.n
20    }
21}
22
23impl Packer for VarUint32 {
24    /// Calculate the size of the serialized VarUint32.
25    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    /// Serialize the VarUint32 value.
40    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    /// Deserialize the VarUint32 value from the given byte slice.
62    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}