Specialize some io::Read and io::Write methods for VecDeque<u8> and &[u8]

This commit is contained in:
Benoît du Garreau 2023-04-20 16:33:01 +02:00
parent 7e23d180c1
commit 1e6a7b4580

View File

@ -9,6 +9,7 @@
self, BorrowedCursor, BufRead, ErrorKind, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write,
};
use crate::mem;
use crate::str;
// =============================================================================
// Forwarding implementations
@ -307,6 +308,17 @@ fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
*self = &self[len..];
Ok(len)
}
#[inline]
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
let content = str::from_utf8(self).map_err(|_| {
io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8")
})?;
buf.push_str(content);
let len = self.len();
*self = &self[len..];
Ok(len)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
@ -434,6 +446,33 @@ fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
self.drain(..n);
Ok(())
}
#[inline]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
// The total len is known upfront so we can reserve it in a single call.
let len = self.len();
buf.reserve(len);
let (front, back) = self.as_slices();
buf.extend_from_slice(front);
buf.extend_from_slice(back);
self.clear();
Ok(len)
}
#[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::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8")
})?;
buf.push_str(string);
self.clear();
Ok(len)
}
}
/// Write is implemented for `VecDeque<u8>` by appending to the `VecDeque`, growing it as needed.
@ -445,6 +484,21 @@ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
Ok(buf.len())
}
#[inline]
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
let len = bufs.iter().map(|b| b.len()).sum();
self.reserve(len);
for buf in bufs {
self.extend(&**buf);
}
Ok(len)
}
#[inline]
fn is_write_vectored(&self) -> bool {
true
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.extend(buf);