Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/rt/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,46 @@ impl ReadBufCursor<'_> {
}
self.buf.filled = end;
}

/// Returns a mutable reference to the unfilled part of the buffer, ensuring it is fully initialized.
#[inline]
pub fn initialize_unfilled(&mut self) -> &mut [u8] {
self.initialize_unfilled_to(self.remaining())
}

/// Returns a mutable reference to the first `n` bytes of the unfilled part of the buffer, ensuring it is
/// fully initialized.
///
/// # Panics
///
/// Panics if `self.remaining()` is less than `n`.
#[inline]
pub fn initialize_unfilled_to(&mut self, n: usize) -> &mut [u8] {
assert!(self.remaining() >= n, "n overflows remaining");

// This can't overflow as the assert above would have panicked otherwise.
let end = self.buf.filled + n;

if self.buf.init < end {
// SAFETY:
// 1. The raw pointer is not null and not dangling either as the slice outlives the
// pointer's usage. The pointer is also properly aligned.
// 2. Further, `end - self.buf.init` is inbounds and hence safe to write
// to.
unsafe {
self.buf.raw[self.buf.init..end]
.as_mut_ptr()
.write_bytes(0, end - self.buf.init);
}
self.buf.init = end;
}

let slice = &mut self.buf.raw[self.buf.filled..end];

// SAFETY: `MaybeUninit<u8>` has the same memory layout as u8 and we properly initialized
// the slice above.
unsafe { &mut *(slice as *mut [MaybeUninit<u8>] as *mut [u8]) }
}
}

macro_rules! deref_async_read {
Expand Down
Loading