diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index 7097dfef88d4e..9aa2ab4af59aa 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -259,6 +259,31 @@ impl BufReader { } } +impl BufReader +where + Self: Read, +{ + #[inline] + pub(crate) fn read_byte(&mut self) -> Option> { + #[cold] + fn slow_path(this: &mut BufReader) -> Option> + where + BufReader: Read, + { + use crate::io::SpecReadByte; + + this.slow_read_byte() + } + + let mut byte = 0; + if self.buf.consume_with(1, |claimed| byte = claimed[0]) { + return Some(Ok(byte)); + } + + slow_path(self) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Read for BufReader { fn read(&mut self, buf: &mut [u8]) -> io::Result { @@ -269,10 +294,8 @@ impl Read for BufReader { self.discard_buffer(); return self.inner.read(buf); } - let nread = { - let mut rem = self.fill_buf()?; - rem.read(buf)? - }; + let mut rem = self.fill_buf()?; + let nread = rem.read(buf)?; self.consume(nread); Ok(nread) } diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index c0a729481121a..e8002ec105b2c 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -2777,11 +2777,33 @@ pub struct Bytes { impl Iterator for Bytes { type Item = Result; - #[inline] fn next(&mut self) -> Option> { + SpecReadByte::spec_read_byte(&mut self.inner) + } + + fn size_hint(&self) -> (usize, Option) { + SizeHint::size_hint(&self.inner) + } +} + +trait SpecReadByte { + fn spec_read_byte(&mut self) -> Option>; + fn slow_read_byte(&mut self) -> Option>; +} + +impl SpecReadByte for R +where + Self: Read, +{ + default fn spec_read_byte(&mut self) -> Option> { + self.slow_read_byte() + } + + #[inline] + fn slow_read_byte(&mut self) -> Option> { let mut byte = 0; loop { - return match self.inner.read(slice::from_mut(&mut byte)) { + return match self.read(slice::from_mut(&mut byte)) { Ok(0) => None, Ok(..) => Some(Ok(byte)), Err(ref e) if e.is_interrupted() => continue, @@ -2789,10 +2811,15 @@ impl Iterator for Bytes { }; } } +} +impl SpecReadByte for BufReader +where + Self: Read, +{ #[inline] - fn size_hint(&self) -> (usize, Option) { - SizeHint::size_hint(&self.inner) + fn spec_read_byte(&mut self) -> Option> { + self.read_byte() } }