rust_chain/serializer.rs
1use core::{
2 mem::size_of,
3};
4
5use crate::{
6 string::String,
7 vec::Vec,
8 vmapi::eosio::{
9 check,
10 slice_copy,
11 },
12 varint::VarUint32,
13};
14
15///
16/// The `Packer` trait provides methods for packing and unpacking values to and from byte arrays.
17///
18/// # Examples
19///
20/// ```
21/// use crate::rust_chain::serializer::{Encoder, Decoder, Packer};
22///
23/// let mut encoder = Encoder::new(4);
24/// let value = 123u32;
25/// value.pack(&mut encoder);
26///
27/// let mut decoder = Decoder::new(&encoder.get_bytes());
28/// let mut unpacked_value = 0u32;
29/// decoder.unpack(&mut unpacked_value);
30///
31/// assert_eq!(value, unpacked_value);
32/// ```
33pub trait Packer {
34 /// Returns the size of the packed representation of this value in bytes.
35 fn size(&self) -> usize;
36
37 /// Packs this value into the given `Encoder`.
38 ///
39 /// # Arguments
40 ///
41 /// * `enc` - The encoder to pack this value into.
42 ///
43 /// # Returns
44 ///
45 /// The number of bytes written to the encoder.
46 fn pack(&self, enc: &mut Encoder) -> usize;
47
48 /// Unpacks this value from the given byte array.
49 ///
50 /// # Arguments
51 ///
52 /// * `data` - The byte array to unpack this value from.
53 ///
54 /// # Returns
55 ///
56 /// The number of bytes read from the byte array.
57 fn unpack(&mut self, data: &[u8]) -> usize;
58}
59
60/// The `Encoder` struct provides methods for packing values that implement the `Packer` trait.
61///
62/// # Examples
63///
64/// ```
65/// use rust_chain::serializer::{Encoder, Packer};
66///
67/// let mut encoder = Encoder::new(4);
68/// let value = 123u32;
69///
70/// let bytes_written = value.pack(&mut encoder);
71/// assert_eq!(bytes_written, 4);
72///
73/// let packed_bytes = encoder.get_bytes();
74/// assert_eq!(packed_bytes, [123, 0, 0, 0]);
75/// ```
76pub struct Encoder {
77 buf: Vec<u8>,
78}
79
80impl Encoder {
81 /// Constructs a new `Encoder` with the given initial capacity.
82 ///
83 /// # Arguments
84 ///
85 /// * `size` - The initial capacity of the encoder in bytes.
86 ///
87 /// # Returns
88 ///
89 /// A new `Encoder` instance with the given initial capacity.
90 pub fn new(size: usize) -> Self {
91 Self {
92 buf: Vec::with_capacity(size)
93 }
94 }
95
96 /// Returns the packed bytes of this encoder as a byte array.
97 ///
98 /// # Returns
99 ///
100 /// A reference to the packed bytes of this encoder as a byte array.
101 pub fn get_bytes(&self) -> &[u8] {
102 &self.buf
103 }
104
105 /// Returns the number of packed bytes in this encoder.
106 ///
107 /// # Returns
108 ///
109 /// The number of packed bytes in this encoder.
110 pub fn get_size(&self) -> usize {
111 self.buf.len()
112 }
113
114 /// Allocates space in this encoder for packing a value of the given size.
115 ///
116 /// # Arguments
117 ///
118 /// * `size` - The number of bytes to allocate in this encoder.
119 ///
120 /// # Returns
121 ///
122 /// A mutable reference to the allocated
123 pub fn alloc(&mut self, size: usize) -> &mut [u8]
124 {
125 let old_size = self.buf.len();
126 self.buf.resize(old_size+size, 0u8);
127 &mut self.buf[old_size..]
128 }
129
130 /// Packs the given value using the encoder
131 ///
132 /// # Arguments
133 ///
134 /// * `value` - The value to be packed
135 ///
136 /// # Examples
137 ///
138 /// ```
139 /// use rust_chain::serializer::{Encoder, Packer};
140 ///
141 /// let data = Encoder::pack(&1234u32);
142 /// assert_eq!(data, vec![210, 4, 0, 0]);
143 /// ```
144 pub fn pack<T: Packer>(value: &T) -> Vec<u8>
145 {
146 // Create a new Encoder with the size of the value being packed
147 let mut enc = Self::new(value.size());
148 // Pack the value using the encoder
149 value.pack(&mut enc);
150 // Return the packed data as a vector of bytes
151 enc.get_bytes().to_vec()
152 }
153
154}
155
156/// A struct for unpacking packed data
157///
158/// # Examples
159///
160/// ```
161/// use crate::rust_chain::serializer::{Decoder, Packer};
162///
163/// let data = &vec![210, 4, 0, 0];
164/// let mut decoder = Decoder::new(&data);
165/// let mut value = 0u32;
166/// decoder.unpack(&mut value);
167/// assert_eq!(value, 1234);
168/// ```
169pub struct Decoder<'a> {
170 buf: &'a [u8],
171 pos: usize
172}
173
174/// A struct for unpacking packed data
175impl<'a> Decoder<'a> {
176
177 /// Creates a new `Decoder` instance from the given byte array.
178 pub fn new(data: &'a [u8]) -> Self {
179 Self {
180 buf: data, pos: 0
181 }
182 }
183
184 /// Unpacks the given value from the decoder
185 pub fn unpack<T>(&mut self, packer: &mut T) -> usize
186 where T: Packer,
187 {
188 let size = packer.unpack(&self.buf[self.pos..]);
189 self.pos += size;
190 size
191 }
192
193 /// Returns the current position of the decoder
194 pub fn get_pos(&self) -> usize {
195 self.pos
196 }
197
198}
199
200/// A trait for packing and unpacking values
201///
202macro_rules! impl_packed {
203 ( $ty:ident ) => {
204 impl Packer for $ty {
205 /// Returns the size of this value in bytes.
206 fn size(&self) -> usize {
207 size_of::<$ty>()
208 }
209
210 /// Packs this value into the given encoder.
211 fn pack(&self, enc: &mut Encoder) -> usize {
212 let data = enc.alloc(size_of::<$ty>());
213 let src = self.to_le_bytes();
214 slice_copy(data, &src);
215 self.size()
216 }
217
218 /// Unpacks this value from the given data.
219 fn unpack(&mut self, data: &[u8]) -> usize {
220 check(data.len() >= self.size(), "number: buffer overflow");
221 *self = $ty::from_le_bytes(data[..self.size()].try_into().unwrap());
222 size_of::<$ty>()
223 }
224 }
225 };
226}
227
228/// Implement`Packer` for bool type.
229impl Packer for bool {
230 fn size(&self) -> usize {
231 1usize
232 }
233
234 /// Packs this value into the given encoder.
235 fn pack(&self, enc: &mut Encoder) -> usize {
236 let data = enc.alloc(self.size());
237 if *self {
238 data[0] = 1u8;
239 } else {
240 data[0] = 0u8;
241 }
242 self.size()
243 }
244
245 /// Unpacks this value from the given data.
246 fn unpack(&mut self, data: &[u8]) -> usize {
247 check(data.len() >= self.size(), "bool::unpack: buffer overflow");
248 if data[0] == 1 {
249 *self = true;
250 } else if data[0] == 0 {
251 *self = false;
252 } else {
253 check(false, "bool::unpack: invalid raw bool value");
254 }
255 self.size()
256 }
257}
258
259/// Implement `Packer` for i8 type.
260impl Packer for i8 {
261
262 /// Returns the size of this value in bytes.
263 fn size(&self) -> usize {
264 1usize
265 }
266
267 /// Packs this value into the given encoder.
268 fn pack(&self, enc: &mut Encoder) -> usize {
269 let data = enc.alloc(self.size());
270 data[0] = *self as u8;
271 self.size()
272 }
273
274 /// Unpacks this value from the given data.
275 fn unpack(&mut self, data: &[u8]) -> usize {
276 check(data.len() >= self.size(), "i8::unpack: buffer overflow");
277 *self = data[0] as i8;
278 self.size()
279 }
280}
281
282/// Implement `Packer` for u8 type.
283impl Packer for u8 {
284
285 /// Returns the size of this value in bytes.
286 fn size(&self) -> usize {
287 1usize
288 }
289
290 /// Packs this value into the given encoder.
291 fn pack(&self, enc: &mut Encoder) -> usize {
292 let data = enc.alloc(self.size());
293 data[0] = *self;
294 self.size()
295 }
296
297 /// Unpacks this value from the given data.
298 fn unpack(&mut self, data: &[u8]) -> usize {
299 check(data.len() >= self.size(), "u8::unpack: buffer overflow");
300 *self = data[0];
301 self.size()
302 }
303}
304
305impl_packed!(i16);
306impl_packed!(u16);
307impl_packed!(i32);
308impl_packed!(u32);
309impl_packed!(i64);
310impl_packed!(u64);
311impl_packed!(i128);
312impl_packed!(u128);
313impl_packed!(f32);
314impl_packed!(f64);
315
316/// Implement `Packer` for `String` type.
317impl Packer for String {
318
319 /// Returns the size of this value in bytes.
320 fn size(&self) -> usize {
321 VarUint32::new(self.len() as u32).size() + self.len()
322 }
323
324 /// Packs this value into the given encoder.
325 fn pack(&self, enc: &mut Encoder) -> usize {
326 let pos = enc.get_size();
327
328 let raw = self.as_bytes();
329
330 let n = VarUint32::new(raw.len() as u32);
331 n.pack(enc);
332
333 let data = enc.alloc(raw.len());
334 slice_copy(data, raw);
335
336 enc.get_size() - pos
337 }
338
339 /// Unpacks this value from the given data.
340 fn unpack(&mut self, data: &[u8]) -> usize {
341 let mut length = VarUint32{n: 0};
342 let size = length.unpack(data);
343 if let Ok(s) = String::from_utf8(data[size..size+length.value() as usize].to_vec()) {
344 *self = s;
345 } else {
346 check(false, "invalid utf8 string");
347 }
348 size + length.value() as usize
349 }
350}
351
352/// Implement `Packer` for `Vec<T>` type.
353impl<T> Packer for Vec<T> where T: Packer + Default {
354 /// Returns the size of this value in bytes.
355 fn size(&self) -> usize {
356 if self.len() == 0 {
357 return 1;
358 }
359
360 let mut size: usize = 0;
361 for i in 0..self.len() {
362 size += self[i].size();
363 }
364 VarUint32::new(size as u32).size() + size
365 }
366
367 /// Packs this value into the given encoder.
368 fn pack(&self, enc: &mut Encoder) -> usize {
369 let pos = enc.get_size();
370 let len = VarUint32{n: self.len() as u32};
371 len.pack(enc);
372 for v in self {
373 v.pack(enc);
374 }
375 enc.get_size() - pos
376 }
377
378 /// Unpacks this value from the given data.
379 fn unpack(&mut self, data: &[u8]) -> usize {
380 let mut dec = Decoder::new(data);
381 let mut size = VarUint32{n: 0};
382 dec.unpack(&mut size);
383 self.reserve(size.value() as usize);
384 for _ in 0..size.value() {
385 let mut v: T = Default::default();
386 dec.unpack(&mut v);
387 self.push(v);
388 }
389 dec.get_pos()
390 }
391}
392
393/// Implement `Packer` for `Option<T>` type.
394impl<T> Packer for Option<T> where T: Packer + Default {
395
396 /// Returns the size of this value in bytes.
397 fn size(&self) -> usize {
398 match self {
399 Some(x) => 1 + x.size(),
400 None => 1,
401 }
402 }
403
404 /// Packs this value into the given encoder.
405 fn pack(&self, enc: &mut Encoder) -> usize {
406 let pos = enc.get_size();
407 match self {
408 Some(x) => {
409 1u8.pack(enc);
410 x.pack(enc);
411 }
412 None => {
413 0u8.pack(enc);
414 }
415 }
416 enc.get_size() - pos
417 }
418
419 /// Unpacks this value from the given data.
420 fn unpack(&mut self, data: &[u8]) -> usize {
421 let mut dec = Decoder::new(data);
422 let mut ty: u8 = 0;
423 let mut value: T = Default::default();
424 dec.unpack(&mut ty);
425 if ty == 0 {
426 *self = None;
427 return 1;
428 }
429
430 check(ty == 1, "bad option type!");
431
432 dec.unpack(&mut value);
433 *self = Some(value);
434 dec.get_pos()
435 }
436}