]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #13049 : alexcrichton/rust/io-fill, r=huonw
authorbors <bors@rust-lang.org>
Mon, 24 Mar 2014 19:06:58 +0000 (12:06 -0700)
committerbors <bors@rust-lang.org>
Mon, 24 Mar 2014 19:06:58 +0000 (12:06 -0700)
This method can be used to fill a byte slice of data entirely, and it's considered an error if any error happens before its entirely filled.

src/librand/reader.rs
src/libstd/io/buffered.rs
src/libstd/io/mem.rs
src/libstd/io/mod.rs

index 744930e028cb9caa8fa869981154a13e2e2e9c8d..9e7e38d27239a85fa9d0f2c70c894fe8bc6c43e5 100644 (file)
@@ -60,10 +60,8 @@ fn next_u64(&mut self) -> u64 {
     }
     fn fill_bytes(&mut self, v: &mut [u8]) {
         if v.len() == 0 { return }
-        match self.reader.read(v) {
-            Ok(n) if n == v.len() => return,
-            Ok(n) => fail!("ReaderRng.fill_bytes could not fill buffer: \
-                            read {} out of {} bytes.", n, v.len()),
+        match self.reader.fill(v) {
+            Ok(()) => {}
             Err(e) => fail!("ReaderRng.fill_bytes error: {}", e)
         }
     }
index 052d5df5ff76129c61381d824ee46a5ff738cef3..fed47dfcff36636d4abdf5f11f2b34dabbe27a3f 100644 (file)
@@ -86,7 +86,7 @@ pub fn unwrap(self) -> R { self.inner }
 }
 
 impl<R: Reader> Buffer for BufferedReader<R> {
-    fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
+    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
         if self.pos == self.cap {
             self.cap = try!(self.inner.read(self.buf.as_mut_slice()));
             self.pos = 0;
@@ -103,7 +103,7 @@ fn consume(&mut self, amt: uint) {
 impl<R: Reader> Reader for BufferedReader<R> {
     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         let nread = {
-            let available = try!(self.fill());
+            let available = try!(self.fill_buf());
             let nread = cmp::min(available.len(), buf.len());
             slice::bytes::copy_memory(buf, available.slice_to(nread));
             nread
@@ -345,7 +345,7 @@ pub fn unwrap(self) -> S {
 }
 
 impl<S: Stream> Buffer for BufferedStream<S> {
-    fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill() }
+    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
     fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
 }
 
index d0c4ef308b3174949d580d85b920447ace322c95..7ae717cfccf971c0bb059a8b93db298c5dac8127 100644 (file)
@@ -190,7 +190,7 @@ fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
 }
 
 impl Buffer for MemReader {
-    fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
+    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
         if self.pos < self.buf.len() {
             Ok(self.buf.slice_from(self.pos))
         } else {
@@ -322,7 +322,7 @@ fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
 }
 
 impl<'a> Buffer for BufReader<'a> {
-    fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
+    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
         if self.pos < self.buf.len() {
             Ok(self.buf.slice_from(self.pos))
         } else {
@@ -555,4 +555,18 @@ fn seek_before_0() {
         let mut r = BufWriter::new(buf);
         assert!(r.seek(-1, SeekSet).is_err());
     }
+
+    #[test]
+    fn io_fill() {
+        let mut r = MemReader::new(~[1, 2, 3, 4, 5, 6, 7, 8]);
+        let mut buf = [0, ..3];
+        assert_eq!(r.fill(buf), Ok(()));
+        assert_eq!(buf.as_slice(), &[1, 2, 3]);
+        assert_eq!(r.fill(buf.mut_slice_to(0)), Ok(()));
+        assert_eq!(buf.as_slice(), &[1, 2, 3]);
+        assert_eq!(r.fill(buf), Ok(()));
+        assert_eq!(buf.as_slice(), &[4, 5, 6]);
+        assert!(r.fill(buf).is_err());
+        assert_eq!(buf.as_slice(), &[7, 8, 6]);
+    }
 }
index 88ffc363e88751e0a4d62368238cb8f23d2eaaa2..6bd8f119ba29b408f9036f2802b6ed26786e384a 100644 (file)
@@ -360,6 +360,23 @@ fn read_byte(&mut self) -> IoResult<u8> {
         }
     }
 
+    /// Fills the provided slice with bytes from this reader
+    ///
+    /// This will continue to call `read` until the slice has been completely
+    /// filled with bytes.
+    ///
+    /// # Error
+    ///
+    /// If an error occurs at any point, that error is returned, and no further
+    /// bytes are read.
+    fn fill(&mut self, buf: &mut [u8]) -> IoResult<()> {
+        let mut read = 0;
+        while read < buf.len() {
+            read += try!(self.read(buf.mut_slice_from(read)));
+        }
+        Ok(())
+    }
+
     /// Reads exactly `len` bytes and appends them to a vector.
     ///
     /// May push fewer than the requested number of bytes on error
@@ -1045,7 +1062,7 @@ pub trait Buffer: Reader {
     /// This function will return an I/O error if the underlying reader was
     /// read, but returned an error. Note that it is not an error to return a
     /// 0-length buffer.
-    fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]>;
+    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]>;
 
     /// Tells this buffer that `amt` bytes have been consumed from the buffer,
     /// so they should no longer be returned in calls to `fill` or `read`.
@@ -1116,7 +1133,7 @@ fn read_until(&mut self, byte: u8) -> IoResult<~[u8]> {
         let mut used;
         loop {
             {
-                let available = match self.fill() {
+                let available = match self.fill_buf() {
                     Ok(n) => n,
                     Err(ref e) if res.len() > 0 && e.kind == EndOfFile => {
                         used = 0;