• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use core::slice;
2 use core::convert::TryInto;
3 use core::convert::TryFrom;
4 
5 pub struct Bytes<'a> {
6     slice: &'a [u8],
7     pos: usize
8 }
9 
10 impl<'a> Bytes<'a> {
11     #[inline]
new(slice: &'a [u8]) -> Bytes<'a>12     pub fn new(slice: &'a [u8]) -> Bytes<'a> {
13         Bytes {
14             slice,
15             pos: 0
16         }
17     }
18 
19     #[inline]
pos(&self) -> usize20     pub fn pos(&self) -> usize {
21         self.pos
22     }
23 
24     #[inline]
peek(&self) -> Option<u8>25     pub fn peek(&self) -> Option<u8> {
26         self.peek_ahead(0)
27     }
28 
29     #[inline]
peek_ahead(&self, n: usize) -> Option<u8>30     pub fn peek_ahead(&self, n: usize) -> Option<u8> {
31         self.slice.get(self.pos + n).copied()
32     }
33 
34     #[inline]
peek_n<U: TryFrom<&'a[u8]>>(&self, n: usize) -> Option<U>35     pub fn peek_n<U: TryFrom<&'a[u8]>>(&self, n: usize) -> Option<U> {
36         self.slice.get(self.pos..self.pos + n)?.try_into().ok()
37     }
38 
39     #[inline]
bump(&mut self)40     pub unsafe fn bump(&mut self) {
41         debug_assert!(self.pos < self.slice.len(), "overflow");
42         self.pos += 1;
43     }
44 
45     #[allow(unused)]
46     #[inline]
advance(&mut self, n: usize)47     pub unsafe fn advance(&mut self, n: usize) {
48         debug_assert!(self.pos + n <= self.slice.len(), "overflow");
49         self.pos += n;
50     }
51 
52     #[inline]
len(&self) -> usize53     pub fn len(&self) -> usize {
54         self.slice.len()
55     }
56 
57     #[inline]
slice(&mut self) -> &'a [u8]58     pub fn slice(&mut self) -> &'a [u8] {
59         // not moving position at all, so it's safe
60         unsafe {
61             self.slice_skip(0)
62         }
63     }
64 
65     #[inline]
slice_skip(&mut self, skip: usize) -> &'a [u8]66     pub unsafe fn slice_skip(&mut self, skip: usize) -> &'a [u8] {
67         debug_assert!(self.pos >= skip);
68         let head_pos = self.pos - skip;
69         let ptr = self.slice.as_ptr();
70         let head = slice::from_raw_parts(ptr, head_pos);
71         let tail = slice::from_raw_parts(ptr.add(self.pos), self.slice.len() - self.pos);
72         self.pos = 0;
73         self.slice = tail;
74         head
75     }
76 
77     #[inline]
advance_and_commit(&mut self, n: usize)78     pub unsafe fn advance_and_commit(&mut self, n: usize) {
79         debug_assert!(self.pos + n <= self.slice.len(), "overflow");
80         self.pos += n;
81         let ptr = self.slice.as_ptr();
82         let tail = slice::from_raw_parts(ptr.add(n), self.slice.len() - n);
83         self.pos = 0;
84         self.slice = tail;
85     }
86 }
87 
88 impl<'a> AsRef<[u8]> for Bytes<'a> {
89     #[inline]
as_ref(&self) -> &[u8]90     fn as_ref(&self) -> &[u8] {
91         &self.slice[self.pos..]
92     }
93 }
94 
95 impl<'a> Iterator for Bytes<'a> {
96     type Item = u8;
97 
98     #[inline]
next(&mut self) -> Option<u8>99     fn next(&mut self) -> Option<u8> {
100         if self.slice.len() > self.pos {
101             let b = unsafe { *self.slice.get_unchecked(self.pos) };
102             self.pos += 1;
103             Some(b)
104         } else {
105             None
106         }
107     }
108 }
109