9 use crate::error
::{ErrorKind, ParseError}
;
10 use crate::input
::{ErrorConvert, InputIsStreaming, InputIter, InputLength, Slice, ToUsize}
;
11 use crate::lib
::std
::ops
::{AddAssign, RangeFrom, Shl, Shr}
;
12 use crate::{Err, IResult, Needed, Parser}
;
14 /// Converts a byte-level input to a bit-level input, for consumption by a parser that uses bits.
16 /// Afterwards, the input is converted back to a byte-level parser, with any remaining bits thrown
21 /// use nom8::bits::{bits, take};
22 /// use nom8::error::Error;
23 /// use nom8::IResult;
25 /// fn parse(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
26 /// bits::<_, _, Error<(&[u8], usize)>, _, _>((take(4usize), take(8usize)))(input)
29 /// let input = &[0x12, 0x34, 0xff, 0xff];
31 /// let output = parse(input).expect("We take 1.5 bytes and the input is longer than 2 bytes");
33 /// // The first byte is consumed, the second byte is partially consumed and dropped.
34 /// let remaining = output.0;
35 /// assert_eq!(remaining, [0xff, 0xff]);
37 /// let parsed = output.1;
38 /// assert_eq!(parsed.0, 0x01);
39 /// assert_eq!(parsed.1, 0x23);
41 pub fn bits
<I
, O
, E1
, E2
, P
>(mut parser
: P
) -> impl FnMut(I
) -> IResult
<I
, O
, E2
>
43 E1
: ParseError
<(I
, usize)> + ErrorConvert
<E2
>,
45 I
: Slice
<RangeFrom
<usize>>,
46 P
: Parser
<(I
, usize), O
, E1
>,
48 move |input
: I
| match parser
.parse((input
, 0)) {
49 Ok(((rest
, offset
), result
)) => {
50 // If the next byte has been partially read, it will be sliced away as well.
51 // The parser functions might already slice away all fully read bytes.
52 // That's why `offset / 8` isn't necessarily needed at all times.
53 let remaining_bytes_index
= offset
/ 8 + if offset
% 8 == 0 { 0 }
else { 1 }
;
54 Ok((rest
.slice(remaining_bytes_index
..), result
))
56 Err(Err
::Incomplete(n
)) => Err(Err
::Incomplete(n
.map(|u
| u
.get() / 8 + 1))),
57 Err(Err
::Error(e
)) => Err(Err
::Error(e
.convert())),
58 Err(Err
::Failure(e
)) => Err(Err
::Failure(e
.convert())),
62 /// Counterpart to `bits`, `bytes` transforms its bit stream input into a byte slice for the underlying
63 /// parser, allowing byte-slice parsers to work on bit streams.
65 /// A partial byte remaining in the input will be ignored and the given parser will start parsing
66 /// at the next full byte.
69 /// use nom8::bits::{bits, bytes, take};
70 /// use nom8::combinator::rest;
71 /// use nom8::error::Error;
72 /// use nom8::IResult;
74 /// fn parse(input: &[u8]) -> IResult<&[u8], (u8, u8, &[u8])> {
75 /// bits::<_, _, Error<(&[u8], usize)>, _, _>((
78 /// bytes::<_, _, Error<&[u8]>, _, _>(rest)
82 /// let input = &[0x12, 0x34, 0xff, 0xff];
84 /// assert_eq!(parse( input ), Ok(( &[][..], (0x01, 0x23, &[0xff, 0xff][..]) )));
86 pub fn bytes
<I
, O
, E1
, E2
, P
>(mut parser
: P
) -> impl FnMut((I
, usize)) -> IResult
<(I
, usize), O
, E2
>
88 E1
: ParseError
<I
> + ErrorConvert
<E2
>,
89 E2
: ParseError
<(I
, usize)>,
90 I
: Slice
<RangeFrom
<usize>> + Clone
,
93 move |(input
, offset
): (I
, usize)| {
94 let inner
= if offset
% 8 != 0 {
95 input
.slice((1 + offset
/ 8)..)
97 input
.slice((offset
/ 8)..)
99 let i
= (input
, offset
);
100 match parser
.parse(inner
) {
101 Ok((rest
, res
)) => Ok(((rest
, 0), res
)),
102 Err(Err
::Incomplete(Needed
::Unknown
)) => Err(Err
::Incomplete(Needed
::Unknown
)),
103 Err(Err
::Incomplete(Needed
::Size(sz
))) => Err(match sz
.get().checked_mul(8) {
104 Some(v
) => Err
::Incomplete(Needed
::new(v
)),
105 None
=> Err
::Failure(E2
::from_error_kind(i
, ErrorKind
::TooLarge
)),
107 Err(Err
::Error(e
)) => Err(Err
::Error(e
.convert())),
108 Err(Err
::Failure(e
)) => Err(Err
::Failure(e
.convert())),
113 /// Generates a parser taking `count` bits
117 /// # use nom8::bits::take;
118 /// # use nom8::IResult;
119 /// # use nom8::error::{Error, ErrorKind};
120 /// // Input is a tuple of (input: I, bit_offset: usize)
121 /// fn parser(input: (&[u8], usize), count: usize)-> IResult<(&[u8], usize), u8> {
122 /// take(count)(input)
125 /// // Consumes 0 bits, returns 0
126 /// assert_eq!(parser(([0b00010010].as_ref(), 0), 0), Ok((([0b00010010].as_ref(), 0), 0)));
128 /// // Consumes 4 bits, returns their values and increase offset to 4
129 /// assert_eq!(parser(([0b00010010].as_ref(), 0), 4), Ok((([0b00010010].as_ref(), 4), 0b00000001)));
131 /// // Consumes 4 bits, offset is 4, returns their values and increase offset to 0 of next byte
132 /// assert_eq!(parser(([0b00010010].as_ref(), 4), 4), Ok((([].as_ref(), 0), 0b00000010)));
134 /// // Tries to consume 12 bits but only 8 are available
135 /// assert_eq!(parser(([0b00010010].as_ref(), 0), 12), Err(nom8::Err::Error(Error{input: ([0b00010010].as_ref(), 0), code: ErrorKind::Eof })));
138 pub fn take
<I
, O
, C
, E
: ParseError
<(I
, usize)>, const STREAMING
: bool
>(
140 ) -> impl Fn((I
, usize)) -> IResult
<(I
, usize), O
, E
>
142 I
: Slice
<RangeFrom
<usize>> + InputIter
<Item
= u8> + InputLength
+ InputIsStreaming
<STREAMING
>,
144 O
: From
<u8> + AddAssign
+ Shl
<usize, Output
= O
> + Shr
<usize, Output
= O
>,
146 let count
= count
.to_usize();
147 move |input
: (I
, usize)| {
149 streaming
::take_internal(input
, count
)
151 complete
::take_internal(input
, count
)
156 /// Generates a parser taking `count` bits and comparing them to `pattern`
158 pub fn tag
<I
, O
, C
, E
: ParseError
<(I
, usize)>, const STREAMING
: bool
>(
161 ) -> impl Fn((I
, usize)) -> IResult
<(I
, usize), O
, E
>
163 I
: Slice
<RangeFrom
<usize>>
164 + InputIter
<Item
= u8>
166 + InputIsStreaming
<STREAMING
>
169 O
: From
<u8> + AddAssign
+ Shl
<usize, Output
= O
> + Shr
<usize, Output
= O
> + PartialEq
,
171 let count
= count
.to_usize();
172 move |input
: (I
, usize)| {
174 streaming
::tag_internal(input
, &pattern
, count
)
176 complete
::tag_internal(input
, &pattern
, count
)