auto merge of #13049 : alexcrichton/rust/io-fill, r=huonw
This method can be used to fill a byte slice of data entirely, and it's considered an error if any error happens before its entirely filled.
This commit is contained in:
commit
e06348ea55
4 changed files with 40 additions and 11 deletions
|
@ -60,10 +60,8 @@ impl<R: Reader> Rng for ReaderRng<R> {
|
||||||
}
|
}
|
||||||
fn fill_bytes(&mut self, v: &mut [u8]) {
|
fn fill_bytes(&mut self, v: &mut [u8]) {
|
||||||
if v.len() == 0 { return }
|
if v.len() == 0 { return }
|
||||||
match self.reader.read(v) {
|
match self.reader.fill(v) {
|
||||||
Ok(n) if n == v.len() => return,
|
Ok(()) => {}
|
||||||
Ok(n) => fail!("ReaderRng.fill_bytes could not fill buffer: \
|
|
||||||
read {} out of {} bytes.", n, v.len()),
|
|
||||||
Err(e) => fail!("ReaderRng.fill_bytes error: {}", e)
|
Err(e) => fail!("ReaderRng.fill_bytes error: {}", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ impl<R: Reader> BufferedReader<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Reader> Buffer for BufferedReader<R> {
|
impl<R: Reader> Buffer for BufferedReader<R> {
|
||||||
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
||||||
if self.pos == self.cap {
|
if self.pos == self.cap {
|
||||||
self.cap = try!(self.inner.read(self.buf.as_mut_slice()));
|
self.cap = try!(self.inner.read(self.buf.as_mut_slice()));
|
||||||
self.pos = 0;
|
self.pos = 0;
|
||||||
|
@ -103,7 +103,7 @@ impl<R: Reader> Buffer for BufferedReader<R> {
|
||||||
impl<R: Reader> Reader for BufferedReader<R> {
|
impl<R: Reader> Reader for BufferedReader<R> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||||
let nread = {
|
let nread = {
|
||||||
let available = try!(self.fill());
|
let available = try!(self.fill_buf());
|
||||||
let nread = cmp::min(available.len(), buf.len());
|
let nread = cmp::min(available.len(), buf.len());
|
||||||
slice::bytes::copy_memory(buf, available.slice_to(nread));
|
slice::bytes::copy_memory(buf, available.slice_to(nread));
|
||||||
nread
|
nread
|
||||||
|
@ -345,7 +345,7 @@ impl<S: Stream> BufferedStream<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Stream> Buffer for BufferedStream<S> {
|
impl<S: Stream> Buffer for BufferedStream<S> {
|
||||||
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill() }
|
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
|
||||||
fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
|
fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -190,7 +190,7 @@ impl Seek for MemReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Buffer for MemReader {
|
impl Buffer for MemReader {
|
||||||
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
||||||
if self.pos < self.buf.len() {
|
if self.pos < self.buf.len() {
|
||||||
Ok(self.buf.slice_from(self.pos))
|
Ok(self.buf.slice_from(self.pos))
|
||||||
} else {
|
} else {
|
||||||
|
@ -322,7 +322,7 @@ impl<'a> Seek for BufReader<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Buffer for BufReader<'a> {
|
impl<'a> Buffer for BufReader<'a> {
|
||||||
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
||||||
if self.pos < self.buf.len() {
|
if self.pos < self.buf.len() {
|
||||||
Ok(self.buf.slice_from(self.pos))
|
Ok(self.buf.slice_from(self.pos))
|
||||||
} else {
|
} else {
|
||||||
|
@ -555,4 +555,18 @@ mod test {
|
||||||
let mut r = BufWriter::new(buf);
|
let mut r = BufWriter::new(buf);
|
||||||
assert!(r.seek(-1, SeekSet).is_err());
|
assert!(r.seek(-1, SeekSet).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn io_fill() {
|
||||||
|
let mut r = MemReader::new(~[1, 2, 3, 4, 5, 6, 7, 8]);
|
||||||
|
let mut buf = [0, ..3];
|
||||||
|
assert_eq!(r.fill(buf), Ok(()));
|
||||||
|
assert_eq!(buf.as_slice(), &[1, 2, 3]);
|
||||||
|
assert_eq!(r.fill(buf.mut_slice_to(0)), Ok(()));
|
||||||
|
assert_eq!(buf.as_slice(), &[1, 2, 3]);
|
||||||
|
assert_eq!(r.fill(buf), Ok(()));
|
||||||
|
assert_eq!(buf.as_slice(), &[4, 5, 6]);
|
||||||
|
assert!(r.fill(buf).is_err());
|
||||||
|
assert_eq!(buf.as_slice(), &[7, 8, 6]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -360,6 +360,23 @@ pub trait Reader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fills the provided slice with bytes from this reader
|
||||||
|
///
|
||||||
|
/// This will continue to call `read` until the slice has been completely
|
||||||
|
/// filled with bytes.
|
||||||
|
///
|
||||||
|
/// # Error
|
||||||
|
///
|
||||||
|
/// If an error occurs at any point, that error is returned, and no further
|
||||||
|
/// bytes are read.
|
||||||
|
fn fill(&mut self, buf: &mut [u8]) -> IoResult<()> {
|
||||||
|
let mut read = 0;
|
||||||
|
while read < buf.len() {
|
||||||
|
read += try!(self.read(buf.mut_slice_from(read)));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Reads exactly `len` bytes and appends them to a vector.
|
/// Reads exactly `len` bytes and appends them to a vector.
|
||||||
///
|
///
|
||||||
/// May push fewer than the requested number of bytes on error
|
/// May push fewer than the requested number of bytes on error
|
||||||
|
@ -1045,7 +1062,7 @@ pub trait Buffer: Reader {
|
||||||
/// This function will return an I/O error if the underlying reader was
|
/// This function will return an I/O error if the underlying reader was
|
||||||
/// read, but returned an error. Note that it is not an error to return a
|
/// read, but returned an error. Note that it is not an error to return a
|
||||||
/// 0-length buffer.
|
/// 0-length buffer.
|
||||||
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]>;
|
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]>;
|
||||||
|
|
||||||
/// Tells this buffer that `amt` bytes have been consumed from the buffer,
|
/// Tells this buffer that `amt` bytes have been consumed from the buffer,
|
||||||
/// so they should no longer be returned in calls to `fill` or `read`.
|
/// so they should no longer be returned in calls to `fill` or `read`.
|
||||||
|
@ -1116,7 +1133,7 @@ pub trait Buffer: Reader {
|
||||||
let mut used;
|
let mut used;
|
||||||
loop {
|
loop {
|
||||||
{
|
{
|
||||||
let available = match self.fill() {
|
let available = match self.fill_buf() {
|
||||||
Ok(n) => n,
|
Ok(n) => n,
|
||||||
Err(ref e) if res.len() > 0 && e.kind == EndOfFile => {
|
Err(ref e) if res.len() > 0 && e.kind == EndOfFile => {
|
||||||
used = 0;
|
used = 0;
|
||||||
|
|
Loading…
Reference in a new issue