diff options
| author | bors <bors@rust-lang.org> | 2024-04-10 11:38:15 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-04-10 11:38:15 +0000 |
| commit | e908cfd125ae9d98550edb9ffd8d7eae4be601ac (patch) | |
| tree | 5521b2b64193518cf054fe3af5d5753886d6626c | |
| parent | b14d8b2ef20c64c1002e2c6c724025c3d0846b91 (diff) | |
| parent | 87348093954be36b2583dda2e6e842950d346254 (diff) | |
| download | rust-e908cfd125ae9d98550edb9ffd8d7eae4be601ac.tar.gz rust-e908cfd125ae9d98550edb9ffd8d7eae4be601ac.zip | |
Auto merge of #122393 - a1phyr:specialize_read_buf_exact, r=joboet
Specialize many implementations of `Read::read_buf_exact` This makes all implementations of `Read` that have a specialized `read_exact` implementation also have one for `read_buf_exact`.
| -rw-r--r-- | library/std/src/io/buffered/bufreader.rs | 8 | ||||
| -rw-r--r-- | library/std/src/io/cursor.rs | 7 | ||||
| -rw-r--r-- | library/std/src/io/impls.rs | 24 | ||||
| -rw-r--r-- | library/std/src/io/mod.rs | 43 | ||||
| -rw-r--r-- | library/std/src/io/stdio.rs | 10 |
5 files changed, 74 insertions, 18 deletions
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index acaa7e9228e..250cd583696 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -322,6 +322,14 @@ impl<R: ?Sized + Read> Read for BufReader<R> { crate::io::default_read_exact(self, buf) } + fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> { + if self.buf.consume_with(cursor.capacity(), |claimed| cursor.append(claimed)) { + return Ok(()); + } + + crate::io::default_read_buf_exact(self, cursor) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { let total_len = bufs.iter().map(|b| b.len()).sum::<usize>(); if self.buf.pos() == self.buf.filled() && total_len >= self.capacity() { diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index 4ef1f1b695e..49dde828c1f 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -357,6 +357,13 @@ where self.pos += n as u64; Ok(()) } + + fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> { + let n = cursor.capacity(); + Read::read_buf_exact(&mut self.remaining_slice(), cursor)?; + self.pos += n as u64; + Ok(()) + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs index cb972abd2b8..ee7ed4bcc9a 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -50,6 +50,10 @@ impl<R: Read + ?Sized> Read for &mut R { fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { (**self).read_exact(buf) } + #[inline] + fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> { + (**self).read_buf_exact(cursor) + } } #[stable(feature = "rust1", since = "1.0.0")] impl<W: Write + ?Sized> Write for &mut W { @@ -154,6 +158,10 @@ impl<R: Read + ?Sized> Read for Box<R> { fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { (**self).read_exact(buf) } + #[inline] + fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> { + (**self).read_buf_exact(cursor) + } } #[stable(feature = "rust1", since = "1.0.0")] impl<W: Write + ?Sized> Write for Box<W> { @@ -302,6 +310,22 @@ impl Read for &[u8] { } #[inline] + fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> { + if cursor.capacity() > self.len() { + return Err(io::const_io_error!( + ErrorKind::UnexpectedEof, + "failed to fill whole buffer" + )); + } + let (a, b) = self.split_at(cursor.capacity()); + + cursor.append(a); + + *self = b; + Ok(()) + } + + #[inline] fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { let len = self.len(); buf.try_reserve(len)?; diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 10bf9c51d16..980b3e7aa48 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -582,6 +582,29 @@ where Ok(()) } +pub(crate) fn default_read_buf_exact<R: Read + ?Sized>( + this: &mut R, + mut cursor: BorrowedCursor<'_>, +) -> Result<()> { + while cursor.capacity() > 0 { + let prev_written = cursor.written(); + match this.read_buf(cursor.reborrow()) { + Ok(()) => {} + Err(e) if e.is_interrupted() => continue, + Err(e) => return Err(e), + } + + if cursor.written() == prev_written { + return Err(error::const_io_error!( + ErrorKind::UnexpectedEof, + "failed to fill whole buffer" + )); + } + } + + Ok(()) +} + /// The `Read` trait allows for reading bytes from a source. /// /// Implementors of the `Read` trait are called 'readers'. @@ -978,24 +1001,8 @@ pub trait Read { /// /// If this function returns an error, all bytes read will be appended to `cursor`. #[unstable(feature = "read_buf", issue = "78485")] - fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> Result<()> { - while cursor.capacity() > 0 { - let prev_written = cursor.written(); - match self.read_buf(cursor.reborrow()) { - Ok(()) => {} - Err(e) if e.is_interrupted() => continue, - Err(e) => return Err(e), - } - - if cursor.written() == prev_written { - return Err(error::const_io_error!( - ErrorKind::UnexpectedEof, - "failed to fill whole buffer" - )); - } - } - - Ok(()) + fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<()> { + default_read_buf_exact(self, cursor) } /// Creates a "by reference" adaptor for this instance of `Read`. diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 8f60b3b1535..73fa7cbc3fe 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -451,6 +451,9 @@ impl Read for Stdin { fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { self.lock().read_exact(buf) } + fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> { + self.lock().read_buf_exact(cursor) + } } #[stable(feature = "read_shared_stdin", since = "1.78.0")] @@ -477,6 +480,9 @@ impl Read for &Stdin { fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { self.lock().read_exact(buf) } + fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> { + self.lock().read_buf_exact(cursor) + } } // only used by platform-dependent io::copy specializations, i.e. unused on some platforms @@ -517,6 +523,10 @@ impl Read for StdinLock<'_> { fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { self.inner.read_exact(buf) } + + fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> { + self.inner.read_buf_exact(cursor) + } } impl SpecReadByte for StdinLock<'_> { |
