1use crate::{
2 codec::{CodecError, NeoSerializable},
3 OpCode,
4};
5use getset::{Getters, Setters};
22use num_bigint::{BigInt, Sign};
23use serde::Deserialize;
24use serde_derive::Serialize;
25
26#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, Getters, Setters)]
28pub struct Decoder<'a> {
29 data: &'a [u8],
30 #[getset(get = "pub")]
31 pointer: usize,
32 marker: usize,
33}
34
35impl<'a> Iterator for Decoder<'a> {
36 type Item = u8;
37
38 fn next(&mut self) -> Option<Self::Item> {
40 if self.pointer < self.data.len() {
41 let val = self.data[self.pointer];
42 self.pointer += 1;
43 Some(val)
44 } else {
45 None
46 }
47 }
48}
49
50impl<'a> Decoder<'a> {
51 pub fn new(data: &'a [u8]) -> Self {
53 Self { data, pointer: 0, marker: 0 }
54 }
55
56 pub fn read_bool(&mut self) -> bool {
58 let val = self.data[self.pointer] == 1;
59 self.pointer += 1;
60 val
61 }
62
63 pub fn read_u8(&mut self) -> u8 {
65 let val = self.data[self.pointer];
66 self.pointer += 1;
67 val
68 }
69
70 pub fn read_u16(&mut self) -> Result<u16, CodecError> {
72 let bytes = self.read_bytes(2)?;
73 bytes
74 .try_into()
75 .map(u16::from_ne_bytes)
76 .map_err(|_| CodecError::InvalidEncoding("Failed to convert bytes to u16".to_string()))
77 }
78
79 pub fn read_i16(&mut self) -> Result<i16, CodecError> {
81 let bytes = self.read_bytes(2)?;
82 bytes
83 .try_into()
84 .map(i16::from_ne_bytes)
85 .map_err(|_| CodecError::InvalidEncoding("Failed to convert bytes to i16".to_string()))
86 }
87
88 pub fn read_u32(&mut self) -> Result<u32, CodecError> {
90 let bytes = self.read_bytes(4)?;
91 bytes
92 .try_into()
93 .map(u32::from_ne_bytes)
94 .map_err(|_| CodecError::InvalidEncoding("Failed to convert bytes to u32".to_string()))
95 }
96
97 pub fn read_i32(&mut self) -> Result<i32, CodecError> {
99 let bytes = self.read_bytes(4)?;
100 bytes
101 .try_into()
102 .map(i32::from_ne_bytes)
103 .map_err(|_| CodecError::InvalidEncoding("Failed to convert bytes to i32".to_string()))
104 }
105
106 pub fn read_u64(&mut self) -> Result<u64, CodecError> {
108 let bytes = self.read_bytes(8)?;
109 bytes
110 .try_into()
111 .map(u64::from_ne_bytes)
112 .map_err(|_| CodecError::InvalidEncoding("Failed to convert bytes to u64".to_string()))
113 }
114
115 pub fn read_i64(&mut self) -> Result<i64, CodecError> {
117 let bytes = self.read_bytes(8)?;
118 bytes
119 .try_into()
120 .map(i64::from_ne_bytes)
121 .map_err(|_| CodecError::InvalidEncoding("Failed to convert bytes to i64".to_string()))
122 }
123
124 pub fn read_bigint(&mut self) -> Result<BigInt, CodecError> {
125 let byte = self.read_u8();
126
127 let negative = byte & 0x80 != 0;
128 let len = match byte {
129 0..=0x4b => 1,
130 0x4c => self.read_u8() as usize,
131 0x4d => self.read_u16()? as usize,
132 0x4e => self.read_u32()? as usize,
133 _ => return Err(CodecError::InvalidFormat),
134 };
135
136 let bytes = self.read_bytes(len)?;
137 if negative {
138 if let Some(byte) = bytes.to_owned().get_mut(len - 1) {
140 *byte ^= 0x80;
141 } else {
142 return Err(CodecError::InvalidFormat);
143 }
144 }
146 let sign = if negative { Sign::Minus } else { Sign::Plus };
149 Ok(BigInt::from_bytes_le(sign, &bytes))
150 }
151
152 pub fn read_encoded_ec_point(&mut self) -> Result<Vec<u8>, CodecError> {
154 let byte = self.read_u8();
155 match byte {
156 0x02 | 0x03 => self.read_bytes(32),
157 _ => Err(CodecError::InvalidEncoding("Invalid encoded EC point".to_string())),
158 }
159 }
160
161 pub fn read_bytes(&mut self, length: usize) -> Result<Vec<u8>, CodecError> {
163 if self.pointer + length > self.data.len() {
164 return Err(CodecError::IndexOutOfBounds("Read beyond end of buffer".to_string()));
165 }
166 let result = self.data[self.pointer..self.pointer + length].to_vec();
167 self.pointer += length;
168 Ok(result)
169 }
170
171 pub fn read_var_bytes(&mut self) -> Result<Vec<u8>, CodecError> {
173 let len = self.read_var_int()? as usize;
174 self.read_bytes(len)
175 }
176
177 pub fn read_var_int(&mut self) -> Result<i64, CodecError> {
179 let first = self.read_u8();
180 match first {
181 0xfd => self.read_i16().map(|v| v as i64),
182 0xfe => self.read_i32().map(|v| v as i64),
183 0xff => self.read_i64(),
184 _ => Ok(first as i64),
185 }
186 }
187
188 pub fn read_var_string(&mut self) -> Result<String, CodecError> {
189 let bytes = self.read_var_bytes()?;
190
191 let string = match String::from_utf8(bytes.to_vec()) {
192 Ok(s) => s,
193 Err(e) => {
194 return Err(CodecError::InvalidEncoding(e.to_string()))
196 },
197 };
198
199 let string = string.trim_end_matches(char::from(0));
201
202 Ok(string.to_string())
203 }
204
205 pub fn read_push_bytes(&mut self) -> Result<Vec<u8>, CodecError> {
207 let opcode = self.read_u8();
208 let len =
209 match OpCode::try_from(opcode)? {
210 OpCode::PushData1 => self.read_u8() as usize,
211 OpCode::PushData2 => self.read_i16().map_err(|e| {
212 CodecError::InvalidEncoding(format!("Failed to read i16: {}", e))
213 })? as usize,
214 OpCode::PushData4 => self.read_i32().map_err(|e| {
215 CodecError::InvalidEncoding(format!("Failed to read i32: {}", e))
216 })? as usize,
217 _ => return Err(CodecError::InvalidOpCode),
218 };
219
220 self.read_bytes(len)
221 }
222
223 pub fn read_push_int(&mut self) -> Result<BigInt, CodecError> {
225 let byte = self.read_u8();
226
227 if (OpCode::PushM1 as u8..=OpCode::Push16 as u8).contains(&byte) {
228 return Ok(BigInt::from(byte as i8 - OpCode::Push0 as i8));
229 }
230
231 let count = match OpCode::try_from(byte)? {
232 OpCode::PushInt8 => 1,
233 OpCode::PushInt16 => 2,
234 OpCode::PushInt32 => 4,
235 OpCode::PushInt64 => 8,
236 OpCode::PushInt128 => 16,
237 OpCode::PushInt256 => 32,
238 _ =>
239 return Err(CodecError::InvalidEncoding("Couldn't parse PUSHINT OpCode".to_string())),
240 };
241
242 let bytes = self.read_bytes(count)?;
243 Ok(BigInt::from_signed_bytes_be(&bytes))
244 }
245
246 pub fn read_push_string(&mut self) -> Result<String, CodecError> {
248 let bytes = self.read_push_bytes()?;
249 String::from_utf8(Vec::from(bytes))
250 .map_err(|_| CodecError::InvalidEncoding("Invalid UTF-8".to_string()))
251 }
252
253 pub fn read_serializable<T: NeoSerializable>(&mut self) -> Result<T, CodecError> {
255 T::decode(self).map_err(|_e| CodecError::InvalidFormat)
256 }
257
258 pub fn read_serializable_list<T: NeoSerializable>(&mut self) -> Result<Vec<T>, CodecError> {
260 let len = self.read_var_int()?;
261 let mut list = Vec::with_capacity(len as usize);
262 for _ in 0..len {
263 T::decode(self)
264 .map(|item| list.push(item))
265 .map_err(|_| CodecError::InvalidFormat)?;
266 }
267 Ok(list)
268 }
269
270 pub fn read_serializable_list_var_bytes<T: NeoSerializable>(
271 &mut self,
272 ) -> Result<Vec<T>, CodecError> {
273 let len = self.read_var_int()?;
274 let mut bytes_read = 0;
275 let offset = self.pointer;
276 let mut list = Vec::with_capacity(len as usize);
277 while bytes_read < len {
278 T::decode(self)
279 .map(|item| list.push(item))
280 .map_err(|_| CodecError::InvalidFormat)?;
281 bytes_read = (self.pointer - offset) as i64;
282 }
283 Ok(list)
284 }
285
286 pub fn mark(&mut self) {
287 self.marker = self.pointer;
288 }
289
290 pub fn reset(&mut self) {
291 self.pointer = self.marker;
292 }
293
294 pub fn available(&self) -> usize {
311 self.data.len() - self.pointer
312 }
313}
314
315#[cfg(test)]
316mod tests {
317 use crate::codec::Decoder;
318 use num_bigint::BigInt;
319
320 #[test]
321 fn test_read_push_data_bytes() {
322 let prefix_count_map = [
323 (hex::decode("0c01").unwrap(), 1),
324 (hex::decode("0cff").unwrap(), 255),
325 (hex::decode("0d0001").unwrap(), 256),
326 (hex::decode("0d0010").unwrap(), 4096),
327 (hex::decode("0e00000100").unwrap(), 65536),
328 ];
329
330 for (prefix, count) in prefix_count_map {
331 let bytes = vec![1u8; count];
332 let data = [prefix.as_slice(), bytes.as_slice()].concat();
333 assert_eq!(Decoder::new(&data).read_push_bytes().unwrap(), bytes);
334 }
335 }
336
337 #[test]
338 fn test_fail_read_push_data() {
339 let data = hex::decode("4b010000").unwrap();
340 let err = Decoder::new(&data).read_push_bytes().unwrap_err();
341 assert_eq!(err.to_string(), "Invalid op code")
342 }
343
344 #[test]
345 fn test_read_push_data_string() {
346 let empty = hex::decode("0c00").unwrap();
347 assert_eq!(Decoder::new(&empty).read_push_string().unwrap(), "");
348
349 let a = hex::decode("0c0161").unwrap();
350 assert_eq!(Decoder::new(&a).read_push_string().unwrap(), "a");
351
352 let bytes = vec![0u8; 10000];
353 let input = [hex::decode("0e10270000").unwrap(), bytes.as_slice().to_vec()].concat();
354 let expected = String::from_utf8(bytes).unwrap();
355
356 assert_eq!(Decoder::new(&input).read_push_string().unwrap(), expected);
357 }
358
359 #[test]
360 fn test_read_push_data_big_integer() {
361 let zero = hex::decode("10").unwrap();
362 assert_eq!(Decoder::new(&zero).read_push_int().unwrap(), BigInt::from(0));
363
364 let one = hex::decode("11").unwrap();
365 assert_eq!(Decoder::new(&one).read_push_int().unwrap(), BigInt::from(1));
366
367 let minus_one = hex::decode("0f").unwrap();
368 assert_eq!(Decoder::new(&minus_one).read_push_int().unwrap(), BigInt::from(-1));
369
370 let sixteen = hex::decode("20").unwrap();
371 assert_eq!(Decoder::new(&sixteen).read_push_int().unwrap(), BigInt::from(16));
372 }
373
374 #[test]
375 fn test_read_u32() {
376 let max = [0xffu8; 4];
377 assert_eq!(Decoder::new(&max).read_u32().unwrap(), 4_294_967_295);
378
379 let one = hex::decode("01000000").unwrap();
380 assert_eq!(Decoder::new(&one).read_u32().unwrap(), 1);
381
382 let zero = [0u8; 4];
383 assert_eq!(Decoder::new(&zero).read_u32().unwrap(), 0);
384
385 let custom = hex::decode("8cae0000ff").unwrap();
386 assert_eq!(Decoder::new(&custom).read_u32().unwrap(), 44_684);
387 }
388
389 #[test]
390 fn test_read_i64() {
391 let min = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80];
392 assert_eq!(Decoder::new(&min).read_i64().unwrap(), i64::MIN);
393
394 let max = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f];
395 assert_eq!(Decoder::new(&max).read_i64().unwrap(), i64::MAX);
396
397 let zero = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
398 assert_eq!(Decoder::new(&zero).read_i64().unwrap(), 0);
399
400 let custom = [0x11, 0x33, 0x22, 0x8c, 0xae, 0x00, 0x00, 0x00, 0xff];
401 assert_eq!(Decoder::new(&custom).read_i64().unwrap(), 749_675_361_041);
402 }
403}