Auto merge of #105917 - a1phyr:read_chain_more_impls, r=workingjubilee
Specialize some methods of `io::Chain` This PR specializes the implementation of some methods of `io::Chain`, which could bring performance improvements when using it.
This commit is contained in:
commit
bea5bebf3d
@ -2672,6 +2672,42 @@ fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
|
|||||||
}
|
}
|
||||||
self.second.read_vectored(bufs)
|
self.second.read_vectored(bufs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_read_vectored(&self) -> bool {
|
||||||
|
self.first.is_read_vectored() || self.second.is_read_vectored()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
|
||||||
|
let mut read = 0;
|
||||||
|
if !self.done_first {
|
||||||
|
read += self.first.read_to_end(buf)?;
|
||||||
|
self.done_first = true;
|
||||||
|
}
|
||||||
|
read += self.second.read_to_end(buf)?;
|
||||||
|
Ok(read)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't override `read_to_string` here because an UTF-8 sequence could
|
||||||
|
// be split between the two parts of the chain
|
||||||
|
|
||||||
|
fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> Result<()> {
|
||||||
|
if buf.capacity() == 0 {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.done_first {
|
||||||
|
let old_len = buf.written();
|
||||||
|
self.first.read_buf(buf.reborrow())?;
|
||||||
|
|
||||||
|
if buf.written() != old_len {
|
||||||
|
return Ok(());
|
||||||
|
} else {
|
||||||
|
self.done_first = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.second.read_buf(buf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "chain_bufread", since = "1.9.0")]
|
#[stable(feature = "chain_bufread", since = "1.9.0")]
|
||||||
@ -2679,9 +2715,7 @@ impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
|
|||||||
fn fill_buf(&mut self) -> Result<&[u8]> {
|
fn fill_buf(&mut self) -> Result<&[u8]> {
|
||||||
if !self.done_first {
|
if !self.done_first {
|
||||||
match self.first.fill_buf()? {
|
match self.first.fill_buf()? {
|
||||||
buf if buf.is_empty() => {
|
buf if buf.is_empty() => self.done_first = true,
|
||||||
self.done_first = true;
|
|
||||||
}
|
|
||||||
buf => return Ok(buf),
|
buf => return Ok(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2691,6 +2725,24 @@ fn fill_buf(&mut self) -> Result<&[u8]> {
|
|||||||
fn consume(&mut self, amt: usize) {
|
fn consume(&mut self, amt: usize) {
|
||||||
if !self.done_first { self.first.consume(amt) } else { self.second.consume(amt) }
|
if !self.done_first { self.first.consume(amt) } else { self.second.consume(amt) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
|
||||||
|
let mut read = 0;
|
||||||
|
if !self.done_first {
|
||||||
|
let n = self.first.read_until(byte, buf)?;
|
||||||
|
read += n;
|
||||||
|
|
||||||
|
match buf.last() {
|
||||||
|
Some(b) if *b == byte && n != 0 => return Ok(read),
|
||||||
|
_ => self.done_first = true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
read += self.second.read_until(byte, buf)?;
|
||||||
|
Ok(read)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't override `read_line` here because an UTF-8 sequence could be
|
||||||
|
// split between the two parts of the chain
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, U> SizeHint for Chain<T, U> {
|
impl<T, U> SizeHint for Chain<T, U> {
|
||||||
|
@ -261,6 +261,17 @@ fn chain_bufread() {
|
|||||||
cmp_bufread(chain1, chain2, &testdata[..]);
|
cmp_bufread(chain1, chain2, &testdata[..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn chain_splitted_char() {
|
||||||
|
let chain = b"\xc3".chain(b"\xa9".as_slice());
|
||||||
|
assert_eq!(crate::io::read_to_string(chain).unwrap(), "é");
|
||||||
|
|
||||||
|
let mut chain = b"\xc3".chain(b"\xa9\n".as_slice());
|
||||||
|
let mut buf = String::new();
|
||||||
|
assert_eq!(chain.read_line(&mut buf).unwrap(), 3);
|
||||||
|
assert_eq!(buf, "é\n");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bufreader_size_hint() {
|
fn bufreader_size_hint() {
|
||||||
let testdata = b"ABCDEFGHIJKL";
|
let testdata = b"ABCDEFGHIJKL";
|
||||||
|
Loading…
Reference in New Issue
Block a user