neo3/neo_codec/
binary_decoder.rs

1use crate::{
2	codec::{CodecError, NeoSerializable},
3	OpCode,
4};
5/// This module provides a binary decoder that can read various types of data from a byte slice.
6///
7/// # Examples
8///
9/// ```rust
10///
11/// use neo3::neo_codec::Decoder;
12/// let data = [0x01, 0x02, 0x03, 0x04];
13/// let mut decoder = Decoder::new(&data);
14///
15/// assert_eq!(decoder.read_bool(), true);
16/// assert_eq!(decoder.read_u8(), 2);
17/// // Note: These examples are simplified - actual methods return Results
18/// // assert_eq!(decoder.read_u16().unwrap(), 0x0403);
19/// // assert_eq!(decoder.read_i16().unwrap(), 0x0403);
20/// ```
21use getset::{Getters, Setters};
22use num_bigint::{BigInt, Sign};
23use serde::Deserialize;
24use serde_derive::Serialize;
25
26/// A binary decoder that can read various types of data from a byte slice.
27#[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	/// Returns the next byte in the byte slice, or None if the end of the slice has been reached.
39	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	/// Creates a new binary decoder that reads from the given byte slice.
52	pub fn new(data: &'a [u8]) -> Self {
53		Self { data, pointer: 0, marker: 0 }
54	}
55
56	/// Reads a boolean value from the byte slice.
57	pub fn read_bool(&mut self) -> bool {
58		let val = self.data[self.pointer] == 1;
59		self.pointer += 1;
60		val
61	}
62
63	/// Reads an unsigned 8-bit integer from the byte slice.
64	pub fn read_u8(&mut self) -> u8 {
65		let val = self.data[self.pointer];
66		self.pointer += 1;
67		val
68	}
69
70	/// Reads an unsigned 16-bit integer from the byte slice.
71	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	/// Reads a signed 16-bit integer from the byte slice.
80	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	/// Reads an unsigned 32-bit integer from the byte slice.
89	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	/// Reads a signed 32-bit integer from the byte slice.
98	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	/// Reads an unsigned 64-bit integer from the byte slice.
107	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	/// Reads a signed 64-bit integer from the byte slice.
116	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			// Flip sign bit
139			if let Some(byte) = bytes.to_owned().get_mut(len - 1) {
140				*byte ^= 0x80;
141			} else {
142				return Err(CodecError::InvalidFormat);
143			}
144			// bytes.get_mut()[len - 1] ^= 0x80;
145		}
146		// Note: NEO uses little-endian byte order for BigIntegers
147		// The sign is determined by the 'negative' flag above
148		let sign = if negative { Sign::Minus } else { Sign::Plus };
149		Ok(BigInt::from_bytes_le(sign, &bytes))
150	}
151
152	/// Reads an encoded EC point from the byte slice.
153	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	/// Reads a byte slice of the given length from the byte slice.
162	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	/// Reads a variable-length byte slice from the byte slice.
172	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	/// Reads a variable-length integer from the byte slice.
178	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				// Handle invalid UTF-8
195				return Err(CodecError::InvalidEncoding(e.to_string()))
196			},
197		};
198
199		// Trim null bytes from end
200		let string = string.trim_end_matches(char::from(0));
201
202		Ok(string.to_string())
203	}
204
205	/// Reads a push byte slice from the byte slice.
206	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	/// Reads a push integer from the byte slice.
224	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	/// Reads a push string from the byte slice.
247	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	/// Reads a deserializable value from the byte slice.
254	pub fn read_serializable<T: NeoSerializable>(&mut self) -> Result<T, CodecError> {
255		T::decode(self).map_err(|_e| CodecError::InvalidFormat)
256	}
257
258	/// Reads a list of deserializable values from the byte slice.
259	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 read_ec_point(&mut self) -> Result<ProjectivePoint, &'static str> {
295	// 	let tag = self.read_u8();
296	// 	let bytes = match tag {
297	// 		0x00 => return Ok(ProjectivePoint::IDENTITY),
298	// 		0x02 | 0x03 => self.read_bytes(32),
299	// 		0x04 => self.read_bytes(64),
300	// 		_ => return Err("Invalid EC point tag"),
301	// 	};
302	//
303	// 	let point = EncodedPoint::from_bytes(bytes).unwrap();
304	// 	match ProjectivePoint::from_encoded_point(&point) {
305	// 		Some(point) => Ok(point),
306	// 		None => Err("Invalid EC point"),
307	// 	}
308	// }
309
310	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}