diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index ab9a837713630..5f3b88d520578 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -87,7 +87,7 @@ impl BufferedReader { } impl Buffer for BufferedReader { - fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> { + fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { if self.pos == self.cap { self.cap = try!(self.inner.read(self.buf)); self.pos = 0; @@ -104,7 +104,7 @@ impl Buffer for BufferedReader { impl Reader for BufferedReader { fn read(&mut self, buf: &mut [u8]) -> IoResult { let nread = { - let available = try!(self.fill()); + let available = try!(self.fill_buf()); let nread = cmp::min(available.len(), buf.len()); slice::bytes::copy_memory(buf, available.slice_to(nread)); nread @@ -336,7 +336,7 @@ impl BufferedStream { } impl Buffer for BufferedStream { - 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) } } diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index d0c4ef308b317..7ae717cfccf97 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -190,7 +190,7 @@ impl Seek 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() { Ok(self.buf.slice_from(self.pos)) } else { @@ -322,7 +322,7 @@ impl<'a> Seek 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() { Ok(self.buf.slice_from(self.pos)) } else { @@ -555,4 +555,18 @@ mod test { let mut r = BufWriter::new(buf); 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]); + } } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 88ffc363e8875..6bd8f119ba29b 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -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. /// /// 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 /// read, but returned an error. Note that it is not an error to return a /// 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, /// so they should no longer be returned in calls to `fill` or `read`. @@ -1116,7 +1133,7 @@ pub trait Buffer: Reader { let mut used; loop { { - let available = match self.fill() { + let available = match self.fill_buf() { Ok(n) => n, Err(ref e) if res.len() > 0 && e.kind == EndOfFile => { used = 0;