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