diff options
| author | bors <bors@rust-lang.org> | 2014-05-07 20:36:37 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-05-07 20:36:37 -0700 |
| commit | e0fcb4eb3d516017c7c2fa8d17e7b8b82bdc065b (patch) | |
| tree | 1084f3850e030cbbb92220c78959960ea72cb771 /src/libstd | |
| parent | ab22d99e73f81f35dd4edbdc9b27152dc653f5b6 (diff) | |
| parent | 678b1659f9a9536a4ee9901e2cd51c7daa4532c9 (diff) | |
| download | rust-e0fcb4eb3d516017c7c2fa8d17e7b8b82bdc065b.tar.gz rust-e0fcb4eb3d516017c7c2fa8d17e7b8b82bdc065b.zip | |
auto merge of #13964 : alexcrichton/rust/more-buffers, r=brson
This will allow methods like read_line() on RefReader, LimitReader, etc.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/io/mod.rs | 5 | ||||
| -rw-r--r-- | src/libstd/io/util.rs | 59 |
2 files changed, 63 insertions, 1 deletions
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index cd069ddc1ea..e2fde98a77c 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -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 diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index b2e6b27caab..05d5f19eeff 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -55,6 +55,24 @@ impl<R: Reader> Reader for LimitReader<R> { } } +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 @@ impl Reader for ZeroReader { } } +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 @@ impl Reader for NullReader { } } +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 @@ mod test { 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())); + } + } } |
