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
1 changed files with 54 additions and 0 deletions

View File

@ -9,6 +9,7 @@ use crate::io::{
self, BorrowedCursor, BufRead, ErrorKind, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write,
};
use crate::mem;
use crate::str;
// =============================================================================
// Forwarding implementations
@ -307,6 +308,17 @@ impl Read for &[u8] {
*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 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
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 @@ impl<A: Allocator> Write for VecDeque<u8, A> {
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);