1//! Bit level parsers
2//!
3
4use crate::error::{ErrorKind, ParseError};
5use crate::internal::{Err, IResult};
6use crate::lib::std::ops::{AddAssign, Div, RangeFrom, Shl, Shr};
7use crate::traits::{InputIter, InputLength, Slice, ToUsize};
8
9/// Generates a parser taking `count` bits
10///
11/// # Example
12/// ```rust
13/// # use nom::bits::complete::take;
14/// # use nom::IResult;
15/// # use nom::error::{Error, ErrorKind};
16/// // Input is a tuple of (input: I, bit_offset: usize)
17/// fn parser(input: (&[u8], usize), count: usize)-> IResult<(&[u8], usize), u8> {
18/// take(count)(input)
19/// }
20///
21/// // Consumes 0 bits, returns 0
22/// assert_eq!(parser(([0b00010010].as_ref(), 0), 0), Ok((([0b00010010].as_ref(), 0), 0)));
23///
24/// // Consumes 4 bits, returns their values and increase offset to 4
25/// assert_eq!(parser(([0b00010010].as_ref(), 0), 4), Ok((([0b00010010].as_ref(), 4), 0b00000001)));
26///
27/// // Consumes 4 bits, offset is 4, returns their values and increase offset to 0 of next byte
28/// assert_eq!(parser(([0b00010010].as_ref(), 4), 4), Ok((([].as_ref(), 0), 0b00000010)));
29///
30/// // Tries to consume 12 bits but only 8 are available
31/// assert_eq!(parser(([0b00010010].as_ref(), 0), 12), Err(nom::Err::Error(Error{input: ([0b00010010].as_ref(), 0), code: ErrorKind::Eof })));
32/// ```
33pub fn take<I, O, C, E: ParseError<(I, usize)>>(
34 count: C,
35) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
36where
37 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
38 C: ToUsize,
39 O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O>,
40{
41 let count = count.to_usize();
42 move |(input, bit_offset): (I, usize)| {
43 if count == 0 {
44 Ok(((input, bit_offset), 0u8.into()))
45 } else {
46 let cnt = (count + bit_offset).div(8);
47 if input.input_len() * 8 < count + bit_offset {
48 Err(Err::Error(E::from_error_kind(
49 (input, bit_offset),
50 ErrorKind::Eof,
51 )))
52 } else {
53 let mut acc: O = 0_u8.into();
54 let mut offset: usize = bit_offset;
55 let mut remaining: usize = count;
56 let mut end_offset: usize = 0;
57
58 for byte in input.iter_elements().take(cnt + 1) {
59 if remaining == 0 {
60 break;
61 }
62 let val: O = if offset == 0 {
63 byte.into()
64 } else {
65 ((byte << offset) as u8 >> offset).into()
66 };
67
68 if remaining < 8 - offset {
69 acc += val >> (8 - offset - remaining);
70 end_offset = remaining + offset;
71 break;
72 } else {
73 acc += val << (remaining - (8 - offset));
74 remaining -= 8 - offset;
75 offset = 0;
76 }
77 }
78 Ok(((input.slice(cnt..), end_offset), acc))
79 }
80 }
81 }
82}
83
84/// Generates a parser taking `count` bits and comparing them to `pattern`
85pub fn tag<I, O, C, E: ParseError<(I, usize)>>(
86 pattern: O,
87 count: C,
88) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
89where
90 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength + Clone,
91 C: ToUsize,
92 O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O> + PartialEq,
93{
94 let count: usize = count.to_usize();
95 move |input: (I, usize)| {
96 let inp: (I, usize) = input.clone();
97
98 take(count)(input).and_then(|(i: (I, usize), o: O)| {
99 if pattern == o {
100 Ok((i, o))
101 } else {
102 Err(Err::Error(error_position!(inp, ErrorKind::TagBits)))
103 }
104 })
105 }
106}
107
108/// Parses one specific bit as a bool.
109///
110/// # Example
111/// ```rust
112/// # use nom::bits::complete::bool;
113/// # use nom::IResult;
114/// # use nom::error::{Error, ErrorKind};
115///
116/// fn parse(input: (&[u8], usize)) -> IResult<(&[u8], usize), bool> {
117/// bool(input)
118/// }
119///
120/// assert_eq!(parse(([0b10000000].as_ref(), 0)), Ok((([0b10000000].as_ref(), 1), true)));
121/// assert_eq!(parse(([0b10000000].as_ref(), 1)), Ok((([0b10000000].as_ref(), 2), false)));
122/// ```
123pub fn bool<I, E: ParseError<(I, usize)>>(input: (I, usize)) -> IResult<(I, usize), bool, E>
124where
125 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
126{
127 let (res: (I, usize), bit: u32): (_, u32) = take(count:1usize)(input)?;
128 Ok((res, bit != 0))
129}
130
131#[cfg(test)]
132mod test {
133 use super::*;
134
135 #[test]
136 fn test_take_0() {
137 let input = [0b00010010].as_ref();
138 let count = 0usize;
139 assert_eq!(count, 0usize);
140 let offset = 0usize;
141
142 let result: crate::IResult<(&[u8], usize), usize> = take(count)((input, offset));
143
144 assert_eq!(result, Ok(((input, offset), 0)));
145 }
146
147 #[test]
148 fn test_take_eof() {
149 let input = [0b00010010].as_ref();
150
151 let result: crate::IResult<(&[u8], usize), usize> = take(1usize)((input, 8));
152
153 assert_eq!(
154 result,
155 Err(crate::Err::Error(crate::error::Error {
156 input: (input, 8),
157 code: ErrorKind::Eof
158 }))
159 )
160 }
161
162 #[test]
163 fn test_take_span_over_multiple_bytes() {
164 let input = [0b00010010, 0b00110100, 0b11111111, 0b11111111].as_ref();
165
166 let result: crate::IResult<(&[u8], usize), usize> = take(24usize)((input, 4));
167
168 assert_eq!(
169 result,
170 Ok((([0b11111111].as_ref(), 4), 0b1000110100111111111111))
171 );
172 }
173
174 #[test]
175 fn test_bool_0() {
176 let input = [0b10000000].as_ref();
177
178 let result: crate::IResult<(&[u8], usize), bool> = bool((input, 0));
179
180 assert_eq!(result, Ok(((input, 1), true)));
181 }
182
183 #[test]
184 fn test_bool_eof() {
185 let input = [0b10000000].as_ref();
186
187 let result: crate::IResult<(&[u8], usize), bool> = bool((input, 8));
188
189 assert_eq!(
190 result,
191 Err(crate::Err::Error(crate::error::Error {
192 input: (input, 8),
193 code: ErrorKind::Eof
194 }))
195 );
196 }
197}
198