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