Skip to content

Commit

Permalink
Add skip(n: uint) to Seek, File and BufferedReader.
Browse files Browse the repository at this point in the history
Resolve rust-lang#13989

Signed-off-by: NODA, Kai <[email protected]>
  • Loading branch information
nodakai committed Oct 18, 2014
1 parent 9fd9953 commit 339c9b1
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 14 deletions.
11 changes: 11 additions & 0 deletions src/libstd/io/buffered.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,17 @@ impl<R: Reader> Reader for BufferedReader<R> {
self.pos += nread;
Ok(nread)
}

fn skip(&mut self, num_bytes: uint) -> IoResult<uint> {
let bytes_in_buf = self.cap - self.pos;
Ok( if num_bytes <= bytes_in_buf {
self.pos += num_bytes;
num_bytes
} else {
self.pos += bytes_in_buf;
bytes_in_buf + try!( self.inner.skip(num_bytes - bytes_in_buf) )
} )
}
}

/// Wraps a Writer and buffers output to it
Expand Down
6 changes: 6 additions & 0 deletions src/libstd/io/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,12 @@ impl File {
err.update_err("couldn't fstat file",
|e| format!("{}; path={}", e, self.path.display()))
}

/// Call Seek::skip(), not Reader::skip().
#[inline]
pub fn skip(&mut self, num_bytes: uint) -> IoResult<uint> {
Seek::skip(self, num_bytes)
}
}

/// Unlink a file from the underlying filesystem.
Expand Down
6 changes: 6 additions & 0 deletions src/libstd/io/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ impl MemReader {
/// Unwraps this `MemReader`, returning the underlying buffer
#[inline]
pub fn unwrap(self) -> Vec<u8> { self.buf }

/// Call Seek::skip(), not Reader::skip().
#[inline]
pub fn skip(&mut self, num_bytes: uint) -> IoResult<uint> {
Seek::skip(self, num_bytes)
}
}

impl Reader for MemReader {
Expand Down
42 changes: 28 additions & 14 deletions src/libstd/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ use string::String;
use uint;
use unicode::char::UnicodeChar;
use vec::Vec;
use num::ToPrimitive;

// Reexports
pub use self::stdio::stdin;
Expand Down Expand Up @@ -1602,6 +1603,16 @@ pub trait Seek {
/// stream, but the next write may cause the previous data to be filled in
/// with a bit pattern.
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()>;

/// Wrap seek(num_byes, SeekCur) to provide something similar with Reader::skip().
///
/// # Failure
///
/// Fails when num_bytes doesn't fit into i64.
#[inline]
fn skip(&mut self, num_bytes: uint) -> IoResult<uint> {
self.seek(num_bytes.to_i64().unwrap(), SeekCur).and(Ok(num_bytes))
}
}

/// A listener is a value that can consume itself to start listening for
Expand Down Expand Up @@ -1947,6 +1958,10 @@ mod tests {
fn new(r: T, behavior: Vec<BadReaderBehavior>) -> BadReader<T> {
BadReader { behavior: behavior, r: r }
}

fn simply_new(r: T) -> BadReader<T> {
BadReader::new(r, vec![])
}
}

impl<T: Reader> Reader for BadReader<T> {
Expand Down Expand Up @@ -1976,20 +1991,18 @@ mod tests {

#[test]
fn test_read_at_least() {
let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()),
vec![GoodBehavior(uint::MAX)]);
let mut r = BadReader::simply_new(MemReader::new(b"hello, world!".to_vec()));
let mut buf = [0u8, ..5];
assert!(r.read_at_least(1, buf).unwrap() >= 1);
assert!(r.read_exact(5).unwrap().len() == 5); // read_exact uses read_at_least
assert!(r.read_at_least(0, buf).is_ok());

let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()),
vec![BadBehavior(50), GoodBehavior(uint::MAX)]);
vec![BadBehavior(50)]);
assert!(r.read_at_least(1, buf).unwrap() >= 1);

let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()),
vec![BadBehavior(1), GoodBehavior(1),
BadBehavior(50), GoodBehavior(uint::MAX)]);
vec![BadBehavior(1), GoodBehavior(1), BadBehavior(50)]);
assert!(r.read_at_least(1, buf).unwrap() >= 1);
assert!(r.read_at_least(1, buf).unwrap() >= 1);

Expand All @@ -2004,19 +2017,17 @@ mod tests {

#[test]
fn test_push_at_least() {
let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()),
vec![GoodBehavior(uint::MAX)]);
let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()), vec![]);
let mut buf = Vec::new();
assert!(r.push_at_least(1, 5, &mut buf).unwrap() >= 1);
assert!(r.push_at_least(0, 5, &mut buf).is_ok());

let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()),
vec![BadBehavior(50), GoodBehavior(uint::MAX)]);
vec![BadBehavior(50)]);
assert!(r.push_at_least(1, 5, &mut buf).unwrap() >= 1);

let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()),
vec![BadBehavior(1), GoodBehavior(1),
BadBehavior(50), GoodBehavior(uint::MAX)]);
vec![BadBehavior(1), GoodBehavior(1), BadBehavior(50)]);
assert!(r.push_at_least(1, 5, &mut buf).unwrap() >= 1);
assert!(r.push_at_least(1, 5, &mut buf).unwrap() >= 1);

Expand All @@ -2031,15 +2042,16 @@ mod tests {
#[test]
fn test_reader_skip() {
{
let mut r = MemReader::new(b"hello, world!".to_vec());
let mut r = BadReader::simply_new(MemReader::new(b"hello, world!".to_vec()));
assert_eq!(7, r.skip(7).unwrap());
let mut buf = [0_u8, .. 10];
assert_eq!(6, r.read(buf).unwrap());
assert_eq!(b"world!".as_slice(), buf.as_slice());
assert_eq!(EndOfFile, r.skip(0).unwrap_err().kind);
}
{
let mut r = MemReader::new(Vec::from_fn(SKIP_SIZE + 20, |i| i as u8));
let mut r = BadReader::simply_new(MemReader::new(
Vec::from_fn(SKIP_SIZE + 20, |i| i as u8)));
assert_eq!(10, r.skip(10).unwrap());
assert_eq!(10, r.read_u8().unwrap());
assert_eq!(SKIP_SIZE, r.skip(SKIP_SIZE).unwrap());
Expand All @@ -2049,7 +2061,8 @@ mod tests {
assert_eq!(EndOfFile, r.read(buf).unwrap_err().kind);
}
{
let mut r = MemReader::new(Vec::from_fn(SKIP_SIZE + 20, |i| i as u8));
let mut r = BadReader::simply_new(MemReader::new(
Vec::from_fn(SKIP_SIZE + 20, |i| i as u8)));
assert_eq!(SKIP_SIZE, r.skip(SKIP_SIZE).unwrap());
assert_eq!(SKIP_SIZE as u8, r.read_u8().unwrap());
assert_eq!(10, r.skip(10).unwrap());
Expand All @@ -2059,7 +2072,8 @@ mod tests {
assert_eq!(EndOfFile, r.read(buf).unwrap_err().kind);
}
{
let mut r = MemReader::new(Vec::from_fn(2 * SKIP_SIZE + 20, |i| i as u8));
let mut r = BadReader::simply_new(MemReader::new(
Vec::from_fn(2 * SKIP_SIZE + 20, |i| i as u8)));
assert_eq!(10, r.skip(10).unwrap());
assert_eq!(10, r.read_u8().unwrap());
assert_eq!(2 * SKIP_SIZE, r.skip(2 * SKIP_SIZE).unwrap());
Expand Down

0 comments on commit 339c9b1

Please sign in to comment.