1#![allow(deprecated)]
5
6use crate::error::{ErrorKind, ParseError};
7use crate::input::{InputIter, InputLength, Slice, ToUsize};
8use crate::lib::std::ops::{AddAssign, Div, RangeFrom, Shl, Shr};
9use crate::{Err, IResult};
10
11#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bits::take`")]
38pub fn take<I, O, C, E: ParseError<(I, usize)>>(
39 count: C,
40) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
41where
42 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
43 C: ToUsize,
44 O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O>,
45{
46 let count = count.to_usize();
47 move |input: (I, usize)| take_internal(input, count)
48}
49
50pub(crate) fn take_internal<I, O, E: ParseError<(I, usize)>>(
51 (input, bit_offset): (I, usize),
52 count: usize,
53) -> IResult<(I, usize), O, E>
54where
55 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
56 O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O>,
57{
58 if count == 0 {
59 Ok(((input, bit_offset), 0u8.into()))
60 } else {
61 let cnt = (count + bit_offset).div(8);
62 if input.input_len() * 8 < count + bit_offset {
63 Err(Err::Error(E::from_error_kind(
64 (input, bit_offset),
65 ErrorKind::Eof,
66 )))
67 } else {
68 let mut acc: O = 0_u8.into();
69 let mut offset: usize = bit_offset;
70 let mut remaining: usize = count;
71 let mut end_offset: usize = 0;
72
73 for byte in input.iter_elements().take(cnt + 1) {
74 if remaining == 0 {
75 break;
76 }
77 let val: O = if offset == 0 {
78 byte.into()
79 } else {
80 ((byte << offset) as u8 >> offset).into()
81 };
82
83 if remaining < 8 - offset {
84 acc += val >> (8 - offset - remaining);
85 end_offset = remaining + offset;
86 break;
87 } else {
88 acc += val << (remaining - (8 - offset));
89 remaining -= 8 - offset;
90 offset = 0;
91 }
92 }
93 Ok(((input.slice(cnt..), end_offset), acc))
94 }
95 }
96}
97
98#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bits::tag`")]
102pub fn tag<I, O, C, E: ParseError<(I, usize)>>(
103 pattern: O,
104 count: C,
105) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
106where
107 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength + Clone,
108 C: ToUsize,
109 O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O> + PartialEq,
110{
111 let count = count.to_usize();
112 move |input: (I, usize)| tag_internal(input, &pattern, count)
113}
114
115pub(crate) fn tag_internal<I, O, E: ParseError<(I, usize)>>(
116 input: (I, usize),
117 pattern: &O,
118 count: usize,
119) -> IResult<(I, usize), O, E>
120where
121 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength + Clone,
122 O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O> + PartialEq,
123{
124 let inp = input.clone();
125
126 take_internal(input, count).and_then(|(i, o)| {
127 if *pattern == o {
128 Ok((i, o))
129 } else {
130 Err(Err::Error(error_position!(inp, ErrorKind::TagBits)))
131 }
132 })
133}
134
135#[cfg(test)]
136mod test {
137 use super::*;
138
139 #[test]
140 fn test_take_0() {
141 let input = [0b00010010].as_ref();
142 let count = 0usize;
143 assert_eq!(count, 0usize);
144 let offset = 0usize;
145
146 let result: crate::IResult<(&[u8], usize), usize> = take(count)((input, offset));
147
148 assert_eq!(result, Ok(((input, offset), 0)));
149 }
150
151 #[test]
152 fn test_take_eof() {
153 let input = [0b00010010].as_ref();
154
155 let result: crate::IResult<(&[u8], usize), usize> = take(1usize)((input, 8));
156
157 assert_eq!(
158 result,
159 Err(crate::Err::Error(crate::error::Error {
160 input: (input, 8),
161 code: ErrorKind::Eof
162 }))
163 )
164 }
165
166 #[test]
167 fn test_take_span_over_multiple_bytes() {
168 let input = [0b00010010, 0b00110100, 0b11111111, 0b11111111].as_ref();
169
170 let result: crate::IResult<(&[u8], usize), usize> = take(24usize)((input, 4));
171
172 assert_eq!(
173 result,
174 Ok((([0b11111111].as_ref(), 4), 0b1000110100111111111111))
175 );
176 }
177}