Skip to content

Commit 339c9b1

Browse files
committed
Add skip(n: uint) to Seek, File and BufferedReader.
Resolve rust-lang#13989 Signed-off-by: NODA, Kai <nodakai@gmail.com>
1 parent 9fd9953 commit 339c9b1

File tree

4 files changed

+51
-14
lines changed

4 files changed

+51
-14
lines changed

src/libstd/io/buffered.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,17 @@ impl<R: Reader> Reader for BufferedReader<R> {
113113
self.pos += nread;
114114
Ok(nread)
115115
}
116+
117+
fn skip(&mut self, num_bytes: uint) -> IoResult<uint> {
118+
let bytes_in_buf = self.cap - self.pos;
119+
Ok( if num_bytes <= bytes_in_buf {
120+
self.pos += num_bytes;
121+
num_bytes
122+
} else {
123+
self.pos += bytes_in_buf;
124+
bytes_in_buf + try!( self.inner.skip(num_bytes - bytes_in_buf) )
125+
} )
126+
}
116127
}
117128

118129
/// Wraps a Writer and buffers output to it

src/libstd/io/fs.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,12 @@ impl File {
259259
err.update_err("couldn't fstat file",
260260
|e| format!("{}; path={}", e, self.path.display()))
261261
}
262+
263+
/// Call Seek::skip(), not Reader::skip().
264+
#[inline]
265+
pub fn skip(&mut self, num_bytes: uint) -> IoResult<uint> {
266+
Seek::skip(self, num_bytes)
267+
}
262268
}
263269

264270
/// Unlink a file from the underlying filesystem.

src/libstd/io/mem.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ impl MemReader {
137137
/// Unwraps this `MemReader`, returning the underlying buffer
138138
#[inline]
139139
pub fn unwrap(self) -> Vec<u8> { self.buf }
140+
141+
/// Call Seek::skip(), not Reader::skip().
142+
#[inline]
143+
pub fn skip(&mut self, num_bytes: uint) -> IoResult<uint> {
144+
Seek::skip(self, num_bytes)
145+
}
140146
}
141147

142148
impl Reader for MemReader {

src/libstd/io/mod.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ use string::String;
243243
use uint;
244244
use unicode::char::UnicodeChar;
245245
use vec::Vec;
246+
use num::ToPrimitive;
246247

247248
// Reexports
248249
pub use self::stdio::stdin;
@@ -1602,6 +1603,16 @@ pub trait Seek {
16021603
/// stream, but the next write may cause the previous data to be filled in
16031604
/// with a bit pattern.
16041605
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()>;
1606+
1607+
/// Wrap seek(num_byes, SeekCur) to provide something similar with Reader::skip().
1608+
///
1609+
/// # Failure
1610+
///
1611+
/// Fails when num_bytes doesn't fit into i64.
1612+
#[inline]
1613+
fn skip(&mut self, num_bytes: uint) -> IoResult<uint> {
1614+
self.seek(num_bytes.to_i64().unwrap(), SeekCur).and(Ok(num_bytes))
1615+
}
16051616
}
16061617

16071618
/// A listener is a value that can consume itself to start listening for
@@ -1947,6 +1958,10 @@ mod tests {
19471958
fn new(r: T, behavior: Vec<BadReaderBehavior>) -> BadReader<T> {
19481959
BadReader { behavior: behavior, r: r }
19491960
}
1961+
1962+
fn simply_new(r: T) -> BadReader<T> {
1963+
BadReader::new(r, vec![])
1964+
}
19501965
}
19511966

19521967
impl<T: Reader> Reader for BadReader<T> {
@@ -1976,20 +1991,18 @@ mod tests {
19761991

19771992
#[test]
19781993
fn test_read_at_least() {
1979-
let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()),
1980-
vec![GoodBehavior(uint::MAX)]);
1994+
let mut r = BadReader::simply_new(MemReader::new(b"hello, world!".to_vec()));
19811995
let mut buf = [0u8, ..5];
19821996
assert!(r.read_at_least(1, buf).unwrap() >= 1);
19831997
assert!(r.read_exact(5).unwrap().len() == 5); // read_exact uses read_at_least
19841998
assert!(r.read_at_least(0, buf).is_ok());
19851999

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

19902004
let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()),
1991-
vec![BadBehavior(1), GoodBehavior(1),
1992-
BadBehavior(50), GoodBehavior(uint::MAX)]);
2005+
vec![BadBehavior(1), GoodBehavior(1), BadBehavior(50)]);
19932006
assert!(r.read_at_least(1, buf).unwrap() >= 1);
19942007
assert!(r.read_at_least(1, buf).unwrap() >= 1);
19952008

@@ -2004,19 +2017,17 @@ mod tests {
20042017

20052018
#[test]
20062019
fn test_push_at_least() {
2007-
let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()),
2008-
vec![GoodBehavior(uint::MAX)]);
2020+
let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()), vec![]);
20092021
let mut buf = Vec::new();
20102022
assert!(r.push_at_least(1, 5, &mut buf).unwrap() >= 1);
20112023
assert!(r.push_at_least(0, 5, &mut buf).is_ok());
20122024

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

20172029
let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()),
2018-
vec![BadBehavior(1), GoodBehavior(1),
2019-
BadBehavior(50), GoodBehavior(uint::MAX)]);
2030+
vec![BadBehavior(1), GoodBehavior(1), BadBehavior(50)]);
20202031
assert!(r.push_at_least(1, 5, &mut buf).unwrap() >= 1);
20212032
assert!(r.push_at_least(1, 5, &mut buf).unwrap() >= 1);
20222033

@@ -2031,15 +2042,16 @@ mod tests {
20312042
#[test]
20322043
fn test_reader_skip() {
20332044
{
2034-
let mut r = MemReader::new(b"hello, world!".to_vec());
2045+
let mut r = BadReader::simply_new(MemReader::new(b"hello, world!".to_vec()));
20352046
assert_eq!(7, r.skip(7).unwrap());
20362047
let mut buf = [0_u8, .. 10];
20372048
assert_eq!(6, r.read(buf).unwrap());
20382049
assert_eq!(b"world!".as_slice(), buf.as_slice());
20392050
assert_eq!(EndOfFile, r.skip(0).unwrap_err().kind);
20402051
}
20412052
{
2042-
let mut r = MemReader::new(Vec::from_fn(SKIP_SIZE + 20, |i| i as u8));
2053+
let mut r = BadReader::simply_new(MemReader::new(
2054+
Vec::from_fn(SKIP_SIZE + 20, |i| i as u8)));
20432055
assert_eq!(10, r.skip(10).unwrap());
20442056
assert_eq!(10, r.read_u8().unwrap());
20452057
assert_eq!(SKIP_SIZE, r.skip(SKIP_SIZE).unwrap());
@@ -2049,7 +2061,8 @@ mod tests {
20492061
assert_eq!(EndOfFile, r.read(buf).unwrap_err().kind);
20502062
}
20512063
{
2052-
let mut r = MemReader::new(Vec::from_fn(SKIP_SIZE + 20, |i| i as u8));
2064+
let mut r = BadReader::simply_new(MemReader::new(
2065+
Vec::from_fn(SKIP_SIZE + 20, |i| i as u8)));
20532066
assert_eq!(SKIP_SIZE, r.skip(SKIP_SIZE).unwrap());
20542067
assert_eq!(SKIP_SIZE as u8, r.read_u8().unwrap());
20552068
assert_eq!(10, r.skip(10).unwrap());
@@ -2059,7 +2072,8 @@ mod tests {
20592072
assert_eq!(EndOfFile, r.read(buf).unwrap_err().kind);
20602073
}
20612074
{
2062-
let mut r = MemReader::new(Vec::from_fn(2 * SKIP_SIZE + 20, |i| i as u8));
2075+
let mut r = BadReader::simply_new(MemReader::new(
2076+
Vec::from_fn(2 * SKIP_SIZE + 20, |i| i as u8)));
20632077
assert_eq!(10, r.skip(10).unwrap());
20642078
assert_eq!(10, r.read_u8().unwrap());
20652079
assert_eq!(2 * SKIP_SIZE, r.skip(2 * SKIP_SIZE).unwrap());

0 commit comments

Comments
 (0)