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>2023-04-20 16:33:01 +0200
committerBenoît du Garreau <bdgdlm@outlook.com>2023-04-20 16:33:01 +0200
commit1e6a7b458002f8a91e1f48733248cde2326d239a (patch)
tree6bedd0aa36f161443381fce3d50055f6f3d323f5 /library/std/src/io/impls.rs
parent7e23d180c1db42941b3bd32542a899e9eee7cbcb (diff)
downloadrust-1e6a7b458002f8a91e1f48733248cde2326d239a.tar.gz
rust-1e6a7b458002f8a91e1f48733248cde2326d239a.zip
Specialize some `io::Read` and `io::Write` methods for `VecDeque<u8>` and `&[u8]`
Diffstat (limited to 'library/std/src/io/impls.rs')
-rw-r--r--library/std/src/io/impls.rs54
1 files changed, 54 insertions, 0 deletions
diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs
index e5048dcc8ac..7511438b02b 100644
--- a/library/std/src/io/impls.rs
+++ b/library/std/src/io/impls.rs
@@ -9,6 +9,7 @@ use crate::io::{
     self, BorrowedCursor, BufRead, ErrorKind, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write,
 };
 use crate::mem;
+use crate::str;
 
 // =============================================================================
 // Forwarding implementations
@@ -307,6 +308,17 @@ impl Read for &[u8] {
         *self = &self[len..];
         Ok(len)
     }
+
+    #[inline]
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
+        let content = str::from_utf8(self).map_err(|_| {
+            io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8")
+        })?;
+        buf.push_str(content);
+        let len = self.len();
+        *self = &self[len..];
+        Ok(len)
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -434,6 +446,33 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
         self.drain(..n);
         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.
+        let len = self.len();
+        buf.reserve(len);
+
+        let (front, back) = self.as_slices();
+        buf.extend_from_slice(front);
+        buf.extend_from_slice(back);
+        self.clear();
+        Ok(len)
+    }
+
+    #[inline]
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
+        // We have to use a single contiguous slice because the `VecDequeue` might be split in the
+        // middle of an UTF-8 character.
+        let len = self.len();
+        let content = self.make_contiguous();
+        let string = str::from_utf8(content).map_err(|_| {
+            io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8")
+        })?;
+        buf.push_str(string);
+        self.clear();
+        Ok(len)
+    }
 }
 
 /// Write is implemented for `VecDeque<u8>` by appending to the `VecDeque`, growing it as needed.
@@ -446,6 +485,21 @@ impl<A: Allocator> Write for VecDeque<u8, A> {
     }
 
     #[inline]
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        let len = bufs.iter().map(|b| b.len()).sum();
+        self.reserve(len);
+        for buf in bufs {
+            self.extend(&**buf);
+        }
+        Ok(len)
+    }
+
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
+    }
+
+    #[inline]
     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
         self.extend(buf);
         Ok(())