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(
240 "Couldn't parse PUSHINT OpCode".to_string(),
241 ))
242 },
243 };
244
245 let bytes = self.read_bytes(count)?;
246 Ok(BigInt::from_signed_bytes_be(&bytes))
247 }
248
249 pub fn read_push_string(&mut self) -> Result<String, CodecError> {
251 let bytes = self.read_push_bytes()?;
252 String::from_utf8(Vec::from(bytes))
253 .map_err(|_| CodecError::InvalidEncoding("Invalid UTF-8".to_string()))
254 }
255
256 pub fn read_serializable<T: NeoSerializable>(&mut self) -> Result<T, CodecError> {
258 T::decode(self).map_err(|_e| CodecError::InvalidFormat)
259 }
260
261 pub fn read_serializable_list<T: NeoSerializable>(&mut self) -> Result<Vec<T>, CodecError> {
263 let len = self.read_var_int()?;
264 let mut list = Vec::with_capacity(len as usize);
265 for _ in 0..len {
266 T::decode(self)
267 .map(|item| list.push(item))
268 .map_err(|_| CodecError::InvalidFormat)?;
269 }
270 Ok(list)
271 }
272
273 pub fn read_serializable_list_var_bytes<T: NeoSerializable>(
274 &mut self,
275 ) -> Result<Vec<T>, CodecError> {
276 let len = self.read_var_int()?;
277 let mut bytes_read = 0;
278 let offset = self.pointer;
279 let mut list = Vec::with_capacity(len as usize);
280 while bytes_read < len {
281 T::decode(self)
282 .map(|item| list.push(item))
283 .map_err(|_| CodecError::InvalidFormat)?;
284 bytes_read = (self.pointer - offset) as i64;
285 }
286 Ok(list)
287 }
288
289 pub fn mark(&mut self) {
290 self.marker = self.pointer;
291 }
292
293 pub fn reset(&mut self) {
294 self.pointer = self.marker;
295 }
296
297 pub fn available(&self) -> usize {
314 self.data.len() - self.pointer
315 }
316}
317
318#[cfg(test)]
319mod tests {
320 use crate::codec::Decoder;
321 use num_bigint::BigInt;
322
323 #[test]
324 fn test_read_push_data_bytes() {
325 let prefix_count_map = [
326 (hex::decode("0c01").unwrap(), 1),
327 (hex::decode("0cff").unwrap(), 255),
328 (hex::decode("0d0001").unwrap(), 256),
329 (hex::decode("0d0010").unwrap(), 4096),
330 (hex::decode("0e00000100").unwrap(), 65536),
331 ];
332
333 for (prefix, count) in prefix_count_map {
334 let bytes = vec![1u8; count];
335 let data = [prefix.as_slice(), bytes.as_slice()].concat();
336 assert_eq!(Decoder::new(&data).read_push_bytes().unwrap(), bytes);
337 }
338 }
339
340 #[test]
341 fn test_fail_read_push_data() {
342 let data = hex::decode("4b010000").unwrap();
343 let err = Decoder::new(&data).read_push_bytes().unwrap_err();
344 assert_eq!(err.to_string(), "Invalid op code")
345 }
346
347 #[test]
348 fn test_read_push_data_string() {
349 let empty = hex::decode("0c00").unwrap();
350 assert_eq!(Decoder::new(&empty).read_push_string().unwrap(), "");
351
352 let a = hex::decode("0c0161").unwrap();
353 assert_eq!(Decoder::new(&a).read_push_string().unwrap(), "a");
354
355 let bytes = vec![0u8; 10000];
356 let input = [hex::decode("0e10270000").unwrap(), bytes.as_slice().to_vec()].concat();
357 let expected = String::from_utf8(bytes).unwrap();
358
359 assert_eq!(Decoder::new(&input).read_push_string().unwrap(), expected);
360 }
361
362 #[test]
363 fn test_read_push_data_big_integer() {
364 let zero = hex::decode("10").unwrap();
365 assert_eq!(Decoder::new(&zero).read_push_int().unwrap(), BigInt::from(0));
366
367 let one = hex::decode("11").unwrap();
368 assert_eq!(Decoder::new(&one).read_push_int().unwrap(), BigInt::from(1));
369
370 let minus_one = hex::decode("0f").unwrap();
371 assert_eq!(Decoder::new(&minus_one).read_push_int().unwrap(), BigInt::from(-1));
372
373 let sixteen = hex::decode("20").unwrap();
374 assert_eq!(Decoder::new(&sixteen).read_push_int().unwrap(), BigInt::from(16));
375 }
376
377 #[test]
378 fn test_read_u32() {
379 let max = [0xffu8; 4];
380 assert_eq!(Decoder::new(&max).read_u32().unwrap(), 4_294_967_295);
381
382 let one = hex::decode("01000000").unwrap();
383 assert_eq!(Decoder::new(&one).read_u32().unwrap(), 1);
384
385 let zero = [0u8; 4];
386 assert_eq!(Decoder::new(&zero).read_u32().unwrap(), 0);
387
388 let custom = hex::decode("8cae0000ff").unwrap();
389 assert_eq!(Decoder::new(&custom).read_u32().unwrap(), 44_684);
390 }
391
392 #[test]
393 fn test_read_i64() {
394 let min = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80];
395 assert_eq!(Decoder::new(&min).read_i64().unwrap(), i64::MIN);
396
397 let max = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f];
398 assert_eq!(Decoder::new(&max).read_i64().unwrap(), i64::MAX);
399
400 let zero = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
401 assert_eq!(Decoder::new(&zero).read_i64().unwrap(), 0);
402
403 let custom = [0x11, 0x33, 0x22, 0x8c, 0xae, 0x00, 0x00, 0x00, 0xff];
404 assert_eq!(Decoder::new(&custom).read_i64().unwrap(), 749_675_361_041);
405 }
406}