diff --git a/src/iter.rs b/src/iter.rs index d4c7e1c..7e86c86 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -1,5 +1,3 @@ -use core::slice; - pub struct Bytes<'a> { slice: &'a [u8], pos: usize @@ -25,14 +23,14 @@ impl<'a> Bytes<'a> { } #[inline] - pub unsafe fn bump(&mut self) { + pub fn bump(&mut self) { debug_assert!(self.pos + 1 <= self.slice.len(), "overflow"); self.pos += 1; } #[allow(unused)] #[inline] - pub unsafe fn advance(&mut self, n: usize) { + pub fn advance(&mut self, n: usize) { debug_assert!(self.pos + n <= self.slice.len(), "overflow"); self.pos += n; } @@ -45,18 +43,15 @@ impl<'a> Bytes<'a> { #[inline] pub fn slice(&mut self) -> &'a [u8] { // not moving position at all, so it's safe - unsafe { - self.slice_skip(0) - } + self.slice_skip(0) } #[inline] - pub unsafe fn slice_skip(&mut self, skip: usize) -> &'a [u8] { + pub fn slice_skip(&mut self, skip: usize) -> &'a [u8] { debug_assert!(self.pos >= skip); let head_pos = self.pos - skip; - let ptr = self.slice.as_ptr(); - let head = slice::from_raw_parts(ptr, head_pos); - let tail = slice::from_raw_parts(ptr.offset(self.pos as isize), self.slice.len() - self.pos); + let head = &self.slice[..head_pos]; + let tail = &self.slice[self.pos..]; self.pos = 0; self.slice = tail; head @@ -84,11 +79,12 @@ impl<'a> Iterator for Bytes<'a> { #[inline] fn next(&mut self) -> Option { - if self.slice.len() > self.pos { - let b = unsafe { *self.slice.get_unchecked(self.pos) }; + let b = self.slice.get(self.pos); + if b.is_some() { self.pos += 1; - Some(b) - } else { + Some(*b.unwrap()) + } + else { None } } @@ -165,7 +161,7 @@ mod tests { let slice = [0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8]; let mut bytes = Bytes::new(&slice); // Skip 3 of them. - unsafe { bytes.advance(3); } + bytes.advance(3); // There should be 7 left, not enough to call next_8. assert!(bytes.next_8().is_none()); } @@ -176,7 +172,7 @@ mod tests { let slice = [0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8]; let mut bytes = Bytes::new(&slice); // Skip 2 of them. - unsafe { bytes.advance(2); } + bytes.advance(2); // There should be 8 left, just enough to call next_8. let ret = bytes.next_8(); assert!(ret.is_some()); @@ -198,7 +194,7 @@ mod tests { let slice = [0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8]; let mut bytes = Bytes::new(&slice); // Skip 1 of them. - unsafe { bytes.advance(1); } + bytes.advance(1); // There should be 9 left, more than enough to call next_8. let ret = bytes.next_8(); assert!(ret.is_some()); diff --git a/src/lib.rs b/src/lib.rs index 75b2098..760c860 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -325,12 +325,12 @@ fn skip_empty_lines(bytes: &mut Bytes) -> Result<()> { match b { Some(b'\r') => { // there's `\r`, so it's safe to bump 1 pos - unsafe { bytes.bump() }; + bytes.bump(); expect!(bytes.next() == b'\n' => Err(Error::NewLine)); }, Some(b'\n') => { // there's `\n`, so it's safe to bump 1 pos - unsafe { bytes.bump(); } + bytes.bump(); }, Some(..) => { bytes.slice(); @@ -486,22 +486,22 @@ fn parse_reason<'a>(bytes: &mut Bytes<'a>) -> Result<&'a str> { let b = next!(bytes); if b == b'\r' { expect!(bytes.next() == b'\n' => Err(Error::Status)); - return Ok(Status::Complete(unsafe { + return Ok(Status::Complete({ let bytes = bytes.slice_skip(2); if !seen_obs_text { // all bytes up till `i` must have been HTAB / SP / VCHAR - str::from_utf8_unchecked(bytes) + unsafe { str::from_utf8_unchecked(bytes) } } else { // obs-text characters were found, so return the fallback empty string "" } })); } else if b == b'\n' { - return Ok(Status::Complete(unsafe { + return Ok(Status::Complete({ let bytes = bytes.slice_skip(1); if !seen_obs_text { // all bytes up till `i` must have been HTAB / SP / VCHAR - str::from_utf8_unchecked(bytes) + unsafe { str::from_utf8_unchecked(bytes) } } else { // obs-text characters were found, so return the fallback empty string "" @@ -686,15 +686,11 @@ fn parse_headers_iter<'a, 'b>(headers: &mut &mut [Header<'a>], bytes: &'b mut By expect!(bytes.next() == b'\n' => Err(Error::HeaderValue)); count += bytes.pos(); // having just check that `\r\n` exists, it's safe to skip those 2 bytes - unsafe { - bytes.slice_skip(2) - } + bytes.slice_skip(2) } else if b == b'\n' { count += bytes.pos(); // having just check that `\r\n` exists, it's safe to skip 1 byte - unsafe { - bytes.slice_skip(1) - } + bytes.slice_skip(1) } else { return Err(Error::HeaderValue); }; diff --git a/src/simd/avx2.rs b/src/simd/avx2.rs index 368c52c..a33dbcd 100644 --- a/src/simd/avx2.rs +++ b/src/simd/avx2.rs @@ -62,7 +62,7 @@ unsafe fn match_url_char_32_avx(buf: &[u8]) -> usize { } #[cfg(target_arch = "x86")] -unsafe fn match_url_char_32_avx(_: &[u8]) -> usize { +fn match_url_char_32_avx(_: &[u8]) -> usize { unreachable!("AVX2 detection should be disabled for x86"); } @@ -111,6 +111,6 @@ unsafe fn match_header_value_char_32_avx(buf: &[u8]) -> usize { } #[cfg(target_arch = "x86")] -unsafe fn match_header_value_char_32_avx(_: &[u8]) -> usize { +fn match_header_value_char_32_avx(_: &[u8]) -> usize { unreachable!("AVX2 detection should be disabled for x86"); }