/rust/registry/src/index.crates.io-1949cf8c6b5b557f/nom-8.0.0/src/bits/mod.rs
Line | Count | Source |
1 | | //! Bit level parsers |
2 | | //! |
3 | | |
4 | | pub mod complete; |
5 | | pub mod streaming; |
6 | | |
7 | | use crate::error::{ErrorKind, ParseError}; |
8 | | use crate::internal::{Err, IResult, Needed, Parser}; |
9 | | use crate::traits::ErrorConvert; |
10 | | use crate::Input; |
11 | | |
12 | | /// Converts a byte-level input to a bit-level input, for consumption by a parser that uses bits. |
13 | | /// |
14 | | /// Afterwards, the input is converted back to a byte-level parser, with any remaining bits thrown |
15 | | /// away. |
16 | | /// |
17 | | /// # Example |
18 | | /// ``` |
19 | | /// use nom::bits::{bits, streaming::take}; |
20 | | /// use nom::error::Error; |
21 | | /// use nom::IResult; |
22 | | /// |
23 | | /// fn parse(input: &[u8]) -> IResult<&[u8], (u8, u8)> { |
24 | | /// bits::<_, _, Error<(&[u8], usize)>, _, _>((take(4usize), take(8usize)))(input) |
25 | | /// } |
26 | | /// |
27 | | /// let input = &[0x12, 0x34, 0xff, 0xff]; |
28 | | /// |
29 | | /// let output = parse(input).expect("We take 1.5 bytes and the input is longer than 2 bytes"); |
30 | | /// |
31 | | /// // The first byte is consumed, the second byte is partially consumed and dropped. |
32 | | /// let remaining = output.0; |
33 | | /// assert_eq!(remaining, [0xff, 0xff]); |
34 | | /// |
35 | | /// let parsed = output.1; |
36 | | /// assert_eq!(parsed.0, 0x01); |
37 | | /// assert_eq!(parsed.1, 0x23); |
38 | | /// ``` |
39 | 32.2M | pub fn bits<I, O, E1, E2, P>(mut parser: P) -> impl FnMut(I) -> IResult<I, O, E2> |
40 | 32.2M | where |
41 | 32.2M | E1: ParseError<(I, usize)> + ErrorConvert<E2>, |
42 | 32.2M | E2: ParseError<I>, |
43 | 32.2M | I: Input, |
44 | 32.2M | P: Parser<(I, usize), Output = O, Error = E1>, |
45 | | { |
46 | 32.2M | move |input: I| match parser.parse((input, 0)) { |
47 | 32.2M | Ok(((rest, offset), result)) => { |
48 | | // If the next byte has been partially read, it will be sliced away as well. |
49 | | // The parser functions might already slice away all fully read bytes. |
50 | | // That's why `offset / 8` isn't necessarily needed at all times. |
51 | 32.2M | let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 }; |
52 | 32.2M | Ok((rest.take_from(remaining_bytes_index), result)) |
53 | | } |
54 | 3.38k | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), nom::bits::bits::<&[u8], (u8, u8), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, suricata::rdp::parser::parse_class_options::{closure#0}>::{closure#0}::{closure#0}Line | Count | Source | 54 | 501 | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), |
Unexecuted instantiation: nom::bits::bits::<&[u8], (u8, u8, u8), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, suricata::rdp::parser::parse_x223_data_class_0::parser::{closure#0}>::{closure#0}::{closure#0}nom::bits::bits::<&[u8], (u8, u8, u8), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, (nom::bits::streaming::take<&[u8], u8, u8, nom::error::Error<(&[u8], usize)>>::{closure#0}, nom::bits::streaming::take<&[u8], u8, u8, nom::error::Error<(&[u8], usize)>>::{closure#0}, nom::bits::streaming::take<&[u8], u8, u8, nom::error::Error<(&[u8], usize)>>::{closure#0})>::{closure#0}::{closure#0}Line | Count | Source | 54 | 234 | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), |
nom::bits::bits::<&[u8], (u32, u32, u32), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, (nom::bits::streaming::take<&[u8], u32, u32, nom::error::Error<(&[u8], usize)>>::{closure#0}, nom::bits::streaming::take<&[u8], u32, u32, nom::error::Error<(&[u8], usize)>>::{closure#0}, nom::bits::streaming::take<&[u8], u32, u32, nom::error::Error<(&[u8], usize)>>::{closure#0})>::{closure#0}::{closure#0}Line | Count | Source | 54 | 2.61k | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), |
nom::bits::bits::<&[u8], (u8, u8, u8, u8), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, suricata::mqtt::parser::parse_fixed_header_flags::{closure#0}>::{closure#0}::{closure#0}Line | Count | Source | 54 | 36 | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), |
Unexecuted instantiation: nom::bits::bits::<_, _, _, _, _>::{closure#0}::{closure#0} |
55 | 3.37k | Err(Err::Error(e)) => Err(Err::Error(e.convert())), |
56 | 0 | Err(Err::Failure(e)) => Err(Err::Failure(e.convert())), |
57 | 32.2M | } nom::bits::bits::<&[u8], (u8, u8), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, suricata::rdp::parser::parse_class_options::{closure#0}>::{closure#0}Line | Count | Source | 46 | 2.12M | move |input: I| match parser.parse((input, 0)) { | 47 | 2.12M | Ok(((rest, offset), result)) => { | 48 | | // If the next byte has been partially read, it will be sliced away as well. | 49 | | // The parser functions might already slice away all fully read bytes. | 50 | | // That's why `offset / 8` isn't necessarily needed at all times. | 51 | 2.12M | let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 }; | 52 | 2.12M | Ok((rest.take_from(remaining_bytes_index), result)) | 53 | | } | 54 | 501 | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), | 55 | 1.16k | Err(Err::Error(e)) => Err(Err::Error(e.convert())), | 56 | 0 | Err(Err::Failure(e)) => Err(Err::Failure(e.convert())), | 57 | 2.12M | } |
nom::bits::bits::<&[u8], (u8, u8, u8), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, suricata::rdp::parser::parse_x223_data_class_0::parser::{closure#0}>::{closure#0}Line | Count | Source | 46 | 38.8k | move |input: I| match parser.parse((input, 0)) { | 47 | 36.5k | Ok(((rest, offset), result)) => { | 48 | | // If the next byte has been partially read, it will be sliced away as well. | 49 | | // The parser functions might already slice away all fully read bytes. | 50 | | // That's why `offset / 8` isn't necessarily needed at all times. | 51 | 36.5k | let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 }; | 52 | 36.5k | Ok((rest.take_from(remaining_bytes_index), result)) | 53 | | } | 54 | 0 | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), | 55 | 2.21k | Err(Err::Error(e)) => Err(Err::Error(e.convert())), | 56 | 0 | Err(Err::Failure(e)) => Err(Err::Failure(e.convert())), | 57 | 38.8k | } |
nom::bits::bits::<&[u8], (u8, u8, u8), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, (nom::bits::streaming::take<&[u8], u8, u8, nom::error::Error<(&[u8], usize)>>::{closure#0}, nom::bits::streaming::take<&[u8], u8, u8, nom::error::Error<(&[u8], usize)>>::{closure#0}, nom::bits::streaming::take<&[u8], u8, u8, nom::error::Error<(&[u8], usize)>>::{closure#0})>::{closure#0}Line | Count | Source | 46 | 93.9k | move |input: I| match parser.parse((input, 0)) { | 47 | 93.6k | Ok(((rest, offset), result)) => { | 48 | | // If the next byte has been partially read, it will be sliced away as well. | 49 | | // The parser functions might already slice away all fully read bytes. | 50 | | // That's why `offset / 8` isn't necessarily needed at all times. | 51 | 93.6k | let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 }; | 52 | 93.6k | Ok((rest.take_from(remaining_bytes_index), result)) | 53 | | } | 54 | 234 | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), | 55 | 0 | Err(Err::Error(e)) => Err(Err::Error(e.convert())), | 56 | 0 | Err(Err::Failure(e)) => Err(Err::Failure(e.convert())), | 57 | 93.9k | } |
nom::bits::bits::<&[u8], (u32, u32, u32), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, (nom::bits::streaming::take<&[u8], u32, u32, nom::error::Error<(&[u8], usize)>>::{closure#0}, nom::bits::streaming::take<&[u8], u32, u32, nom::error::Error<(&[u8], usize)>>::{closure#0}, nom::bits::streaming::take<&[u8], u32, u32, nom::error::Error<(&[u8], usize)>>::{closure#0})>::{closure#0}Line | Count | Source | 46 | 93.6k | move |input: I| match parser.parse((input, 0)) { | 47 | 91.0k | Ok(((rest, offset), result)) => { | 48 | | // If the next byte has been partially read, it will be sliced away as well. | 49 | | // The parser functions might already slice away all fully read bytes. | 50 | | // That's why `offset / 8` isn't necessarily needed at all times. | 51 | 91.0k | let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 }; | 52 | 91.0k | Ok((rest.take_from(remaining_bytes_index), result)) | 53 | | } | 54 | 2.61k | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), | 55 | 0 | Err(Err::Error(e)) => Err(Err::Error(e.convert())), | 56 | 0 | Err(Err::Failure(e)) => Err(Err::Failure(e.convert())), | 57 | 93.6k | } |
nom::bits::bits::<&[u8], (u8, u8, u8, u8), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, suricata::mqtt::parser::parse_fixed_header_flags::{closure#0}>::{closure#0}Line | Count | Source | 46 | 29.9M | move |input: I| match parser.parse((input, 0)) { | 47 | 29.9M | Ok(((rest, offset), result)) => { | 48 | | // If the next byte has been partially read, it will be sliced away as well. | 49 | | // The parser functions might already slice away all fully read bytes. | 50 | | // That's why `offset / 8` isn't necessarily needed at all times. | 51 | 29.9M | let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 }; | 52 | 29.9M | Ok((rest.take_from(remaining_bytes_index), result)) | 53 | | } | 54 | 36 | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), | 55 | 0 | Err(Err::Error(e)) => Err(Err::Error(e.convert())), | 56 | 0 | Err(Err::Failure(e)) => Err(Err::Failure(e.convert())), | 57 | 29.9M | } |
Unexecuted instantiation: nom::bits::bits::<_, _, _, _, _>::{closure#0} |
58 | 32.2M | } nom::bits::bits::<&[u8], (u8, u8, u8), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, (nom::bits::streaming::take<&[u8], u8, u8, nom::error::Error<(&[u8], usize)>>::{closure#0}, nom::bits::streaming::take<&[u8], u8, u8, nom::error::Error<(&[u8], usize)>>::{closure#0}, nom::bits::streaming::take<&[u8], u8, u8, nom::error::Error<(&[u8], usize)>>::{closure#0})>Line | Count | Source | 39 | 93.9k | pub fn bits<I, O, E1, E2, P>(mut parser: P) -> impl FnMut(I) -> IResult<I, O, E2> | 40 | 93.9k | where | 41 | 93.9k | E1: ParseError<(I, usize)> + ErrorConvert<E2>, | 42 | 93.9k | E2: ParseError<I>, | 43 | 93.9k | I: Input, | 44 | 93.9k | P: Parser<(I, usize), Output = O, Error = E1>, | 45 | | { | 46 | | move |input: I| match parser.parse((input, 0)) { | 47 | | Ok(((rest, offset), result)) => { | 48 | | // If the next byte has been partially read, it will be sliced away as well. | 49 | | // The parser functions might already slice away all fully read bytes. | 50 | | // That's why `offset / 8` isn't necessarily needed at all times. | 51 | | let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 }; | 52 | | Ok((rest.take_from(remaining_bytes_index), result)) | 53 | | } | 54 | | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), | 55 | | Err(Err::Error(e)) => Err(Err::Error(e.convert())), | 56 | | Err(Err::Failure(e)) => Err(Err::Failure(e.convert())), | 57 | | } | 58 | 93.9k | } |
nom::bits::bits::<&[u8], (u32, u32, u32), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, (nom::bits::streaming::take<&[u8], u32, u32, nom::error::Error<(&[u8], usize)>>::{closure#0}, nom::bits::streaming::take<&[u8], u32, u32, nom::error::Error<(&[u8], usize)>>::{closure#0}, nom::bits::streaming::take<&[u8], u32, u32, nom::error::Error<(&[u8], usize)>>::{closure#0})>Line | Count | Source | 39 | 93.6k | pub fn bits<I, O, E1, E2, P>(mut parser: P) -> impl FnMut(I) -> IResult<I, O, E2> | 40 | 93.6k | where | 41 | 93.6k | E1: ParseError<(I, usize)> + ErrorConvert<E2>, | 42 | 93.6k | E2: ParseError<I>, | 43 | 93.6k | I: Input, | 44 | 93.6k | P: Parser<(I, usize), Output = O, Error = E1>, | 45 | | { | 46 | | move |input: I| match parser.parse((input, 0)) { | 47 | | Ok(((rest, offset), result)) => { | 48 | | // If the next byte has been partially read, it will be sliced away as well. | 49 | | // The parser functions might already slice away all fully read bytes. | 50 | | // That's why `offset / 8` isn't necessarily needed at all times. | 51 | | let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 }; | 52 | | Ok((rest.take_from(remaining_bytes_index), result)) | 53 | | } | 54 | | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), | 55 | | Err(Err::Error(e)) => Err(Err::Error(e.convert())), | 56 | | Err(Err::Failure(e)) => Err(Err::Failure(e.convert())), | 57 | | } | 58 | 93.6k | } |
nom::bits::bits::<&[u8], (u8, u8), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, suricata::rdp::parser::parse_class_options::{closure#0}>Line | Count | Source | 39 | 2.12M | pub fn bits<I, O, E1, E2, P>(mut parser: P) -> impl FnMut(I) -> IResult<I, O, E2> | 40 | 2.12M | where | 41 | 2.12M | E1: ParseError<(I, usize)> + ErrorConvert<E2>, | 42 | 2.12M | E2: ParseError<I>, | 43 | 2.12M | I: Input, | 44 | 2.12M | P: Parser<(I, usize), Output = O, Error = E1>, | 45 | | { | 46 | | move |input: I| match parser.parse((input, 0)) { | 47 | | Ok(((rest, offset), result)) => { | 48 | | // If the next byte has been partially read, it will be sliced away as well. | 49 | | // The parser functions might already slice away all fully read bytes. | 50 | | // That's why `offset / 8` isn't necessarily needed at all times. | 51 | | let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 }; | 52 | | Ok((rest.take_from(remaining_bytes_index), result)) | 53 | | } | 54 | | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), | 55 | | Err(Err::Error(e)) => Err(Err::Error(e.convert())), | 56 | | Err(Err::Failure(e)) => Err(Err::Failure(e.convert())), | 57 | | } | 58 | 2.12M | } |
nom::bits::bits::<&[u8], (u8, u8, u8), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, suricata::rdp::parser::parse_x223_data_class_0::parser::{closure#0}>Line | Count | Source | 39 | 38.8k | pub fn bits<I, O, E1, E2, P>(mut parser: P) -> impl FnMut(I) -> IResult<I, O, E2> | 40 | 38.8k | where | 41 | 38.8k | E1: ParseError<(I, usize)> + ErrorConvert<E2>, | 42 | 38.8k | E2: ParseError<I>, | 43 | 38.8k | I: Input, | 44 | 38.8k | P: Parser<(I, usize), Output = O, Error = E1>, | 45 | | { | 46 | | move |input: I| match parser.parse((input, 0)) { | 47 | | Ok(((rest, offset), result)) => { | 48 | | // If the next byte has been partially read, it will be sliced away as well. | 49 | | // The parser functions might already slice away all fully read bytes. | 50 | | // That's why `offset / 8` isn't necessarily needed at all times. | 51 | | let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 }; | 52 | | Ok((rest.take_from(remaining_bytes_index), result)) | 53 | | } | 54 | | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), | 55 | | Err(Err::Error(e)) => Err(Err::Error(e.convert())), | 56 | | Err(Err::Failure(e)) => Err(Err::Failure(e.convert())), | 57 | | } | 58 | 38.8k | } |
nom::bits::bits::<&[u8], (u8, u8, u8, u8), nom::error::Error<(&[u8], usize)>, nom::error::Error<&[u8]>, suricata::mqtt::parser::parse_fixed_header_flags::{closure#0}>Line | Count | Source | 39 | 29.9M | pub fn bits<I, O, E1, E2, P>(mut parser: P) -> impl FnMut(I) -> IResult<I, O, E2> | 40 | 29.9M | where | 41 | 29.9M | E1: ParseError<(I, usize)> + ErrorConvert<E2>, | 42 | 29.9M | E2: ParseError<I>, | 43 | 29.9M | I: Input, | 44 | 29.9M | P: Parser<(I, usize), Output = O, Error = E1>, | 45 | | { | 46 | | move |input: I| match parser.parse((input, 0)) { | 47 | | Ok(((rest, offset), result)) => { | 48 | | // If the next byte has been partially read, it will be sliced away as well. | 49 | | // The parser functions might already slice away all fully read bytes. | 50 | | // That's why `offset / 8` isn't necessarily needed at all times. | 51 | | let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 }; | 52 | | Ok((rest.take_from(remaining_bytes_index), result)) | 53 | | } | 54 | | Err(Err::Incomplete(n)) => Err(Err::Incomplete(n.map(|u| u.get() / 8 + 1))), | 55 | | Err(Err::Error(e)) => Err(Err::Error(e.convert())), | 56 | | Err(Err::Failure(e)) => Err(Err::Failure(e.convert())), | 57 | | } | 58 | 29.9M | } |
Unexecuted instantiation: nom::bits::bits::<_, _, _, _, _> |
59 | | |
60 | | /// Counterpart to `bits`, `bytes` transforms its bit stream input into a byte slice for the underlying |
61 | | /// parser, allowing byte-slice parsers to work on bit streams. |
62 | | /// |
63 | | /// A partial byte remaining in the input will be ignored and the given parser will start parsing |
64 | | /// at the next full byte. |
65 | | /// |
66 | | /// ``` |
67 | | /// use nom::bits::{bits, bytes, streaming::take}; |
68 | | /// use nom::combinator::rest; |
69 | | /// use nom::error::Error; |
70 | | /// use nom::IResult; |
71 | | /// |
72 | | /// fn parse(input: &[u8]) -> IResult<&[u8], (u8, u8, &[u8])> { |
73 | | /// bits::<_, _, Error<(&[u8], usize)>, _, _>(( |
74 | | /// take(4usize), |
75 | | /// take(8usize), |
76 | | /// bytes::<_, _, Error<&[u8]>, _, _>(rest) |
77 | | /// ))(input) |
78 | | /// } |
79 | | /// |
80 | | /// let input = &[0x12, 0x34, 0xff, 0xff]; |
81 | | /// |
82 | | /// assert_eq!(parse( input ), Ok(( &[][..], (0x01, 0x23, &[0xff, 0xff][..]) ))); |
83 | | /// ``` |
84 | 0 | pub fn bytes<I, O, E1, E2, P>(mut parser: P) -> impl FnMut((I, usize)) -> IResult<(I, usize), O, E2> |
85 | 0 | where |
86 | 0 | E1: ParseError<I> + ErrorConvert<E2>, |
87 | 0 | E2: ParseError<(I, usize)>, |
88 | 0 | I: Input + Clone, |
89 | 0 | P: Parser<I, Output = O, Error = E1>, |
90 | | { |
91 | 0 | move |(input, offset): (I, usize)| { |
92 | 0 | let inner = if offset % 8 != 0 { |
93 | 0 | input.take_from(1 + offset / 8) |
94 | | } else { |
95 | 0 | input.take_from(offset / 8) |
96 | | }; |
97 | 0 | let i = (input, offset); |
98 | 0 | match parser.parse(inner) { |
99 | 0 | Ok((rest, res)) => Ok(((rest, 0), res)), |
100 | 0 | Err(Err::Incomplete(Needed::Unknown)) => Err(Err::Incomplete(Needed::Unknown)), |
101 | 0 | Err(Err::Incomplete(Needed::Size(sz))) => Err(match sz.get().checked_mul(8) { |
102 | 0 | Some(v) => Err::Incomplete(Needed::new(v)), |
103 | 0 | None => Err::Failure(E2::from_error_kind(i, ErrorKind::TooLarge)), |
104 | | }), |
105 | 0 | Err(Err::Error(e)) => Err(Err::Error(e.convert())), |
106 | 0 | Err(Err::Failure(e)) => Err(Err::Failure(e.convert())), |
107 | | } |
108 | 0 | } |
109 | 0 | } |
110 | | |
111 | | #[cfg(test)] |
112 | | mod test { |
113 | | use super::*; |
114 | | use crate::bits::streaming::take; |
115 | | use crate::error::Error; |
116 | | |
117 | | #[test] |
118 | | /// Take the `bits` function and assert that remaining bytes are correctly returned, if the |
119 | | /// previous bytes are fully consumed |
120 | | fn test_complete_byte_consumption_bits() { |
121 | | let input = &[0x12, 0x34, 0x56, 0x78]; |
122 | | |
123 | | // Take 3 bit slices with sizes [4, 8, 4]. |
124 | | let result: IResult<&[u8], (u8, u8, u8)> = |
125 | | bits::<_, _, Error<(&[u8], usize)>, _, _>((take(4usize), take(8usize), take(4usize)))(input); |
126 | | |
127 | | let output = result.expect("We take 2 bytes and the input is longer than 2 bytes"); |
128 | | |
129 | | let remaining = output.0; |
130 | | assert_eq!(remaining, [0x56, 0x78]); |
131 | | |
132 | | let parsed = output.1; |
133 | | assert_eq!(parsed.0, 0x01); |
134 | | assert_eq!(parsed.1, 0x23); |
135 | | assert_eq!(parsed.2, 0x04); |
136 | | } |
137 | | |
138 | | #[test] |
139 | | /// Take the `bits` function and assert that remaining bytes are correctly returned, if the |
140 | | /// previous bytes are NOT fully consumed. Partially consumed bytes are supposed to be dropped. |
141 | | /// I.e. if we consume 1.5 bytes of 4 bytes, 2 bytes will be returned, bits 13-16 will be |
142 | | /// dropped. |
143 | | fn test_partial_byte_consumption_bits() { |
144 | | let input = &[0x12, 0x34, 0x56, 0x78]; |
145 | | |
146 | | // Take bit slices with sizes [4, 8]. |
147 | | let result: IResult<&[u8], (u8, u8)> = |
148 | | bits::<_, _, Error<(&[u8], usize)>, _, _>((take(4usize), take(8usize)))(input); |
149 | | |
150 | | let output = result.expect("We take 1.5 bytes and the input is longer than 2 bytes"); |
151 | | |
152 | | let remaining = output.0; |
153 | | assert_eq!(remaining, [0x56, 0x78]); |
154 | | |
155 | | let parsed = output.1; |
156 | | assert_eq!(parsed.0, 0x01); |
157 | | assert_eq!(parsed.1, 0x23); |
158 | | } |
159 | | |
160 | | #[test] |
161 | | #[cfg(feature = "std")] |
162 | | /// Ensure that in Incomplete error is thrown, if too few bytes are passed for a given parser. |
163 | | fn test_incomplete_bits() { |
164 | | let input = &[0x12]; |
165 | | |
166 | | // Take bit slices with sizes [4, 8]. |
167 | | let result: IResult<&[u8], (u8, u8)> = |
168 | | bits::<_, _, Error<(&[u8], usize)>, _, _>((take(4usize), take(8usize)))(input); |
169 | | |
170 | | assert!(result.is_err()); |
171 | | let error = result.err().unwrap(); |
172 | | assert_eq!("Parsing requires 2 bytes/chars", error.to_string()); |
173 | | } |
174 | | } |