-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! Utility implementations of Reader and Writer
+#![allow(missing_copy_implementations)]
use prelude::v1::*;
-use cmp;
-use io;
-use slice::bytes::MutableByteVector;
-/// Wraps a `Reader`, limiting the number of bytes that can be read from it.
-#[derive(Show)]
-pub struct LimitReader<R> {
- limit: uint,
- inner: R
-}
-
-impl<R: Reader> LimitReader<R> {
- /// Creates a new `LimitReader`
- pub fn new(r: R, limit: uint) -> LimitReader<R> {
- LimitReader { limit: limit, inner: r }
- }
-
- /// Consumes the `LimitReader`, returning the underlying `Reader`.
- pub fn into_inner(self) -> R { self.inner }
-
- /// 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 }
-}
-
-impl<R: Reader> Reader for LimitReader<R> {
- fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
- if self.limit == 0 {
- return Err(io::standard_error(io::EndOfFile));
- }
-
- let len = cmp::min(self.limit, buf.len());
- let res = self.inner.read(buf.slice_to_mut(len));
- match res {
- Ok(len) => self.limit -= len,
- _ => {}
- }
- res
- }
-}
-
-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[..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) {
- // Don't let callers reset the limit by passing an overlarge value
- let amt = cmp::min(amt, self.limit);
- self.limit -= amt;
- self.inner.consume(amt);
- }
-
-}
-
-/// A `Writer` which ignores bytes written to it, like /dev/null.
-#[derive(Copy, Show)]
-pub struct NullWriter;
-
-impl Writer for NullWriter {
- #[inline]
- fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> { Ok(()) }
-}
-
-/// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
-#[derive(Copy, Show)]
-pub struct ZeroReader;
-
-impl Reader for ZeroReader {
- #[inline]
- fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
- buf.set_memory(0);
- Ok(buf.len())
- }
-}
-
-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) {}
-}
+use io::{self, Read, Write, ErrorKind, BufRead};
-/// A `Reader` which is always at EOF, like /dev/null.
-#[derive(Copy, Show)]
-pub struct NullReader;
-
-impl Reader for NullReader {
- #[inline]
- fn read(&mut self, _buf: &mut [u8]) -> io::IoResult<uint> {
- Err(io::standard_error(io::EndOfFile))
- }
-}
-
-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 `Writer`s.
+/// Copies the entire contents of a reader into a writer.
///
-/// 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.
-#[derive(Show)]
-pub struct MultiWriter<W> {
- writers: Vec<W>
-}
-
-impl<W> MultiWriter<W> where W: Writer {
- /// Creates a new `MultiWriter`
- pub fn new(writers: Vec<W>) -> MultiWriter<W> {
- MultiWriter { writers: writers }
- }
-}
-
-impl<W> Writer for MultiWriter<W> where W: Writer {
- #[inline]
- fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
- for writer in self.writers.iter_mut() {
- try!(writer.write(buf));
- }
- Ok(())
- }
-
- #[inline]
- fn flush(&mut self) -> io::IoResult<()> {
- for writer in self.writers.iter_mut() {
- try!(writer.flush());
- }
- Ok(())
- }
-}
-
-/// A `Reader` which chains input from multiple `Reader`s, reading each to
-/// completion before moving onto the next.
-#[derive(Clone, Show)]
-pub struct ChainedReader<I, R> {
- readers: I,
- cur_reader: Option<R>,
-}
-
-impl<R: Reader, I: Iterator<Item=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<Item=R>> Reader for ChainedReader<I, R> {
- fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
- loop {
- let err = match self.cur_reader {
- Some(ref mut r) => {
- match r.read(buf) {
- Ok(len) => return Ok(len),
- Err(ref e) if e.kind == io::EndOfFile => None,
- Err(e) => Some(e),
- }
- }
- None => break
- };
- self.cur_reader = self.readers.next();
- match err {
- Some(e) => return Err(e),
- None => {}
- }
- }
- Err(io::standard_error(io::EndOfFile))
- }
-}
-
-/// A `Reader` which forwards input from another `Reader`, passing it along to
-/// a `Writer` as well. Similar to the `tee(1)` command.
-#[derive(Show)]
-pub struct TeeReader<R, W> {
- reader: R,
- writer: W,
-}
-
-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 into_inner(self) -> (R, W) {
- let TeeReader { reader, writer } = self;
- (reader, writer)
- }
-}
-
-impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
- fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
- self.reader.read(buf).and_then(|len| {
- self.writer.write(&mut buf[..len]).map(|()| len)
- })
- }
-}
-
-/// Copies all data from a `Reader` to a `Writer`.
-pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
+/// This function will continuously read data from `r` and then write it into
+/// `w` in a streaming fashion until `r` returns EOF.
+///
+/// On success the total number of bytes that were copied from `r` to `w` is
+/// returned.
+///
+/// # Errors
+///
+/// This function will return an error immediately if any call to `read` or
+/// `write` returns an error. All instances of `ErrorKind::Interrupted` are
+/// handled by this function and the underlying operation is retried.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn copy<R: Read, W: Write>(r: &mut R, w: &mut W) -> io::Result<u64> {
let mut buf = [0; super::DEFAULT_BUF_SIZE];
+ let mut written = 0;
loop {
let len = match r.read(&mut buf) {
+ Ok(0) => return Ok(written),
Ok(len) => len,
- Err(ref e) if e.kind == io::EndOfFile => return Ok(()),
+ Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
};
- try!(w.write(&buf[..len]));
+ try!(w.write_all(&buf[..len]));
+ written += len as u64;
}
}
-/// An adaptor converting an `Iterator<u8>` to a `Reader`.
-#[derive(Clone, Show)]
-pub struct IterReader<T> {
- iter: T,
-}
+/// A reader which is always at EOF.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Empty { _priv: () }
-impl<T: Iterator<Item=u8>> IterReader<T> {
- /// Creates a new `IterReader` which will read from the specified
- /// `Iterator`.
- pub fn new(iter: T) -> IterReader<T> {
- IterReader { iter: iter }
- }
-}
+/// Creates an instance of an empty reader.
+///
+/// All reads from the returned reader will return `Ok(0)`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn empty() -> Empty { Empty { _priv: () } }
-impl<T: Iterator<Item=u8>> Reader for IterReader<T> {
- #[inline]
- fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
- let mut len = 0;
- for (slot, elt) in buf.iter_mut().zip(self.iter.by_ref()) {
- *slot = elt;
- len += 1;
- }
- if len == 0 && buf.len() != 0 {
- Err(io::standard_error(io::EndOfFile))
- } else {
- Ok(len)
- }
- }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Read for Empty {
+ fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl BufRead for Empty {
+ fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) }
+ fn consume(&mut self, _n: usize) {}
}
-#[cfg(test)]
-mod test {
- use prelude::v1::*;
-
- use io::{MemReader, ByRefReader};
- use io;
- use super::*;
+/// A reader which infinitely yields one byte.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Repeat { byte: u8 }
- #[test]
- fn test_limit_reader_unlimited() {
- let mut r = MemReader::new(vec!(0, 1, 2));
- {
- let mut r = LimitReader::new(r.by_ref(), 4);
- assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
- }
- }
-
- #[test]
- fn test_limit_reader_limited() {
- let mut r = MemReader::new(vec!(0, 1, 2));
- {
- let mut r = LimitReader::new(r.by_ref(), 2);
- assert_eq!(vec!(0, 1), r.read_to_end().unwrap());
+/// Creates an instance of a reader that infinitely repeats one byte.
+///
+/// All reads from this reader will succeed by filling the specified buffer with
+/// the given byte.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Read for Repeat {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ for slot in buf.iter_mut() {
+ *slot = self.byte;
}
- assert_eq!(vec!(2), r.read_to_end().unwrap());
+ Ok(buf.len())
}
+}
- #[test]
- fn test_limit_reader_limit() {
- let r = MemReader::new(vec!(0, 1, 2));
- let mut r = LimitReader::new(r, 3);
- assert_eq!(3, r.limit());
- assert_eq!(0, r.read_byte().unwrap());
- assert_eq!(2, r.limit());
- assert_eq!(vec!(1, 2), r.read_to_end().unwrap());
- assert_eq!(0, r.limit());
- }
+/// A writer which will move data into the void.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Sink { _priv: () }
- #[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());
- }
+/// Creates an instance of a writer which will successfully consume all data.
+///
+/// All calls to `write` on the returned instance will return `Ok(buf.len())`
+/// and the contents of the buffer will not be inspected.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn sink() -> Sink { Sink { _priv: () } }
- #[test]
- fn test_null_writer() {
- let mut s = NullWriter;
- let buf = vec![0, 0, 0];
- s.write(buf.as_slice()).unwrap();
- s.flush().unwrap();
- }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Write for Sink {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
+ fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
- #[test]
- fn test_zero_reader() {
- let mut s = ZeroReader;
- let mut buf = vec![1, 2, 3];
- assert_eq!(s.read(buf.as_mut_slice()), Ok(3));
- assert_eq!(vec![0, 0, 0], buf);
- }
+#[cfg(test)]
+mod test {
+ use prelude::v1::*;
- #[test]
- fn test_null_reader() {
- let mut r = NullReader;
- let mut buf = vec![0];
- assert!(r.read(buf.as_mut_slice()).is_err());
- }
+ use io::prelude::*;
+ use io::{sink, empty, repeat};
#[test]
- fn test_multi_writer() {
- static mut writes: uint = 0;
- static mut flushes: uint = 0;
-
- struct TestWriter;
- impl Writer for TestWriter {
- fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> {
- unsafe { writes += 1 }
- Ok(())
- }
-
- fn flush(&mut self) -> io::IoResult<()> {
- unsafe { flushes += 1 }
- Ok(())
- }
- }
-
- let mut multi = MultiWriter::new(vec!(box TestWriter as Box<Writer>,
- box TestWriter as Box<Writer>));
- multi.write(&[1, 2, 3]).unwrap();
- assert_eq!(2, unsafe { writes });
- assert_eq!(0, unsafe { flushes });
- multi.flush().unwrap();
- assert_eq!(2, unsafe { writes });
- assert_eq!(2, unsafe { flushes });
+ fn sink_sinks() {
+ let mut s = sink();
+ assert_eq!(s.write(&[]).unwrap(), 0);
+ assert_eq!(s.write(&[0]).unwrap(), 1);
+ assert_eq!(s.write(&[0; 1024]).unwrap(), 1024);
+ assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024);
}
#[test]
- fn test_chained_reader() {
- let rs = vec!(MemReader::new(vec!(0, 1)), MemReader::new(vec!()),
- MemReader::new(vec!(2, 3)));
- let mut r = ChainedReader::new(rs.into_iter());
- assert_eq!(vec!(0, 1, 2, 3), r.read_to_end().unwrap());
+ fn empty_reads() {
+ let mut e = empty();
+ assert_eq!(e.read(&mut []).unwrap(), 0);
+ assert_eq!(e.read(&mut [0]).unwrap(), 0);
+ assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
+ assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
}
#[test]
- fn test_tee_reader() {
- let mut r = TeeReader::new(MemReader::new(vec!(0, 1, 2)),
- Vec::new());
- assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
- let (_, w) = r.into_inner();
- assert_eq!(vec!(0, 1, 2), w);
+ fn repeat_repeats() {
+ let mut r = repeat(4);
+ let mut b = [0; 1024];
+ assert_eq!(r.read(&mut b).unwrap(), 1024);
+ assert!(b.iter().all(|b| *b == 4));
}
#[test]
- fn test_copy() {
- let mut r = MemReader::new(vec!(0, 1, 2, 3, 4));
- let mut w = Vec::new();
- copy(&mut r, &mut w).unwrap();
- assert_eq!(vec!(0, 1, 2, 3, 4), w);
+ fn take_some_bytes() {
+ assert_eq!(repeat(4).take(100).bytes().count(), 100);
+ assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4);
+ assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20);
}
#[test]
- fn limit_reader_buffer() {
- let r = &mut b"0123456789\n0123456789\n";
- {
- let mut r = LimitReader::new(r.by_ref(), 3);
- assert_eq!(r.read_line(), Ok("012".to_string()));
- 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_string()));
- assert_eq!(r.limit(), 1);
- assert_eq!(r.read_line(), Ok("0".to_string()));
- }
+ fn tee() {
+ let mut buf = [0; 10];
{
- 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_string()));
+ let mut ptr: &mut [u8] = &mut buf;
+ assert_eq!(repeat(4).tee(&mut ptr).take(5).read(&mut [0; 10]).unwrap(), 5);
}
+ assert_eq!(buf, [4, 4, 4, 4, 4, 0, 0, 0, 0, 0]);
}
#[test]
- fn test_iter_reader() {
- let mut r = IterReader::new(range(0u8, 8));
- let mut buf = [0, 0, 0];
- let len = r.read(&mut buf).unwrap();
- assert_eq!(len, 3);
- assert!(buf == [0, 1, 2]);
-
- let len = r.read(&mut buf).unwrap();
- assert_eq!(len, 3);
- assert!(buf == [3, 4, 5]);
-
- let len = r.read(&mut buf).unwrap();
- assert_eq!(len, 2);
- assert!(buf == [6, 7, 5]);
-
- assert_eq!(r.read(&mut buf).unwrap_err().kind, io::EndOfFile);
- }
+ fn broadcast() {
+ let mut buf1 = [0; 10];
+ let mut buf2 = [0; 10];
+ {
+ let mut ptr1: &mut [u8] = &mut buf1;
+ let mut ptr2: &mut [u8] = &mut buf2;
- #[test]
- fn iter_reader_zero_length() {
- let mut r = IterReader::new(range(0u8, 8));
- let mut buf = [];
- assert_eq!(Ok(0), r.read(&mut buf));
+ assert_eq!((&mut ptr1).broadcast(&mut ptr2)
+ .write(&[1, 2, 3]).unwrap(), 3);
+ }
+ assert_eq!(buf1, buf2);
+ assert_eq!(buf1, [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]);
}
}