Skip to content

Commit 6e4b1f2

Browse files
authored
Rename and expose BytesMut::spare_capacity_mut (#572)
1 parent a36f661 commit 6e4b1f2

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

src/buf/uninit_slice.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ use core::ops::{
2222
pub struct UninitSlice([MaybeUninit<u8>]);
2323

2424
impl UninitSlice {
25+
pub(crate) fn from_slice(slice: &mut [MaybeUninit<u8>]) -> &mut UninitSlice {
26+
unsafe { &mut *(slice as *mut [MaybeUninit<u8>] as *mut UninitSlice) }
27+
}
28+
2529
/// Create a `&mut UninitSlice` from a pointer and a length.
2630
///
2731
/// # Safety
@@ -44,7 +48,7 @@ impl UninitSlice {
4448
pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut u8, len: usize) -> &'a mut UninitSlice {
4549
let maybe_init: &mut [MaybeUninit<u8>] =
4650
core::slice::from_raw_parts_mut(ptr as *mut _, len);
47-
&mut *(maybe_init as *mut [MaybeUninit<u8>] as *mut UninitSlice)
51+
Self::from_slice(maybe_init)
4852
}
4953

5054
/// Write a single byte at the specified offset.

src/bytes_mut.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use core::iter::{FromIterator, Iterator};
2-
use core::mem::{self, ManuallyDrop};
2+
use core::mem::{self, ManuallyDrop, MaybeUninit};
33
use core::ops::{Deref, DerefMut};
44
use core::ptr::{self, NonNull};
55
use core::{cmp, fmt, hash, isize, slice, usize};
@@ -766,11 +766,11 @@ impl BytesMut {
766766
self.reserve(cnt);
767767

768768
unsafe {
769-
let dst = self.uninit_slice();
769+
let dst = self.spare_capacity_mut();
770770
// Reserved above
771771
debug_assert!(dst.len() >= cnt);
772772

773-
ptr::copy_nonoverlapping(extend.as_ptr(), dst.as_mut_ptr(), cnt);
773+
ptr::copy_nonoverlapping(extend.as_ptr(), dst.as_mut_ptr().cast(), cnt);
774774
}
775775

776776
unsafe {
@@ -992,13 +992,42 @@ impl BytesMut {
992992
self.data = invalid_ptr((pos << VEC_POS_OFFSET) | (prev & NOT_VEC_POS_MASK));
993993
}
994994

995+
/// Returns the remaining spare capacity of the buffer as a slice of `MaybeUninit<u8>`.
996+
///
997+
/// The returned slice can be used to fill the buffer with data (e.g. by
998+
/// reading from a file) before marking the data as initialized using the
999+
/// [`set_len`] method.
1000+
///
1001+
/// [`set_len`]: BytesMut::set_len
1002+
///
1003+
/// # Examples
1004+
///
1005+
/// ```
1006+
/// use bytes::BytesMut;
1007+
///
1008+
/// // Allocate buffer big enough for 10 bytes.
1009+
/// let mut buf = BytesMut::with_capacity(10);
1010+
///
1011+
/// // Fill in the first 3 elements.
1012+
/// let uninit = buf.spare_capacity_mut();
1013+
/// uninit[0].write(0);
1014+
/// uninit[1].write(1);
1015+
/// uninit[2].write(2);
1016+
///
1017+
/// // Mark the first 3 bytes of the buffer as being initialized.
1018+
/// unsafe {
1019+
/// buf.set_len(3);
1020+
/// }
1021+
///
1022+
/// assert_eq!(&buf[..], &[0, 1, 2]);
1023+
/// ```
9951024
#[inline]
996-
fn uninit_slice(&mut self) -> &mut UninitSlice {
1025+
pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<u8>] {
9971026
unsafe {
9981027
let ptr = self.ptr.as_ptr().add(self.len);
9991028
let len = self.cap - self.len;
10001029

1001-
UninitSlice::from_raw_parts_mut(ptr, len)
1030+
slice::from_raw_parts_mut(ptr.cast(), len)
10021031
}
10031032
}
10041033
}
@@ -1072,7 +1101,7 @@ unsafe impl BufMut for BytesMut {
10721101
if self.capacity() == self.len() {
10731102
self.reserve(64);
10741103
}
1075-
self.uninit_slice()
1104+
UninitSlice::from_slice(self.spare_capacity_mut())
10761105
}
10771106

10781107
// Specialize these methods so they can skip checking `remaining_mut`
@@ -1097,7 +1126,7 @@ unsafe impl BufMut for BytesMut {
10971126
fn put_bytes(&mut self, val: u8, cnt: usize) {
10981127
self.reserve(cnt);
10991128
unsafe {
1100-
let dst = self.uninit_slice();
1129+
let dst = self.spare_capacity_mut();
11011130
// Reserved above
11021131
debug_assert!(dst.len() >= cnt);
11031132

0 commit comments

Comments
 (0)