Skip to content

Commit cc92a9b

Browse files
committed
Improve several Read implementations
1 parent 9ce37dc commit cc92a9b

File tree

5 files changed

+69
-1
lines changed

5 files changed

+69
-1
lines changed

library/std/src/io/cursor.rs

+22
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,28 @@ where
355355
self.pos += n as u64;
356356
Ok(())
357357
}
358+
359+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
360+
let content = self.remaining_slice();
361+
let len = content.len();
362+
buf.try_reserve(len)?;
363+
buf.extend_from_slice(content);
364+
self.pos = self.inner.as_ref().len() as u64;
365+
366+
Ok(len)
367+
}
368+
369+
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
370+
let content = crate::str::from_utf8(self.remaining_slice()).map_err(|_| {
371+
io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8")
372+
})?;
373+
let len = content.len();
374+
buf.try_reserve(len)?;
375+
buf.push_str(content);
376+
self.pos = self.inner.as_ref().len() as u64;
377+
378+
Ok(len)
379+
}
358380
}
359381

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

library/std/src/io/impls.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,9 @@ impl Read for &[u8] {
315315
let content = str::from_utf8(self).map_err(|_| {
316316
io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8")
317317
})?;
318-
buf.push_str(content);
319318
let len = self.len();
319+
buf.try_reserve(len)?;
320+
buf.push_str(content);
320321
*self = &self[len..];
321322
Ok(len)
322323
}
@@ -470,6 +471,7 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
470471
let string = str::from_utf8(content).map_err(|_| {
471472
io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8")
472473
})?;
474+
buf.try_reserve(len)?;
473475
buf.push_str(string);
474476
self.clear();
475477
Ok(len)

library/std/src/io/mod.rs

+32
Original file line numberDiff line numberDiff line change
@@ -2924,6 +2924,22 @@ impl<T: Read> Read for Take<T> {
29242924
Ok(n)
29252925
}
29262926

2927+
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
2928+
// Don't call into inner reader at all at EOF because it may still block
2929+
if self.limit == 0 {
2930+
return Ok(());
2931+
}
2932+
2933+
let len = buf.len() as u64;
2934+
if self.limit > len {
2935+
self.inner.read_exact(buf)?;
2936+
self.limit += len;
2937+
Ok(())
2938+
} else {
2939+
Err(error::const_io_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer"))
2940+
}
2941+
}
2942+
29272943
fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> Result<()> {
29282944
// Don't call into inner reader at all at EOF because it may still block
29292945
if self.limit == 0 {
@@ -2970,6 +2986,22 @@ impl<T: Read> Read for Take<T> {
29702986

29712987
Ok(())
29722988
}
2989+
2990+
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<()> {
2991+
// Don't call into inner reader at all at EOF because it may still block
2992+
if self.limit == 0 {
2993+
return Ok(());
2994+
}
2995+
2996+
let cap = cursor.capacity() as u64;
2997+
if self.limit > cap {
2998+
self.inner.read_buf_exact(cursor)?;
2999+
self.limit += cap;
3000+
Ok(())
3001+
} else {
3002+
Err(error::const_io_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer"))
3003+
}
3004+
}
29733005
}
29743006

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

library/std/src/os/unix/net/stream.rs

+8
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,10 @@ impl io::Read for UnixStream {
578578
io::Read::read(&mut &*self, buf)
579579
}
580580

581+
fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> {
582+
io::Read::read_buf(&mut &*self, buf)
583+
}
584+
581585
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
582586
io::Read::read_vectored(&mut &*self, bufs)
583587
}
@@ -594,6 +598,10 @@ impl<'a> io::Read for &'a UnixStream {
594598
self.0.read(buf)
595599
}
596600

601+
fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> {
602+
self.0.read_buf(buf)
603+
}
604+
597605
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
598606
self.0.read_vectored(bufs)
599607
}

library/std/src/process.rs

+4
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,10 @@ impl Read for ChildStderr {
439439
fn is_read_vectored(&self) -> bool {
440440
self.inner.is_read_vectored()
441441
}
442+
443+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
444+
self.inner.read_to_end(buf)
445+
}
442446
}
443447

444448
impl AsInner<AnonPipe> for ChildStderr {

0 commit comments

Comments
 (0)