Change BufMut methods that expose maybe-uninitialized bytes (#305)

- The return type of `BufMut::bytes_mut` is now
  `&mut [MaybeUninit<u8>]`.
- The argument type of `BufMut::bytes_vectored_mut` is now
  `&mut [bytes::buf::IoSliceMut]`.
- `bytes::buf::IoSliceMut` is a `repr(transparent)` wrapper around an
  `std::io::IoSliceMut`, but does not expose the inner bytes with a safe
  API, since they might be uninitialized.
- `BufMut::bytesMut` and `BufMut::bytes_vectored_mut` are no longer
  `unsafe fn`, since the types encapsulate the unsafety instead.
This commit is contained in:
Sean McArthur
2019-10-24 14:40:45 -07:00
committed by GitHub
parent fe2183dc2f
commit 2ac72333fa
7 changed files with 108 additions and 58 deletions
+7 -16
View File
@@ -926,19 +926,9 @@ impl BufMut for BytesMut {
}
#[inline]
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
slice::from_raw_parts_mut(self.ptr.as_ptr().offset(self.len as isize), self.cap)
}
#[inline]
fn put_slice(&mut self, src: &[u8]) {
assert!(self.remaining_mut() >= src.len());
let len = src.len();
fn bytes_mut(&mut self) -> &mut [mem::MaybeUninit<u8>] {
unsafe {
self.bytes_mut()[..len].copy_from_slice(src);
self.advance_mut(len);
slice::from_raw_parts_mut(self.ptr.as_ptr().offset(self.len as isize) as *mut mem::MaybeUninit<u8>, self.cap)
}
}
}
@@ -1085,11 +1075,12 @@ impl Extend<u8> for BytesMut {
let (lower, _) = iter.size_hint();
self.reserve(lower);
// TODO: optimize
// 1. If self.kind() == KIND_VEC, use Vec::extend
// 2. Make `reserve` inline-able
for b in iter {
unsafe {
self.bytes_mut()[0] = b;
self.advance_mut(1);
}
self.reserve(1);
self.put_u8(b);
}
}
}