]> git.lizzy.rs Git - rust.git/commitdiff
Add Buffer::consume_with to enable direct buffer access with one check
authorBen Kimock <kimockb@gmail.com>
Wed, 27 Jul 2022 00:03:14 +0000 (20:03 -0400)
committerBen Kimock <kimockb@gmail.com>
Wed, 27 Jul 2022 00:16:55 +0000 (20:16 -0400)
library/std/src/io/buffered/bufreader.rs
library/std/src/io/buffered/bufreader/buffer.rs

index 0be559044070292fed19337b1a1377963400537a..f7fbaa9c27649dfc9230079c7e5be6c095510246 100644 (file)
@@ -290,9 +290,7 @@ fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
     // 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(());
         }
 
index bf3462bf00cb85ae8a3f701da15ea4f1f3e71f67..8ae01f3b0ad8ac44d184aa0c666bc12b77d875f8 100644 (file)
@@ -62,6 +62,23 @@ pub fn consume(&mut self, amt: usize) {
         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);