diff options
Diffstat (limited to 'src/octets.rs')
-rw-r--r-- | src/octets.rs | 1277 |
1 files changed, 0 insertions, 1277 deletions
diff --git a/src/octets.rs b/src/octets.rs deleted file mode 100644 index 3983667..0000000 --- a/src/octets.rs +++ /dev/null @@ -1,1277 +0,0 @@ -// Copyright (C) 2018-2019, Cloudflare, Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#![allow(dead_code)] - -/// Zero-copy abstraction for parsing and constructing network packets. -use std::mem; -use std::ptr; - -/// A specialized [`Result`] type for [`OctetsMut`] operations. -/// -/// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html -/// [`OctetsMut`]: struct.OctetsMut.html -pub type Result<T> = std::result::Result<T, BufferTooShortError>; - -/// An error indicating that the provided [`OctetsMut`] is not big enough. -/// -/// [`OctetsMut`]: struct.OctetsMut.html -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct BufferTooShortError; - -impl std::fmt::Display for BufferTooShortError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "BufferTooShortError") - } -} - -impl std::error::Error for BufferTooShortError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - None - } -} - -macro_rules! peek_u { - ($b:expr, $ty:ty, $len:expr) => {{ - let len = $len; - let src = &$b.buf[$b.off..]; - - if src.len() < len { - return Err(BufferTooShortError); - } - - let mut out: $ty = 0; - unsafe { - let dst = &mut out as *mut $ty as *mut u8; - let off = (mem::size_of::<$ty>() - len) as isize; - - ptr::copy_nonoverlapping(src.as_ptr(), dst.offset(off), len); - }; - - Ok(<$ty>::from_be(out)) - }}; -} - -macro_rules! get_u { - ($b:expr, $ty:ty, $len:expr) => {{ - let out = peek_u!($b, $ty, $len); - - $b.off += $len; - - out - }}; -} - -macro_rules! put_u { - ($b:expr, $ty:ty, $v:expr, $len:expr) => {{ - let len = $len; - - if $b.buf.len() < $b.off + len { - return Err(BufferTooShortError); - } - - let v = $v; - - #[allow(clippy::range_plus_one)] - let dst = &mut $b.buf[$b.off..($b.off + len)]; - - unsafe { - let src = &<$ty>::to_be(v) as *const $ty as *const u8; - let off = (mem::size_of::<$ty>() - len) as isize; - - ptr::copy_nonoverlapping(src.offset(off), dst.as_mut_ptr(), len); - } - - $b.off += $len; - - Ok(dst) - }}; -} - -/// A zero-copy immutable byte buffer. -/// -/// `Octets` wraps an in-memory buffer of bytes and provides utility functions -/// for manipulating it. The underlying buffer is provided by the user and is -/// not copied when creating an `Octets`. Operations are panic-free and will -/// avoid indexing the buffer past its end. -/// -/// Additionally, an offset (initially set to the start of the buffer) is -/// incremented as bytes are read from / written to the buffer, to allow for -/// sequential operations. -#[derive(Debug, PartialEq)] -pub struct Octets<'a> { - buf: &'a [u8], - off: usize, -} - -impl<'a> Octets<'a> { - /// Creates an `Octets` from the given slice, without copying. - /// - /// Since there's no copy, the input slice needs to be mutable to allow - /// modifications. - pub fn with_slice(buf: &'a [u8]) -> Self { - Octets { buf, off: 0 } - } - - /// Reads an unsigned 8-bit integer from the current offset and advances - /// the buffer. - pub fn get_u8(&mut self) -> Result<u8> { - get_u!(self, u8, 1) - } - - /// Reads an unsigned 8-bit integer from the current offset without - /// advancing the buffer. - pub fn peek_u8(&mut self) -> Result<u8> { - peek_u!(self, u8, 1) - } - - /// Reads an unsigned 16-bit integer in network byte-order from the current - /// offset and advances the buffer. - pub fn get_u16(&mut self) -> Result<u16> { - get_u!(self, u16, 2) - } - - /// Reads an unsigned 24-bit integer in network byte-order from the current - /// offset and advances the buffer. - pub fn get_u24(&mut self) -> Result<u32> { - get_u!(self, u32, 3) - } - - /// Reads an unsigned 32-bit integer in network byte-order from the current - /// offset and advances the buffer. - pub fn get_u32(&mut self) -> Result<u32> { - get_u!(self, u32, 4) - } - - /// Reads an unsigned 64-bit integer in network byte-order from the current - /// offset and advances the buffer. - pub fn get_u64(&mut self) -> Result<u64> { - get_u!(self, u64, 8) - } - - /// Reads an unsigned variable-length integer in network byte-order from - /// the current offset and advances the buffer. - pub fn get_varint(&mut self) -> Result<u64> { - let first = self.peek_u8()?; - - let len = varint_parse_len(first); - - if len > self.cap() { - return Err(BufferTooShortError); - } - - let out = match len { - 1 => u64::from(self.get_u8()?), - - 2 => u64::from(self.get_u16()? & 0x3fff), - - 4 => u64::from(self.get_u32()? & 0x3fffffff), - - 8 => self.get_u64()? & 0x3fffffffffffffff, - - _ => unreachable!(), - }; - - Ok(out) - } - - /// Reads `len` bytes from the current offset without copying and advances - /// the buffer. - pub fn get_bytes(&mut self, len: usize) -> Result<Octets> { - if self.cap() < len { - return Err(BufferTooShortError); - } - - let out = Octets { - buf: &self.buf[self.off..self.off + len], - off: 0, - }; - - self.off += len; - - Ok(out) - } - - /// Reads `len` bytes from the current offset without copying and advances - /// the buffer, where `len` is an unsigned 8-bit integer prefix. - pub fn get_bytes_with_u8_length(&mut self) -> Result<Octets> { - let len = self.get_u8()?; - self.get_bytes(len as usize) - } - - /// Reads `len` bytes from the current offset without copying and advances - /// the buffer, where `len` is an unsigned 16-bit integer prefix in network - /// byte-order. - pub fn get_bytes_with_u16_length(&mut self) -> Result<Octets> { - let len = self.get_u16()?; - self.get_bytes(len as usize) - } - - /// Reads `len` bytes from the current offset without copying and advances - /// the buffer, where `len` is an unsigned variable-length integer prefix - /// in network byte-order. - pub fn get_bytes_with_varint_length(&mut self) -> Result<Octets> { - let len = self.get_varint()?; - self.get_bytes(len as usize) - } - - /// Reads `len` bytes from the current offset without copying and without - /// advancing the buffer. - pub fn peek_bytes(&self, len: usize) -> Result<Octets> { - if self.cap() < len { - return Err(BufferTooShortError); - } - - let out = Octets { - buf: &self.buf[self.off..self.off + len], - off: 0, - }; - - Ok(out) - } - - /// Returns a slice of `len` elements from the current offset. - pub fn slice(&'a self, len: usize) -> Result<&'a [u8]> { - if len > self.cap() { - return Err(BufferTooShortError); - } - - Ok(&self.buf[self.off..self.off + len]) - } - - /// Returns a slice of `len` elements from the end of the buffer. - pub fn slice_last(&'a self, len: usize) -> Result<&'a [u8]> { - if len > self.cap() { - return Err(BufferTooShortError); - } - - let cap = self.cap(); - Ok(&self.buf[cap - len..]) - } - - /// Advances the buffer's offset. - pub fn skip(&mut self, skip: usize) -> Result<()> { - if skip > self.cap() { - return Err(BufferTooShortError); - } - - self.off += skip; - - Ok(()) - } - - /// Returns the remaining capacity in the buffer. - pub fn cap(&self) -> usize { - self.buf.len() - self.off - } - - /// Returns the total length of the buffer. - pub fn len(&self) -> usize { - self.buf.len() - } - - /// Returns the current offset of the buffer. - pub fn off(&self) -> usize { - self.off - } - - /// Returns a reference to the internal buffer. - pub fn buf(&self) -> &[u8] { - self.buf - } - - /// Copies the buffer from the current offset into a new `Vec<u8>`. - pub fn to_vec(&self) -> Vec<u8> { - self.as_ref().to_vec() - } -} - -impl<'a> AsRef<[u8]> for Octets<'a> { - fn as_ref(&self) -> &[u8] { - &self.buf[self.off..] - } -} - -/// A zero-copy mutable byte buffer. -/// -/// Like `Octets` but mutable. -#[derive(Debug, PartialEq)] -pub struct OctetsMut<'a> { - buf: &'a mut [u8], - off: usize, -} - -impl<'a> OctetsMut<'a> { - /// Creates an `OctetsMut` from the given slice, without copying. - /// - /// Since there's no copy, the input slice needs to be mutable to allow - /// modifications. - pub fn with_slice(buf: &'a mut [u8]) -> Self { - OctetsMut { buf, off: 0 } - } - - /// Reads an unsigned 8-bit integer from the current offset and advances - /// the buffer. - pub fn get_u8(&mut self) -> Result<u8> { - get_u!(self, u8, 1) - } - - /// Reads an unsigned 8-bit integer from the current offset without - /// advancing the buffer. - pub fn peek_u8(&mut self) -> Result<u8> { - peek_u!(self, u8, 1) - } - - /// Writes an unsigned 8-bit integer at the current offset and advances - /// the buffer. - pub fn put_u8(&mut self, v: u8) -> Result<&mut [u8]> { - put_u!(self, u8, v, 1) - } - - /// Reads an unsigned 16-bit integer in network byte-order from the current - /// offset and advances the buffer. - pub fn get_u16(&mut self) -> Result<u16> { - get_u!(self, u16, 2) - } - - /// Writes an unsigned 16-bit integer in network byte-order at the current - /// offset and advances the buffer. - pub fn put_u16(&mut self, v: u16) -> Result<&mut [u8]> { - put_u!(self, u16, v, 2) - } - - /// Reads an unsigned 24-bit integer in network byte-order from the current - /// offset and advances the buffer. - pub fn get_u24(&mut self) -> Result<u32> { - get_u!(self, u32, 3) - } - - /// Writes an unsigned 24-bit integer in network byte-order at the current - /// offset and advances the buffer. - pub fn put_u24(&mut self, v: u32) -> Result<&mut [u8]> { - put_u!(self, u32, v, 3) - } - - /// Reads an unsigned 32-bit integer in network byte-order from the current - /// offset and advances the buffer. - pub fn get_u32(&mut self) -> Result<u32> { - get_u!(self, u32, 4) - } - - /// Writes an unsigned 32-bit integer in network byte-order at the current - /// offset and advances the buffer. - pub fn put_u32(&mut self, v: u32) -> Result<&mut [u8]> { - put_u!(self, u32, v, 4) - } - - /// Reads an unsigned 64-bit integer in network byte-order from the current - /// offset and advances the buffer. - pub fn get_u64(&mut self) -> Result<u64> { - get_u!(self, u64, 8) - } - - /// Writes an unsigned 64-bit integer in network byte-order at the current - /// offset and advances the buffer. - pub fn put_u64(&mut self, v: u64) -> Result<&mut [u8]> { - put_u!(self, u64, v, 8) - } - - /// Reads an unsigned variable-length integer in network byte-order from - /// the current offset and advances the buffer. - pub fn get_varint(&mut self) -> Result<u64> { - let first = self.peek_u8()?; - - let len = varint_parse_len(first); - - if len > self.cap() { - return Err(BufferTooShortError); - } - - let out = match len { - 1 => u64::from(self.get_u8()?), - - 2 => u64::from(self.get_u16()? & 0x3fff), - - 4 => u64::from(self.get_u32()? & 0x3fffffff), - - 8 => self.get_u64()? & 0x3fffffffffffffff, - - _ => unreachable!(), - }; - - Ok(out) - } - - /// Writes an unsigned variable-length integer in network byte-order at the - /// current offset and advances the buffer. - pub fn put_varint(&mut self, v: u64) -> Result<&mut [u8]> { - self.put_varint_with_len(v, varint_len(v)) - } - - /// Writes an unsigned variable-length integer of the specified length, in - /// network byte-order at the current offset and advances the buffer. - pub fn put_varint_with_len( - &mut self, v: u64, len: usize, - ) -> Result<&mut [u8]> { - if self.cap() < len { - return Err(BufferTooShortError); - } - - let buf = match len { - 1 => self.put_u8(v as u8)?, - - 2 => { - let buf = self.put_u16(v as u16)?; - buf[0] |= 0x40; - buf - }, - - 4 => { - let buf = self.put_u32(v as u32)?; - buf[0] |= 0x80; - buf - }, - - 8 => { - let buf = self.put_u64(v)?; - buf[0] |= 0xc0; - buf - }, - - _ => panic!("value is too large for varint"), - }; - - Ok(buf) - } - - /// Reads `len` bytes from the current offset without copying and advances - /// the buffer. - pub fn get_bytes(&mut self, len: usize) -> Result<Octets> { - if self.cap() < len { - return Err(BufferTooShortError); - } - - let out = Octets { - buf: &self.buf[self.off..self.off + len], - off: 0, - }; - - self.off += len; - - Ok(out) - } - - /// Reads `len` bytes from the current offset without copying and advances - /// the buffer. - pub fn get_bytes_mut(&mut self, len: usize) -> Result<OctetsMut> { - if self.cap() < len { - return Err(BufferTooShortError); - } - - let out = OctetsMut { - buf: &mut self.buf[self.off..self.off + len], - off: 0, - }; - - self.off += len; - - Ok(out) - } - - /// Reads `len` bytes from the current offset without copying and advances - /// the buffer, where `len` is an unsigned 8-bit integer prefix. - pub fn get_bytes_with_u8_length(&mut self) -> Result<Octets> { - let len = self.get_u8()?; - self.get_bytes(len as usize) - } - - /// Reads `len` bytes from the current offset without copying and advances - /// the buffer, where `len` is an unsigned 16-bit integer prefix in network - /// byte-order. - pub fn get_bytes_with_u16_length(&mut self) -> Result<Octets> { - let len = self.get_u16()?; - self.get_bytes(len as usize) - } - - /// Reads `len` bytes from the current offset without copying and advances - /// the buffer, where `len` is an unsigned variable-length integer prefix - /// in network byte-order. - pub fn get_bytes_with_varint_length(&mut self) -> Result<Octets> { - let len = self.get_varint()?; - self.get_bytes(len as usize) - } - - /// Reads `len` bytes from the current offset without copying and without - /// advancing the buffer. - pub fn peek_bytes(&mut self, len: usize) -> Result<Octets> { - if self.cap() < len { - return Err(BufferTooShortError); - } - - let out = Octets { - buf: &self.buf[self.off..self.off + len], - off: 0, - }; - - Ok(out) - } - - /// Reads `len` bytes from the current offset without copying and without - /// advancing the buffer. - pub fn peek_bytes_mut(&mut self, len: usize) -> Result<OctetsMut> { - if self.cap() < len { - return Err(BufferTooShortError); - } - - let out = OctetsMut { - buf: &mut self.buf[self.off..self.off + len], - off: 0, - }; - - Ok(out) - } - - /// Writes `len` bytes from the current offset without copying and advances - /// the buffer. - pub fn put_bytes(&mut self, v: &[u8]) -> Result<()> { - let len = v.len(); - - if self.cap() < len { - return Err(BufferTooShortError); - } - - if len == 0 { - return Ok(()); - } - - self.as_mut()[..len].copy_from_slice(v); - - self.off += len; - - Ok(()) - } - - /// Splits the buffer in two at the given absolute offset. - pub fn split_at(&mut self, off: usize) -> Result<(OctetsMut, OctetsMut)> { - if self.len() < off { - return Err(BufferTooShortError); - } - - let (left, right) = self.buf.split_at_mut(off); - - let first = OctetsMut { buf: left, off: 0 }; - - let last = OctetsMut { buf: right, off: 0 }; - - Ok((first, last)) - } - - /// Returns a slice of `len` elements from the current offset. - pub fn slice(&'a mut self, len: usize) -> Result<&'a mut [u8]> { - if len > self.cap() { - return Err(BufferTooShortError); - } - - Ok(&mut self.buf[self.off..self.off + len]) - } - - /// Returns a slice of `len` elements from the end of the buffer. - pub fn slice_last(&'a mut self, len: usize) -> Result<&'a mut [u8]> { - if len > self.cap() { - return Err(BufferTooShortError); - } - - let cap = self.cap(); - Ok(&mut self.buf[cap - len..]) - } - - /// Advances the buffer's offset. - pub fn skip(&mut self, skip: usize) -> Result<()> { - if skip > self.cap() { - return Err(BufferTooShortError); - } - - self.off += skip; - - Ok(()) - } - - /// Returns the remaining capacity in the buffer. - pub fn cap(&self) -> usize { - self.buf.len() - self.off - } - - /// Returns the total length of the buffer. - pub fn len(&self) -> usize { - self.buf.len() - } - - /// Returns the current offset of the buffer. - pub fn off(&self) -> usize { - self.off - } - - /// Returns a reference to the internal buffer. - pub fn buf(&self) -> &[u8] { - self.buf - } - - /// Copies the buffer from the current offset into a new `Vec<u8>`. - pub fn to_vec(&self) -> Vec<u8> { - self.as_ref().to_vec() - } -} - -impl<'a> AsRef<[u8]> for OctetsMut<'a> { - fn as_ref(&self) -> &[u8] { - &self.buf[self.off..] - } -} - -impl<'a> AsMut<[u8]> for OctetsMut<'a> { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.buf[self.off..] - } -} - -/// Returns how many bytes it would take to encode `v` as a variable-length -/// integer. -pub fn varint_len(v: u64) -> usize { - if v <= 63 { - 1 - } else if v <= 16383 { - 2 - } else if v <= 1_073_741_823 { - 4 - } else if v <= 4_611_686_018_427_387_903 { - 8 - } else { - unreachable!() - } -} - -/// Returns how long the variable-length integer is, given its first byte. -pub fn varint_parse_len(first: u8) -> usize { - match first >> 6 { - 0 => 1, - 1 => 2, - 2 => 4, - 3 => 8, - _ => unreachable!(), - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn get_u() { - let d = [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - ]; - - let mut b = Octets::with_slice(&d); - assert_eq!(b.cap(), 18); - assert_eq!(b.off(), 0); - - assert_eq!(b.get_u8().unwrap(), 1); - assert_eq!(b.cap(), 17); - assert_eq!(b.off(), 1); - - assert_eq!(b.get_u16().unwrap(), 0x203); - assert_eq!(b.cap(), 15); - assert_eq!(b.off(), 3); - - assert_eq!(b.get_u24().unwrap(), 0x40506); - assert_eq!(b.cap(), 12); - assert_eq!(b.off(), 6); - - assert_eq!(b.get_u32().unwrap(), 0x0708090a); - assert_eq!(b.cap(), 8); - assert_eq!(b.off(), 10); - - assert_eq!(b.get_u64().unwrap(), 0x0b0c0d0e0f101112); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 18); - - assert!(b.get_u8().is_err()); - assert!(b.get_u16().is_err()); - assert!(b.get_u24().is_err()); - assert!(b.get_u32().is_err()); - assert!(b.get_u64().is_err()); - } - - #[test] - fn get_u_mut() { - let mut d = [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - ]; - - let mut b = OctetsMut::with_slice(&mut d); - assert_eq!(b.cap(), 18); - assert_eq!(b.off(), 0); - - assert_eq!(b.get_u8().unwrap(), 1); - assert_eq!(b.cap(), 17); - assert_eq!(b.off(), 1); - - assert_eq!(b.get_u16().unwrap(), 0x203); - assert_eq!(b.cap(), 15); - assert_eq!(b.off(), 3); - - assert_eq!(b.get_u24().unwrap(), 0x40506); - assert_eq!(b.cap(), 12); - assert_eq!(b.off(), 6); - - assert_eq!(b.get_u32().unwrap(), 0x0708090a); - assert_eq!(b.cap(), 8); - assert_eq!(b.off(), 10); - - assert_eq!(b.get_u64().unwrap(), 0x0b0c0d0e0f101112); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 18); - - assert!(b.get_u8().is_err()); - assert!(b.get_u16().is_err()); - assert!(b.get_u24().is_err()); - assert!(b.get_u32().is_err()); - assert!(b.get_u64().is_err()); - } - - #[test] - fn peek_u() { - let d = [1, 2]; - - let mut b = Octets::with_slice(&d); - assert_eq!(b.cap(), 2); - assert_eq!(b.off(), 0); - - assert_eq!(b.peek_u8().unwrap(), 1); - assert_eq!(b.cap(), 2); - assert_eq!(b.off(), 0); - - assert_eq!(b.peek_u8().unwrap(), 1); - assert_eq!(b.cap(), 2); - assert_eq!(b.off(), 0); - - b.get_u16().unwrap(); - - assert!(b.peek_u8().is_err()); - } - - #[test] - fn peek_u_mut() { - let mut d = [1, 2]; - - let mut b = OctetsMut::with_slice(&mut d); - assert_eq!(b.cap(), 2); - assert_eq!(b.off(), 0); - - assert_eq!(b.peek_u8().unwrap(), 1); - assert_eq!(b.cap(), 2); - assert_eq!(b.off(), 0); - - assert_eq!(b.peek_u8().unwrap(), 1); - assert_eq!(b.cap(), 2); - assert_eq!(b.off(), 0); - - b.get_u16().unwrap(); - - assert!(b.peek_u8().is_err()); - } - - #[test] - fn get_bytes() { - let d = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - let mut b = Octets::with_slice(&d); - assert_eq!(b.cap(), 10); - assert_eq!(b.off(), 0); - - assert_eq!(b.get_bytes(5).unwrap().as_ref(), [1, 2, 3, 4, 5]); - assert_eq!(b.cap(), 5); - assert_eq!(b.off(), 5); - - assert_eq!(b.get_bytes(3).unwrap().as_ref(), [6, 7, 8]); - assert_eq!(b.cap(), 2); - assert_eq!(b.off(), 8); - - assert!(b.get_bytes(3).is_err()); - assert_eq!(b.cap(), 2); - assert_eq!(b.off(), 8); - - assert_eq!(b.get_bytes(2).unwrap().as_ref(), [9, 10]); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 10); - - assert!(b.get_bytes(2).is_err()); - } - - #[test] - fn get_bytes_mut() { - let mut d = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - let mut b = OctetsMut::with_slice(&mut d); - assert_eq!(b.cap(), 10); - assert_eq!(b.off(), 0); - - assert_eq!(b.get_bytes(5).unwrap().as_ref(), [1, 2, 3, 4, 5]); - assert_eq!(b.cap(), 5); - assert_eq!(b.off(), 5); - - assert_eq!(b.get_bytes(3).unwrap().as_ref(), [6, 7, 8]); - assert_eq!(b.cap(), 2); - assert_eq!(b.off(), 8); - - assert!(b.get_bytes(3).is_err()); - assert_eq!(b.cap(), 2); - assert_eq!(b.off(), 8); - - assert_eq!(b.get_bytes(2).unwrap().as_ref(), [9, 10]); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 10); - - assert!(b.get_bytes(2).is_err()); - } - - #[test] - fn peek_bytes() { - let d = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - let mut b = Octets::with_slice(&d); - assert_eq!(b.cap(), 10); - assert_eq!(b.off(), 0); - - assert_eq!(b.peek_bytes(5).unwrap().as_ref(), [1, 2, 3, 4, 5]); - assert_eq!(b.cap(), 10); - assert_eq!(b.off(), 0); - - assert_eq!(b.peek_bytes(5).unwrap().as_ref(), [1, 2, 3, 4, 5]); - assert_eq!(b.cap(), 10); - assert_eq!(b.off(), 0); - - b.get_bytes(5).unwrap(); - } - - #[test] - fn peek_bytes_mut() { - let mut d = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - let mut b = OctetsMut::with_slice(&mut d); - assert_eq!(b.cap(), 10); - assert_eq!(b.off(), 0); - - assert_eq!(b.peek_bytes(5).unwrap().as_ref(), [1, 2, 3, 4, 5]); - assert_eq!(b.cap(), 10); - assert_eq!(b.off(), 0); - - assert_eq!(b.peek_bytes(5).unwrap().as_ref(), [1, 2, 3, 4, 5]); - assert_eq!(b.cap(), 10); - assert_eq!(b.off(), 0); - - b.get_bytes(5).unwrap(); - } - - #[test] - fn get_varint() { - let d = [0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c]; - let mut b = Octets::with_slice(&d); - assert_eq!(b.get_varint().unwrap(), 151288809941952652); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 8); - - let d = [0x9d, 0x7f, 0x3e, 0x7d]; - let mut b = Octets::with_slice(&d); - assert_eq!(b.get_varint().unwrap(), 494878333); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 4); - - let d = [0x7b, 0xbd]; - let mut b = Octets::with_slice(&d); - assert_eq!(b.get_varint().unwrap(), 15293); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 2); - - let d = [0x40, 0x25]; - let mut b = Octets::with_slice(&d); - assert_eq!(b.get_varint().unwrap(), 37); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 2); - - let d = [0x25]; - let mut b = Octets::with_slice(&d); - assert_eq!(b.get_varint().unwrap(), 37); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 1); - } - - #[test] - fn get_varint_mut() { - let mut d = [0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c]; - let mut b = OctetsMut::with_slice(&mut d); - assert_eq!(b.get_varint().unwrap(), 151288809941952652); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 8); - - let mut d = [0x9d, 0x7f, 0x3e, 0x7d]; - let mut b = OctetsMut::with_slice(&mut d); - assert_eq!(b.get_varint().unwrap(), 494878333); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 4); - - let mut d = [0x7b, 0xbd]; - let mut b = OctetsMut::with_slice(&mut d); - assert_eq!(b.get_varint().unwrap(), 15293); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 2); - - let mut d = [0x40, 0x25]; - let mut b = OctetsMut::with_slice(&mut d); - assert_eq!(b.get_varint().unwrap(), 37); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 2); - - let mut d = [0x25]; - let mut b = OctetsMut::with_slice(&mut d); - assert_eq!(b.get_varint().unwrap(), 37); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 1); - } - - #[test] - fn put_varint() { - let mut d = [0; 8]; - { - let mut b = OctetsMut::with_slice(&mut d); - assert!(b.put_varint(151288809941952652).is_ok()); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 8); - } - let exp = [0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c]; - assert_eq!(&d, &exp); - - let mut d = [0; 4]; - { - let mut b = OctetsMut::with_slice(&mut d); - assert!(b.put_varint(494878333).is_ok()); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 4); - } - let exp = [0x9d, 0x7f, 0x3e, 0x7d]; - assert_eq!(&d, &exp); - - let mut d = [0; 2]; - { - let mut b = OctetsMut::with_slice(&mut d); - assert!(b.put_varint(15293).is_ok()); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 2); - } - let exp = [0x7b, 0xbd]; - assert_eq!(&d, &exp); - - let mut d = [0; 1]; - { - let mut b = OctetsMut::with_slice(&mut d); - assert!(b.put_varint(37).is_ok()); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 1); - } - let exp = [0x25]; - assert_eq!(&d, &exp); - - let mut d = [0; 3]; - { - let mut b = OctetsMut::with_slice(&mut d); - assert!(b.put_varint(151288809941952652).is_err()); - assert_eq!(b.cap(), 3); - assert_eq!(b.off(), 0); - } - let exp = [0; 3]; - assert_eq!(&d, &exp); - } - - #[test] - #[should_panic] - fn varint_too_large() { - let mut d = [0; 3]; - let mut b = OctetsMut::with_slice(&mut d); - assert!(b.put_varint(std::u64::MAX).is_err()); - } - - #[test] - fn put_u() { - let mut d = [0; 18]; - - { - let mut b = OctetsMut::with_slice(&mut d); - assert_eq!(b.cap(), 18); - assert_eq!(b.off(), 0); - - assert!(b.put_u8(1).is_ok()); - assert_eq!(b.cap(), 17); - assert_eq!(b.off(), 1); - - assert!(b.put_u16(0x203).is_ok()); - assert_eq!(b.cap(), 15); - assert_eq!(b.off(), 3); - - assert!(b.put_u24(0x40506).is_ok()); - assert_eq!(b.cap(), 12); - assert_eq!(b.off(), 6); - - assert!(b.put_u32(0x0708090a).is_ok()); - assert_eq!(b.cap(), 8); - assert_eq!(b.off(), 10); - - assert!(b.put_u64(0x0b0c0d0e0f101112).is_ok()); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 18); - - assert!(b.put_u8(1).is_err()); - } - - let exp = [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - ]; - assert_eq!(&d, &exp); - } - - #[test] - fn put_bytes() { - let mut d = [0; 5]; - - { - let mut b = OctetsMut::with_slice(&mut d); - assert_eq!(b.cap(), 5); - assert_eq!(b.off(), 0); - - let p = [0x0a, 0x0b, 0x0c, 0x0d, 0x0e]; - assert!(b.put_bytes(&p).is_ok()); - assert_eq!(b.cap(), 0); - assert_eq!(b.off(), 5); - - assert!(b.put_u8(1).is_err()); - } - - let exp = [0xa, 0xb, 0xc, 0xd, 0xe]; - assert_eq!(&d, &exp); - } - - #[test] - fn split() { - let mut d = b"helloworld".to_vec(); - - let mut b = OctetsMut::with_slice(&mut d); - assert_eq!(b.cap(), 10); - assert_eq!(b.off(), 0); - assert_eq!(b.as_ref(), b"helloworld"); - - assert!(b.get_bytes(5).is_ok()); - assert_eq!(b.cap(), 5); - assert_eq!(b.off(), 5); - assert_eq!(b.as_ref(), b"world"); - - let off = b.off(); - - let (first, last) = b.split_at(off).unwrap(); - assert_eq!(first.cap(), 5); - assert_eq!(first.off(), 0); - assert_eq!(first.as_ref(), b"hello"); - - assert_eq!(last.cap(), 5); - assert_eq!(last.off(), 0); - assert_eq!(last.as_ref(), b"world"); - } - - #[test] - fn split_at() { - let mut d = b"helloworld".to_vec(); - - { - let mut b = OctetsMut::with_slice(&mut d); - let (first, second) = b.split_at(5).unwrap(); - - let mut exp1 = b"hello".to_vec(); - assert_eq!(first.as_ref(), &mut exp1[..]); - - let mut exp2 = b"world".to_vec(); - assert_eq!(second.as_ref(), &mut exp2[..]); - } - - { - let mut b = OctetsMut::with_slice(&mut d); - let (first, second) = b.split_at(10).unwrap(); - - let mut exp1 = b"helloworld".to_vec(); - assert_eq!(first.as_ref(), &mut exp1[..]); - - let mut exp2 = b"".to_vec(); - assert_eq!(second.as_ref(), &mut exp2[..]); - } - - { - let mut b = OctetsMut::with_slice(&mut d); - let (first, second) = b.split_at(9).unwrap(); - - let mut exp1 = b"helloworl".to_vec(); - assert_eq!(first.as_ref(), &mut exp1[..]); - - let mut exp2 = b"d".to_vec(); - assert_eq!(second.as_ref(), &mut exp2[..]); - } - - { - let mut b = OctetsMut::with_slice(&mut d); - assert!(b.split_at(11).is_err()); - } - } - - #[test] - fn slice() { - let d = b"helloworld".to_vec(); - - { - let b = Octets::with_slice(&d); - let exp = b"hello".to_vec(); - assert_eq!(b.slice(5), Ok(&exp[..])); - } - - { - let b = Octets::with_slice(&d); - let exp = b"".to_vec(); - assert_eq!(b.slice(0), Ok(&exp[..])); - } - - { - let mut b = Octets::with_slice(&d); - b.get_bytes(5).unwrap(); - - let exp = b"world".to_vec(); - assert_eq!(b.slice(5), Ok(&exp[..])); - } - - { - let b = Octets::with_slice(&d); - assert!(b.slice(11).is_err()); - } - } - - #[test] - fn slice_mut() { - let mut d = b"helloworld".to_vec(); - - { - let mut b = OctetsMut::with_slice(&mut d); - let mut exp = b"hello".to_vec(); - assert_eq!(b.slice(5), Ok(&mut exp[..])); - } - - { - let mut b = OctetsMut::with_slice(&mut d); - let mut exp = b"".to_vec(); - assert_eq!(b.slice(0), Ok(&mut exp[..])); - } - - { - let mut b = OctetsMut::with_slice(&mut d); - b.get_bytes(5).unwrap(); - - let mut exp = b"world".to_vec(); - assert_eq!(b.slice(5), Ok(&mut exp[..])); - } - - { - let mut b = OctetsMut::with_slice(&mut d); - assert!(b.slice(11).is_err()); - } - } - - #[test] - fn slice_last() { - let d = b"helloworld".to_vec(); - - { - let b = Octets::with_slice(&d); - let exp = b"orld".to_vec(); - assert_eq!(b.slice_last(4), Ok(&exp[..])); - } - - { - let b = Octets::with_slice(&d); - let exp = b"d".to_vec(); - assert_eq!(b.slice_last(1), Ok(&exp[..])); - } - - { - let b = Octets::with_slice(&d); - let exp = b"".to_vec(); - assert_eq!(b.slice_last(0), Ok(&exp[..])); - } - - { - let b = Octets::with_slice(&d); - let exp = b"helloworld".to_vec(); - assert_eq!(b.slice_last(10), Ok(&exp[..])); - } - - { - let b = Octets::with_slice(&d); - assert!(b.slice_last(11).is_err()); - } - } - - #[test] - fn slice_last_mut() { - let mut d = b"helloworld".to_vec(); - - { - let mut b = OctetsMut::with_slice(&mut d); - let mut exp = b"orld".to_vec(); - assert_eq!(b.slice_last(4), Ok(&mut exp[..])); - } - - { - let mut b = OctetsMut::with_slice(&mut d); - let mut exp = b"d".to_vec(); - assert_eq!(b.slice_last(1), Ok(&mut exp[..])); - } - - { - let mut b = OctetsMut::with_slice(&mut d); - let mut exp = b"".to_vec(); - assert_eq!(b.slice_last(0), Ok(&mut exp[..])); - } - - { - let mut b = OctetsMut::with_slice(&mut d); - let mut exp = b"helloworld".to_vec(); - assert_eq!(b.slice_last(10), Ok(&mut exp[..])); - } - - { - let mut b = OctetsMut::with_slice(&mut d); - assert!(b.slice_last(11).is_err()); - } - } -} |