mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-21 00:00:12 +02:00
Remove BufMut::bytes_vectored_mut() (#430)
There are issues with regard to uninitialized memory. We are avoiding stabilizing this function for now.
This commit is contained in:
@@ -4,9 +4,6 @@ use core::{
|
|||||||
ptr, usize,
|
ptr, usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
use alloc::{boxed::Box, vec::Vec};
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
|
|
||||||
/// A trait for values that provide sequential write access to bytes.
|
/// A trait for values that provide sequential write access to bytes.
|
||||||
@@ -168,48 +165,6 @@ pub trait BufMut {
|
|||||||
/// return an empty slice.
|
/// return an empty slice.
|
||||||
fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>];
|
fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>];
|
||||||
|
|
||||||
/// Fills `dst` with potentially multiple mutable slices starting at `self`'s
|
|
||||||
/// current position.
|
|
||||||
///
|
|
||||||
/// If the `BufMut` is backed by disjoint slices of bytes, `bytes_vectored_mut`
|
|
||||||
/// enables fetching more than one slice at once. `dst` is a slice of
|
|
||||||
/// mutable `IoSliceMut` references, enabling the slice to be directly used with
|
|
||||||
/// [`readv`] without any further conversion. The sum of the lengths of all
|
|
||||||
/// the buffers in `dst` will be less than or equal to
|
|
||||||
/// `Buf::remaining_mut()`.
|
|
||||||
///
|
|
||||||
/// The entries in `dst` will be overwritten, but the data **contained** by
|
|
||||||
/// the slices **will not** be modified. If `bytes_vectored_mut` does not fill every
|
|
||||||
/// entry in `dst`, then `dst` is guaranteed to contain all remaining slices
|
|
||||||
/// in `self.
|
|
||||||
///
|
|
||||||
/// This is a lower level function. Most operations are done with other
|
|
||||||
/// functions.
|
|
||||||
///
|
|
||||||
/// # Implementer notes
|
|
||||||
///
|
|
||||||
/// This function should never panic. Once the end of the buffer is reached,
|
|
||||||
/// i.e., `BufMut::remaining_mut` returns 0, calls to `bytes_vectored_mut` must
|
|
||||||
/// return 0 without mutating `dst`.
|
|
||||||
///
|
|
||||||
/// Implementations should also take care to properly handle being called
|
|
||||||
/// with `dst` being a zero length slice.
|
|
||||||
///
|
|
||||||
/// [`readv`]: http://man7.org/linux/man-pages/man2/readv.2.html
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
fn bytes_vectored_mut<'a>(&'a mut self, dst: &mut [IoSliceMut<'a>]) -> usize {
|
|
||||||
if dst.is_empty() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.has_remaining_mut() {
|
|
||||||
dst[0] = IoSliceMut::from(self.bytes_mut());
|
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Transfer bytes into `self` from `src` and advance the cursor by the
|
/// Transfer bytes into `self` from `src` and advance the cursor by the
|
||||||
/// number of bytes written.
|
/// number of bytes written.
|
||||||
///
|
///
|
||||||
@@ -890,11 +845,6 @@ macro_rules! deref_forward_bufmut {
|
|||||||
(**self).bytes_mut()
|
(**self).bytes_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
fn bytes_vectored_mut<'b>(&'b mut self, dst: &mut [IoSliceMut<'b>]) -> usize {
|
|
||||||
(**self).bytes_vectored_mut(dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
unsafe fn advance_mut(&mut self, cnt: usize) {
|
||||||
(**self).advance_mut(cnt)
|
(**self).advance_mut(cnt)
|
||||||
}
|
}
|
||||||
@@ -1057,44 +1007,3 @@ impl BufMut for Vec<u8> {
|
|||||||
// The existence of this function makes the compiler catch if the BufMut
|
// The existence of this function makes the compiler catch if the BufMut
|
||||||
// trait is "object-safe" or not.
|
// trait is "object-safe" or not.
|
||||||
fn _assert_trait_object(_b: &dyn BufMut) {}
|
fn _assert_trait_object(_b: &dyn BufMut) {}
|
||||||
|
|
||||||
// ===== impl IoSliceMut =====
|
|
||||||
|
|
||||||
/// A buffer type used for `readv`.
|
|
||||||
///
|
|
||||||
/// This is a wrapper around an `std::io::IoSliceMut`, but does not expose
|
|
||||||
/// the inner bytes in a safe API, as they may point at uninitialized memory.
|
|
||||||
///
|
|
||||||
/// This is `repr(transparent)` of the `std::io::IoSliceMut`, so it is valid to
|
|
||||||
/// transmute them. However, as the memory might be uninitialized, care must be
|
|
||||||
/// taken to not *read* the internal bytes, only *write* to them.
|
|
||||||
#[repr(transparent)]
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
pub struct IoSliceMut<'a>(std::io::IoSliceMut<'a>);
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl fmt::Debug for IoSliceMut<'_> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
f.debug_struct("IoSliceMut")
|
|
||||||
.field("len", &self.0.len())
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl<'a> From<&'a mut [u8]> for IoSliceMut<'a> {
|
|
||||||
fn from(buf: &'a mut [u8]) -> IoSliceMut<'a> {
|
|
||||||
IoSliceMut(std::io::IoSliceMut::new(buf))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl<'a> From<&'a mut [MaybeUninit<u8>]> for IoSliceMut<'a> {
|
|
||||||
fn from(buf: &'a mut [MaybeUninit<u8>]) -> IoSliceMut<'a> {
|
|
||||||
IoSliceMut(std::io::IoSliceMut::new(unsafe {
|
|
||||||
// We don't look at the contents, and `std::io::IoSliceMut`
|
|
||||||
// doesn't either.
|
|
||||||
mem::transmute::<&'a mut [MaybeUninit<u8>], &'a mut [u8]>(buf)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ use crate::{Buf, BufMut};
|
|||||||
|
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::MaybeUninit;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use crate::buf::IoSliceMut;
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::io::IoSlice;
|
use std::io::IoSlice;
|
||||||
|
|
||||||
@@ -210,13 +208,6 @@ where
|
|||||||
|
|
||||||
self.b.advance_mut(cnt);
|
self.b.advance_mut(cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
fn bytes_vectored_mut<'a>(&'a mut self, dst: &mut [IoSliceMut<'a>]) -> usize {
|
|
||||||
let mut n = self.a.bytes_vectored_mut(dst);
|
|
||||||
n += self.b.bytes_vectored_mut(&mut dst[n..]);
|
|
||||||
n
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, U> IntoIterator for Chain<T, U>
|
impl<T, U> IntoIterator for Chain<T, U>
|
||||||
|
|||||||
@@ -24,7 +24,5 @@ mod vec_deque;
|
|||||||
|
|
||||||
pub use self::buf_impl::Buf;
|
pub use self::buf_impl::Buf;
|
||||||
pub use self::buf_mut::BufMut;
|
pub use self::buf_mut::BufMut;
|
||||||
#[cfg(feature = "std")]
|
|
||||||
pub use self::buf_mut::IoSliceMut;
|
|
||||||
pub use self::ext::{BufExt, BufMutExt};
|
pub use self::ext::{BufExt, BufMutExt};
|
||||||
pub use self::iter::IntoIter;
|
pub use self::iter::IntoIter;
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use bytes::buf::IoSliceMut;
|
|
||||||
use bytes::{BufMut, BytesMut};
|
use bytes::{BufMut, BytesMut};
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
use core::usize;
|
use core::usize;
|
||||||
@@ -66,23 +64,6 @@ fn test_clone() {
|
|||||||
assert!(buf != buf2);
|
assert!(buf != buf2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
#[test]
|
|
||||||
fn test_bufs_vec_mut() {
|
|
||||||
let b1: &mut [u8] = &mut [];
|
|
||||||
let b2: &mut [u8] = &mut [];
|
|
||||||
let mut dst = [IoSliceMut::from(b1), IoSliceMut::from(b2)];
|
|
||||||
|
|
||||||
// with no capacity
|
|
||||||
let mut buf = BytesMut::new();
|
|
||||||
assert_eq!(buf.capacity(), 0);
|
|
||||||
assert_eq!(1, buf.bytes_vectored_mut(&mut dst[..]));
|
|
||||||
|
|
||||||
// with capacity
|
|
||||||
let mut buf = BytesMut::with_capacity(64);
|
|
||||||
assert_eq!(1, buf.bytes_vectored_mut(&mut dst[..]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mut_slice() {
|
fn test_mut_slice() {
|
||||||
let mut v = vec![0, 0, 0, 0];
|
let mut v = vec![0, 0, 0, 0];
|
||||||
|
|||||||
Reference in New Issue
Block a user