cml_crypto/chain_core/
abor.rs

1/// ABOR Encoder
2pub struct Encoder {
3    data: Vec<u8>,
4    hole: Vec<(usize, usize)>,
5    current_element: usize,
6}
7
8/// ABOR Types
9#[repr(u8)]
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum Tag {
12    U8 = 1,
13    U16 = 2,
14    U32 = 3,
15    U64 = 4,
16    U128 = 5,
17    Bytes = 6,
18    Array = 7,
19}
20
21impl Tag {
22    pub fn from_u8(v: u8) -> Option<Tag> {
23        match v {
24            1 => Some(Tag::U8),
25            2 => Some(Tag::U16),
26            3 => Some(Tag::U32),
27            4 => Some(Tag::U64),
28            5 => Some(Tag::U128),
29            6 => Some(Tag::Bytes),
30            7 => Some(Tag::Array),
31            _ => None,
32        }
33    }
34}
35
36impl Encoder {
37    pub fn new() -> Self {
38        Encoder {
39            data: Vec::new(),
40            hole: Vec::new(),
41            current_element: 0,
42        }
43    }
44
45    fn push_byte(self, u: u8) -> Self {
46        let mut v = self.data;
47        v.push(u);
48        Self {
49            data: v,
50            hole: self.hole,
51            current_element: self.current_element,
52        }
53    }
54
55    fn push_tag(self, tag: Tag) -> Self {
56        self.push_byte(tag as u8)
57    }
58
59    fn push_slice(self, s: &[u8]) -> Self {
60        let mut v = self.data;
61        v.extend_from_slice(s);
62        Self {
63            data: v,
64            hole: self.hole,
65            current_element: self.current_element,
66        }
67    }
68
69    fn incr(self) -> Self {
70        Self {
71            data: self.data,
72            hole: self.hole,
73            current_element: self.current_element + 1,
74        }
75    }
76
77    /// Add an unsigned byte
78    pub fn u8(self, u: u8) -> Self {
79        self.push_tag(Tag::U8).push_byte(u).incr()
80    }
81
82    /// Add a 16-bit unsigned value in little endian format
83    pub fn u16(self, u: u16) -> Self {
84        self.push_tag(Tag::U16).push_slice(&u.to_le_bytes()).incr()
85    }
86
87    /// Add a 32-bit unsigned value in little endian format
88    pub fn u32(self, u: u32) -> Self {
89        self.push_tag(Tag::U32).push_slice(&u.to_le_bytes()).incr()
90    }
91
92    /// Add a 64-bit unsigned value in little endian format
93    pub fn u64(self, u: u64) -> Self {
94        self.push_tag(Tag::U64).push_slice(&u.to_le_bytes()).incr()
95    }
96
97    /// Add a 128-bit unsigned value in little endian format
98    pub fn u128(self, u: u128) -> Self {
99        self.push_tag(Tag::U128).push_slice(&u.to_le_bytes()).incr()
100    }
101
102    /// cannot serialize more than 256 bytes of contiguous data
103    pub fn bytes(self, bs: &[u8]) -> Self {
104        assert!(bs.len() < 256);
105        self.push_tag(Tag::Bytes)
106            .push_byte(bs.len() as u8)
107            .push_slice(bs)
108            .incr()
109    }
110
111    /// Array cannot contain more than 256 elements
112    pub fn struct_start(self) -> Self {
113        let mut d = self.push_tag(Tag::Array);
114        let mut h = d.hole;
115        let c = d.current_element + 1;
116        h.push((c, d.data.len()));
117        d.data.push(0xfe); // placeholder poison until struct end fill the actual size
118        Self {
119            data: d.data,
120            hole: h,
121            current_element: c,
122        }
123    }
124
125    /// Terminate an array
126    pub fn struct_end(self) -> Self {
127        let mut h = self.hole;
128        match h.pop() {
129            None => panic!("unmatched end"),
130            Some((start_element, ofs)) => {
131                let mut v = self.data;
132                let nb_elements = self.current_element - start_element;
133                assert!(nb_elements < 256);
134                v[ofs] = nb_elements as u8;
135                Self {
136                    data: v,
137                    hole: h,
138                    current_element: self.current_element,
139                }
140            }
141        }
142    }
143
144    /// Finalize the encoder into an immutable array of data
145    pub fn finalize(self) -> Box<[u8]> {
146        assert_eq!(self.hole.len(), 0);
147        self.data.into()
148    }
149}
150
151impl Default for Encoder {
152    fn default() -> Self {
153        Self::new()
154    }
155}
156
157/// Create a decoder on some data
158pub struct Decoder<'a> {
159    slice: &'a [u8],
160    //ctx: Vec<usize>,
161    //element: usize,
162}
163
164#[derive(Debug, Clone)]
165pub enum DecodeError {
166    EndOfStream,
167    StreamTooSmall { want: usize, has: usize },
168    StreamPending { left: usize },
169    TypeUnknown(u8),
170    TypeMismatch { got: Tag, expected: Tag },
171}
172
173impl<'a> Decoder<'a> {
174    #[must_use]
175    pub fn new(data: &'a [u8]) -> Self {
176        Decoder { slice: data }
177    }
178
179    fn pop(&mut self) -> Result<u8, DecodeError> {
180        if !self.slice.is_empty() {
181            let v = self.slice[0];
182            self.slice = &self.slice[1..];
183            Ok(v)
184        } else {
185            Err(DecodeError::EndOfStream)
186        }
187    }
188
189    fn expect_tag(&mut self, tag: Tag) -> Result<(), DecodeError> {
190        let t = self.pop()?;
191        match Tag::from_u8(t) {
192            None => Err(DecodeError::TypeUnknown(self.slice[0])),
193            Some(got) if got == tag => Ok(()),
194            Some(got) => Err(DecodeError::TypeMismatch { got, expected: tag }),
195        }
196    }
197
198    fn expect_size(&self, nb_bytes: usize) -> Result<(), DecodeError> {
199        if nb_bytes <= self.slice.len() {
200            Ok(())
201        } else {
202            Err(DecodeError::StreamTooSmall {
203                want: nb_bytes,
204                has: self.slice.len(),
205            })
206        }
207    }
208
209    fn expect_tag_size(&mut self, tag: Tag, nb_bytes: usize) -> Result<(), DecodeError> {
210        self.expect_tag(tag)?;
211        self.expect_size(nb_bytes)
212    }
213
214    pub fn array(&mut self) -> Result<usize, DecodeError> {
215        self.expect_tag_size(Tag::Array, 1)?;
216        let len = self.pop()?;
217        Ok(len as usize)
218    }
219
220    pub fn u8(&mut self) -> Result<u8, DecodeError> {
221        self.expect_tag_size(Tag::U8, 1)?;
222        let len = self.pop()?;
223        Ok(len)
224    }
225
226    pub fn u16(&mut self) -> Result<u16, DecodeError> {
227        self.expect_tag_size(Tag::U16, 2)?;
228        let v = {
229            let mut b = [0; 2];
230            b.copy_from_slice(&self.slice[0..2]);
231            u16::from_le_bytes(b)
232        };
233        self.slice = &self.slice[2..];
234        Ok(v)
235    }
236
237    pub fn u32(&mut self) -> Result<u32, DecodeError> {
238        self.expect_tag_size(Tag::U32, 2)?;
239        let v = {
240            let mut b = [0; 4];
241            b.copy_from_slice(&self.slice[0..4]);
242            u32::from_le_bytes(b)
243        };
244        self.slice = &self.slice[4..];
245        Ok(v)
246    }
247
248    pub fn u64(&mut self) -> Result<u64, DecodeError> {
249        self.expect_tag_size(Tag::U64, 8)?;
250        let v = {
251            let mut b = [0; 8];
252            b.copy_from_slice(&self.slice[0..8]);
253            u64::from_le_bytes(b)
254        };
255        self.slice = &self.slice[8..];
256        Ok(v)
257    }
258
259    pub fn u128(&mut self) -> Result<u128, DecodeError> {
260        self.expect_tag_size(Tag::U128, 16)?;
261        let v = {
262            let mut b = [0; 16];
263            b.copy_from_slice(&self.slice[0..16]);
264            u128::from_le_bytes(b)
265        };
266        self.slice = &self.slice[16..];
267        Ok(v)
268    }
269
270    pub fn bytes(&mut self) -> Result<Box<[u8]>, DecodeError> {
271        self.expect_tag_size(Tag::Bytes, 1)?;
272        let len = self.pop()? as usize;
273        self.expect_size(len)?;
274        let mut v = Vec::with_capacity(len);
275        v.extend_from_slice(&self.slice[0..len]);
276        self.slice = &self.slice[len..];
277        Ok(v.into())
278    }
279
280    pub fn end(self) -> Result<(), DecodeError> {
281        if self.slice.is_empty() {
282            Ok(())
283        } else {
284            Err(DecodeError::StreamPending {
285                left: self.slice.len(),
286            })
287        }
288    }
289}
290
291#[cfg(test)]
292mod tests {
293    use super::*;
294
295    #[test]
296    pub fn serialize_unit1() {
297        let v = 0xf12_35fc;
298        let e = Encoder::new().u32(v).finalize();
299        let mut d = Decoder::new(&e);
300        let ev = d.u32().unwrap();
301        assert!(d.end().is_ok());
302        assert_eq!(v, ev)
303    }
304
305    #[test]
306    pub fn serialize_unit2() {
307        let v1 = 10;
308        let v2 = 0x12345;
309        let v3 = 0xffeeddcc00112233;
310        let v4 = 0xffeeddcc0011223321490219480912;
311        let bs1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
312        let e = Encoder::new()
313            .u16(v1)
314            .u32(v2)
315            .u64(v3)
316            .u128(v4)
317            .bytes(&bs1[..])
318            .finalize();
319        let mut d = Decoder::new(&e);
320        let ev1 = d.u16().unwrap();
321        let ev2 = d.u32().unwrap();
322        let ev3 = d.u64().unwrap();
323        let ev4 = d.u128().unwrap();
324        let ebs1 = d.bytes().unwrap();
325        let is_end = d.end();
326        assert_eq!(v1, ev1);
327        assert_eq!(v2, ev2);
328        assert_eq!(v3, ev3);
329        assert_eq!(v4, ev4);
330        assert_eq!(&bs1[..], &ebs1[..]);
331        assert!(is_end.is_ok(), "not reached end {:?}", is_end.unwrap_err());
332    }
333}