diff --git a/src/buf/buf_impl.rs b/src/buf/buf_impl.rs index ab715e4..192034f 100644 --- a/src/buf/buf_impl.rs +++ b/src/buf/buf_impl.rs @@ -3,19 +3,22 @@ use crate::buf::{reader, Reader}; use crate::buf::{take, Chain, Take}; #[cfg(feature = "std")] use crate::{min_u64_usize, saturating_sub_usize_u64}; -use crate::{panic_advance, panic_does_not_fit}; +use crate::{panic_advance, panic_does_not_fit, TryGetError}; #[cfg(feature = "std")] use std::io::IoSlice; use alloc::boxed::Box; -macro_rules! buf_get_impl { +macro_rules! buf_try_get_impl { ($this:ident, $typ:tt::$conv:tt) => {{ const SIZE: usize = core::mem::size_of::<$typ>(); if $this.remaining() < SIZE { - panic_advance(SIZE, $this.remaining()); + return Err(TryGetError { + requested: SIZE, + available: $this.remaining(), + }); } // try to convert directly from the bytes @@ -29,12 +32,12 @@ macro_rules! buf_get_impl { if let Some(ret) = ret { // if the direct conversion was possible, advance and return $this.advance(SIZE); - return ret; + return Ok(ret); } else { // if not we copy the bytes in a temp buffer then convert let mut buf = [0; SIZE]; $this.copy_to_slice(&mut buf); // (do the advance) - return $typ::$conv(buf); + return Ok($typ::$conv(buf)); } }}; (le => $this:ident, $typ:tt, $len_to_read:expr) => {{ @@ -49,8 +52,8 @@ macro_rules! buf_get_impl { None => panic_does_not_fit(SIZE, $len_to_read), }; - $this.copy_to_slice(subslice); - return $typ::from_le_bytes(buf); + $this.try_copy_to_slice(subslice)?; + return Ok($typ::from_le_bytes(buf)); }}; (be => $this:ident, $typ:tt, $len_to_read:expr) => {{ const SIZE: usize = core::mem::size_of::<$typ>(); @@ -61,8 +64,23 @@ macro_rules! buf_get_impl { }; let mut buf = [0; SIZE]; - $this.copy_to_slice(&mut buf[slice_at..]); - return $typ::from_be_bytes(buf); + $this.try_copy_to_slice(&mut buf[slice_at..])?; + return Ok($typ::from_be_bytes(buf)); + }}; +} + +macro_rules! buf_get_impl { + ($this:ident, $typ:tt::$conv:tt) => {{ + return (|| buf_try_get_impl!($this, $typ::$conv))() + .unwrap_or_else(|error| panic_advance(&error)); + }}; + (le => $this:ident, $typ:tt, $len_to_read:expr) => {{ + return (|| buf_try_get_impl!(le => $this, $typ, $len_to_read))() + .unwrap_or_else(|error| panic_advance(&error)); + }}; + (be => $this:ident, $typ:tt, $len_to_read:expr) => {{ + return (|| buf_try_get_impl!(be => $this, $typ, $len_to_read))() + .unwrap_or_else(|error| panic_advance(&error)); }}; } @@ -273,20 +291,9 @@ pub trait Buf { /// # Panics /// /// This function panics if `self.remaining() < dst.len()`. - fn copy_to_slice(&mut self, mut dst: &mut [u8]) { - if self.remaining() < dst.len() { - panic_advance(dst.len(), self.remaining()); - } - - while !dst.is_empty() { - let src = self.chunk(); - let cnt = usize::min(src.len(), dst.len()); - - dst[..cnt].copy_from_slice(&src[..cnt]); - dst = &mut dst[cnt..]; - - self.advance(cnt); - } + fn copy_to_slice(&mut self, dst: &mut [u8]) { + self.try_copy_to_slice(dst) + .unwrap_or_else(|error| panic_advance(&error)); } /// Gets an unsigned 8 bit integer from `self`. @@ -307,7 +314,10 @@ pub trait Buf { /// This function panics if there is no more remaining data in `self`. fn get_u8(&mut self) -> u8 { if self.remaining() < 1 { - panic_advance(1, 0); + panic_advance(&TryGetError { + requested: 1, + available: 0, + }) } let ret = self.chunk()[0]; self.advance(1); @@ -332,7 +342,10 @@ pub trait Buf { /// This function panics if there is no more remaining data in `self`. fn get_i8(&mut self) -> i8 { if self.remaining() < 1 { - panic_advance(1, 0); + panic_advance(&TryGetError { + requested: 1, + available: 0, + }); } let ret = self.chunk()[0] as i8; self.advance(1); @@ -858,7 +871,8 @@ pub trait Buf { /// /// # Panics /// - /// This function panics if there is not enough remaining data in `self`. + /// This function panics if there is not enough remaining data in `self`, or + /// if `nbytes` is greater than 8. fn get_uint(&mut self, nbytes: usize) -> u64 { buf_get_impl!(be => self, u64, nbytes); } @@ -878,7 +892,8 @@ pub trait Buf { /// /// # Panics /// - /// This function panics if there is not enough remaining data in `self`. + /// This function panics if there is not enough remaining data in `self`, or + /// if `nbytes` is greater than 8. fn get_uint_le(&mut self, nbytes: usize) -> u64 { buf_get_impl!(le => self, u64, nbytes); } @@ -1113,6 +1128,1214 @@ pub trait Buf { f64::from_bits(self.get_u64_ne()) } + /// Copies bytes from `self` into `dst`. + /// + /// The cursor is advanced by the number of bytes copied. `self` must have + /// enough remaining bytes to fill `dst`. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"hello world"[..]; + /// let mut dst = [0; 5]; + /// + /// assert_eq!(Ok(()), buf.try_copy_to_slice(&mut dst)); + /// assert_eq!(&b"hello"[..], &dst); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"hello world"[..]; + /// let mut dst = [0; 12]; + /// + /// assert_eq!(Err(TryGetError{requested: 12, available: 11}), buf.try_copy_to_slice(&mut dst)); + /// assert_eq!(11, buf.remaining()); + /// ``` + fn try_copy_to_slice(&mut self, mut dst: &mut [u8]) -> Result<(), TryGetError> { + if self.remaining() < dst.len() { + return Err(TryGetError { + requested: dst.len(), + available: self.remaining(), + }); + } + + while !dst.is_empty() { + let src = self.chunk(); + let cnt = usize::min(src.len(), dst.len()); + + dst[..cnt].copy_from_slice(&src[..cnt]); + dst = &mut dst[cnt..]; + + self.advance(cnt); + } + Ok(()) + } + + /// Gets an unsigned 8 bit integer from `self`. + /// + /// The current position is advanced by 1. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x08 hello"[..]; + /// assert_eq!(Ok(0x08_u8), buf.try_get_u8()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b""[..]; + /// assert_eq!(Err(TryGetError{requested: 1, available: 0}), buf.try_get_u8()); + /// ``` + fn try_get_u8(&mut self) -> Result { + if self.remaining() < 1 { + return Err(TryGetError { + requested: 1, + available: self.remaining(), + }); + } + let ret = self.chunk()[0]; + self.advance(1); + Ok(ret) + } + + /// Gets a signed 8 bit integer from `self`. + /// + /// The current position is advanced by 1. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x08 hello"[..]; + /// assert_eq!(Ok(0x08_i8), buf.try_get_i8()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b""[..]; + /// assert_eq!(Err(TryGetError{requested: 1, available: 0}), buf.try_get_i8()); + /// ``` + fn try_get_i8(&mut self) -> Result { + if self.remaining() < 1 { + return Err(TryGetError { + requested: 1, + available: self.remaining(), + }); + } + let ret = self.chunk()[0] as i8; + self.advance(1); + Ok(ret) + } + + /// Gets an unsigned 16 bit integer from `self` in big-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x08\x09 hello"[..]; + /// assert_eq!(Ok(0x0809_u16), buf.try_get_u16()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x08"[..]; + /// assert_eq!(Err(TryGetError{requested: 2, available: 1}), buf.try_get_u16()); + /// assert_eq!(1, buf.remaining()); + /// ``` + fn try_get_u16(&mut self) -> Result { + buf_try_get_impl!(self, u16::from_be_bytes) + } + + /// Gets an unsigned 16 bit integer from `self` in little-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x09\x08 hello"[..]; + /// assert_eq!(Ok(0x0809_u16), buf.try_get_u16_le()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x08"[..]; + /// assert_eq!(Err(TryGetError{requested: 2, available: 1}), buf.try_get_u16_le()); + /// assert_eq!(1, buf.remaining()); + /// ``` + fn try_get_u16_le(&mut self) -> Result { + buf_try_get_impl!(self, u16::from_le_bytes) + } + + /// Gets an unsigned 16 bit integer from `self` in native-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x08\x09 hello", + /// false => b"\x09\x08 hello", + /// }; + /// assert_eq!(Ok(0x0809_u16), buf.try_get_u16_ne()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x08"[..]; + /// assert_eq!(Err(TryGetError{requested: 2, available: 1}), buf.try_get_u16_ne()); + /// assert_eq!(1, buf.remaining()); + /// ``` + fn try_get_u16_ne(&mut self) -> Result { + buf_try_get_impl!(self, u16::from_ne_bytes) + } + + /// Gets a signed 16 bit integer from `self` in big-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x08\x09 hello"[..]; + /// assert_eq!(Ok(0x0809_i16), buf.try_get_i16()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x08"[..]; + /// assert_eq!(Err(TryGetError{requested: 2, available: 1}), buf.try_get_i16()); + /// assert_eq!(1, buf.remaining()); + /// ``` + fn try_get_i16(&mut self) -> Result { + buf_try_get_impl!(self, i16::from_be_bytes) + } + + /// Gets an signed 16 bit integer from `self` in little-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x09\x08 hello"[..]; + /// assert_eq!(Ok(0x0809_i16), buf.try_get_i16_le()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x08"[..]; + /// assert_eq!(Err(TryGetError{requested: 2, available: 1}), buf.try_get_i16_le()); + /// assert_eq!(1, buf.remaining()); + /// ``` + fn try_get_i16_le(&mut self) -> Result { + buf_try_get_impl!(self, i16::from_le_bytes) + } + + /// Gets a signed 16 bit integer from `self` in native-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x08\x09 hello", + /// false => b"\x09\x08 hello", + /// }; + /// assert_eq!(Ok(0x0809_i16), buf.try_get_i16_ne()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x08"[..]; + /// assert_eq!(Err(TryGetError{requested: 2, available: 1}), buf.try_get_i16_ne()); + /// assert_eq!(1, buf.remaining()); + /// ``` + fn try_get_i16_ne(&mut self) -> Result { + buf_try_get_impl!(self, i16::from_ne_bytes) + } + + /// Gets an unsigned 32 bit integer from `self` in big-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x08\x09\xA0\xA1 hello"[..]; + /// assert_eq!(Ok(0x0809A0A1), buf.try_get_u32()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03"[..]; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_u32()); + /// assert_eq!(3, buf.remaining()); + /// ``` + fn try_get_u32(&mut self) -> Result { + buf_try_get_impl!(self, u32::from_be_bytes) + } + + /// Gets an unsigned 32 bit integer from `self` in little-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\xA1\xA0\x09\x08 hello"[..]; + /// assert_eq!(Ok(0x0809A0A1_u32), buf.try_get_u32_le()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x08\x09\xA0"[..]; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_u32_le()); + /// assert_eq!(3, buf.remaining()); + /// ``` + fn try_get_u32_le(&mut self) -> Result { + buf_try_get_impl!(self, u32::from_le_bytes) + } + + /// Gets an unsigned 32 bit integer from `self` in native-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x08\x09\xA0\xA1 hello", + /// false => b"\xA1\xA0\x09\x08 hello", + /// }; + /// assert_eq!(Ok(0x0809A0A1_u32), buf.try_get_u32_ne()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x08\x09\xA0"[..]; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_u32_ne()); + /// assert_eq!(3, buf.remaining()); + /// ``` + fn try_get_u32_ne(&mut self) -> Result { + buf_try_get_impl!(self, u32::from_ne_bytes) + } + + /// Gets a signed 32 bit integer from `self` in big-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x08\x09\xA0\xA1 hello"[..]; + /// assert_eq!(Ok(0x0809A0A1_i32), buf.try_get_i32()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03"[..]; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_i32()); + /// assert_eq!(3, buf.remaining()); + /// ``` + fn try_get_i32(&mut self) -> Result { + buf_try_get_impl!(self, i32::from_be_bytes) + } + + /// Gets a signed 32 bit integer from `self` in little-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\xA1\xA0\x09\x08 hello"[..]; + /// assert_eq!(Ok(0x0809A0A1_i32), buf.try_get_i32_le()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x08\x09\xA0"[..]; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_i32_le()); + /// assert_eq!(3, buf.remaining()); + /// ``` + fn try_get_i32_le(&mut self) -> Result { + buf_try_get_impl!(self, i32::from_le_bytes) + } + + /// Gets a signed 32 bit integer from `self` in native-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x08\x09\xA0\xA1 hello", + /// false => b"\xA1\xA0\x09\x08 hello", + /// }; + /// assert_eq!(Ok(0x0809A0A1_i32), buf.try_get_i32_ne()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x08\x09\xA0"[..]; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_i32_ne()); + /// assert_eq!(3, buf.remaining()); + /// ``` + fn try_get_i32_ne(&mut self) -> Result { + buf_try_get_impl!(self, i32::from_ne_bytes) + } + + /// Gets an unsigned 64 bit integer from `self` in big-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..]; + /// assert_eq!(Ok(0x0102030405060708_u64), buf.try_get_u64()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07"[..]; + /// assert_eq!(Err(TryGetError{requested: 8, available: 7}), buf.try_get_u64()); + /// assert_eq!(7, buf.remaining()); + /// ``` + fn try_get_u64(&mut self) -> Result { + buf_try_get_impl!(self, u64::from_be_bytes) + } + + /// Gets an unsigned 64 bit integer from `self` in little-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..]; + /// assert_eq!(Ok(0x0102030405060708_u64), buf.try_get_u64_le()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02"[..]; + /// assert_eq!(Err(TryGetError{requested: 8, available: 7}), buf.try_get_u64_le()); + /// assert_eq!(7, buf.remaining()); + /// ``` + fn try_get_u64_le(&mut self) -> Result { + buf_try_get_impl!(self, u64::from_le_bytes) + } + + /// Gets an unsigned 64 bit integer from `self` in native-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x01\x02\x03\x04\x05\x06\x07\x08 hello", + /// false => b"\x08\x07\x06\x05\x04\x03\x02\x01 hello", + /// }; + /// assert_eq!(Ok(0x0102030405060708_u64), buf.try_get_u64_ne()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07"[..]; + /// assert_eq!(Err(TryGetError{requested: 8, available: 7}), buf.try_get_u64_ne()); + /// assert_eq!(7, buf.remaining()); + /// ``` + fn try_get_u64_ne(&mut self) -> Result { + buf_try_get_impl!(self, u64::from_ne_bytes) + } + + /// Gets a signed 64 bit integer from `self` in big-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..]; + /// assert_eq!(Ok(0x0102030405060708_i64), buf.try_get_i64()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07"[..]; + /// assert_eq!(Err(TryGetError{requested: 8, available: 7}), buf.try_get_i64()); + /// assert_eq!(7, buf.remaining()); + /// ``` + fn try_get_i64(&mut self) -> Result { + buf_try_get_impl!(self, i64::from_be_bytes) + } + + /// Gets a signed 64 bit integer from `self` in little-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..]; + /// assert_eq!(Ok(0x0102030405060708_i64), buf.try_get_i64_le()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02"[..]; + /// assert_eq!(Err(TryGetError{requested: 8, available: 7}), buf.try_get_i64_le()); + /// assert_eq!(7, buf.remaining()); + /// ``` + fn try_get_i64_le(&mut self) -> Result { + buf_try_get_impl!(self, i64::from_le_bytes) + } + + /// Gets a signed 64 bit integer from `self` in native-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x01\x02\x03\x04\x05\x06\x07\x08 hello", + /// false => b"\x08\x07\x06\x05\x04\x03\x02\x01 hello", + /// }; + /// assert_eq!(Ok(0x0102030405060708_i64), buf.try_get_i64_ne()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07"[..]; + /// assert_eq!(Err(TryGetError{requested: 8, available: 7}), buf.try_get_i64_ne()); + /// assert_eq!(7, buf.remaining()); + /// ``` + fn try_get_i64_ne(&mut self) -> Result { + buf_try_get_impl!(self, i64::from_ne_bytes) + } + + /// Gets an unsigned 128 bit integer from `self` in big-endian byte order. + /// + /// The current position is advanced by 16. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..]; + /// assert_eq!(Ok(0x01020304050607080910111213141516_u128), buf.try_get_u128()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15"[..]; + /// assert_eq!(Err(TryGetError{requested: 16, available: 15}), buf.try_get_u128()); + /// assert_eq!(15, buf.remaining()); + /// ``` + fn try_get_u128(&mut self) -> Result { + buf_try_get_impl!(self, u128::from_be_bytes) + } + + /// Gets an unsigned 128 bit integer from `self` in little-endian byte order. + /// + /// The current position is advanced by 16. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..]; + /// assert_eq!(Ok(0x01020304050607080910111213141516_u128), buf.try_get_u128_le()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02"[..]; + /// assert_eq!(Err(TryGetError{requested: 16, available: 15}), buf.try_get_u128_le()); + /// assert_eq!(15, buf.remaining()); + /// ``` + fn try_get_u128_le(&mut self) -> Result { + buf_try_get_impl!(self, u128::from_le_bytes) + } + + /// Gets an unsigned 128 bit integer from `self` in native-endian byte order. + /// + /// The current position is advanced by 16. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello", + /// false => b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello", + /// }; + /// assert_eq!(Ok(0x01020304050607080910111213141516_u128), buf.try_get_u128_ne()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15"[..]; + /// assert_eq!(Err(TryGetError{requested: 16, available: 15}), buf.try_get_u128_ne()); + /// assert_eq!(15, buf.remaining()); + /// ``` + fn try_get_u128_ne(&mut self) -> Result { + buf_try_get_impl!(self, u128::from_ne_bytes) + } + + /// Gets a signed 128 bit integer from `self` in big-endian byte order. + /// + /// The current position is advanced by 16. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..]; + /// assert_eq!(Ok(0x01020304050607080910111213141516_i128), buf.try_get_i128()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15"[..]; + /// assert_eq!(Err(TryGetError{requested: 16, available: 15}), buf.try_get_i128()); + /// assert_eq!(15, buf.remaining()); + /// ``` + fn try_get_i128(&mut self) -> Result { + buf_try_get_impl!(self, i128::from_be_bytes) + } + + /// Gets a signed 128 bit integer from `self` in little-endian byte order. + /// + /// The current position is advanced by 16. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..]; + /// assert_eq!(Ok(0x01020304050607080910111213141516_i128), buf.try_get_i128_le()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02"[..]; + /// assert_eq!(Err(TryGetError{requested: 16, available: 15}), buf.try_get_i128_le()); + /// assert_eq!(15, buf.remaining()); + /// ``` + fn try_get_i128_le(&mut self) -> Result { + buf_try_get_impl!(self, i128::from_le_bytes) + } + + /// Gets a signed 128 bit integer from `self` in native-endian byte order. + /// + /// The current position is advanced by 16. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello", + /// false => b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello", + /// }; + /// assert_eq!(Ok(0x01020304050607080910111213141516_i128), buf.try_get_i128_ne()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15"[..]; + /// assert_eq!(Err(TryGetError{requested: 16, available: 15}), buf.try_get_i128_ne()); + /// assert_eq!(15, buf.remaining()); + /// ``` + fn try_get_i128_ne(&mut self) -> Result { + buf_try_get_impl!(self, i128::from_ne_bytes) + } + + /// Gets an unsigned n-byte integer from `self` in big-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x01\x02\x03 hello"[..]; + /// assert_eq!(Ok(0x010203_u64), buf.try_get_uint(3)); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03"[..]; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_uint(4)); + /// assert_eq!(3, buf.remaining()); + /// ``` + /// + /// # Panics + /// + /// This function panics if `nbytes` > 8. + fn try_get_uint(&mut self, nbytes: usize) -> Result { + buf_try_get_impl!(be => self, u64, nbytes); + } + + /// Gets an unsigned n-byte integer from `self` in little-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x03\x02\x01 hello"[..]; + /// assert_eq!(Ok(0x010203_u64), buf.try_get_uint_le(3)); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03"[..]; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_uint_le(4)); + /// assert_eq!(3, buf.remaining()); + /// ``` + /// + /// # Panics + /// + /// This function panics if `nbytes` > 8. + fn try_get_uint_le(&mut self, nbytes: usize) -> Result { + buf_try_get_impl!(le => self, u64, nbytes); + } + + /// Gets an unsigned n-byte integer from `self` in native-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x01\x02\x03 hello", + /// false => b"\x03\x02\x01 hello", + /// }; + /// assert_eq!(Ok(0x010203_u64), buf.try_get_uint_ne(3)); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x01\x02\x03", + /// false => b"\x03\x02\x01", + /// }; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_uint_ne(4)); + /// assert_eq!(3, buf.remaining()); + /// ``` + /// + /// # Panics + /// + /// This function panics if `nbytes` is greater than 8. + fn try_get_uint_ne(&mut self, nbytes: usize) -> Result { + if cfg!(target_endian = "big") { + self.try_get_uint(nbytes) + } else { + self.try_get_uint_le(nbytes) + } + } + + /// Gets a signed n-byte integer from `self` in big-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x01\x02\x03 hello"[..]; + /// assert_eq!(Ok(0x010203_i64), buf.try_get_int(3)); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03"[..]; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_int(4)); + /// assert_eq!(3, buf.remaining()); + /// ``` + /// + /// # Panics + /// + /// This function panics if `nbytes` is greater than 8. + fn try_get_int(&mut self, nbytes: usize) -> Result { + buf_try_get_impl!(be => self, i64, nbytes); + } + + /// Gets a signed n-byte integer from `self` in little-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x03\x02\x01 hello"[..]; + /// assert_eq!(Ok(0x010203_i64), buf.try_get_int_le(3)); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x01\x02\x03"[..]; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_int_le(4)); + /// assert_eq!(3, buf.remaining()); + /// ``` + /// + /// # Panics + /// + /// This function panics if `nbytes` is greater than 8. + fn try_get_int_le(&mut self, nbytes: usize) -> Result { + buf_try_get_impl!(le => self, i64, nbytes); + } + + /// Gets a signed n-byte integer from `self` in native-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x01\x02\x03 hello", + /// false => b"\x03\x02\x01 hello", + /// }; + /// assert_eq!(Ok(0x010203_i64), buf.try_get_int_ne(3)); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x01\x02\x03", + /// false => b"\x03\x02\x01", + /// }; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_int_ne(4)); + /// assert_eq!(3, buf.remaining()); + /// ``` + /// + /// # Panics + /// + /// This function panics if `nbytes` is greater than 8. + fn try_get_int_ne(&mut self, nbytes: usize) -> Result { + if cfg!(target_endian = "big") { + self.try_get_int(nbytes) + } else { + self.try_get_int_le(nbytes) + } + } + + /// Gets an IEEE754 single-precision (4 bytes) floating point number from + /// `self` in big-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x3F\x99\x99\x9A hello"[..]; + /// assert_eq!(1.2f32, buf.get_f32()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x3F\x99\x99"[..]; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_f32()); + /// assert_eq!(3, buf.remaining()); + /// ``` + fn try_get_f32(&mut self) -> Result { + Ok(f32::from_bits(self.try_get_u32()?)) + } + + /// Gets an IEEE754 single-precision (4 bytes) floating point number from + /// `self` in little-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x9A\x99\x99\x3F hello"[..]; + /// assert_eq!(1.2f32, buf.get_f32_le()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x3F\x99\x99"[..]; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_f32_le()); + /// assert_eq!(3, buf.remaining()); + /// ``` + fn try_get_f32_le(&mut self) -> Result { + Ok(f32::from_bits(self.try_get_u32_le()?)) + } + + /// Gets an IEEE754 single-precision (4 bytes) floating point number from + /// `self` in native-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x3F\x99\x99\x9A hello", + /// false => b"\x9A\x99\x99\x3F hello", + /// }; + /// assert_eq!(1.2f32, buf.get_f32_ne()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x3F\x99\x99"[..]; + /// assert_eq!(Err(TryGetError{requested: 4, available: 3}), buf.try_get_f32_ne()); + /// assert_eq!(3, buf.remaining()); + /// ``` + fn try_get_f32_ne(&mut self) -> Result { + Ok(f32::from_bits(self.try_get_u32_ne()?)) + } + + /// Gets an IEEE754 double-precision (8 bytes) floating point number from + /// `self` in big-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"[..]; + /// assert_eq!(1.2f64, buf.get_f64()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33"[..]; + /// assert_eq!(Err(TryGetError{requested: 8, available: 7}), buf.try_get_f64()); + /// assert_eq!(7, buf.remaining()); + /// ``` + fn try_get_f64(&mut self) -> Result { + Ok(f64::from_bits(self.try_get_u64()?)) + } + + /// Gets an IEEE754 double-precision (8 bytes) floating point number from + /// `self` in little-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf = &b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello"[..]; + /// assert_eq!(1.2f64, buf.get_f64_le()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33"[..]; + /// assert_eq!(Err(TryGetError{requested: 8, available: 7}), buf.try_get_f64_le()); + /// assert_eq!(7, buf.remaining()); + /// ``` + fn try_get_f64_le(&mut self) -> Result { + Ok(f64::from_bits(self.try_get_u64_le()?)) + } + + /// Gets an IEEE754 double-precision (8 bytes) floating point number from + /// `self` in native-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// Returns `Err(TryGetError)` when there are not enough + /// remaining bytes to read the value. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// + /// let mut buf: &[u8] = match cfg!(target_endian = "big") { + /// true => b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello", + /// false => b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello", + /// }; + /// assert_eq!(1.2f64, buf.get_f64_ne()); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// ``` + /// use bytes::{Buf, TryGetError}; + /// + /// let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33"[..]; + /// assert_eq!(Err(TryGetError{requested: 8, available: 7}), buf.try_get_f64_ne()); + /// assert_eq!(7, buf.remaining()); + /// ``` + fn try_get_f64_ne(&mut self) -> Result { + Ok(f64::from_bits(self.try_get_u64_ne()?)) + } + /// Consumes `len` bytes inside self and returns new instance of `Bytes` /// with this data. /// @@ -1136,7 +2359,10 @@ pub trait Buf { use super::BufMut; if self.remaining() < len { - panic_advance(len, self.remaining()); + panic_advance(&TryGetError { + requested: len, + available: self.remaining(), + }); } let mut ret = crate::BytesMut::with_capacity(len); @@ -1360,6 +2586,36 @@ macro_rules! deref_forward_buf { (**self).get_i64_ne() } + #[inline] + fn get_u128(&mut self) -> u128 { + (**self).get_u128() + } + + #[inline] + fn get_u128_le(&mut self) -> u128 { + (**self).get_u128_le() + } + + #[inline] + fn get_u128_ne(&mut self) -> u128 { + (**self).get_u128_ne() + } + + #[inline] + fn get_i128(&mut self) -> i128 { + (**self).get_i128() + } + + #[inline] + fn get_i128_le(&mut self) -> i128 { + (**self).get_i128_le() + } + + #[inline] + fn get_i128_ne(&mut self) -> i128 { + (**self).get_i128_ne() + } + #[inline] fn get_uint(&mut self, nbytes: usize) -> u64 { (**self).get_uint(nbytes) @@ -1390,6 +2646,231 @@ macro_rules! deref_forward_buf { (**self).get_int_ne(nbytes) } + #[inline] + fn get_f32(&mut self) -> f32 { + (**self).get_f32() + } + + #[inline] + fn get_f32_le(&mut self) -> f32 { + (**self).get_f32_le() + } + + #[inline] + fn get_f32_ne(&mut self) -> f32 { + (**self).get_f32_ne() + } + + #[inline] + fn get_f64(&mut self) -> f64 { + (**self).get_f64() + } + + #[inline] + fn get_f64_le(&mut self) -> f64 { + (**self).get_f64_le() + } + + #[inline] + fn get_f64_ne(&mut self) -> f64 { + (**self).get_f64_ne() + } + + #[inline] + fn try_copy_to_slice(&mut self, dst: &mut [u8]) -> Result<(), TryGetError> { + (**self).try_copy_to_slice(dst) + } + + #[inline] + fn try_get_u8(&mut self) -> Result { + (**self).try_get_u8() + } + + #[inline] + fn try_get_i8(&mut self) -> Result { + (**self).try_get_i8() + } + + #[inline] + fn try_get_u16(&mut self) -> Result { + (**self).try_get_u16() + } + + #[inline] + fn try_get_u16_le(&mut self) -> Result { + (**self).try_get_u16_le() + } + + #[inline] + fn try_get_u16_ne(&mut self) -> Result { + (**self).try_get_u16_ne() + } + + #[inline] + fn try_get_i16(&mut self) -> Result { + (**self).try_get_i16() + } + + #[inline] + fn try_get_i16_le(&mut self) -> Result { + (**self).try_get_i16_le() + } + + #[inline] + fn try_get_i16_ne(&mut self) -> Result { + (**self).try_get_i16_ne() + } + + #[inline] + fn try_get_u32(&mut self) -> Result { + (**self).try_get_u32() + } + + #[inline] + fn try_get_u32_le(&mut self) -> Result { + (**self).try_get_u32_le() + } + + #[inline] + fn try_get_u32_ne(&mut self) -> Result { + (**self).try_get_u32_ne() + } + + #[inline] + fn try_get_i32(&mut self) -> Result { + (**self).try_get_i32() + } + + #[inline] + fn try_get_i32_le(&mut self) -> Result { + (**self).try_get_i32_le() + } + + #[inline] + fn try_get_i32_ne(&mut self) -> Result { + (**self).try_get_i32_ne() + } + + #[inline] + fn try_get_u64(&mut self) -> Result { + (**self).try_get_u64() + } + + #[inline] + fn try_get_u64_le(&mut self) -> Result { + (**self).try_get_u64_le() + } + + #[inline] + fn try_get_u64_ne(&mut self) -> Result { + (**self).try_get_u64_ne() + } + + #[inline] + fn try_get_i64(&mut self) -> Result { + (**self).try_get_i64() + } + + #[inline] + fn try_get_i64_le(&mut self) -> Result { + (**self).try_get_i64_le() + } + + #[inline] + fn try_get_i64_ne(&mut self) -> Result { + (**self).try_get_i64_ne() + } + + #[inline] + fn try_get_u128(&mut self) -> Result { + (**self).try_get_u128() + } + + #[inline] + fn try_get_u128_le(&mut self) -> Result { + (**self).try_get_u128_le() + } + + #[inline] + fn try_get_u128_ne(&mut self) -> Result { + (**self).try_get_u128_ne() + } + + #[inline] + fn try_get_i128(&mut self) -> Result { + (**self).try_get_i128() + } + + #[inline] + fn try_get_i128_le(&mut self) -> Result { + (**self).try_get_i128_le() + } + + #[inline] + fn try_get_i128_ne(&mut self) -> Result { + (**self).try_get_i128_ne() + } + + #[inline] + fn try_get_uint(&mut self, nbytes: usize) -> Result { + (**self).try_get_uint(nbytes) + } + + #[inline] + fn try_get_uint_le(&mut self, nbytes: usize) -> Result { + (**self).try_get_uint_le(nbytes) + } + + #[inline] + fn try_get_uint_ne(&mut self, nbytes: usize) -> Result { + (**self).try_get_uint_ne(nbytes) + } + + #[inline] + fn try_get_int(&mut self, nbytes: usize) -> Result { + (**self).try_get_int(nbytes) + } + + #[inline] + fn try_get_int_le(&mut self, nbytes: usize) -> Result { + (**self).try_get_int_le(nbytes) + } + + #[inline] + fn try_get_int_ne(&mut self, nbytes: usize) -> Result { + (**self).try_get_int_ne(nbytes) + } + + #[inline] + fn try_get_f32(&mut self) -> Result { + (**self).try_get_f32() + } + + #[inline] + fn try_get_f32_le(&mut self) -> Result { + (**self).try_get_f32_le() + } + + #[inline] + fn try_get_f32_ne(&mut self) -> Result { + (**self).try_get_f32_ne() + } + + #[inline] + fn try_get_f64(&mut self) -> Result { + (**self).try_get_f64() + } + + #[inline] + fn try_get_f64_le(&mut self) -> Result { + (**self).try_get_f64_le() + } + + #[inline] + fn try_get_f64_ne(&mut self) -> Result { + (**self).try_get_f64_ne() + } + #[inline] fn copy_to_bytes(&mut self, len: usize) -> crate::Bytes { (**self).copy_to_bytes(len) @@ -1419,7 +2900,10 @@ impl Buf for &[u8] { #[inline] fn advance(&mut self, cnt: usize) { if self.len() < cnt { - panic_advance(cnt, self.len()); + panic_advance(&TryGetError { + requested: cnt, + available: self.len(), + }); } *self = &self[cnt..]; @@ -1428,7 +2912,10 @@ impl Buf for &[u8] { #[inline] fn copy_to_slice(&mut self, dst: &mut [u8]) { if self.len() < dst.len() { - panic_advance(dst.len(), self.len()); + panic_advance(&TryGetError { + requested: dst.len(), + available: self.len(), + }); } dst.copy_from_slice(&self[..dst.len()]); @@ -1458,7 +2945,10 @@ impl> Buf for std::io::Cursor { // We intentionally allow `cnt == 0` here even if `pos > len`. let max_cnt = saturating_sub_usize_u64(len, pos); if cnt > max_cnt { - panic_advance(cnt, max_cnt); + panic_advance(&TryGetError { + requested: cnt, + available: max_cnt, + }); } // This will not overflow because either `cnt == 0` or the sum is not diff --git a/src/buf/buf_mut.rs b/src/buf/buf_mut.rs index 2a3b5e9..26645c6 100644 --- a/src/buf/buf_mut.rs +++ b/src/buf/buf_mut.rs @@ -1,7 +1,7 @@ use crate::buf::{limit, Chain, Limit, UninitSlice}; #[cfg(feature = "std")] use crate::buf::{writer, Writer}; -use crate::{panic_advance, panic_does_not_fit}; +use crate::{panic_advance, panic_does_not_fit, TryGetError}; use core::{mem, ptr, usize}; @@ -204,7 +204,10 @@ pub unsafe trait BufMut { Self: Sized, { if self.remaining_mut() < src.remaining() { - panic_advance(src.remaining(), self.remaining_mut()); + panic_advance(&TryGetError { + requested: src.remaining(), + available: self.remaining_mut(), + }); } while src.has_remaining() { @@ -242,7 +245,10 @@ pub unsafe trait BufMut { #[inline] fn put_slice(&mut self, mut src: &[u8]) { if self.remaining_mut() < src.len() { - panic_advance(src.len(), self.remaining_mut()); + panic_advance(&TryGetError { + requested: src.len(), + available: self.remaining_mut(), + }); } while !src.is_empty() { @@ -285,7 +291,10 @@ pub unsafe trait BufMut { #[inline] fn put_bytes(&mut self, val: u8, mut cnt: usize) { if self.remaining_mut() < cnt { - panic_advance(cnt, self.remaining_mut()); + panic_advance(&TryGetError { + requested: cnt, + available: self.remaining_mut(), + }) } while cnt > 0 { @@ -1487,7 +1496,10 @@ unsafe impl BufMut for &mut [u8] { #[inline] unsafe fn advance_mut(&mut self, cnt: usize) { if self.len() < cnt { - panic_advance(cnt, self.len()); + panic_advance(&TryGetError { + requested: cnt, + available: self.len(), + }); } // Lifetime dance taken from `impl Write for &mut [u8]`. @@ -1498,7 +1510,10 @@ unsafe impl BufMut for &mut [u8] { #[inline] fn put_slice(&mut self, src: &[u8]) { if self.len() < src.len() { - panic_advance(src.len(), self.len()); + panic_advance(&TryGetError { + requested: src.len(), + available: self.len(), + }); } self[..src.len()].copy_from_slice(src); @@ -1509,7 +1524,10 @@ unsafe impl BufMut for &mut [u8] { #[inline] fn put_bytes(&mut self, val: u8, cnt: usize) { if self.len() < cnt { - panic_advance(cnt, self.len()); + panic_advance(&TryGetError { + requested: cnt, + available: self.len(), + }); } // SAFETY: We just checked that the pointer is valid for `cnt` bytes. @@ -1534,7 +1552,10 @@ unsafe impl BufMut for &mut [core::mem::MaybeUninit] { #[inline] unsafe fn advance_mut(&mut self, cnt: usize) { if self.len() < cnt { - panic_advance(cnt, self.len()); + panic_advance(&TryGetError { + requested: cnt, + available: self.len(), + }); } // Lifetime dance taken from `impl Write for &mut [u8]`. @@ -1545,7 +1566,10 @@ unsafe impl BufMut for &mut [core::mem::MaybeUninit] { #[inline] fn put_slice(&mut self, src: &[u8]) { if self.len() < src.len() { - panic_advance(src.len(), self.len()); + panic_advance(&TryGetError { + requested: src.len(), + available: self.len(), + }); } // SAFETY: We just checked that the pointer is valid for `src.len()` bytes. @@ -1558,7 +1582,10 @@ unsafe impl BufMut for &mut [core::mem::MaybeUninit] { #[inline] fn put_bytes(&mut self, val: u8, cnt: usize) { if self.len() < cnt { - panic_advance(cnt, self.len()); + panic_advance(&TryGetError { + requested: cnt, + available: self.len(), + }); } // SAFETY: We just checked that the pointer is valid for `cnt` bytes. @@ -1582,7 +1609,10 @@ unsafe impl BufMut for Vec { let remaining = self.capacity() - len; if remaining < cnt { - panic_advance(cnt, remaining); + panic_advance(&TryGetError { + requested: cnt, + available: remaining, + }); } // Addition will not overflow since the sum is at most the capacity. diff --git a/src/bytes_mut.rs b/src/bytes_mut.rs index a0d77bc..d5db512 100644 --- a/src/bytes_mut.rs +++ b/src/bytes_mut.rs @@ -17,7 +17,7 @@ use crate::bytes::Vtable; #[allow(unused)] use crate::loom::sync::atomic::AtomicMut; use crate::loom::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; -use crate::{offset_from, Buf, BufMut, Bytes}; +use crate::{offset_from, Buf, BufMut, Bytes, TryGetError}; /// A unique reference to a contiguous slice of memory. /// @@ -1178,7 +1178,10 @@ unsafe impl BufMut for BytesMut { unsafe fn advance_mut(&mut self, cnt: usize) { let remaining = self.cap - self.len(); if cnt > remaining { - super::panic_advance(cnt, remaining); + super::panic_advance(&TryGetError { + requested: cnt, + available: remaining, + }); } // Addition won't overflow since it is at most `self.cap`. self.len = self.len() + cnt; diff --git a/src/lib.rs b/src/lib.rs index 7ddd220..cfc8281 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -132,12 +132,47 @@ fn min_u64_usize(a: u64, b: usize) -> usize { } } +/// Error type for the `try_get_` methods of [`Buf`]. +/// Indicates that there were not enough remaining +/// bytes in the buffer while attempting +/// to get a value from a [`Buf`] with one +/// of the `try_get_` methods. +#[derive(Debug, PartialEq, Eq)] +pub struct TryGetError { + /// The number of bytes necessary to get the value + pub requested: usize, + + /// The number of bytes available in the buffer + pub available: usize, +} + +impl core::fmt::Display for TryGetError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + write!( + f, + "Not enough bytes remaining in buffer to read value (requested {} but only {} available)", + self.requested, + self.available + ) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for TryGetError {} + +#[cfg(feature = "std")] +impl From for std::io::Error { + fn from(error: TryGetError) -> Self { + std::io::Error::new(std::io::ErrorKind::Other, error) + } +} + /// Panic with a nice error message. #[cold] -fn panic_advance(idx: usize, len: usize) -> ! { +fn panic_advance(error_info: &TryGetError) -> ! { panic!( "advance out of bounds: the len is {} but advancing by {}", - len, idx + error_info.available, error_info.requested ); }