2013-12-10 00:53:09 -06:00
|
|
|
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
2014-01-29 18:33:57 -06:00
|
|
|
|
2014-02-23 14:48:26 -06:00
|
|
|
/*! Utility implementations of Reader and Writer */
|
|
|
|
|
2013-12-10 00:53:09 -06:00
|
|
|
use prelude::*;
|
|
|
|
use cmp;
|
2014-01-29 18:33:57 -06:00
|
|
|
use io;
|
2014-03-08 17:11:52 -06:00
|
|
|
use slice::bytes::MutableByteVector;
|
2013-12-10 00:53:09 -06:00
|
|
|
|
|
|
|
/// Wraps a `Reader`, limiting the number of bytes that can be read from it.
|
2014-02-13 22:28:11 -06:00
|
|
|
pub struct LimitReader<R> {
|
2014-03-27 17:09:47 -05:00
|
|
|
limit: uint,
|
|
|
|
inner: R
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
2014-02-13 22:28:11 -06:00
|
|
|
impl<R: Reader> LimitReader<R> {
|
2013-12-10 00:53:09 -06:00
|
|
|
/// Creates a new `LimitReader`
|
2014-02-13 22:28:11 -06:00
|
|
|
pub fn new(r: R, limit: uint) -> LimitReader<R> {
|
2013-12-10 00:53:09 -06:00
|
|
|
LimitReader { limit: limit, inner: r }
|
|
|
|
}
|
2014-02-15 15:51:37 -06:00
|
|
|
|
|
|
|
/// Consumes the `LimitReader`, returning the underlying `Reader`.
|
2014-02-13 22:28:11 -06:00
|
|
|
pub fn unwrap(self) -> R { self.inner }
|
2014-02-15 15:51:37 -06:00
|
|
|
|
|
|
|
/// Returns the number of bytes that can be read before the `LimitReader`
|
|
|
|
/// will return EOF.
|
|
|
|
///
|
|
|
|
/// # Note
|
|
|
|
///
|
|
|
|
/// The reader may reach EOF after reading fewer bytes than indicated by
|
|
|
|
/// this method if the underlying reader reaches EOF.
|
|
|
|
pub fn limit(&self) -> uint { self.limit }
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
2014-02-13 22:28:11 -06:00
|
|
|
impl<R: Reader> Reader for LimitReader<R> {
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
2013-12-10 00:53:09 -06:00
|
|
|
if self.limit == 0 {
|
2014-01-29 18:33:57 -06:00
|
|
|
return Err(io::standard_error(io::EndOfFile));
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
let len = cmp::min(self.limit, buf.len());
|
2014-09-24 06:41:09 -05:00
|
|
|
let res = self.inner.read(buf[mut ..len]);
|
2014-08-15 01:06:30 -05:00
|
|
|
match res {
|
|
|
|
Ok(len) => self.limit -= len,
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
res
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-06 01:50:07 -05:00
|
|
|
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());
|
2014-09-24 06:41:09 -05:00
|
|
|
let buf = amt[..cmp::min(amt.len(), self.limit)];
|
2014-05-06 01:50:07 -05:00
|
|
|
if buf.len() == 0 {
|
|
|
|
Err(io::standard_error(io::EndOfFile))
|
|
|
|
} else {
|
|
|
|
Ok(buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn consume(&mut self, amt: uint) {
|
2014-08-15 01:06:30 -05:00
|
|
|
// Don't let callers reset the limit by passing an overlarge value
|
|
|
|
let amt = cmp::min(amt, self.limit);
|
2014-05-06 01:50:07 -05:00
|
|
|
self.limit -= amt;
|
|
|
|
self.inner.consume(amt);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-12-10 00:53:09 -06:00
|
|
|
/// A `Writer` which ignores bytes written to it, like /dev/null.
|
|
|
|
pub struct NullWriter;
|
|
|
|
|
|
|
|
impl Writer for NullWriter {
|
|
|
|
#[inline]
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> { Ok(()) }
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
|
|
|
|
pub struct ZeroReader;
|
|
|
|
|
|
|
|
impl Reader for ZeroReader {
|
|
|
|
#[inline]
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
2013-12-10 00:53:09 -06:00
|
|
|
buf.set_memory(0);
|
2014-01-29 18:33:57 -06:00
|
|
|
Ok(buf.len())
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-06 01:50:07 -05:00
|
|
|
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())
|
|
|
|
}
|
2014-08-15 01:06:30 -05:00
|
|
|
|
2014-05-06 01:50:07 -05:00
|
|
|
fn consume(&mut self, _amt: uint) {}
|
|
|
|
}
|
|
|
|
|
2013-12-10 00:53:09 -06:00
|
|
|
/// A `Reader` which is always at EOF, like /dev/null.
|
|
|
|
pub struct NullReader;
|
|
|
|
|
|
|
|
impl Reader for NullReader {
|
|
|
|
#[inline]
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read(&mut self, _buf: &mut [u8]) -> io::IoResult<uint> {
|
|
|
|
Err(io::standard_error(io::EndOfFile))
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-06 01:50:07 -05:00
|
|
|
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) {}
|
|
|
|
}
|
|
|
|
|
2014-08-15 01:06:30 -05:00
|
|
|
/// A `Writer` which multiplexes writes to a set of `Writer`s.
|
|
|
|
///
|
|
|
|
/// The `Writer`s are delegated to in order. If any `Writer` returns an error,
|
|
|
|
/// that error is returned immediately and remaining `Writer`s are not called.
|
2013-12-10 00:53:09 -06:00
|
|
|
pub struct MultiWriter {
|
2014-08-27 20:46:52 -05:00
|
|
|
writers: Vec<Box<Writer+'static>>
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
impl MultiWriter {
|
|
|
|
/// Creates a new `MultiWriter`
|
2014-08-27 20:46:52 -05:00
|
|
|
pub fn new(writers: Vec<Box<Writer+'static>>) -> MultiWriter {
|
2013-12-10 00:53:09 -06:00
|
|
|
MultiWriter { writers: writers }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Writer for MultiWriter {
|
|
|
|
#[inline]
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
|
2014-09-14 22:27:36 -05:00
|
|
|
for writer in self.writers.iter_mut() {
|
2014-08-15 01:06:30 -05:00
|
|
|
try!(writer.write(buf));
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
2014-08-15 01:06:30 -05:00
|
|
|
Ok(())
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-01-29 18:33:57 -06:00
|
|
|
fn flush(&mut self) -> io::IoResult<()> {
|
2014-09-14 22:27:36 -05:00
|
|
|
for writer in self.writers.iter_mut() {
|
2014-08-15 01:06:30 -05:00
|
|
|
try!(writer.flush());
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
2014-08-15 01:06:30 -05:00
|
|
|
Ok(())
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-15 01:06:30 -05:00
|
|
|
/// A `Reader` which chains input from multiple `Reader`s, reading each to
|
2013-12-10 00:53:09 -06:00
|
|
|
/// completion before moving onto the next.
|
|
|
|
pub struct ChainedReader<I, R> {
|
2014-03-27 17:09:47 -05:00
|
|
|
readers: I,
|
|
|
|
cur_reader: Option<R>,
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<R: Reader, I: Iterator<R>> ChainedReader<I, R> {
|
|
|
|
/// Creates a new `ChainedReader`
|
|
|
|
pub fn new(mut readers: I) -> ChainedReader<I, R> {
|
|
|
|
let r = readers.next();
|
|
|
|
ChainedReader { readers: readers, cur_reader: r }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<R: Reader, I: Iterator<R>> Reader for ChainedReader<I, R> {
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
2013-12-10 00:53:09 -06:00
|
|
|
loop {
|
2014-01-29 18:33:57 -06:00
|
|
|
let err = match self.cur_reader {
|
2013-12-10 00:53:09 -06:00
|
|
|
Some(ref mut r) => {
|
|
|
|
match r.read(buf) {
|
2014-01-29 18:33:57 -06:00
|
|
|
Ok(len) => return Ok(len),
|
|
|
|
Err(ref e) if e.kind == io::EndOfFile => None,
|
|
|
|
Err(e) => Some(e),
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
None => break
|
2014-01-29 18:33:57 -06:00
|
|
|
};
|
|
|
|
self.cur_reader = self.readers.next();
|
|
|
|
match err {
|
|
|
|
Some(e) => return Err(e),
|
|
|
|
None => {}
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
}
|
2014-01-29 18:33:57 -06:00
|
|
|
Err(io::standard_error(io::EndOfFile))
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A `Reader` which forwards input from another `Reader`, passing it along to
|
|
|
|
/// a `Writer` as well. Similar to the `tee(1)` command.
|
|
|
|
pub struct TeeReader<R, W> {
|
2014-03-27 17:09:47 -05:00
|
|
|
reader: R,
|
|
|
|
writer: W,
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<R: Reader, W: Writer> TeeReader<R, W> {
|
|
|
|
/// Creates a new `TeeReader`
|
|
|
|
pub fn new(r: R, w: W) -> TeeReader<R, W> {
|
|
|
|
TeeReader { reader: r, writer: w }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Consumes the `TeeReader`, returning the underlying `Reader` and
|
|
|
|
/// `Writer`.
|
|
|
|
pub fn unwrap(self) -> (R, W) {
|
|
|
|
let TeeReader { reader, writer } = self;
|
|
|
|
(reader, writer)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
|
|
|
self.reader.read(buf).and_then(|len| {
|
2014-09-24 06:41:09 -05:00
|
|
|
self.writer.write(buf[mut ..len]).map(|()| len)
|
2013-12-10 00:53:09 -06:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Copies all data from a `Reader` to a `Writer`.
|
2014-01-29 18:33:57 -06:00
|
|
|
pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
|
2013-12-10 00:53:09 -06:00
|
|
|
let mut buf = [0, ..super::DEFAULT_BUF_SIZE];
|
|
|
|
loop {
|
2014-01-29 18:33:57 -06:00
|
|
|
let len = match r.read(buf) {
|
|
|
|
Ok(len) => len,
|
|
|
|
Err(ref e) if e.kind == io::EndOfFile => return Ok(()),
|
|
|
|
Err(e) => return Err(e),
|
|
|
|
};
|
2014-09-24 06:41:09 -05:00
|
|
|
try!(w.write(buf[..len]));
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-15 01:06:30 -05:00
|
|
|
/// An adaptor converting an `Iterator<u8>` to a `Reader`.
|
2014-06-02 22:42:41 -05:00
|
|
|
pub struct IterReader<T> {
|
|
|
|
iter: T,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Iterator<u8>> IterReader<T> {
|
2014-08-15 01:06:30 -05:00
|
|
|
/// Creates a new `IterReader` which will read from the specified
|
|
|
|
/// `Iterator`.
|
2014-06-02 22:42:41 -05:00
|
|
|
pub fn new(iter: T) -> IterReader<T> {
|
2014-08-15 01:06:30 -05:00
|
|
|
IterReader { iter: iter }
|
2014-06-02 22:42:41 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Iterator<u8>> Reader for IterReader<T> {
|
|
|
|
#[inline]
|
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
|
|
|
let mut len = 0;
|
2014-09-14 22:27:36 -05:00
|
|
|
for (slot, elt) in buf.iter_mut().zip(self.iter.by_ref()) {
|
2014-06-02 22:42:41 -05:00
|
|
|
*slot = elt;
|
|
|
|
len += 1;
|
|
|
|
}
|
2014-08-15 01:06:30 -05:00
|
|
|
if len == 0 && buf.len() != 0 {
|
2014-06-02 22:42:41 -05:00
|
|
|
Err(io::standard_error(io::EndOfFile))
|
|
|
|
} else {
|
|
|
|
Ok(len)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-10 00:53:09 -06:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
2014-05-06 01:50:07 -05:00
|
|
|
use io::{MemReader, MemWriter, BufReader};
|
2014-01-30 16:10:53 -06:00
|
|
|
use io;
|
2014-07-10 16:19:17 -05:00
|
|
|
use boxed::Box;
|
2013-12-10 00:53:09 -06:00
|
|
|
use super::*;
|
|
|
|
use prelude::*;
|
|
|
|
|
|
|
|
#[test]
|
2014-02-15 15:51:37 -06:00
|
|
|
fn test_limit_reader_unlimited() {
|
2014-03-27 00:46:25 -05:00
|
|
|
let mut r = MemReader::new(vec!(0, 1, 2));
|
2013-12-10 00:53:09 -06:00
|
|
|
{
|
2014-02-13 22:28:11 -06:00
|
|
|
let mut r = LimitReader::new(r.by_ref(), 4);
|
2014-03-26 11:24:16 -05:00
|
|
|
assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2014-02-15 15:51:37 -06:00
|
|
|
fn test_limit_reader_limited() {
|
2014-03-27 00:46:25 -05:00
|
|
|
let mut r = MemReader::new(vec!(0, 1, 2));
|
2013-12-10 00:53:09 -06:00
|
|
|
{
|
2014-02-13 22:28:11 -06:00
|
|
|
let mut r = LimitReader::new(r.by_ref(), 2);
|
2014-03-26 11:24:16 -05:00
|
|
|
assert_eq!(vec!(0, 1), r.read_to_end().unwrap());
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
2014-03-26 11:24:16 -05:00
|
|
|
assert_eq!(vec!(2), r.read_to_end().unwrap());
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
2014-02-15 15:51:37 -06:00
|
|
|
#[test]
|
|
|
|
fn test_limit_reader_limit() {
|
2014-03-27 00:46:25 -05:00
|
|
|
let r = MemReader::new(vec!(0, 1, 2));
|
2014-02-15 15:51:37 -06:00
|
|
|
let mut r = LimitReader::new(r, 3);
|
|
|
|
assert_eq!(3, r.limit());
|
|
|
|
assert_eq!(0, r.read_byte().unwrap());
|
|
|
|
assert_eq!(2, r.limit());
|
2014-03-26 11:24:16 -05:00
|
|
|
assert_eq!(vec!(1, 2), r.read_to_end().unwrap());
|
2014-02-15 15:51:37 -06:00
|
|
|
assert_eq!(0, r.limit());
|
|
|
|
}
|
|
|
|
|
2014-08-15 01:06:30 -05:00
|
|
|
#[test]
|
|
|
|
fn test_limit_reader_overlong_consume() {
|
|
|
|
let mut r = MemReader::new(vec![0, 1, 2, 3, 4, 5]);
|
|
|
|
let mut r = LimitReader::new(r.by_ref(), 1);
|
|
|
|
r.consume(2);
|
|
|
|
assert_eq!(vec![], r.read_to_end().unwrap());
|
|
|
|
}
|
|
|
|
|
2013-12-10 00:53:09 -06:00
|
|
|
#[test]
|
|
|
|
fn test_null_writer() {
|
|
|
|
let mut s = NullWriter;
|
2014-06-06 12:27:49 -05:00
|
|
|
let buf = vec![0, 0, 0];
|
|
|
|
s.write(buf.as_slice()).unwrap();
|
2014-01-30 16:10:53 -06:00
|
|
|
s.flush().unwrap();
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_zero_reader() {
|
|
|
|
let mut s = ZeroReader;
|
2014-06-06 12:27:49 -05:00
|
|
|
let mut buf = vec![1, 2, 3];
|
|
|
|
assert_eq!(s.read(buf.as_mut_slice()), Ok(3));
|
|
|
|
assert_eq!(vec![0, 0, 0], buf);
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_null_reader() {
|
|
|
|
let mut r = NullReader;
|
2014-06-06 12:27:49 -05:00
|
|
|
let mut buf = vec![0];
|
|
|
|
assert!(r.read(buf.as_mut_slice()).is_err());
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_multi_writer() {
|
|
|
|
static mut writes: uint = 0;
|
|
|
|
static mut flushes: uint = 0;
|
|
|
|
|
|
|
|
struct TestWriter;
|
|
|
|
impl Writer for TestWriter {
|
2014-01-30 16:10:53 -06:00
|
|
|
fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> {
|
2013-12-10 00:53:09 -06:00
|
|
|
unsafe { writes += 1 }
|
2014-01-30 16:10:53 -06:00
|
|
|
Ok(())
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
2014-01-30 16:10:53 -06:00
|
|
|
fn flush(&mut self) -> io::IoResult<()> {
|
2013-12-10 00:53:09 -06:00
|
|
|
unsafe { flushes += 1 }
|
2014-01-30 16:10:53 -06:00
|
|
|
Ok(())
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-05 20:56:44 -05:00
|
|
|
let mut multi = MultiWriter::new(vec!(box TestWriter as Box<Writer>,
|
|
|
|
box TestWriter as Box<Writer>));
|
2014-01-30 16:10:53 -06:00
|
|
|
multi.write([1, 2, 3]).unwrap();
|
2013-12-10 00:53:09 -06:00
|
|
|
assert_eq!(2, unsafe { writes });
|
|
|
|
assert_eq!(0, unsafe { flushes });
|
2014-01-30 16:10:53 -06:00
|
|
|
multi.flush().unwrap();
|
2013-12-10 00:53:09 -06:00
|
|
|
assert_eq!(2, unsafe { writes });
|
|
|
|
assert_eq!(2, unsafe { flushes });
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_chained_reader() {
|
2014-03-27 00:53:30 -05:00
|
|
|
let rs = vec!(MemReader::new(vec!(0, 1)), MemReader::new(vec!()),
|
|
|
|
MemReader::new(vec!(2, 3)));
|
2014-09-14 22:27:36 -05:00
|
|
|
let mut r = ChainedReader::new(rs.into_iter());
|
2014-03-26 11:24:16 -05:00
|
|
|
assert_eq!(vec!(0, 1, 2, 3), r.read_to_end().unwrap());
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_tee_reader() {
|
2014-03-27 00:46:25 -05:00
|
|
|
let mut r = TeeReader::new(MemReader::new(vec!(0, 1, 2)),
|
2013-12-10 00:53:09 -06:00
|
|
|
MemWriter::new());
|
2014-03-26 11:24:16 -05:00
|
|
|
assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
|
2013-12-10 00:53:09 -06:00
|
|
|
let (_, w) = r.unwrap();
|
2014-03-27 00:46:25 -05:00
|
|
|
assert_eq!(vec!(0, 1, 2), w.unwrap());
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_copy() {
|
2014-03-27 00:46:25 -05:00
|
|
|
let mut r = MemReader::new(vec!(0, 1, 2, 3, 4));
|
2013-12-10 00:53:09 -06:00
|
|
|
let mut w = MemWriter::new();
|
2014-01-30 16:10:53 -06:00
|
|
|
copy(&mut r, &mut w).unwrap();
|
2014-03-27 00:46:25 -05:00
|
|
|
assert_eq!(vec!(0, 1, 2, 3, 4), w.unwrap());
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|
2014-05-06 01:50:07 -05:00
|
|
|
|
|
|
|
#[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);
|
2014-06-21 05:39:03 -05:00
|
|
|
assert_eq!(r.read_line(), Ok("012".to_string()));
|
2014-05-06 01:50:07 -05:00
|
|
|
assert_eq!(r.limit(), 0);
|
|
|
|
assert_eq!(r.read_line().err().unwrap().kind, io::EndOfFile);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let mut r = LimitReader::new(r.by_ref(), 9);
|
2014-06-21 05:39:03 -05:00
|
|
|
assert_eq!(r.read_line(), Ok("3456789\n".to_string()));
|
2014-05-06 01:50:07 -05:00
|
|
|
assert_eq!(r.limit(), 1);
|
2014-06-21 05:39:03 -05:00
|
|
|
assert_eq!(r.read_line(), Ok("0".to_string()));
|
2014-05-06 01:50:07 -05:00
|
|
|
}
|
|
|
|
{
|
|
|
|
let mut r = LimitReader::new(r.by_ref(), 100);
|
|
|
|
assert_eq!(r.read_char(), Ok('1'));
|
|
|
|
assert_eq!(r.limit(), 99);
|
2014-06-21 05:39:03 -05:00
|
|
|
assert_eq!(r.read_line(), Ok("23456789\n".to_string()));
|
2014-05-06 01:50:07 -05:00
|
|
|
}
|
|
|
|
}
|
2014-06-02 22:42:41 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_iter_reader() {
|
|
|
|
let mut r = IterReader::new(range(0u8, 8));
|
|
|
|
let mut buf = [0, 0, 0];
|
|
|
|
let len = r.read(buf).unwrap();
|
|
|
|
assert_eq!(len, 3);
|
|
|
|
assert!(buf == [0, 1, 2]);
|
|
|
|
|
|
|
|
let len = r.read(buf).unwrap();
|
|
|
|
assert_eq!(len, 3);
|
|
|
|
assert!(buf == [3, 4, 5]);
|
|
|
|
|
|
|
|
let len = r.read(buf).unwrap();
|
|
|
|
assert_eq!(len, 2);
|
|
|
|
assert!(buf == [6, 7, 5]);
|
|
|
|
|
|
|
|
assert_eq!(r.read(buf).unwrap_err().kind, io::EndOfFile);
|
|
|
|
}
|
2014-08-15 01:06:30 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn iter_reader_zero_length() {
|
|
|
|
let mut r = IterReader::new(range(0u8, 8));
|
|
|
|
let mut buf = [];
|
|
|
|
assert_eq!(Ok(0), r.read(buf));
|
|
|
|
}
|
2013-12-10 00:53:09 -06:00
|
|
|
}
|