Rollup merge of #122441 - a1phyr:improve_read_impls, r=ChrisDenton
Improve several `Read` implementations - `read_to_end` and `read_to_string` for `Cursor` - Error on OOM in `read_to_string` of `&[u8]` and `VecDeque<u8>` - Avoid making the slices contiguous in `VecDeque::read_to_string` - ~`read_exact` and (unstable) `read_buf_exact` for `Take`~ - ~`read_buf` for `UnixStream` and `&UnixStream`~ (moved to #123084) - `read_to_end` for `ChildStdErr`
This commit is contained in:
commit
00bc2a425c
@ -364,6 +364,27 @@ fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
|
||||
self.pos += n as u64;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
let content = self.remaining_slice();
|
||||
let len = content.len();
|
||||
buf.try_reserve(len)?;
|
||||
buf.extend_from_slice(content);
|
||||
self.pos += len as u64;
|
||||
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
|
||||
let content =
|
||||
crate::str::from_utf8(self.remaining_slice()).map_err(|_| io::Error::INVALID_UTF8)?;
|
||||
let len = content.len();
|
||||
buf.try_reserve(len)?;
|
||||
buf.push_str(content);
|
||||
self.pos += len as u64;
|
||||
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -329,8 +329,9 @@ fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
#[inline]
|
||||
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
|
||||
let content = str::from_utf8(self).map_err(|_| io::Error::INVALID_UTF8)?;
|
||||
buf.push_str(content);
|
||||
let len = self.len();
|
||||
buf.try_reserve(len)?;
|
||||
buf.push_str(content);
|
||||
*self = &self[len..];
|
||||
Ok(len)
|
||||
}
|
||||
@ -473,14 +474,8 @@ fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
|
||||
#[inline]
|
||||
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
|
||||
// We have to use a single contiguous slice because the `VecDequeue` might be split in the
|
||||
// middle of an UTF-8 character.
|
||||
let len = self.len();
|
||||
let content = self.make_contiguous();
|
||||
let string = str::from_utf8(content).map_err(|_| io::Error::INVALID_UTF8)?;
|
||||
buf.push_str(string);
|
||||
self.clear();
|
||||
Ok(len)
|
||||
// SAFETY: We only append to the buffer
|
||||
unsafe { io::append_to_string(buf, |buf| self.read_to_end(buf)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,7 +384,10 @@ pub(crate) unsafe fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize
|
||||
{
|
||||
let mut g = Guard { len: buf.len(), buf: buf.as_mut_vec() };
|
||||
let ret = f(g.buf);
|
||||
if str::from_utf8(&g.buf[g.len..]).is_err() {
|
||||
|
||||
// SAFETY: the caller promises to only append data to `buf`
|
||||
let appended = g.buf.get_unchecked(g.len..);
|
||||
if str::from_utf8(appended).is_err() {
|
||||
ret.and_then(|_| Err(Error::INVALID_UTF8))
|
||||
} else {
|
||||
g.len = g.buf.len();
|
||||
|
@ -486,6 +486,10 @@ fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.inner.is_read_vectored()
|
||||
}
|
||||
|
||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
self.inner.read_to_end(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<AnonPipe> for ChildStderr {
|
||||
|
Loading…
Reference in New Issue
Block a user