bit_byte_bit/
iteration.rs

1use std::iter::FusedIterator;
2use std::ptr;
3use crate::{Bits, RawBytes};
4
5
6macro_rules! skip_bits {
7    ($n:expr, $iter:expr) => {{
8        if $iter.exhausted {
9            return;
10        } else if ($iter.index + $n) >= $iter.bits.len() {
11            $iter.index = $iter.bits.len();
12            $iter.exhausted = true;
13        } else {
14            $iter.index += $n;
15        }
16    }};
17    ($iter:expr => $f:expr) => {{
18        if $iter.exhausted { return 0; }
19
20        match ($f(0), $f(1)) {
21            (true, true) => {
22                let rem = $iter.bits.len() - $iter.index;
23
24                $iter.index = $iter.bits.len();
25                $iter.exhausted = true;
26
27                rem
28            },
29            (false, false) => 0,
30            (z, _) => {
31                let ct =
32                    if z { $iter.bits.trailing_zeros() } else { $iter.bits.trailing_ones() };
33
34                if ct > $iter.index {
35                    let skipped = ct - $iter.index;
36
37                    $iter.index = ct;
38                    $iter.exhausted = $iter.index == $iter.bits.len();
39
40                    skipped
41                } else {
42                    0
43                }
44            }
45        }
46    }};
47}
48
49
50impl IntoIterator for Bits {
51    type Item = u8;
52    type IntoIter = IntoBits;
53
54    fn into_iter(self) -> Self::IntoIter { IntoBits::new(self, 0) }
55}
56
57
58pub(crate) struct Bytes {
59    start: *const u8,
60    end: *const u8
61}
62
63impl Bytes {
64    pub unsafe fn new(slice: &[u8]) -> Self {
65        Bytes {
66            start: slice.as_ptr(),
67            end: if slice.len() == 0 {
68                slice.as_ptr()
69            } else {
70                unsafe{ slice.as_ptr().add(slice.len()) }
71            }
72        }
73    }
74}
75
76impl DoubleEndedIterator for Bytes {
77    fn next_back(&mut self) -> Option<Self::Item> {
78        if self.start == self.end {
79            None
80        } else {
81            unsafe {
82                self.end = self.end.offset(-1);
83                Some(ptr::read(self.end))
84            }
85        }
86    }
87}
88
89impl ExactSizeIterator for Bytes {
90    fn len(&self) -> usize { self.end as usize - self.start as usize }
91}
92
93impl FusedIterator for Bytes { }
94
95impl Iterator for Bytes {
96    type Item = u8;
97
98    fn next(&mut self) -> Option<u8> {
99        match self.start == self.end {
100            true => None,
101            false => unsafe {
102                let old_ptr = self.start;
103                self.start = self.start.add(1);
104
105                Some(ptr::read(old_ptr))
106            }
107        }
108    }
109
110    fn size_hint(&self) -> (usize, Option<usize>) {
111        let len = self.end as usize - self.start as usize;
112
113        (len, Some(len))
114    }
115}
116
117
118pub struct Iter<'a> {
119    bits: &'a Bits,
120    index: usize,
121    exhausted: bool
122}
123
124impl<'a> Iter<'a> {
125    pub(crate)fn new(bits: &'a Bits, index: usize) -> Self {
126        Iter { bits, index, exhausted: bits.nbits == index }
127    }
128
129    /// Moves the iterator ahead until the predicate returns true.
130    ///
131    /// This method behaves like [Iterator::skip_while], but doesn't
132    /// rely on repeated calls to [Iterator::next].
133    pub fn skip_bits_while<P: FnMut(u8) -> bool>(&mut self, mut f: P) -> usize {
134        skip_bits!(self => f)
135    }
136
137    /// Moves the iterator ahead.
138    ///
139    /// This method behaves like [Iterator::skip], but doesn't rely on
140    /// repeated calls to [Iterator::next].
141    pub fn skip_bits(&mut self, n: usize) { skip_bits!(n, self); }
142}
143
144impl<'a> DoubleEndedIterator for Iter<'a> {
145    fn next_back(&mut self) -> Option<Self::Item> {
146        if self.index == 0 {
147            None
148        } else {
149            self.index -= 1;
150            self.exhausted = false;
151
152            Some(self.bits.i(self.index))
153        }
154    }
155
156    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
157        if self.index < n {
158            None
159        } else {
160            self.index -= n;
161            self.exhausted = false;
162
163            Some(self.bits.i(self.index))
164        }
165    }
166}
167
168impl<'a> ExactSizeIterator for Iter<'a> {
169    fn len(&self) -> usize { self.bits.len() - self.index }
170}
171
172impl<'a> FusedIterator for Iter<'a> { }
173
174impl<'a> Iterator for Iter<'a> {
175    type Item = u8;
176
177    fn next(&mut self) -> Option<Self::Item> {
178        match self.exhausted {
179            true => None,
180            false => {
181                let bit = self.bits.i(self.index);
182                self.index += 1;
183                self.exhausted = self.bits.len() == self.index;
184
185                Some(bit)
186            }
187        }
188    }
189
190    fn size_hint(&self) -> (usize, Option<usize>) {
191        let rem = self.bits.len() - self.index;
192
193        (rem, Some(rem))
194    }
195
196    fn count(mut self) -> usize {
197        let rem = self.bits.len() - self.index;
198
199        self.index = self.bits.len();
200        self.exhausted = true;
201
202        rem
203    }
204
205    fn last(mut self) -> Option<u8> {
206        if self.exhausted {
207            None
208        } else {
209            let bit = self.bits.i(self.bits.len() - 1);
210
211            self.index = self.bits.len();
212            self.exhausted = true;
213
214            Some(bit)
215        }
216    }
217
218    fn nth(&mut self, n: usize) -> Option<u8> {
219        if self.exhausted {
220            None
221        } else if self.index + n >= self.bits.len() {
222            self.index = self.bits.len();
223            self.exhausted = true;
224
225            None
226        } else {
227            let bit = self.bits.i(self.index + n);
228            self.index += n + 1;
229            self.exhausted = self.index == self.bits.len();
230
231            Some(bit)
232        }
233    }
234}
235
236
237pub struct IntoBits {
238    bits: Bits,
239    index: usize,
240    exhausted: bool
241}
242
243impl IntoBits {
244    pub(crate) fn new(bits: Bits, index: usize) -> Self {
245        let exhausted = bits.nbits == index;
246
247        IntoBits { bits, index, exhausted }
248    }
249
250    /// Moves the iterator ahead until the predicate returns true.
251    ///
252    /// This method behaves like [Iterator::skip_while], but doesn't
253    /// rely on repeated calls to [Iterator::next], instead on the
254    /// return values to `f(0)` and `f(1)`.
255    pub fn skip_bits_while<P: FnMut(u8) -> bool>(&mut self, mut f: P) -> usize {
256        skip_bits!(self => f)
257    }
258
259    /// Moves the iterator ahead.
260    ///
261    /// This method behaves like [Iterator::skip], but doesn't rely on
262    /// repeated calls to [Iterator::next].
263    pub fn skip_bits(&mut self, n: usize) { skip_bits!(n, self); }
264}
265
266impl DoubleEndedIterator for IntoBits {
267    fn next_back(&mut self) -> Option<Self::Item> {
268        if self.index == 0 {
269            None
270        } else {
271            self.index -= 1;
272            self.exhausted = false;
273
274            Some(self.bits.i(self.index))
275        }
276    }
277
278    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
279        if self.index < n {
280            None
281        } else {
282            self.index -= n;
283            self.exhausted = false;
284
285            Some(self.bits.i(self.index))
286        }
287    }
288}
289
290impl ExactSizeIterator for IntoBits {
291    fn len(&self) -> usize { self.bits.len() - self.index }
292}
293
294impl FusedIterator for IntoBits { }
295
296impl Iterator for IntoBits {
297    type Item = u8;
298
299    fn next(&mut self) -> Option<Self::Item> {
300        match self.exhausted {
301            true => None,
302            false => {
303                let bit = self.bits.i(self.index);
304                self.index += 1;
305                self.exhausted = self.bits.len() == self.index;
306
307                Some(bit)
308            }
309        }
310    }
311
312    fn size_hint(&self) -> (usize, Option<usize>) {
313        let rem = self.bits.len() - self.index;
314
315        (rem, Some(rem))
316    }
317
318    fn count(mut self) -> usize {
319        let rem = self.bits.len() - self.index;
320
321        self.index = self.bits.len();
322        self.exhausted = true;
323
324        rem
325    }
326
327    fn last(mut self) -> Option<u8> {
328        if self.exhausted {
329            None
330        } else {
331            let bit = self.bits.i(self.bits.len() - 1);
332
333            self.index = self.bits.len();
334            self.exhausted = true;
335
336            Some(bit)
337        }
338    }
339
340    fn nth(&mut self, n: usize) -> Option<u8> {
341        if self.exhausted {
342            None
343        } else if self.index + n >= self.bits.len() {
344            self.index = self.bits.len();
345            self.exhausted = true;
346
347            None
348        } else {
349            let bit = self.bits.i(self.index + n);
350            self.index += n + 1;
351            self.exhausted = self.index == self.bits.len();
352
353            Some(bit)
354        }
355    }
356}
357
358
359pub struct IntoBytes {
360    _bytes: RawBytes,
361    iter: Bytes
362}
363
364impl IntoBytes {
365    pub(crate) fn new(bytes: Bytes, raw_bytes: RawBytes) -> Self {
366        IntoBytes { _bytes: raw_bytes, iter: bytes }
367    }
368}
369
370impl DoubleEndedIterator for IntoBytes {
371    fn next_back(&mut self) -> Option<Self::Item> { self.iter.next_back() }
372}
373
374impl Drop for IntoBytes {
375    fn drop(&mut self) { for _ in &mut *self { } }
376}
377
378impl ExactSizeIterator for IntoBytes {
379    fn len(&self) -> usize { self.iter.len() }
380}
381
382impl FusedIterator for IntoBytes { }
383
384impl Iterator for IntoBytes {
385    type Item = u8;
386
387    fn next(&mut self) -> Option<u8> { self.iter.next() }
388
389    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
390}