diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index f5c6c15857aec..b34a23a4b2fc1 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -115,6 +115,18 @@ impl Reader for BufferedReader { self.pos += nread; Ok(nread) } + + fn skip_exact(&mut self, n: uint) -> IoResult<()> { + if self.pos + n <= self.cap { + self.pos += n; + } + else { + let skip = n - (self.cap - self.pos); + self.pos = self.cap; + try!(self.inner.skip_exact(skip)); + } + Ok(()) + } } /// Wraps a Writer and buffers output to it @@ -356,6 +368,10 @@ impl Reader for BufferedStream { fn read(&mut self, buf: &mut [u8]) -> IoResult { self.inner.read(buf) } + + fn skip_exact(&mut self, n: uint) -> IoResult<()> { + self.inner.skip_exact(n) + } } impl Writer for BufferedStream { diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index 5c2a5c3512d32..777d42b399f4b 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -55,7 +55,7 @@ fs::unlink(&path); use clone::Clone; use io::standard_error; use io::{FilePermission, Write, Open, FileAccess, FileMode}; -use io::{IoResult, IoError, FileStat, SeekStyle, Seek, Writer, Reader}; +use io::{IoResult, IoError, FileStat, SeekStyle, Seek, SeekCur, Writer, Reader}; use io::{Read, Truncate, ReadWrite, Append}; use io::UpdateIoError; use io; @@ -67,6 +67,7 @@ use result::{Err, Ok}; use slice::SlicePrelude; use string::String; use vec::Vec; +use num::ToPrimitive; use sys::fs as fs_imp; use sys_common; @@ -706,6 +707,13 @@ impl Reader for File { Err(e) => Err(e) } } + + fn skip_exact(&mut self, n: uint) -> IoResult<()> { + match n.to_i64() { + Some(i) => self.seek(i, SeekCur), + None => Err(io::standard_error(io::InvalidInput)), + } + } } impl Writer for File { diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index 51935862600d0..5099c650db7c8 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -159,6 +159,19 @@ impl Reader for MemReader { return Ok(write_len); } + + #[inline] + fn skip_exact(&mut self, n: uint) -> IoResult<()> { + let remaining = self.buf.len() - self.pos; + if remaining < n { + self.pos = self.buf.len(); + Err(io::standard_error(io::EndOfFile)) + } + else { + self.pos += n; + Ok(()) + } + } } impl Seek for MemReader { @@ -305,6 +318,19 @@ impl<'a> Reader for BufReader<'a> { return Ok(write_len); } + + #[inline] + fn skip_exact(&mut self, n: uint) -> IoResult<()> { + let remaining = self.buf.len() - self.pos; + if remaining < n { + self.pos = self.buf.len(); + Err(io::standard_error(io::EndOfFile)) + } + else { + self.pos += n; + Ok(()) + } + } } impl<'a> Seek for BufReader<'a> { diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 90345cb0535eb..85ff4ad38f646 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -846,6 +846,12 @@ pub trait Reader { fn read_i8(&mut self) -> IoResult { self.read_byte().map(|i| i as i8) } + + /// Skip `n` bytes of input. + fn skip_exact(&mut self, n: uint) -> IoResult<()> { + try!(self.read_exact(n)); + Ok(()) + } } /// A reader which can be converted to a RefReader. @@ -903,10 +909,21 @@ impl<'a> Reader for Box { let reader: &mut Reader = &mut **self; reader.read(buf) } + + fn skip_exact(&mut self, n: uint) -> IoResult<()> { + let reader: &mut Reader = &mut **self; + reader.skip_exact(n) + } } impl<'a> Reader for &'a mut Reader+'a { - fn read(&mut self, buf: &mut [u8]) -> IoResult { (*self).read(buf) } + fn read(&mut self, buf: &mut [u8]) -> IoResult { + (*self).read(buf) + } + + fn skip_exact(&mut self, n: uint) -> IoResult<()> { + (*self).skip_exact(n) + } } /// Returns a slice of `v` between `start` and `end`. @@ -963,7 +980,13 @@ pub struct RefReader<'a, R:'a> { } impl<'a, R: Reader> Reader for RefReader<'a, R> { - fn read(&mut self, buf: &mut [u8]) -> IoResult { self.inner.read(buf) } + fn read(&mut self, buf: &mut [u8]) -> IoResult { + self.inner.read(buf) + } + + fn skip_exact(&mut self, n: uint) -> IoResult<()> { + self.inner.skip_exact(n) + } } impl<'a, R: Buffer> Buffer for RefReader<'a, R> { diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index 765af0dfbc0d9..ba5d50b472da2 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -93,6 +93,11 @@ impl Reader for ZeroReader { buf.set_memory(0); Ok(buf.len()) } + + #[inline] + fn skip_exact(&mut self, _: uint) -> io::IoResult<()> { + Ok(()) + } } impl Buffer for ZeroReader {