about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/std/src/io/buffered/bufreader.rs4
-rw-r--r--library/std/src/io/buffered/bufreader/buffer.rs17
2 files changed, 18 insertions, 3 deletions
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index 0be55904407..f7fbaa9c276 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -290,9 +290,7 @@ impl<R: Read> Read for BufReader<R> {
     // generation for the common path where the buffer has enough bytes to fill the passed-in
     // buffer.
     fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
-        if let Some(claimed) = self.buffer().get(..buf.len()) {
-            buf.copy_from_slice(claimed);
-            self.consume(claimed.len());
+        if self.buf.consume_with(buf.len(), |claimed| buf.copy_from_slice(claimed)) {
             return Ok(());
         }
 
diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs
index bf3462bf00c..8ae01f3b0ad 100644
--- a/library/std/src/io/buffered/bufreader/buffer.rs
+++ b/library/std/src/io/buffered/bufreader/buffer.rs
@@ -62,6 +62,23 @@ impl Buffer {
         self.pos = cmp::min(self.pos + amt, self.filled);
     }
 
+    /// If there are `amt` bytes available in the buffer, pass a slice containing those bytes to
+    /// `visitor` and return true. If there are not enough bytes available, return false.
+    #[inline]
+    pub fn consume_with<V>(&mut self, amt: usize, mut visitor: V) -> bool
+    where
+        V: FnMut(&[u8]),
+    {
+        if let Some(claimed) = self.buffer().get(..amt) {
+            visitor(claimed);
+            // If the indexing into self.buffer() succeeds, amt must be a valid increment.
+            self.pos += amt;
+            true
+        } else {
+            false
+        }
+    }
+
     #[inline]
     pub fn unconsume(&mut self, amt: usize) {
         self.pos = self.pos.saturating_sub(amt);