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 | 0 | pub fn bits<I, O, E1, E2, P>(mut parser: P) -> impl FnMut(I) -> IResult<I, O, E2> |
40 | 0 | where |
41 | 0 | E1: ParseError<(I, usize)> + ErrorConvert<E2>, |
42 | 0 | E2: ParseError<I>, |
43 | 0 | I: Input, |
44 | 0 | P: Parser<(I, usize), Output = O, Error = E1>, |
45 | | { |
46 | 0 | move |input: I| match parser.parse((input, 0)) { |
47 | 0 | 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 | 0 | let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 }; |
52 | 0 | 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 | 0 | Err(Err::Error(e)) => Err(Err::Error(e.convert())), |
56 | 0 | Err(Err::Failure(e)) => Err(Err::Failure(e.convert())), |
57 | 0 | } |
58 | 0 | } |
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 | | } |