1use crate::endianness::ParsingEndian;
2use crate::errors::BytesParserError;
3
4use std::convert::TryInto;
5use std::mem;
6use std::str;
7
8#[derive(Debug, Copy, Clone)]
25pub struct BytesParser<'a> {
26 buffer: &'a [u8],
27 length: usize,
28 cursor: usize,
29 endian: ParsingEndian,
30}
31
32impl<'a> From<&'a [u8]> for BytesParser<'a> {
33 fn from(bytes: &'a [u8]) -> Self {
34 BytesParser {
35 buffer: bytes,
36 length: bytes.len(),
37 cursor: 0,
38 endian: ParsingEndian::default(),
39 }
40 }
41}
42
43macro_rules! build_parse_type_fn {
44 ($fn_name:ident, $parsed_type:ty) => {
45 #[doc = "Parse a`"]
46 #[doc=stringify!($parsed_type)]
47 #[doc = "` and update the internal cursor accordingly.\n\n"]
48 #[doc = "It produces an error if [`BytesParser::parseable`] returns an amount inferior to"]
49 #[doc = "the amount of bytes occupied by a `"]
50 #[doc=stringify!($parsed_type)]
51 #[doc = "`."]
52 pub fn $fn_name(&mut self) -> Result<$parsed_type, BytesParserError> {
53 let size = mem::size_of::<$parsed_type>();
54 if self.parseable() < size {
55 return Err(BytesParserError::NotEnoughBytesForTypeError(stringify!($parsed_type).to_string()));
56 }
57
58 let start = self.cursor;
59 let end = self.cursor + size;
60 let slice = self.buffer[start..end].try_into().unwrap();
61
62 let value = match self.endian {
63 ParsingEndian::BE => <$parsed_type>::from_be_bytes(slice),
64 ParsingEndian::LE => <$parsed_type>::from_le_bytes(slice),
65 };
66
67 self.cursor += size;
68
69 Ok(value)
70 }
71 };
72}
73
74impl<'a> BytesParser<'a> {
75 build_parse_type_fn!(parse_i8, i8);
76 build_parse_type_fn!(parse_u8, u8);
77
78 build_parse_type_fn!(parse_i16, i16);
79 build_parse_type_fn!(parse_u16, u16);
80
81 build_parse_type_fn!(parse_i32, i32);
82 build_parse_type_fn!(parse_u32, u32);
83
84 build_parse_type_fn!(parse_i64, i64);
85 build_parse_type_fn!(parse_u64, u64);
86
87 build_parse_type_fn!(parse_i128, i128);
88 build_parse_type_fn!(parse_u128, u128);
89
90 build_parse_type_fn!(parse_f32, f32);
91 build_parse_type_fn!(parse_f64, f64);
92
93 build_parse_type_fn!(parse_isize, isize);
94 build_parse_type_fn!(parse_usize, usize);
95
96 pub fn parse_str_utf8(&mut self, size: usize) -> Result<&str, BytesParserError> {
119 if self.parseable() < size {
120 return Err(BytesParserError::NotEnoughBytesForStringError(size));
121 }
122
123 let start = self.cursor;
124 let end = self.cursor + size;
125 let slice = self.buffer[start..end].try_into().unwrap();
126
127 match str::from_utf8(slice) {
128 Ok(result) => {
129 self.cursor += size;
130 Ok(result)
131 },
132 Err(err) => Err(BytesParserError::StringParseError(err)),
133 }
134 }
135
136 pub fn parse_char_u32(&mut self) -> Result<char, BytesParserError> {
141 let u32value = self.parse_u32()?;
142 let result = char::from_u32(u32value).ok_or(BytesParserError::InvalidU32ForCharError)?;
143 Ok(result)
144 }
145
146 pub fn parse_slice(&mut self, size: usize) -> Result<&[u8], BytesParserError> {
160 if self.parseable() < size {
161 return Err(BytesParserError::NotEnoughBytesForSlice(size));
162 }
163
164 let start = self.cursor;
165 let end = self.cursor + size;
166
167 self.cursor += size;
168
169 Ok(self.buffer[start..end].try_into().unwrap())
170 }
171
172 pub fn from_slice(&mut self, size: usize) -> Result<BytesParser, BytesParserError> {
181 let slice = self.parse_slice(size)?;
182
183 Ok(BytesParser::from(slice))
184 }
185
186 pub const fn length(&self) -> usize {
188 self.length
189 }
190
191 pub const fn is_empty(&self) -> bool {
193 self.length == 0
194 }
195
196 pub const fn position(&self) -> usize {
200 self.cursor
201 }
202
203 pub const fn is_at_start(&self) -> bool {
207 self.cursor == 0
208 }
209
210 pub const fn is_at_end(&self) -> bool {
214 self.cursor == self.length
215 }
216
217 pub const fn parseable(&self) -> usize {
224 self.length - self.cursor
225 }
226
227 pub fn reset(&mut self) {
233 self.cursor = 0
234 }
235
236 pub fn move_forward(&mut self, amount: usize) -> Result<(), BytesParserError> {
246 let mut new_cursor = self.cursor;
247 new_cursor += amount;
248
249 if new_cursor >= self.length {
250 Err(BytesParserError::CursorOutOfBoundError(new_cursor as isize, self.length, self.cursor))
251 } else {
252 self.cursor = new_cursor;
253 Ok(())
254 }
255 }
256
257 pub fn move_backward(&mut self, amount: usize) -> Result<(), BytesParserError> {
267 let mut new_cursor = self.cursor as isize;
268 new_cursor -= amount as isize;
269
270 if new_cursor < 0 {
271 Err(BytesParserError::CursorOutOfBoundError(new_cursor, self.length, self.cursor))
272 } else {
273 self.cursor = new_cursor as usize;
274 Ok(())
275 }
276 }
277
278 pub fn move_at(&mut self, position: usize) -> Result<(), BytesParserError> {
288 if position >= self.length {
289 Err(BytesParserError::CursorOutOfBoundError(position as isize, self.length, self.cursor))
290 } else {
291 self.cursor = position;
292 Ok(())
293 }
294 }
295
296 pub fn set_endian(&mut self, endian: ParsingEndian) {
302 self.endian = endian;
303 }
304
305 pub const fn endian(&self) -> ParsingEndian {
307 self.endian
308 }
309}
310
311#[cfg(test)]
312mod tests {
313 use super::BytesParser;
314 use crate::{BytesParserError, ParsingEndian};
315 use std::error::Error;
316
317 #[test]
318 fn parse_unsigned_scalars_using_big_endian() {
319 let input: &[u8] = &[
320 0x12, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE,
325 0xF0, ];
327
328 let mut p = BytesParser::from(input);
329
330 assert_eq!(p.endian(), ParsingEndian::BE);
331 assert_eq!(p.length(), 31);
332 assert_eq!(p.parseable(), 31);
333 assert_eq!(p.is_empty(), false);
334 assert_eq!(p.is_at_start(), true);
335
336 assert_eq!(p.parse_u8().unwrap(), 0x12);
337 assert_eq!(p.parseable(), 30);
338 assert_eq!(p.parse_u16().unwrap(), 0x1234);
339 assert_eq!(p.parseable(), 28);
340 assert_eq!(p.parse_u32().unwrap(), 0x12345678);
341 assert_eq!(p.parseable(), 24);
342 assert_eq!(p.parse_u64().unwrap(), 0x123456789ABCDEF0);
343 assert_eq!(p.parseable(), 16);
344 assert_eq!(p.parse_u128().unwrap(), 0x123456789ABCDEF0123456789ABCDEF0);
345 assert_eq!(p.parseable(), 0);
346
347 assert_eq!(p.is_at_end(), true);
348 }
349
350 #[test]
351 fn parse_unsigned_scalars_using_little_endian() {
352 let input: &[u8] = &[
353 0x12, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12, 0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, 0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, 0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34,
358 0x12, ];
360
361 let mut p = BytesParser::from(input);
362 p.set_endian(ParsingEndian::LE);
363
364 assert_eq!(p.endian(), ParsingEndian::LE);
365 assert_eq!(p.length(), 31);
366 assert_eq!(p.parseable(), 31);
367 assert_eq!(p.is_empty(), false);
368 assert_eq!(p.is_at_start(), true);
369
370 assert_eq!(p.parse_u8().unwrap(), 0x12);
371 assert_eq!(p.parseable(), 30);
372 assert_eq!(p.parse_u16().unwrap(), 0x1234);
373 assert_eq!(p.parseable(), 28);
374 assert_eq!(p.parse_u32().unwrap(), 0x12345678);
375 assert_eq!(p.parseable(), 24);
376 assert_eq!(p.parse_u64().unwrap(), 0x123456789ABCDEF0);
377 assert_eq!(p.parseable(), 16);
378 assert_eq!(p.parse_u128().unwrap(), 0x123456789ABCDEF0123456789ABCDEF0);
379 assert_eq!(p.parseable(), 0);
380
381 assert_eq!(p.is_at_end(), true);
382 }
383
384 #[test]
385 fn parse_signed_scalars_using_big_endian() {
386 let input: &[u8] = &[
387 0x12, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE,
392 0xF0, 0xFF, 0x7F, 0xFF, 0xFF, 0x7F, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ];
396
397 let mut p = BytesParser::from(input);
398
399 assert_eq!(p.endian(), ParsingEndian::BE);
400 assert_eq!(p.length(), 43);
401 assert_eq!(p.is_empty(), false);
402 assert_eq!(p.is_at_start(), true);
403
404 assert_eq!(p.parse_i8().unwrap(), 0x12);
405 assert_eq!(p.parse_i16().unwrap(), 0x1234);
406 assert_eq!(p.parse_i32().unwrap(), 0x12345678);
407 assert_eq!(p.parse_i64().unwrap(), 0x123456789ABCDEF0);
408 assert_eq!(p.parse_i128().unwrap(), 0x123456789ABCDEF0123456789ABCDEF0);
409 assert_eq!(p.parse_f32().unwrap(), f32::MIN);
410 assert_eq!(p.parse_f64().unwrap(), f64::MAX);
411
412 assert_eq!(p.is_at_end(), true);
413 }
414
415 #[test]
416 fn parse_signed_scalars_using_little_endian() {
417 let input: &[u8] = &[
418 0x12, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12, 0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, 0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, 0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34,
423 0x12, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7F, ];
427
428 let mut p = BytesParser::from(input);
429 p.set_endian(ParsingEndian::LE);
430 assert_eq!(p.length(), 43);
431 assert_eq!(p.is_empty(), false);
432 assert_eq!(p.is_at_start(), true);
433
434 assert_eq!(p.endian(), ParsingEndian::LE);
435
436 assert_eq!(p.parse_i8().unwrap(), 0x12);
437 assert_eq!(p.parse_i16().unwrap(), 0x1234);
438 assert_eq!(p.parse_i32().unwrap(), 0x12345678);
439 assert_eq!(p.parse_i64().unwrap(), 0x123456789ABCDEF0);
440 assert_eq!(p.parse_i128().unwrap(), 0x123456789ABCDEF0123456789ABCDEF0);
441 assert_eq!(p.parse_f32().unwrap(), f32::MIN);
442 assert_eq!(p.parse_f64().unwrap(), f64::MAX);
443
444 assert_eq!(p.is_at_end(), true);
445 }
446
447 #[test]
448 fn parse_moving_the_cursor_around() {
449 let input: &[u8] = &[
450 0x12, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE,
455 0xF0, ];
457
458 let mut p = BytesParser::from(input);
459
460 assert_eq!(p.position(), 0);
462 assert_eq!(p.parse_u8().unwrap(), 0x12);
463
464 assert_eq!(p.move_forward(14), Ok(()));
466 assert_eq!(p.parse_u128().unwrap(), 0x123456789ABCDEF0123456789ABCDEF0);
467 assert_eq!(p.position(), 31);
468
469 assert_eq!(p.move_backward(28), Ok(()));
471 assert_eq!(p.parse_u32().unwrap(), 0x12345678);
472
473 assert_eq!(p.move_at(15), Ok(()));
475 assert_eq!(p.parse_u128().unwrap(), 0x123456789ABCDEF0123456789ABCDEF0);
476
477 assert_eq!(p.move_at(1), Ok(()));
479 assert_eq!(p.parse_u16().unwrap(), 0x1234);
480
481 p.reset();
483 assert_eq!(p.position(), 0);
484 assert_eq!(p.parse_u8().unwrap(), 0x12);
485 }
486
487 #[test]
488 fn parse_string() {
489 let input: &[u8] = &[
490 0x00, 0x13, 0x46, 0x6F, 0x72, 0x7A, 0x61, 0x20, 0x4E, 0x61, 0x70, 0x6F, 0x6C, 0x69, 0x20, 0x53, 0x65, 0x6D, 0x70, 0x72, 0x65, ];
495
496 let mut p = BytesParser::from(input);
497
498 let str_len = p.parse_u16().unwrap();
499 assert_eq!(str_len, 19);
500
501 let str = p.parse_str_utf8(str_len as usize).unwrap();
502 assert_eq!(str, "Forza Napoli Sempre");
503 }
504
505 #[test]
506 fn parse_char() {
507 let input: &[u8] = &[
508 0x00, 0x01, 0xF9, 0x80, 0x80, 0xF9, 0x01, 0x00, ];
511
512 let mut p = BytesParser::from(input);
513
514 assert_eq!(p.parse_char_u32().unwrap(), '🦀');
515
516 p.set_endian(ParsingEndian::LE);
517
518 assert_eq!(p.parse_char_u32().unwrap(), '🦀');
519 }
520
521 #[test]
522 fn parse_slice() {
523 let input: &[u8] = &[
524 0x12, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, ];
529
530 let mut p = BytesParser::from(input);
531
532 assert!(p.move_forward(3).is_ok());
533
534 let input_slice = p.parse_slice(4).unwrap();
535 let mut ps = BytesParser::from(input_slice);
536
537 assert!(ps.is_at_start());
538 assert_eq!(ps.parseable(), 4);
539 assert_eq!(ps.parse_u32().unwrap(), 0x12345678);
540 assert!(ps.is_at_end());
541
542 assert_eq!(p.parse_u32().unwrap(), 0x12345678);
543 }
544
545 #[test]
546 fn from_slice() {
547 let input: &[u8] = &[
548 0x12, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, ];
553
554 let mut p = BytesParser::from(input);
555
556 assert!(p.move_forward(3).is_ok());
557
558 let mut ps = p.from_slice(4).unwrap();
559
560 assert!(ps.is_at_start());
561 assert_eq!(ps.parseable(), 4);
562 assert_eq!(ps.parse_u32().unwrap(), 0x12345678);
563 assert!(ps.is_at_end());
564
565 assert_eq!(p.parse_u32().unwrap(), 0x12345678);
566 }
567
568 #[test]
569 fn try_parse_empty() {
570 let input: &[u8] = &[];
571
572 let mut p = BytesParser::from(input);
573
574 assert_eq!(p.parseable(), 0);
575 assert_eq!(p.is_empty(), true);
576 assert_eq!(p.is_at_start(), p.is_at_end());
577
578 assert_eq!(p.parse_u16().unwrap_err(), BytesParserError::NotEnoughBytesForTypeError("u16".to_string()));
579 assert_eq!(p.parse_char_u32().unwrap_err(), BytesParserError::NotEnoughBytesForTypeError("u32".to_string()));
580 assert_eq!(p.parse_str_utf8(10).unwrap_err(), BytesParserError::NotEnoughBytesForStringError(10));
581 }
582
583 #[test]
584 fn try_moving_cursor_out_of_bound() {
585 let input: &[u8] = &[0x00, 0x11, 0x22];
586
587 let mut p = BytesParser::from(input);
588
589 assert_eq!(p.position(), 0);
590 assert_eq!(p.move_at(3).unwrap_err(), BytesParserError::CursorOutOfBoundError(3, 3, 0));
591 assert_eq!(p.move_at(33).unwrap_err(), BytesParserError::CursorOutOfBoundError(33, 3, 0));
592
593 assert_eq!(p.move_forward(1).unwrap(), ());
594 assert_eq!(p.move_forward(4).unwrap_err(), BytesParserError::CursorOutOfBoundError(5, 3, 1));
595
596 assert_eq!(p.move_backward(2).unwrap_err(), BytesParserError::CursorOutOfBoundError(-1, 3, 1));
597 }
598
599 #[test]
600 fn try_parsing_char_from_invalid_u32_scalar() {
601 let input: &[u8] = &[0x00, 0x11, 0x22, 0x33];
602
603 let mut p = BytesParser::from(input);
604
605 assert_eq!(p.parse_char_u32().unwrap_err(), BytesParserError::InvalidU32ForCharError);
606 }
607
608 #[test]
609 fn try_parsing_invalid_str() {
610 let input: &[u8] = &[0, 159, 146, 150];
611
612 let mut p = BytesParser::from(input);
613
614 let err = p.parse_str_utf8(4).unwrap_err();
615 assert_eq!(err.to_string(), "Failed to parse UTF-8 string: invalid utf-8 sequence of 1 bytes from index 1");
616 assert_eq!(err.source().unwrap().to_string(), "invalid utf-8 sequence of 1 bytes from index 1");
617 }
618}