1 use core::slice; 2 3 pub struct Bytes<'a> { 4 slice: &'a [u8], 5 pos: usize 6 } 7 8 impl<'a> Bytes<'a> { 9 #[inline] new(slice: &'a [u8]) -> Bytes<'a>10 pub fn new(slice: &'a [u8]) -> Bytes<'a> { 11 Bytes { 12 slice: slice, 13 pos: 0 14 } 15 } 16 17 #[inline] pos(&self) -> usize18 pub fn pos(&self) -> usize { 19 self.pos 20 } 21 22 #[inline] peek(&self) -> Option<u8>23 pub fn peek(&self) -> Option<u8> { 24 self.slice.get(self.pos).cloned() 25 } 26 27 #[inline] bump(&mut self)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] advance(&mut self, n: usize)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] len(&self) -> usize41 pub fn len(&self) -> usize { 42 self.slice.len() 43 } 44 45 #[inline] slice(&mut self) -> &'a [u8]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] slice_skip(&mut self, skip: usize) -> &'a [u8]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] next_8<'b>(&'b mut self) -> Option<Bytes8<'b, 'a>>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 75 impl<'a> AsRef<[u8]> for Bytes<'a> { 76 #[inline] as_ref(&self) -> &[u8]77 fn as_ref(&self) -> &[u8] { 78 &self.slice[self.pos..] 79 } 80 } 81 82 impl<'a> Iterator for Bytes<'a> { 83 type Item = u8; 84 85 #[inline] next(&mut self) -> Option<u8>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 97 pub struct Bytes8<'a, 'b: 'a> { 98 bytes: &'a mut Bytes<'b>, 99 #[cfg(debug_assertions)] 100 pos: usize 101 } 102 103 macro_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 125 impl<'a, 'b: 'a> Bytes8<'a, 'b> { 126 bytes8_methods! {} 127 128 #[cfg(not(debug_assertions))] 129 #[inline] new(bytes: &'a mut Bytes<'b>) -> Bytes8<'a, 'b>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] new(bytes: &'a mut Bytes<'b>) -> Bytes8<'a, 'b>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] assert_pos(&mut self, _pos: usize)147 fn assert_pos(&mut self, _pos: usize) { 148 } 149 150 #[cfg(debug_assertions)] 151 #[inline] assert_pos(&mut self, pos: usize)152 fn assert_pos(&mut self, pos: usize) { 153 assert!(self.pos == pos); 154 self.pos += 1; 155 } 156 } 157 158 #[cfg(test)] 159 mod tests { 160 use super::Bytes; 161 162 #[test] test_next_8_too_short()163 fn test_next_8_too_short() { 164 // Start with 10 bytes. 165 let slice = [0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8]; 166 let mut bytes = Bytes::new(&slice); 167 // Skip 3 of them. 168 unsafe { bytes.advance(3); } 169 // There should be 7 left, not enough to call next_8. 170 assert!(bytes.next_8().is_none()); 171 } 172 173 #[test] test_next_8_just_right()174 fn test_next_8_just_right() { 175 // Start with 10 bytes. 176 let slice = [0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8]; 177 let mut bytes = Bytes::new(&slice); 178 // Skip 2 of them. 179 unsafe { bytes.advance(2); } 180 // There should be 8 left, just enough to call next_8. 181 let ret = bytes.next_8(); 182 assert!(ret.is_some()); 183 let mut ret = ret.unwrap(); 184 // They should be the bytes starting with 2. 185 assert_eq!(ret._0(), 2u8); 186 assert_eq!(ret._1(), 3u8); 187 assert_eq!(ret._2(), 4u8); 188 assert_eq!(ret._3(), 5u8); 189 assert_eq!(ret._4(), 6u8); 190 assert_eq!(ret._5(), 7u8); 191 assert_eq!(ret._6(), 8u8); 192 assert_eq!(ret._7(), 9u8); 193 } 194 195 #[test] test_next_8_extra()196 fn test_next_8_extra() { 197 // Start with 10 bytes. 198 let slice = [0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8]; 199 let mut bytes = Bytes::new(&slice); 200 // Skip 1 of them. 201 unsafe { bytes.advance(1); } 202 // There should be 9 left, more than enough to call next_8. 203 let ret = bytes.next_8(); 204 assert!(ret.is_some()); 205 let mut ret = ret.unwrap(); 206 // They should be the bytes starting with 1. 207 assert_eq!(ret._0(), 1u8); 208 assert_eq!(ret._1(), 2u8); 209 assert_eq!(ret._2(), 3u8); 210 assert_eq!(ret._3(), 4u8); 211 assert_eq!(ret._4(), 5u8); 212 assert_eq!(ret._5(), 6u8); 213 assert_eq!(ret._6(), 7u8); 214 assert_eq!(ret._7(), 8u8); 215 } 216 } 217