numbat_codec/
codec_de.rs

1use alloc::vec::Vec;
2use crate::codec_err::DecodeError;
3use crate::TypeInfo;
4use arrayvec::ArrayVec;
5
6/// Trait that allows reading of data into a slice.
7pub trait Input {
8	/// Should return the remaining length of the input data. If no information about the input
9	/// length is available, `None` should be returned.
10	///
11	/// The length is used to constrain the preallocation while decoding. Returning a garbage
12	/// length can open the doors for a denial of service attack to your application.
13	/// Otherwise, returning `None` can decrease the performance of your application.
14    fn remaining_len(&mut self) -> usize;
15    
16    fn empty(&mut self)-> bool {
17        self.remaining_len() == 0
18    }
19
20	/// Read the exact number of bytes required to fill the given buffer.
21    fn read_into(&mut self, into: &mut [u8]) -> Result<(), DecodeError>;
22
23	/// Read a single byte from the input.
24	fn read_byte(&mut self) -> Result<u8, DecodeError> {
25		let mut buf = [0u8];
26		self.read_into(&mut buf[..])?;
27		Ok(buf[0])
28    }
29
30    /// Read the exact number of bytes required to fill the given buffer.
31	fn read_slice(&mut self, length: usize) -> Result<&[u8], DecodeError>;
32    
33    fn flush(&mut self) -> Result<&[u8], DecodeError>;
34
35}
36
37impl<'a> Input for &'a [u8] {
38	fn remaining_len(&mut self) -> usize {
39		self.len()
40    }
41
42	fn read_into(&mut self, into: &mut [u8]) -> Result<(), DecodeError> {
43		if into.len() > self.len() {
44			return Err(DecodeError::InputTooShort);
45		}
46		let len = into.len();
47		into.copy_from_slice(&self[..len]);
48		*self = &self[len..];
49		Ok(())
50    }
51
52    fn read_slice(&mut self, length: usize) -> Result<&[u8], DecodeError> {
53        if length > self.len() {
54            return Err(DecodeError::InputTooShort);
55        }
56
57        let (result, rest) = self.split_at(length);
58        *self = rest;
59        Ok(result)
60    }
61    
62    fn flush(&mut self) -> Result<&[u8], DecodeError> {
63        let result = &self[..];
64        *self = &[];
65        Ok(result)
66    }
67}
68
69/// Trait that allows zero-copy read of value-references from slices in LE format.
70pub trait Decode: Sized {
71	// !INTERNAL USE ONLY!
72	// This const helps SCALE to optimize the encoding/decoding by doing fake specialization.
73	#[doc(hidden)]
74	const TYPE_INFO: TypeInfo = TypeInfo::Unknown;
75    
76    /// Attempt to deserialise the value from input.
77	fn top_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError> {
78        let result = Self::dep_decode(input)?;
79        if input.remaining_len() > 0 {
80            return Err(DecodeError::InputTooLong);
81        }
82        Ok(result)
83    }
84
85    /// Attempt to deserialise the value from input,
86    /// using the format of an object nested inside another structure.
87    /// In case of success returns the deserialized value and the number of bytes consumed during the operation.
88    fn dep_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError>;
89}
90
91/// Convenience method, to avoid having to specify type when calling `top_decode`.
92/// Especially useful in the macros.
93#[inline]
94pub fn decode_from_byte_slice<D: Decode>(input: &[u8]) -> Result<D, DecodeError> {
95    // the input doesn't need to be mutable because we are not changing the underlying data 
96    D::top_decode(&mut &*input)
97}
98
99impl Decode for () {
100    const TYPE_INFO: TypeInfo = TypeInfo::Unit;
101
102	fn dep_decode<I: Input>(_: &mut I) -> Result<(), DecodeError> {
103		Ok(())
104	}
105}
106
107impl Decode for u8 {
108    const TYPE_INFO: TypeInfo = TypeInfo::U8;
109    
110	fn top_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError> {
111        let bytes = input.flush()?;
112        match bytes.len() {
113            0 => Ok(0u8),
114            1 => Ok(bytes[0]),
115            _ => Err(DecodeError::InputTooLong),
116        }
117    }
118    
119    fn dep_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError> {
120        input.read_byte()
121    }
122}
123
124impl<T: Decode> Decode for Vec<T> {
125	fn top_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError> {
126        match T::TYPE_INFO {
127			TypeInfo::U8 => {
128                let bytes = input.flush()?;
129                let bytes_copy = bytes.to_vec(); // copy is needed because result might outlive input
130                let cast_vec: Vec<T> = unsafe { core::mem::transmute(bytes_copy) };
131                Ok(cast_vec)
132			},
133			_ => {
134                let mut result: Vec<T> = Vec::new();
135                while input.remaining_len() > 0 {
136                    result.push(T::dep_decode(input)?);
137                }
138                Ok(result)
139			}
140        }
141    }
142    
143    fn dep_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError> {
144        let size = usize::dep_decode(input)?;
145        match T::TYPE_INFO {
146			TypeInfo::U8 => {
147                let bytes = input.read_slice(size)?;
148                let bytes_copy = bytes.to_vec(); // copy is needed because result might outlive input
149                let cast_vec: Vec<T> = unsafe { core::mem::transmute(bytes_copy) };
150                Ok(cast_vec)
151			},
152			_ => {
153                let mut result: Vec<T> = Vec::with_capacity(size);
154				for _ in 0..size {
155                    result.push(T::dep_decode(input)?);
156                }
157                Ok(result)
158			}
159        }
160    }
161}
162
163/// Handles both signed and unsigned of any length.
164/// No generics here, because we want the executable binary as small as possible.
165pub fn bytes_to_number(bytes: &[u8], signed: bool) -> u64 {
166    if bytes.is_empty() {
167        return 0;
168    }
169    let negative = signed && bytes[0] >> 7 == 1;
170    let mut result = 
171        if negative {
172            // start with all bits set to 1, 
173            // to ensure that if there are fewer bytes than the result type width,
174            // the leading bits will be 1 instead of 0
175            0xffffffffffffffffu64 
176        } else { 
177            0u64 
178        };
179    for byte in bytes.iter() {
180        result <<= 8;
181        result |= *byte as u64;
182    }
183    result
184}
185
186macro_rules! impl_nums {
187    ($ty:ty, $num_bytes:expr, $signed:expr, $type_info:expr) => {
188        impl Decode for $ty {
189            const TYPE_INFO: TypeInfo = $type_info;
190            
191            fn top_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError> {
192                let bytes = input.flush()?;
193                if bytes.len() > $num_bytes {
194                    return Err(DecodeError::InputTooLong)
195                }
196                let num = bytes_to_number(bytes, $signed) as $ty;
197                Ok(num)
198            }
199            
200            fn dep_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError> {
201                let bytes = input.read_slice($num_bytes)?;
202                let num = bytes_to_number(bytes, $signed) as $ty;
203                Ok(num)
204            }
205        }
206    }
207}
208
209impl_nums!(u16, 2, false, TypeInfo::U16);
210impl_nums!(u32, 4, false, TypeInfo::U32);
211impl_nums!(usize, 4, false, TypeInfo::U32);
212impl_nums!(u64, 8, false, TypeInfo::U64);
213
214impl_nums!(i8 , 1, true, TypeInfo::I8);
215impl_nums!(i16, 2, true, TypeInfo::I16);
216impl_nums!(i32, 4, true, TypeInfo::I32);
217impl_nums!(isize, 4, true, TypeInfo::I32);
218impl_nums!(i64, 8, true, TypeInfo::I64);
219
220impl Decode for bool {
221    const TYPE_INFO: TypeInfo = TypeInfo::Bool;
222    
223	fn top_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError> {
224        let bytes = input.flush()?;
225        match bytes.len() {
226            0 => Ok(false),
227            1 => match bytes[0] {
228                0 => Ok(false),
229                1 => Ok(true),
230                _ => Err(DecodeError::InvalidValue),
231            }
232            _ => Err(DecodeError::InputTooLong),
233        }
234    }
235    
236    fn dep_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError> {
237        match input.read_byte()? {
238            0 => Ok(false),
239            1 => Ok(true),
240            _ => Err(DecodeError::InvalidValue),
241        }
242    }
243}
244
245impl<T: Decode> Decode for Option<T> {
246	fn top_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError> {
247        if input.empty() {
248            Ok(None)
249        } else {
250            let result = Self::dep_decode(input);
251            if input.remaining_len() > 0 {
252                return Err(DecodeError::InputTooLong);
253            }
254            result
255        }
256    }
257    
258    fn dep_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError> {
259        match input.read_byte()? {
260			0 => Ok(None),
261			1 => Ok(Some(T::dep_decode(input)?)),
262			_ => Err(DecodeError::InvalidValue),
263		}
264    }
265}
266
267macro_rules! tuple_impls {
268    ($($len:expr => ($($n:tt $name:ident)+))+) => {
269        $(
270            impl<$($name),+> Decode for ($($name,)+)
271            where
272                $($name: Decode,)+
273            {
274                fn dep_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError> {
275                    let tuple = (
276                        $(
277                            $name::dep_decode(input)?,
278                        )+
279                    );
280                    Ok(tuple)
281                }
282            }
283        )+
284    }
285}
286
287tuple_impls! {
288    1 => (0 T0)
289    2 => (0 T0 1 T1)
290    3 => (0 T0 1 T1 2 T2)
291    4 => (0 T0 1 T1 2 T2 3 T3)
292    5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
293    6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
294    7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
295    8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
296    9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
297    10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
298    11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
299    12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
300    13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
301    14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
302    15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
303    16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
304}
305
306macro_rules! array_impls {
307    ($($n: tt,)+) => {
308        $(
309            impl<T: Decode> Decode for [T; $n] {
310				fn dep_decode<I: Input>(input: &mut I) -> Result<Self, DecodeError> {
311					let mut r = ArrayVec::new();
312					for _ in 0..$n {
313						r.push(T::dep_decode(input)?);
314					}
315					let i = r.into_inner();
316
317					match i {
318						Ok(a) => Ok(a),
319						Err(_) => Err(DecodeError::ArrayDecodeErr),
320					}
321				}
322            }
323        )+
324    }
325}
326
327array_impls!(
328	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
329	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
330	32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
331	52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
332	72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
333	92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
334	109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
335	125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
336	141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
337	157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,
338	173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
339	189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,
340	205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
341	221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236,
342	237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
343	253, 254, 255, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768,
344);
345
346////////////////////////////////////////////////////////////////////////////////
347
348#[cfg(test)]
349mod tests {
350    use super::*;
351	use super::super::test_struct::*;
352    use core::fmt::Debug;
353
354    fn deser_ok<V>(element: V, bytes: &[u8])
355    where
356        V: Decode + PartialEq + Debug + 'static,
357    {
358        let input = bytes.to_vec();
359        let deserialized: V = V::top_decode(&mut &input[..]).unwrap();
360        assert_eq!(deserialized, element);
361    }
362
363    #[test]
364    fn test_top_numbers_decompacted() {
365        // unsigned positive
366        deser_ok(5u8, &[5]);
367        deser_ok(5u16, &[5]);
368        deser_ok(5u32, &[5]);
369        deser_ok(5u64, &[5]);
370        deser_ok(5usize, &[5]);
371        // signed positive
372        deser_ok(5i8, &[5]);
373        deser_ok(5i16, &[5]);
374        deser_ok(5i32, &[5]);
375        deser_ok(5i64, &[5]);
376        deser_ok(5isize, &[5]);
377        // signed negative
378        deser_ok(-5i8, &[251]);
379        deser_ok(-5i16, &[251]);
380        deser_ok(-5i32, &[251]);
381        deser_ok(-5i64, &[251]);
382        deser_ok(-5isize, &[251]);
383    }
384
385    
386
387    #[test]
388    fn test_struct() {
389        let test = Test {
390            int: 1,
391            seq: [5, 6].to_vec(),
392            another_byte: 7,
393        };
394        deser_ok(test, &[0, 1, 0, 0, 0, 2, 5, 6, 7]);
395    }
396
397    #[test]
398    fn test_enum() {
399        let u = E::Unit;
400        let expected: &[u8] = &[/*variant index*/ 0, 0, 0, 0];
401        deser_ok(u, expected);
402
403        let n = E::Newtype(1);
404        let expected: &[u8] = &[/*variant index*/ 0, 0, 0, 1, /*data*/ 0, 0, 0, 1];
405        deser_ok(n, expected);
406
407        let t = E::Tuple(1, 2);
408        let expected: &[u8] = &[/*variant index*/ 0, 0, 0, 2, /*(*/ 0, 0, 0, 1, /*,*/ 0, 0, 0, 2 /*)*/];
409        deser_ok(t, expected);
410
411        let s = E::Struct { a: 1 };
412        let expected: &[u8] = &[/*variant index*/ 0, 0, 0, 3, /*data*/ 0, 0, 0, 1];
413        deser_ok(s, expected);
414    }
415}