]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #13964 : alexcrichton/rust/more-buffers, r=brson
authorbors <bors@rust-lang.org>
Thu, 8 May 2014 03:36:37 +0000 (20:36 -0700)
committerbors <bors@rust-lang.org>
Thu, 8 May 2014 03:36:37 +0000 (20:36 -0700)
This will allow methods like read_line() on RefReader, LimitReader, etc.

src/libstd/io/mod.rs
src/libstd/io/util.rs

index cd069ddc1ea40df9ccecadd5d7f9008912528558..e2fde98a77ca80b28fa47b287e94699e1d0bc07d 100644 (file)
@@ -853,6 +853,11 @@ impl<'a, R: Reader> Reader for RefReader<'a, R> {
     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.inner.read(buf) }
 }
 
+impl<'a, R: Buffer> Buffer for RefReader<'a, R> {
+    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
+    fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
+}
+
 fn extend_sign(val: u64, nbytes: uint) -> i64 {
     let shift = (8 - nbytes) * 8;
     (val << shift) as i64 >> shift
index b2e6b27caabfe1fe441d605f3e9bb1a66ae05c77..05d5f19eeffad832e8b2af75a667ac31d6f256ee 100644 (file)
@@ -55,6 +55,24 @@ fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
     }
 }
 
+impl<R: Buffer> Buffer for LimitReader<R> {
+    fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
+        let amt = try!(self.inner.fill_buf());
+        let buf = amt.slice_to(cmp::min(amt.len(), self.limit));
+        if buf.len() == 0 {
+            Err(io::standard_error(io::EndOfFile))
+        } else {
+            Ok(buf)
+        }
+    }
+
+    fn consume(&mut self, amt: uint) {
+        self.limit -= amt;
+        self.inner.consume(amt);
+    }
+
+}
+
 /// A `Writer` which ignores bytes written to it, like /dev/null.
 pub struct NullWriter;
 
@@ -74,6 +92,14 @@ fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
     }
 }
 
+impl Buffer for ZeroReader {
+    fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
+        static DATA: [u8, ..64] = [0, ..64];
+        Ok(DATA.as_slice())
+    }
+    fn consume(&mut self, _amt: uint) {}
+}
+
 /// A `Reader` which is always at EOF, like /dev/null.
 pub struct NullReader;
 
@@ -84,6 +110,13 @@ fn read(&mut self, _buf: &mut [u8]) -> io::IoResult<uint> {
     }
 }
 
+impl Buffer for NullReader {
+    fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
+        Err(io::standard_error(io::EndOfFile))
+    }
+    fn consume(&mut self, _amt: uint) {}
+}
+
 /// A `Writer` which multiplexes writes to a set of `Writers`.
 pub struct MultiWriter {
     writers: Vec<Box<Writer>>
@@ -198,8 +231,8 @@ pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
 
 #[cfg(test)]
 mod test {
+    use io::{MemReader, MemWriter, BufReader};
     use io;
-    use io::{MemReader, MemWriter};
     use owned::Box;
     use super::*;
     use prelude::*;
@@ -309,4 +342,28 @@ fn test_copy() {
         copy(&mut r, &mut w).unwrap();
         assert_eq!(vec!(0, 1, 2, 3, 4), w.unwrap());
     }
+
+    #[test]
+    fn limit_reader_buffer() {
+        let data = "0123456789\n0123456789\n";
+        let mut r = BufReader::new(data.as_bytes());
+        {
+            let mut r = LimitReader::new(r.by_ref(), 3);
+            assert_eq!(r.read_line(), Ok("012".to_str()));
+            assert_eq!(r.limit(), 0);
+            assert_eq!(r.read_line().err().unwrap().kind, io::EndOfFile);
+        }
+        {
+            let mut r = LimitReader::new(r.by_ref(), 9);
+            assert_eq!(r.read_line(), Ok("3456789\n".to_str()));
+            assert_eq!(r.limit(), 1);
+            assert_eq!(r.read_line(), Ok("0".to_str()));
+        }
+        {
+            let mut r = LimitReader::new(r.by_ref(), 100);
+            assert_eq!(r.read_char(), Ok('1'));
+            assert_eq!(r.limit(), 99);
+            assert_eq!(r.read_line(), Ok("23456789\n".to_str()));
+        }
+    }
 }