about summary refs log tree commit diff
path: root/library/std/src/io/impls.rs
diff options
context:
space:
mode:
authorBenoît du Garreau <bdgdlm@outlook.com>2024-10-22 17:09:10 +0200
committerBenoît du Garreau <bdgdlm@outlook.com>2024-10-23 10:09:24 +0200
commit77a7164ec99c5ba195f107b221d37a55667f3a87 (patch)
tree9430eea81a0755589b01c653464220eeeaadaae6 /library/std/src/io/impls.rs
parentbca5fdebe0e539d123f33df5f2149d5976392e76 (diff)
downloadrust-77a7164ec99c5ba195f107b221d37a55667f3a87.tar.gz
rust-77a7164ec99c5ba195f107b221d37a55667f3a87.zip
Specialize `read_exact` and `read_buf_exact` for `VecDeque`
Diffstat (limited to 'library/std/src/io/impls.rs')
-rw-r--r--library/std/src/io/impls.rs46
1 files changed, 46 insertions, 0 deletions
diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs
index 85023540a81..b952c85addf 100644
--- a/library/std/src/io/impls.rs
+++ b/library/std/src/io/impls.rs
@@ -453,6 +453,29 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
         Ok(n)
     }
 
+    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
+        let (front, back) = self.as_slices();
+
+        // Use only the front buffer if it is big enough to fill `buf`, else use
+        // the back buffer too.
+        match buf.split_at_mut_checked(front.len()) {
+            None => buf.copy_from_slice(&front[..buf.len()]),
+            Some((buf_front, buf_back)) => match back.split_at_checked(buf_back.len()) {
+                Some((back, _)) => {
+                    buf_front.copy_from_slice(front);
+                    buf_back.copy_from_slice(back);
+                }
+                None => {
+                    self.clear();
+                    return Err(io::Error::READ_EXACT_EOF);
+                }
+            },
+        }
+
+        self.drain(..buf.len());
+        Ok(())
+    }
+
     #[inline]
     fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
         let (ref mut front, _) = self.as_slices();
@@ -462,6 +485,29 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
         Ok(())
     }
 
+    fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        let len = cursor.capacity();
+        let (front, back) = self.as_slices();
+
+        match front.split_at_checked(cursor.capacity()) {
+            Some((front, _)) => cursor.append(front),
+            None => {
+                cursor.append(front);
+                match back.split_at_checked(cursor.capacity()) {
+                    Some((back, _)) => cursor.append(back),
+                    None => {
+                        cursor.append(back);
+                        self.clear();
+                        return Err(io::Error::READ_EXACT_EOF);
+                    }
+                }
+            }
+        }
+
+        self.drain(..len);
+        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.