auto merge of #13964 : alexcrichton/rust/more-buffers, r=brson

This will allow methods like read_line() on RefReader, LimitReader, etc.
This commit is contained in:
bors 2014-05-07 20:36:37 -07:00
commit e0fcb4eb3d
2 changed files with 63 additions and 1 deletions

View 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

View File

@ -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()));
}
}
}