Skip to content

Implement Container for some Reader/Writers #12559

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 72 additions & 2 deletions src/libstd/io/buffered.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand Down Expand Up @@ -113,6 +113,12 @@ impl<R: Reader> Reader for BufferedReader<R> {
}
}

impl<R: Container> Container for BufferedReader<R> {
fn len(&self) -> uint {
self.inner.len()
}
}

/// Wraps a Writer and buffers output to it
///
/// Note that `BufferedWriter` will NOT flush its buffer when dropped.
Expand Down Expand Up @@ -200,6 +206,12 @@ impl<W: Writer> Writer for BufferedWriter<W> {
}
}

impl<W: Container> Container for BufferedWriter<W> {
fn len(&self) -> uint {
self.inner.len()
}
}

/// Wraps a Writer and buffers output to it, flushing whenever a newline (`0x0a`,
/// `'\n'`) is detected.
///
Expand Down Expand Up @@ -245,6 +257,12 @@ impl<W: Writer> Writer for LineBufferedWriter<W> {
fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
}

impl<W: Container> Container for LineBufferedWriter<W> {
fn len(&self) -> uint {
self.inner.len()
}
}

struct InternalBufferedWriter<W>(BufferedWriter<W>);

impl<W> InternalBufferedWriter<W> {
Expand All @@ -260,6 +278,13 @@ impl<W: Reader> Reader for InternalBufferedWriter<W> {
}
}

impl<W: Container> Container for InternalBufferedWriter<W> {
fn len(&self) -> uint {
let InternalBufferedWriter(ref inner) = *self;
inner.len()
}
}

/// Wraps a Stream and buffers input and output to and from it
///
/// Note that `BufferedStream` will NOT flush its output buffer when dropped.
Expand Down Expand Up @@ -344,13 +369,20 @@ impl<S: Stream> Writer for BufferedStream<S> {
}
}

impl<S: Container> Container for BufferedStream<S> {
fn len(&self) -> uint {
self.inner.len()
}
}

#[cfg(test)]
mod test {
extern crate test;
use container::Container;
use io;
use prelude::*;
use super::*;
use super::super::mem::{MemReader, MemWriter, BufReader};
use super::super::mem::{MemReader, MemWriter, BufReader, BufWriter};
use Harness = self::test::BenchHarness;

/// A type, free to create, primarily intended for benchmarking creation of
Expand Down Expand Up @@ -563,6 +595,44 @@ mod test {
assert_eq!(it.next(), None);
}

#[test]
fn len() {
let buf = [0xff];
let r = BufferedReader::new(BufReader::new(buf));
assert_eq!(r.len(), buf.len());

let mut buf = [0];
let r = BufferedWriter::new(BufWriter::new(buf));
assert_eq!(r.len(), 1);

let mut buf = [0];
let r = LineBufferedWriter::new(BufWriter::new(buf));
assert_eq!(r.len(), 1);

struct S;

impl io::Writer for S {
fn write(&mut self, _: &[u8]) -> io::IoResult<()> {
Err(io::standard_error(io::EndOfFile))
}
}

impl io::Reader for S {
fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
Err(io::standard_error(io::EndOfFile))
}
}

impl Container for S {
fn len(&self) -> uint {
0
}
}

let s = BufferedStream::new(S);
assert_eq!(s.len(), 0);
}

#[bench]
fn bench_buffered_reader(bh: &mut Harness) {
bh.iter(|| {
Expand Down
46 changes: 45 additions & 1 deletion src/libstd/io/mem.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand Down Expand Up @@ -119,6 +119,12 @@ impl Seek for MemWriter {
}
}

impl Container for MemWriter {
fn len(&self) -> uint {
self.buf.len()
}
}

/// Reads from an owned byte vector
///
/// # Example
Expand Down Expand Up @@ -200,6 +206,12 @@ impl Buffer for MemReader {
fn consume(&mut self, amt: uint) { self.pos += amt; }
}

impl Container for MemReader {
fn len(&self) -> uint {
self.buf.len()
}
}

/// Writes to a fixed-size byte slice
///
/// If a write will not fit in the buffer, it returns an error and does not
Expand Down Expand Up @@ -259,6 +271,12 @@ impl<'a> Seek for BufWriter<'a> {
}
}

impl<'a> Container for BufWriter<'a> {
fn len(&self) -> uint {
self.buf.len()
}
}

/// Reads from a fixed-size byte slice
///
/// # Example
Expand Down Expand Up @@ -330,12 +348,19 @@ impl<'a> Buffer for BufReader<'a> {
fn consume(&mut self, amt: uint) { self.pos += amt; }
}

impl<'a> Container for BufReader<'a> {
fn len(&self) -> uint {
self.buf.len()
}
}

#[cfg(test)]
mod test {
use prelude::*;
use super::*;
use io::*;
use io;
use container::Container;

#[test]
fn test_mem_writer() {
Expand Down Expand Up @@ -553,4 +578,23 @@ mod test {
let mut r = BufWriter::new(buf);
assert!(r.seek(-1, SeekSet).is_err());
}

#[test]
fn len() {
let buf = [0xff];
let r = BufReader::new(buf);
assert_eq!(r.len(), buf.len());

let r = MemReader::new(~[10]);
assert_eq!(r.len(), 1);

let mut r = MemWriter::new();
let str = "abc";
r.write_str(str).unwrap();
assert_eq!(r.len(), str.len());

let mut buf = [0];
let r = BufWriter::new(buf);
assert_eq!(r.len(), 1);
}
}
33 changes: 33 additions & 0 deletions src/libstd/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,12 @@ 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: Container> Container for RefReader<'a, R> {
fn len(&self) -> uint {
self.inner.len()
}
}

fn extend_sign(val: u64, nbytes: uint) -> i64 {
let shift = (8 - nbytes) * 8;
(val << shift) as i64 >> shift
Expand Down Expand Up @@ -886,6 +892,12 @@ impl<'a, W: Writer> Writer for RefWriter<'a, W> {
fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
}

impl<'a, W: Container> Container for RefWriter<'a, W> {
fn len(&self) -> uint {
self.inner.len()
}
}


pub trait Stream: Reader + Writer { }

Expand Down Expand Up @@ -1310,3 +1322,24 @@ pub static UserExec: FilePermission = UserDir;

/// A mask for all possible permission bits
pub static AllPermissions: FilePermission = 0x1ff;

#[cfg(test)]
mod tests {
use prelude::*;
use io::*;
use io::mem::{BufReader, BufWriter};
use container::Container;

#[test]
fn len() {
let buf = [0xff];
let mut r = BufReader::new(buf);
let r = r.by_ref();
assert_eq!(r.len(), buf.len());

let mut buf = [0];
let mut r = BufWriter::new(buf);
let r = r.by_ref();
assert_eq!(r.len(), 1);
}
}
17 changes: 16 additions & 1 deletion src/libstd/io/util.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand All @@ -10,6 +10,7 @@

use prelude::*;
use cmp;
use container::Container;
use io;
use vec::bytes::MutableByteVector;

Expand Down Expand Up @@ -52,6 +53,12 @@ impl<R: Reader> Reader for LimitReader<R> {
}
}

impl<R> Container for LimitReader<R> {
fn len(&self) -> uint {
self.limit
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this true? What about something like LimitReader::new(BufReader::new([]), 100), where the reader is actually empty?

}
}

/// A `Writer` which ignores bytes written to it, like /dev/null.
pub struct NullWriter;

Expand Down Expand Up @@ -199,6 +206,7 @@ mod test {
use io::{MemReader, MemWriter};
use super::*;
use prelude::*;
use container::Container;

#[test]
fn test_limit_reader_unlimited() {
Expand Down Expand Up @@ -305,4 +313,11 @@ mod test {
copy(&mut r, &mut w).unwrap();
assert_eq!(~[0, 1, 2, 3, 4], w.unwrap());
}

#[test]
fn len() {
let r = MemReader::new(~[0, 1, 2, 4]);
let r = LimitReader::new(r, 3);
assert_eq!(r.len(), 3);
}
}