rtsparse/
iter.rs

1use core::slice;
2
3pub struct Bytes<'a> {
4    slice: &'a [u8],
5    pos: usize
6}
7
8impl<'a> Bytes<'a> {
9    #[inline]
10    pub fn new(slice: &'a [u8]) -> Bytes<'a> {
11        Bytes {
12            slice: slice,
13            pos: 0
14        }
15    }
16
17    #[inline]
18    pub fn pos(&self) -> usize {
19        self.pos
20    }
21
22    #[inline]
23    pub fn peek(&self) -> Option<u8> {
24        self.slice.get(self.pos).cloned()
25    }
26
27    #[inline]
28    pub unsafe fn bump(&mut self) {
29        debug_assert!(self.pos + 1 <= self.slice.len(), "overflow");
30        self.pos += 1;
31    }
32
33    #[allow(unused)]
34    #[inline]
35    pub unsafe fn advance(&mut self, n: usize) {
36        debug_assert!(self.pos + n <= self.slice.len(), "overflow");
37        self.pos += n;
38    }
39
40    #[inline]
41    pub fn len(&self) -> usize {
42        self.slice.len()
43    }
44
45    #[inline]
46    pub fn slice(&mut self) -> &'a [u8] {
47        // not moving position at all, so it's safe
48        unsafe {
49            self.slice_skip(0)
50        }
51    }
52
53    #[inline]
54    pub unsafe fn slice_skip(&mut self, skip: usize) -> &'a [u8] {
55        debug_assert!(self.pos >= skip);
56        let head_pos = self.pos - skip;
57        let ptr = self.slice.as_ptr();
58        let head = slice::from_raw_parts(ptr, head_pos);
59        let tail = slice::from_raw_parts(ptr.offset(self.pos as isize), self.slice.len() - self.pos);
60        self.pos = 0;
61        self.slice = tail;
62        head
63    }
64
65    #[inline]
66    pub fn next_8<'b>(&'b mut self) -> Option<Bytes8<'b, 'a>> {
67        if self.slice.len() > self.pos + 8 {
68            Some(Bytes8::new(self))
69        } else {
70            None
71        }
72    }
73}
74
75impl<'a> AsRef<[u8]> for Bytes<'a> {
76    #[inline]
77    fn as_ref(&self) -> &[u8] {
78        &self.slice[self.pos..]
79    }
80}
81
82impl<'a> Iterator for Bytes<'a> {
83    type Item = u8;
84
85    #[inline]
86    fn next(&mut self) -> Option<u8> {
87        if self.slice.len() > self.pos {
88            let b = unsafe { *self.slice.get_unchecked(self.pos) };
89            self.pos += 1;
90            Some(b)
91        } else {
92            None
93        }
94    }
95}
96
97pub struct Bytes8<'a, 'b: 'a> {
98    bytes: &'a mut Bytes<'b>,
99    #[cfg(debug_assertions)]
100    pos: usize
101}
102
103macro_rules! bytes8_methods {
104    ($f:ident, $pos:expr) => {
105        #[inline]
106        pub fn $f(&mut self) -> u8 {
107            self.assert_pos($pos);
108            let b = unsafe { *self.bytes.slice.get_unchecked(self.bytes.pos) };
109            self.bytes.pos += 1;
110            b
111        }
112    };
113    () => {
114        bytes8_methods!(_0, 0);
115        bytes8_methods!(_1, 1);
116        bytes8_methods!(_2, 2);
117        bytes8_methods!(_3, 3);
118        bytes8_methods!(_4, 4);
119        bytes8_methods!(_5, 5);
120        bytes8_methods!(_6, 6);
121        bytes8_methods!(_7, 7);
122    }
123}
124
125impl<'a, 'b: 'a> Bytes8<'a, 'b> {
126    bytes8_methods! {}
127
128    #[cfg(not(debug_assertions))]
129    #[inline]
130    fn new(bytes: &'a mut Bytes<'b>) -> Bytes8<'a, 'b> {
131        Bytes8 {
132            bytes: bytes,
133        }
134    }
135
136    #[cfg(debug_assertions)]
137    #[inline]
138    fn new(bytes: &'a mut Bytes<'b>) -> Bytes8<'a, 'b> {
139        Bytes8 {
140            bytes: bytes,
141            pos: 0,
142        }
143    }
144
145    #[cfg(not(debug_assertions))]
146    #[inline]
147    fn assert_pos(&mut self, _pos: usize) {
148    }
149
150    #[cfg(debug_assertions)]
151    #[inline]
152    fn assert_pos(&mut self, pos: usize) {
153        assert!(self.pos == pos);
154        self.pos += 1;
155    }
156}