cml_crypto/chain_core/
mempack.rs

1use std::error::Error;
2use std::fmt;
3use std::num::{NonZeroU32, NonZeroU64};
4
5/// A local memory buffer to serialize data to
6pub struct WriteBuf(Vec<u8>);
7
8impl WriteBuf {
9    pub fn new() -> Self {
10        WriteBuf(Vec::new())
11    }
12
13    pub fn put_u8(&mut self, v: u8) {
14        self.0.push(v)
15    }
16    pub fn put_u16(&mut self, v: u16) {
17        self.0.extend_from_slice(&v.to_be_bytes())
18    }
19    pub fn put_u32(&mut self, v: u32) {
20        self.0.extend_from_slice(&v.to_be_bytes())
21    }
22    pub fn put_u64(&mut self, v: u64) {
23        self.0.extend_from_slice(&v.to_be_bytes())
24    }
25    pub fn put_u128(&mut self, v: u128) {
26        self.0.extend_from_slice(&v.to_be_bytes())
27    }
28    pub fn put_bytes(&mut self, v: &[u8]) {
29        self.0.extend_from_slice(v)
30    }
31}
32
33impl Default for WriteBuf {
34    fn default() -> Self {
35        Self::new()
36    }
37}
38
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub enum ReadError {
41    /// Return the number of bytes left and the number of bytes demanded
42    NotEnoughBytes(usize, usize),
43    /// Data is left in the buffer
44    UnconsumedData(usize),
45    /// Expecting a size that is above the limit
46    SizeTooBig(usize, usize),
47    /// Structure of data is not what it should be
48    StructureInvalid(String),
49    /// Unknown enumeration tag
50    UnknownTag(u32),
51}
52
53impl fmt::Display for ReadError {
54    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55        match self {
56            ReadError::NotEnoughBytes(left, demanded) => write!(
57                f,
58                "NotEnoughBytes: demanded {demanded} bytes but got {left}"
59            ),
60            ReadError::UnconsumedData(len) => write!(f, "Unconsumed data: {len} bytes left"),
61            ReadError::SizeTooBig(e, limit) => write!(
62                f,
63                "Ask for number of elements {e} above expected limit value: {limit}"
64            ),
65            ReadError::StructureInvalid(s) => write!(f, "Structure invalid: {s}"),
66            ReadError::UnknownTag(t) => write!(f, "Unknown tag: {t}"),
67        }
68    }
69}
70
71impl Error for ReadError {}
72
73/// A local memory slice to read from memory
74pub struct ReadBuf<'a> {
75    offset: usize,
76    data: &'a [u8],
77    //trace: Vec<(usize, String)>,
78}
79
80impl<'a> ReadBuf<'a> {
81    /// Create a readbuf from a slice
82    pub fn from(slice: &'a [u8]) -> Self {
83        ReadBuf {
84            offset: 0,
85            data: slice,
86            //trace: Vec::new(),
87        }
88    }
89
90    pub fn position(&self) -> usize {
91        self.offset
92    }
93
94    fn left(&self) -> usize {
95        self.data.len() - self.offset
96    }
97
98    fn assure_size(&self, expected: usize) -> Result<(), ReadError> {
99        let left = self.left();
100        if left >= expected {
101            Ok(())
102        } else {
103            dbg!(self.debug());
104            Err(ReadError::NotEnoughBytes(left, expected))
105        }
106    }
107
108    /// Check if everything has been properly consumed
109    pub fn expect_end(&mut self) -> Result<(), ReadError> {
110        let l = self.left();
111        if l == 0 {
112            Ok(())
113        } else {
114            Err(ReadError::UnconsumedData(l))
115        }
116    }
117
118    /// Check if we reach the end of the buffer
119    pub fn is_end(&self) -> bool {
120        self.left() == 0
121    }
122
123    /// Skip a number of bytes from the buffer.
124    pub fn skip_bytes(&mut self, sz: usize) -> Result<(), ReadError> {
125        self.assure_size(sz)?;
126        self.offset += sz;
127        Ok(())
128    }
129
130    /// Return a slice of the next bytes from the buffer
131    pub fn get_slice(&mut self, sz: usize) -> Result<&'a [u8], ReadError> {
132        self.assure_size(sz)?;
133        let s = &self.data[self.offset..self.offset + sz];
134        self.offset += sz;
135        Ok(s)
136    }
137
138    pub fn get_slice_end(&mut self) -> &'a [u8] {
139        let s = &self.data[self.offset..];
140        self.offset = self.data.len();
141        s
142    }
143
144    pub fn into_slice_mut(&mut self, slice: &mut [u8]) -> Result<(), ReadError> {
145        let s = self.get_slice(slice.len())?;
146        slice.copy_from_slice(s);
147        Ok(())
148    }
149
150    /// Return a sub-buffer ending at the given byte offset
151    pub fn split_to(&mut self, sz: usize) -> Result<ReadBuf<'a>, ReadError> {
152        let slice = self.get_slice(sz)?;
153        Ok(ReadBuf::from(slice))
154    }
155
156    /// Peek at the next u8 from the buffer. the cursor is **not** advanced to the next byte.
157    pub fn peek_u8(&mut self) -> Result<u8, ReadError> {
158        self.assure_size(1)?;
159        let v = self.data[self.offset];
160        Ok(v)
161    }
162
163    /// Return the next u8 from the buffer
164    pub fn get_u8(&mut self) -> Result<u8, ReadError> {
165        self.assure_size(1)?;
166        let v = self.data[self.offset];
167        self.offset += 1;
168        Ok(v)
169    }
170
171    /// Return the next u16 from the buffer
172    pub fn get_u16(&mut self) -> Result<u16, ReadError> {
173        const SIZE: usize = 2;
174        let mut buf = [0u8; SIZE];
175        buf.copy_from_slice(self.get_slice(SIZE)?);
176        Ok(u16::from_be_bytes(buf))
177    }
178
179    /// Return the next u32 from the buffer
180    pub fn get_u32(&mut self) -> Result<u32, ReadError> {
181        const SIZE: usize = 4;
182        let mut buf = [0u8; SIZE];
183        buf.copy_from_slice(self.get_slice(SIZE)?);
184        Ok(u32::from_be_bytes(buf))
185    }
186
187    pub fn get_nz_u32(&mut self) -> Result<NonZeroU32, ReadError> {
188        let v = self.get_u32()?;
189        NonZeroU32::new(v).ok_or(ReadError::StructureInvalid("received zero u32".to_string()))
190    }
191
192    /// Return the next u64 from the buffer
193    pub fn get_u64(&mut self) -> Result<u64, ReadError> {
194        const SIZE: usize = 8;
195        let mut buf = [0u8; SIZE];
196        buf.copy_from_slice(self.get_slice(SIZE)?);
197        Ok(u64::from_be_bytes(buf))
198    }
199
200    pub fn get_nz_u64(&mut self) -> Result<NonZeroU64, ReadError> {
201        let v = self.get_u64()?;
202        NonZeroU64::new(v).ok_or(ReadError::StructureInvalid("received zero u64".to_string()))
203    }
204
205    /// Return the next u128 from the buffer
206    pub fn get_u128(&mut self) -> Result<u128, ReadError> {
207        const SIZE: usize = 16;
208        let mut buf = [0u8; SIZE];
209        buf.copy_from_slice(self.get_slice(SIZE)?);
210        Ok(u128::from_be_bytes(buf))
211    }
212
213    /*
214    pub fn trace(&mut self, s: &str) {
215        self.trace.push((self.offset, s.to_string()))
216    }
217    */
218
219    pub fn debug(&self) -> String {
220        let mut s = String::new();
221        for (i, x) in self.data.iter().enumerate() {
222            //self.trace.iter().find(|(ofs,_)| ofs == &i).map(|(_,name)| { s.push_str(&name); s.push(' ') });
223            if i == self.offset {
224                s.push_str(".. ");
225            }
226            let bytes = format!("{x:02x} ");
227            s.push_str(&bytes);
228        }
229        s
230    }
231}
232
233pub trait Readable: Sized {
234    fn read(buf: &mut ReadBuf) -> Result<Self, ReadError>;
235
236    fn read_validate(buf: &mut ReadBuf) -> Result<(), ReadError> {
237        Self::read(buf).map(|_| ())
238    }
239}
240
241impl Readable for () {
242    fn read(_: &mut ReadBuf) -> Result<(), ReadError> {
243        Ok(())
244    }
245    fn read_validate(buf: &mut ReadBuf) -> Result<(), ReadError> {
246        Self::read(buf)
247    }
248}
249
250macro_rules! read_prim_impl {
251    ($Ty: ty, $meth: ident) => {
252        impl Readable for $Ty {
253            fn read(buf: &mut ReadBuf) -> Result<Self, ReadError> {
254                buf.$meth()
255            }
256        }
257    };
258}
259
260read_prim_impl! { u8, get_u8 }
261read_prim_impl! { u16, get_u16 }
262read_prim_impl! { u32, get_u32 }
263read_prim_impl! { u64, get_u64 }
264read_prim_impl! { u128, get_u128 }
265
266macro_rules! read_array_impls {
267    ($($N: expr)+) => {
268        $(
269        impl Readable for [u8; $N] {
270            fn read(readbuf: &mut ReadBuf) -> Result<Self, ReadError> {
271                let mut buf = [0u8; $N];
272                buf.copy_from_slice(readbuf.get_slice($N)?);
273                Ok(buf)
274            }
275        }
276        )+
277    };
278}
279
280read_array_impls! {
281    4 8 12 16 20 24 28 32 64 96 128
282}
283
284/// read N times for a T elements in sequences
285pub fn read_vec<T: Readable>(readbuf: &mut ReadBuf, n: usize) -> Result<Vec<T>, ReadError> {
286    let mut v = Vec::with_capacity(n);
287    for _ in 0..n {
288        let t = T::read(readbuf)?;
289        v.push(t)
290    }
291    Ok(v)
292}
293
294/// Fill a mutable slice with as many T as filling requires
295pub fn read_mut_slice<T: Readable>(readbuf: &mut ReadBuf, v: &mut [T]) -> Result<(), ReadError> {
296    for elem in v.iter_mut() {
297        let t = T::read(readbuf)?;
298        *elem = t
299    }
300    Ok(())
301}
302
303/// Transform a raw buffer into a Header
304pub fn read_from_raw<T: Readable>(raw: &[u8]) -> Result<T, std::io::Error> {
305    let mut rbuf = ReadBuf::from(raw);
306    match T::read(&mut rbuf) {
307        Err(e) => Err(std::io::Error::new(
308            std::io::ErrorKind::InvalidData,
309            format!("invalid data {e:?} {raw:?}"),
310        )),
311        Ok(h) => match rbuf.expect_end() {
312            Err(e) => Err(std::io::Error::new(
313                std::io::ErrorKind::InvalidData,
314                format!("end of data {e:?}"),
315            )),
316            Ok(()) => Ok(h),
317        },
318    }
319}