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