eosio_chain/
serializer.rs

1use crate::{
2    vec,
3    vec::Vec,
4};
5
6use core::mem::{
7    size_of
8};
9
10use crate::vmapi::eosio::{
11    eosio_memcpy,
12    check,
13};
14
15use crate::varint::{
16    VarUint32,
17};
18
19// use crate::{
20//     eosio_println,
21// };
22
23// use crate::print::{
24//     Printable,
25//     prints,
26// };
27
28///
29pub trait Packer {
30    ///
31    fn size(&self) -> usize;
32    ///
33    fn pack(&self) -> Vec<u8>;
34    ///
35    fn unpack(&mut self, data: &[u8]) -> usize;
36}
37
38
39macro_rules! impl_packed {
40    ( $ty:ident ) => {
41        impl Packer for $ty {
42            fn size(&self) -> usize {
43                size_of::<$ty>()
44            }
45        
46            fn pack(&self) -> Vec<u8> {
47                let ptr: *const $ty = self;
48                let mut data: Vec<u8> = Vec::with_capacity(size_of::<$ty>());
49                data.resize_with(size_of::<$ty>(), Default::default);
50                eosio_memcpy(data.as_mut_ptr(), ptr as *mut u8, size_of::<$ty>());
51                return data;
52            }
53        
54            fn unpack(&mut self, data: &[u8]) -> usize {
55                check(data.len() >= self.size(), "number: buffer overflow");
56                let ptr: *const $ty = self;
57                eosio_memcpy(ptr as *mut u8, data.as_ptr(), size_of::<$ty>());
58                return size_of::<$ty>();
59            }
60        }
61    };
62}
63
64impl_packed!(bool);
65impl_packed!(i8);
66impl_packed!(u8);
67
68impl_packed!(i16);
69impl_packed!(u16);
70
71impl_packed!(i32);
72impl_packed!(u32);
73
74impl_packed!(i64);
75impl_packed!(u64);
76
77impl_packed!(i128);
78impl_packed!(u128);
79
80impl_packed!(f32);
81impl_packed!(f64);
82
83///
84pub struct Encoder {
85    buf: Vec<u8>,
86}
87
88impl Encoder {
89    ///
90    pub fn new(size: usize) -> Self {
91        Self {
92            buf: Vec::with_capacity(size)
93        }
94    }
95    
96    ///
97    pub fn get_bytes(&self) -> Vec<u8> {
98        return self.buf[0..].to_vec();
99    }
100
101    ///
102    pub fn pack<T>(&mut self, value: &T) -> usize 
103    where T: Packer,
104    {
105        let mut data = value.pack();
106        self.buf.append(&mut data);
107        return data.len();
108    }
109
110    ///
111    pub fn pack_number<T>(&mut self, n: T) -> usize {
112        let size: usize = size_of::<T>();
113        let vec_size = self.buf.len();
114        self.buf.resize_with(vec_size + size, Default::default);
115        eosio_memcpy(self.buf[vec_size..].as_mut_ptr(), &n as *const T as *const u8, size);
116        return size;
117    }
118}
119
120///
121pub struct Decoder<'a> {
122    buf: &'a [u8],
123    pos: usize
124}
125
126impl<'a> Decoder<'a> {
127    ///
128    pub fn new(data: &'a [u8]) -> Self {
129        Self {
130            buf: data, pos: 0
131        }
132    }
133
134    ///
135    pub fn unpack<T>(&mut self, packer: &mut T) -> usize
136    where T: Packer,
137    {
138        let size = packer.unpack(&self.buf[self.pos..]);
139        self.pos += size;
140        return size;
141    }
142
143    ///
144    pub fn unpack_number<T>(&mut self) -> T 
145    where T: Default
146    {
147        let size: usize = size_of::<T>();
148        let n = T::default();
149        check(self.pos + size <= self.buf.len(), "Decoder::unpack_number: buffer overflow!");
150        eosio_memcpy(&n as *const T as *mut T as *mut u8, self.buf[self.pos..].as_ptr(), size);
151        self.pos += size;
152        return n;
153    }
154
155    ///
156    pub fn get_pos(&self) -> usize {
157        return self.pos;
158    }
159
160}
161
162use crate::{
163    string::String,
164};
165
166impl Packer for String {
167    ///
168    fn size(&self) -> usize {
169        return VarUint32::new(self.len() as u32).size() + self.len();
170    }
171
172    ///
173    fn pack(&self) -> Vec<u8> {
174        let raw = self.as_bytes().to_vec();
175        return raw.pack();
176    }
177
178    ///
179    fn unpack(&mut self, data: &[u8]) -> usize {
180        let mut length = VarUint32{n: 0};
181        let size = length.unpack(data);
182        if let Ok(s) = String::from_utf8(data[size..size+length.value() as usize].to_vec()) {
183            *self = s;
184        } else {
185            check(false, "invalid utf8 string");
186        }
187        return size + length.value() as usize;
188    }
189}
190
191impl<T> Packer for Vec<T> where T: Packer + Default {
192    ///
193    fn size(&self) -> usize {
194        if self.len() == 0 {
195            return 1;
196        }
197
198        let mut size: usize = 0;
199        for i in 0..self.len() {
200            size += self[i].size();
201        }
202        return VarUint32::new(size as u32).size() + size;
203    }
204
205    ///
206    fn pack(&self) -> Vec<u8> {
207        let len = VarUint32 { n: self.len() as u32};
208        let mut enc = Encoder::new(self.size());
209        enc.pack(&len);
210        for v in self {
211            enc.pack(v);
212        }
213        return enc.get_bytes();
214    }
215
216    ///
217    fn unpack(&mut self, data: &[u8]) -> usize {
218        let mut dec = Decoder::new(data);
219        let mut size = VarUint32{n: 0};
220        dec.unpack(&mut size);
221        self.reserve(size.value() as usize);
222        for _ in 0..size.value() {
223            let mut v: T = Default::default();
224            dec.unpack(&mut v);
225            self.push(v);
226        }
227        return dec.get_pos();
228    }
229}
230
231impl<T> Packer for Option<T> where T: Packer + Default {
232    ///
233    fn size(&self) -> usize {
234        match self {
235            Some(x) => 1 + x.size(),
236            None => 1,
237        }
238    }
239
240    ///
241    fn pack(&self) -> Vec<u8> {
242        match self {
243            Some(x) => {
244                let mut enc = Encoder::new(1 + x.size());
245                enc.pack_number(1u8);
246                enc.get_bytes()
247            }
248            None => {
249                vec![0]
250            }
251        }
252    }
253
254    ///
255    fn unpack(&mut self, data: &[u8]) -> usize {
256        let mut dec = Decoder::new(data);
257        let mut ty: u8 = 0;
258        let mut value: T = Default::default();
259        dec.unpack(&mut ty);
260        if ty == 0 {
261            return 1;
262        }
263
264        check(ty == 1, "bad option type!");
265
266        dec.unpack(&mut value);
267        if ty == 0 {
268            *self = None;
269        } else {
270            *self = Some(value);
271        }
272        dec.get_pos()
273    }
274}