Skip to content

Commit

Permalink
core::rt:: Implement Reader/Writer for MemReader/MemWriter
Browse files Browse the repository at this point in the history
  • Loading branch information
brson committed Apr 21, 2013
1 parent fa478f5 commit 4eff313
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 7 deletions.
69 changes: 62 additions & 7 deletions src/libcore/rt/io/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

use prelude::*;
use super::*;

use cmp::min;

/// Writes to an owned, growable byte vector
pub struct MemWriter {
Expand All @@ -29,13 +29,15 @@ impl MemWriter {
}

impl Writer for MemWriter {
fn write(&mut self, _buf: &[u8]) { fail!() }
fn write(&mut self, buf: &[u8]) {
self.buf.push_all(buf)
}

fn flush(&mut self) { /* no-op */ }
}

impl Seek for MemWriter {
fn tell(&self) -> u64 { fail!() }
fn tell(&self) -> u64 { self.buf.len() as u64 }

fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
}
Expand Down Expand Up @@ -77,13 +79,27 @@ impl MemReader {
}

impl Reader for MemReader {
fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
{ if self.eof() { return None; } }

let write_len = min(buf.len(), self.buf.len() - self.pos);
{
let input = self.buf.slice(self.pos, self.pos + write_len);
let output = vec::mut_slice(buf, 0, write_len);
assert!(input.len() == output.len());
vec::bytes::copy_memory(output, input, write_len);
}
self.pos += write_len;
assert!(self.pos <= self.buf.len());

fn eof(&mut self) -> bool { fail!() }
return Some(write_len);
}

fn eof(&mut self) -> bool { self.pos == self.buf.len() }
}

impl Seek for MemReader {
fn tell(&self) -> u64 { fail!() }
fn tell(&self) -> u64 { self.pos as u64 }

fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
}
Expand Down Expand Up @@ -163,4 +179,43 @@ impl<'self> Seek for BufReader<'self> {
fn tell(&self) -> u64 { fail!() }

fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
}
}

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

#[test]
fn test_mem_writer() {
let mut writer = MemWriter::new();
assert!(writer.tell() == 0);
writer.write([0]);
assert!(writer.tell() == 1);
writer.write([1, 2, 3]);
writer.write([4, 5, 6, 7]);
assert!(writer.tell() == 8);
assert!(writer.inner() == ~[0, 1, 2, 3, 4, 5 , 6, 7]);
}

#[test]
fn test_mem_reader() {
let mut reader = MemReader::new(~[0, 1, 2, 3, 4, 5, 6, 7]);
let mut buf = [];
assert!(reader.read(buf) == Some(0));
assert!(reader.tell() == 0);
let mut buf = [0];
assert!(reader.read(buf) == Some(1));
assert!(reader.tell() == 1);
assert!(buf == [0]);
let mut buf = [0, ..4];
assert!(reader.read(buf) == Some(4));
assert!(reader.tell() == 5);
assert!(buf == [1, 2, 3, 4]);
assert!(reader.read(buf) == Some(3));
assert!(buf.slice(0, 3) == [5, 6, 7]);
assert!(reader.eof());
assert!(reader.read(buf) == None);
assert!(reader.eof());
}
}
8 changes: 8 additions & 0 deletions src/libcore/rt/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,14 @@ pub enum SeekStyle {
/// * Are `u64` and `i64` the right choices?
pub trait Seek {
fn tell(&self) -> u64;

/// Seek to an offset in a stream
///
/// A successful seek clears the EOF indicator.
///
/// # XXX
///
/// * What is the behavior when seeking past the end of a stream?
fn seek(&mut self, pos: i64, style: SeekStyle);
}

Expand Down

0 comments on commit 4eff313

Please sign in to comment.