self.inner.read_vectored(bufs)
}
- fn read_buf(&mut self, cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
self.inner.read_buf(cursor)
}
self.inner.read(buf)
}
- fn read_buf(&mut self, cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
self.inner.read_buf(cursor)
}
Ok(nread)
}
- fn read_buf(&mut self, mut cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ fn read_buf(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
// If we don't have any buffered data and we're doing a massive read
// (larger than our internal buffer), bypass our internal buffer
// entirely.
let prev = cursor.written();
let mut rem = self.fill_buf()?;
- rem.read_buf(cursor.clone())?;
+ rem.read_buf(cursor.reborrow())?;
self.consume(cursor.written() - prev); //slice impl of read_buf known to never unfill buf
if self.pos >= self.filled {
debug_assert!(self.pos == self.filled);
- let mut buf: BorrowedBuf<'_> = (&mut *self.buf).into();
+ let mut buf = BorrowedBuf::from(&mut *self.buf);
// SAFETY: `self.filled` bytes will always have been initialized.
unsafe {
buf.set_init(self.filled);
if read_buf.capacity() >= DEFAULT_BUF_SIZE {
let mut cursor = read_buf.unfilled();
- match reader.read_buf(cursor.clone()) {
+ match reader.read_buf(cursor.reborrow()) {
Ok(()) => {
let bytes_read = cursor.written();
Ok(n)
}
- fn read_buf(&mut self, mut cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ fn read_buf(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
let prev_written = cursor.written();
- Read::read_buf(&mut self.fill_buf()?, cursor.clone())?;
+ Read::read_buf(&mut self.fill_buf()?, cursor.reborrow())?;
self.pos += (cursor.written() - prev_written) as u64;
}
#[inline]
- fn read_buf(&mut self, cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
(**self).read_buf(cursor)
}
}
#[inline]
- fn read_buf(&mut self, cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
(**self).read_buf(cursor)
}
}
#[inline]
- fn read_buf(&mut self, mut cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ fn read_buf(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
let amt = cmp::min(cursor.capacity(), self.len());
let (a, b) = self.split_at(amt);
}
#[inline]
- fn read_buf(&mut self, cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
let (ref mut front, _) = self.as_slices();
let n = cmp::min(cursor.capacity(), front.len());
Read::read_buf(front, cursor)?;
}
let mut cursor = read_buf.unfilled();
- match r.read_buf(cursor.clone()) {
+ match r.read_buf(cursor.reborrow()) {
Ok(()) => {}
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
}
}
-pub(crate) fn default_read_buf<F>(read: F, mut cursor: BorrowedCursor<'_, '_>) -> Result<()>
+pub(crate) fn default_read_buf<F>(read: F, mut cursor: BorrowedCursor<'_>) -> Result<()>
where
F: FnOnce(&mut [u8]) -> Result<usize>,
{
///
/// The default implementation delegates to `read`.
#[unstable(feature = "read_buf", issue = "78485")]
- fn read_buf(&mut self, buf: BorrowedCursor<'_, '_>) -> Result<()> {
+ fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<()> {
default_read_buf(|b| self.read(b), buf)
}
/// This is equivalent to the [`read_exact`](Read::read_exact) method, except that it is passed a [`BorrowedCursor`] rather than `[u8]` to
/// allow use with uninitialized buffers.
#[unstable(feature = "read_buf", issue = "78485")]
- fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_, '_>) -> Result<()> {
+ fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> Result<()> {
while cursor.capacity() > 0 {
let prev_written = cursor.written();
- match self.read_buf(cursor.clone()) {
+ match self.read_buf(cursor.reborrow()) {
Ok(()) => {}
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
Ok(n)
}
- fn read_buf(&mut self, mut buf: BorrowedCursor<'_, '_>) -> Result<()> {
+ fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> Result<()> {
// Don't call into inner reader at all at EOF because it may still block
if self.limit == 0 {
return Ok(());
}
let mut cursor = sliced_buf.unfilled();
- self.inner.read_buf(cursor.clone())?;
+ self.inner.read_buf(cursor.reborrow())?;
let new_init = cursor.init_ref().len();
let filled = sliced_buf.len();
self.limit -= filled as u64;
} else {
let written = buf.written();
- self.inner.read_buf(buf.clone())?;
+ self.inner.read_buf(buf.reborrow())?;
self.limit -= (buf.written() - written) as u64;
}
use crate::cmp;
use crate::fmt::{self, Debug, Formatter};
use crate::io::{Result, Write};
-use crate::mem::MaybeUninit;
+use crate::mem::{self, MaybeUninit};
/// A borrowed byte buffer which is incrementally filled and initialized.
///
/// ```
///
/// A `BorrowedBuf` is created around some existing data (or capacity for data) via a unique reference
-/// (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_init`), but otherwise
-/// is read-only. To write into the buffer, use `unfilled` to create a `BorrowedCursor`. The cursor
-/// has write-only access to the unfilled portion of the buffer (you can think of it like a
+/// (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_init`), but cannot be
+/// directly written. To write into the buffer, use `unfilled` to create a `BorrowedCursor`. The cursor
+/// has write-only access to the unfilled portion of the buffer (you can think of it as a
/// write-only iterator).
///
/// The lifetime `'data` is a bound on the lifetime of the underlying data.
let len = slice.len();
BorrowedBuf {
- //SAFETY: initialized data never becoming uninitialized is an invariant of BorrowedBuf
+ // SAFETY: initialized data never becoming uninitialized is an invariant of BorrowedBuf
buf: unsafe { (slice as *mut [u8]).as_uninit_slice_mut().unwrap() },
filled: 0,
init: len,
/// Returns a shared reference to the filled portion of the buffer.
#[inline]
pub fn filled(&self) -> &[u8] {
- //SAFETY: We only slice the filled part of the buffer, which is always valid
+ // SAFETY: We only slice the filled part of the buffer, which is always valid
unsafe { MaybeUninit::slice_assume_init_ref(&self.buf[0..self.filled]) }
}
/// Returns a cursor over the unfilled part of the buffer.
#[inline]
- pub fn unfilled<'this>(&'this mut self) -> BorrowedCursor<'this, 'data> {
- BorrowedCursor { start: self.filled, buf: self }
+ pub fn unfilled<'this>(&'this mut self) -> BorrowedCursor<'this> {
+ BorrowedCursor {
+ start: self.filled,
+ // SAFETY: we never assign into `BorrowedCursor::buf`, so treating its
+ // lifetime covariantly is safe.
+ buf: unsafe {
+ mem::transmute::<&'this mut BorrowedBuf<'data>, &'this mut BorrowedBuf<'this>>(self)
+ },
+ }
}
/// Clears the buffer, resetting the filled region to empty.
/// `BorrowedBuf` and can no longer be accessed or re-written by the cursor. I.e., the cursor tracks
/// the unfilled part of the underlying `BorrowedBuf`.
///
-/// The `'buf` lifetime is a bound on the lifetime of the underlying buffer. `'data` is a bound on
-/// that buffer's underlying data.
+/// The lifetime `'a` is a bound on the lifetime of the underlying buffer (which means it is a bound
+/// on the data in that buffer by transitivity).
#[derive(Debug)]
-pub struct BorrowedCursor<'buf, 'data> {
+pub struct BorrowedCursor<'a> {
/// The underlying buffer.
- buf: &'buf mut BorrowedBuf<'data>,
+ // Safety invariant: we treat the type of buf as covariant in the lifetime of `BorrowedBuf` when
+ // we create a `BorrowedCursor`. This is only safe if we never replace `buf` by assigning into
+ // it, so don't do that!
+ buf: &'a mut BorrowedBuf<'a>,
/// The length of the filled portion of the underlying buffer at the time of the cursor's
/// creation.
start: usize,
}
-impl<'buf, 'data> BorrowedCursor<'buf, 'data> {
- /// Clone this cursor.
+impl<'a> BorrowedCursor<'a> {
+ /// Reborrow this cursor by cloning it with a smaller lifetime.
///
- /// Since a cursor maintains unique access to its underlying buffer, the cloned cursor is not
- /// accessible while the clone is alive.
+ /// Since a cursor maintains unique access to its underlying buffer, the borrowed cursor is
+ /// not accessible while the new cursor exists.
#[inline]
- pub fn clone<'this>(&'this mut self) -> BorrowedCursor<'this, 'data> {
- BorrowedCursor { buf: self.buf, start: self.start }
+ pub fn reborrow<'this>(&'this mut self) -> BorrowedCursor<'this> {
+ BorrowedCursor {
+ // SAFETY: we never assign into `BorrowedCursor::buf`, so treating its
+ // lifetime covariantly is safe.
+ buf: unsafe {
+ mem::transmute::<&'this mut BorrowedBuf<'a>, &'this mut BorrowedBuf<'this>>(
+ self.buf,
+ )
+ },
+ start: self.start,
+ }
}
/// Returns the available space in the cursor.
/// Returns the number of bytes written to this cursor since it was created from a `BorrowedBuf`.
///
- /// Note that if this cursor is a clone of another, then the count returned is the count written
- /// via either cursor, not the count since the cursor was cloned.
+ /// Note that if this cursor is a reborrowed clone of another, then the count returned is the
+ /// count written via either cursor, not the count since the cursor was reborrowed.
#[inline]
pub fn written(&self) -> usize {
self.buf.filled - self.start
/// Returns a shared reference to the initialized portion of the cursor.
#[inline]
pub fn init_ref(&self) -> &[u8] {
- //SAFETY: We only slice the initialized part of the buffer, which is always valid
+ // SAFETY: We only slice the initialized part of the buffer, which is always valid
unsafe { MaybeUninit::slice_assume_init_ref(&self.buf.buf[self.buf.filled..self.buf.init]) }
}
/// Returns a mutable reference to the initialized portion of the cursor.
#[inline]
pub fn init_mut(&mut self) -> &mut [u8] {
- //SAFETY: We only slice the initialized part of the buffer, which is always valid
+ // SAFETY: We only slice the initialized part of the buffer, which is always valid
unsafe {
MaybeUninit::slice_assume_init_mut(&mut self.buf.buf[self.buf.filled..self.buf.init])
}
}
}
-impl<'buf, 'data> Write for BorrowedCursor<'buf, 'data> {
+impl<'a> Write for BorrowedCursor<'a> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.append(buf);
Ok(buf.len())
}
#[test]
-fn clone_written() {
+fn reborrow_written() {
let buf: &mut [_] = &mut [MaybeUninit::new(0); 32];
let mut buf: BorrowedBuf<'_> = buf.into();
let mut cursor = buf.unfilled();
cursor.append(&[1; 16]);
- let mut cursor2 = cursor.clone();
+ let mut cursor2 = cursor.reborrow();
cursor2.append(&[2; 16]);
assert_eq!(cursor2.written(), 32);
}
#[inline]
- fn read_buf(&mut self, _cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ fn read_buf(&mut self, _cursor: BorrowedCursor<'_>) -> io::Result<()> {
Ok(())
}
}
Ok(buf.len())
}
- fn read_buf(&mut self, mut buf: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {
// SAFETY: No uninit bytes are being written
for slot in unsafe { buf.as_mut() } {
slot.write(self.byte);
false
}
- pub fn read_buf(&self, cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
crate::io::default_read_buf(|buf| self.read(buf), cursor)
}
}
}
- pub fn read_buf(&self, mut cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ pub fn read_buf(&self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
unsafe {
let len = cursor.capacity();
let mut out_num_bytes = MaybeUninit::uninit();
}
}
- pub fn read_buf(&self, mut cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ pub fn read_buf(&self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
let ret = cvt(unsafe {
libc::read(
self.as_raw_fd(),
self.0.read_at(buf, offset)
}
- pub fn read_buf(&self, cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
self.0.read_buf(cursor)
}
self.0
}
- pub fn read_buf(&self, _cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ pub fn read_buf(&self, _cursor: BorrowedCursor<'_>) -> io::Result<()> {
self.0
}
true
}
- pub fn read_buf(&self, cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
crate::io::default_read_buf(|buf| self.read(buf), cursor)
}
self.handle.read_at(buf, offset)
}
- pub fn read_buf(&self, cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
self.handle.read_buf(cursor)
}
}
}
- pub fn read_buf(&self, mut cursor: BorrowedCursor<'_, '_>) -> io::Result<()> {
+ pub fn read_buf(&self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
let res =
unsafe { self.synchronous_read(cursor.as_mut().as_mut_ptr(), cursor.capacity(), None) };