cml_crypto/chain_core/
mempack.rs1use std::error::Error;
2use std::fmt;
3use std::num::{NonZeroU32, NonZeroU64};
4
5pub 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 NotEnoughBytes(usize, usize),
43 UnconsumedData(usize),
45 SizeTooBig(usize, usize),
47 StructureInvalid(String),
49 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
73pub struct ReadBuf<'a> {
75 offset: usize,
76 data: &'a [u8],
77 }
79
80impl<'a> ReadBuf<'a> {
81 pub fn from(slice: &'a [u8]) -> Self {
83 ReadBuf {
84 offset: 0,
85 data: slice,
86 }
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 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 pub fn is_end(&self) -> bool {
120 self.left() == 0
121 }
122
123 pub fn skip_bytes(&mut self, sz: usize) -> Result<(), ReadError> {
125 self.assure_size(sz)?;
126 self.offset += sz;
127 Ok(())
128 }
129
130 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 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 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 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 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 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 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 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 pub fn debug(&self) -> String {
220 let mut s = String::new();
221 for (i, x) in self.data.iter().enumerate() {
222 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
284pub 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
294pub 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
303pub 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}