Try get methods for Buf trait (#753)

This commit is contained in:
hpenne
2025-01-21 13:41:42 +01:00
committed by GitHub
parent a1b1208127
commit 3ab876fee6
4 changed files with 1604 additions and 46 deletions
+1521 -31
View File
File diff suppressed because it is too large Load Diff
+41 -11
View File
@@ -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<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]`.
@@ -1545,7 +1566,10 @@ unsafe impl BufMut for &mut [core::mem::MaybeUninit<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(),
});
}
// 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<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.
@@ -1582,7 +1609,10 @@ unsafe impl BufMut for Vec<u8> {
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.
+5 -2
View File
@@ -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;
+37 -2
View File
@@ -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<TryGetError> 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
);
}