Skip to content

Commit 8734809

Browse files
committed
Specialize many implementations of Read::read_buf_exact
1 parent 7de1a1f commit 8734809

File tree

5 files changed

+74
-18
lines changed

5 files changed

+74
-18
lines changed

library/std/src/io/buffered/bufreader.rs

+8
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,14 @@ impl<R: ?Sized + Read> Read for BufReader<R> {
322322
crate::io::default_read_exact(self, buf)
323323
}
324324

325+
fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
326+
if self.buf.consume_with(cursor.capacity(), |claimed| cursor.append(claimed)) {
327+
return Ok(());
328+
}
329+
330+
crate::io::default_read_buf_exact(self, cursor)
331+
}
332+
325333
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
326334
let total_len = bufs.iter().map(|b| b.len()).sum::<usize>();
327335
if self.buf.pos() == self.buf.filled() && total_len >= self.capacity() {

library/std/src/io/cursor.rs

+7
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,13 @@ where
355355
self.pos += n as u64;
356356
Ok(())
357357
}
358+
359+
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
360+
let n = cursor.capacity();
361+
Read::read_buf_exact(&mut self.remaining_slice(), cursor)?;
362+
self.pos += n as u64;
363+
Ok(())
364+
}
358365
}
359366

360367
#[stable(feature = "rust1", since = "1.0.0")]

library/std/src/io/impls.rs

+24
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ impl<R: Read + ?Sized> Read for &mut R {
5050
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
5151
(**self).read_exact(buf)
5252
}
53+
#[inline]
54+
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
55+
(**self).read_buf_exact(cursor)
56+
}
5357
}
5458
#[stable(feature = "rust1", since = "1.0.0")]
5559
impl<W: Write + ?Sized> Write for &mut W {
@@ -154,6 +158,10 @@ impl<R: Read + ?Sized> Read for Box<R> {
154158
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
155159
(**self).read_exact(buf)
156160
}
161+
#[inline]
162+
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
163+
(**self).read_buf_exact(cursor)
164+
}
157165
}
158166
#[stable(feature = "rust1", since = "1.0.0")]
159167
impl<W: Write + ?Sized> Write for Box<W> {
@@ -301,6 +309,22 @@ impl Read for &[u8] {
301309
Ok(())
302310
}
303311

312+
#[inline]
313+
fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
314+
if cursor.capacity() > self.len() {
315+
return Err(io::const_io_error!(
316+
ErrorKind::UnexpectedEof,
317+
"failed to fill whole buffer"
318+
));
319+
}
320+
let (a, b) = self.split_at(cursor.capacity());
321+
322+
cursor.append(a);
323+
324+
*self = b;
325+
Ok(())
326+
}
327+
304328
#[inline]
305329
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
306330
let len = self.len();

library/std/src/io/mod.rs

+25-18
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,29 @@ where
582582
Ok(())
583583
}
584584

585+
pub(crate) fn default_read_buf_exact<R: Read + ?Sized>(
586+
this: &mut R,
587+
mut cursor: BorrowedCursor<'_>,
588+
) -> Result<()> {
589+
while cursor.capacity() > 0 {
590+
let prev_written = cursor.written();
591+
match this.read_buf(cursor.reborrow()) {
592+
Ok(()) => {}
593+
Err(e) if e.is_interrupted() => continue,
594+
Err(e) => return Err(e),
595+
}
596+
597+
if cursor.written() == prev_written {
598+
return Err(error::const_io_error!(
599+
ErrorKind::UnexpectedEof,
600+
"failed to fill whole buffer"
601+
));
602+
}
603+
}
604+
605+
Ok(())
606+
}
607+
585608
/// The `Read` trait allows for reading bytes from a source.
586609
///
587610
/// Implementors of the `Read` trait are called 'readers'.
@@ -978,24 +1001,8 @@ pub trait Read {
9781001
///
9791002
/// If this function returns an error, all bytes read will be appended to `cursor`.
9801003
#[unstable(feature = "read_buf", issue = "78485")]
981-
fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> Result<()> {
982-
while cursor.capacity() > 0 {
983-
let prev_written = cursor.written();
984-
match self.read_buf(cursor.reborrow()) {
985-
Ok(()) => {}
986-
Err(e) if e.is_interrupted() => continue,
987-
Err(e) => return Err(e),
988-
}
989-
990-
if cursor.written() == prev_written {
991-
return Err(error::const_io_error!(
992-
ErrorKind::UnexpectedEof,
993-
"failed to fill whole buffer"
994-
));
995-
}
996-
}
997-
998-
Ok(())
1004+
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<()> {
1005+
default_read_buf_exact(self, cursor)
9991006
}
10001007

10011008
/// Creates a "by reference" adaptor for this instance of `Read`.

library/std/src/io/stdio.rs

+10
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,9 @@ impl Read for Stdin {
451451
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
452452
self.lock().read_exact(buf)
453453
}
454+
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
455+
self.lock().read_buf_exact(cursor)
456+
}
454457
}
455458

456459
#[stable(feature = "read_shared_stdin", since = "CURRENT_RUSTC_VERSION")]
@@ -477,6 +480,9 @@ impl Read for &Stdin {
477480
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
478481
self.lock().read_exact(buf)
479482
}
483+
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
484+
self.lock().read_buf_exact(cursor)
485+
}
480486
}
481487

482488
// only used by platform-dependent io::copy specializations, i.e. unused on some platforms
@@ -517,6 +523,10 @@ impl Read for StdinLock<'_> {
517523
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
518524
self.inner.read_exact(buf)
519525
}
526+
527+
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
528+
self.inner.read_buf_exact(cursor)
529+
}
520530
}
521531

522532
impl SpecReadByte for StdinLock<'_> {

0 commit comments

Comments
 (0)