Skip to content

Create RefReader/RefWriter for io traits #12230

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
33 changes: 33 additions & 0 deletions src/libstd/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,13 @@ pub trait Reader {
self.read_byte().map(|i| i as i8)
}

/// Creates a wrapper around a mutable reference to the reader.
///
/// This is useful to allow applying adaptors while still
/// retaining ownership of the original value.
fn by_ref<'a>(&'a mut self) -> RefReader<'a, Self> {
RefReader { inner: self }
}
}

impl Reader for ~Reader {
Expand All @@ -789,6 +796,14 @@ impl<'a> Reader for &'a mut Reader {
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
}

pub struct RefReader<'a, R> {
priv inner: &'a mut R
}

impl<'a, R: Reader> Reader for RefReader<'a, R> {
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.inner.read(buf) }
}

fn extend_sign(val: u64, nbytes: uint) -> i64 {
let shift = (8 - nbytes) * 8;
(val << shift) as i64 >> shift
Expand Down Expand Up @@ -969,6 +984,14 @@ pub trait Writer {
fn write_i8(&mut self, n: i8) -> IoResult<()> {
self.write([n as u8])
}

/// Creates a wrapper around a mutable reference to the writer.
///
/// This is useful to allow applying wrappers while still
/// retaining ownership of the original value.
fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self> {
RefWriter { inner: self }
}
}

impl Writer for ~Writer {
Expand All @@ -981,6 +1004,16 @@ impl<'a> Writer for &'a mut Writer {
fn flush(&mut self) -> IoResult<()> { self.flush() }
}

pub struct RefWriter<'a, W> {
inner: &'a mut W
}

impl<'a, W: Writer> Writer for RefWriter<'a, W> {
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.inner.write(buf) }
fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
}


pub trait Stream: Reader + Writer { }

impl<T: Reader + Writer> Stream for T {}
Expand Down
15 changes: 8 additions & 7 deletions src/libstd/io/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@ use io;
use vec::bytes::MutableByteVector;

/// Wraps a `Reader`, limiting the number of bytes that can be read from it.
pub struct LimitReader<'a, R> {
pub struct LimitReader<R> {
priv limit: uint,
priv inner: &'a mut R
priv inner: R
}

impl<'a, R: Reader> LimitReader<'a, R> {
impl<R: Reader> LimitReader<R> {
/// Creates a new `LimitReader`
pub fn new<'a>(r: &'a mut R, limit: uint) -> LimitReader<'a, R> {
pub fn new(r: R, limit: uint) -> LimitReader<R> {
LimitReader { limit: limit, inner: r }
}
pub fn unwrap(self) -> R { self.inner }
}

impl<'a, R: Reader> Reader for LimitReader<'a, R> {
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));
Expand Down Expand Up @@ -192,7 +193,7 @@ mod test {
fn test_bounded_reader_unlimited() {
let mut r = MemReader::new(~[0, 1, 2]);
{
let mut r = LimitReader::new(&mut r, 4);
let mut r = LimitReader::new(r.by_ref(), 4);
assert_eq!(~[0, 1, 2], r.read_to_end().unwrap());
}
}
Expand All @@ -201,7 +202,7 @@ mod test {
fn test_bound_reader_limited() {
let mut r = MemReader::new(~[0, 1, 2]);
{
let mut r = LimitReader::new(&mut r, 2);
let mut r = LimitReader::new(r.by_ref(), 2);
assert_eq!(~[0, 1], r.read_to_end().unwrap());
}
assert_eq!(~[2], r.read_to_end().unwrap());
Expand Down