Skip to content

Commit 5560383

Browse files
committed
std: Add an I/O reader method to fill a buffer
I've found a common use case being to fill a slice (not an owned vector) completely with bytes. It's posible for short reads to happen, and if you're trying to get an exact number of bytes then this helper will be useful.
1 parent e233a43 commit 5560383

File tree

3 files changed

+38
-7
lines changed

3 files changed

+38
-7
lines changed

src/libstd/io/buffered.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl<R: Reader> BufferedReader<R> {
8787
}
8888

8989
impl<R: Reader> Buffer for BufferedReader<R> {
90-
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
90+
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
9191
if self.pos == self.cap {
9292
self.cap = try!(self.inner.read(self.buf));
9393
self.pos = 0;
@@ -104,7 +104,7 @@ impl<R: Reader> Buffer for BufferedReader<R> {
104104
impl<R: Reader> Reader for BufferedReader<R> {
105105
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
106106
let nread = {
107-
let available = try!(self.fill());
107+
let available = try!(self.fill_buf());
108108
let nread = cmp::min(available.len(), buf.len());
109109
slice::bytes::copy_memory(buf, available.slice_to(nread));
110110
nread
@@ -336,7 +336,7 @@ impl<S: Stream> BufferedStream<S> {
336336
}
337337

338338
impl<S: Stream> Buffer for BufferedStream<S> {
339-
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill() }
339+
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
340340
fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
341341
}
342342

src/libstd/io/mem.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ impl Seek for MemReader {
190190
}
191191

192192
impl Buffer for MemReader {
193-
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
193+
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
194194
if self.pos < self.buf.len() {
195195
Ok(self.buf.slice_from(self.pos))
196196
} else {
@@ -322,7 +322,7 @@ impl<'a> Seek for BufReader<'a> {
322322
}
323323

324324
impl<'a> Buffer for BufReader<'a> {
325-
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
325+
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
326326
if self.pos < self.buf.len() {
327327
Ok(self.buf.slice_from(self.pos))
328328
} else {
@@ -555,4 +555,18 @@ mod test {
555555
let mut r = BufWriter::new(buf);
556556
assert!(r.seek(-1, SeekSet).is_err());
557557
}
558+
559+
#[test]
560+
fn io_fill() {
561+
let mut r = MemReader::new(~[1, 2, 3, 4, 5, 6, 7, 8]);
562+
let mut buf = [0, ..3];
563+
assert_eq!(r.fill(buf), Ok(()));
564+
assert_eq!(buf.as_slice(), &[1, 2, 3]);
565+
assert_eq!(r.fill(buf.mut_slice_to(0)), Ok(()));
566+
assert_eq!(buf.as_slice(), &[1, 2, 3]);
567+
assert_eq!(r.fill(buf), Ok(()));
568+
assert_eq!(buf.as_slice(), &[4, 5, 6]);
569+
assert!(r.fill(buf).is_err());
570+
assert_eq!(buf.as_slice(), &[7, 8, 6]);
571+
}
558572
}

src/libstd/io/mod.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,23 @@ pub trait Reader {
360360
}
361361
}
362362

363+
/// Fills the provided slice with bytes from this reader
364+
///
365+
/// This will continue to call `read` until the slice has been completely
366+
/// filled with bytes.
367+
///
368+
/// # Error
369+
///
370+
/// If an error occurs at any point, that error is returned, and no further
371+
/// bytes are read.
372+
fn fill(&mut self, buf: &mut [u8]) -> IoResult<()> {
373+
let mut read = 0;
374+
while read < buf.len() {
375+
read += try!(self.read(buf.mut_slice_from(read)));
376+
}
377+
Ok(())
378+
}
379+
363380
/// Reads exactly `len` bytes and appends them to a vector.
364381
///
365382
/// May push fewer than the requested number of bytes on error
@@ -1045,7 +1062,7 @@ pub trait Buffer: Reader {
10451062
/// This function will return an I/O error if the underlying reader was
10461063
/// read, but returned an error. Note that it is not an error to return a
10471064
/// 0-length buffer.
1048-
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]>;
1065+
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]>;
10491066

10501067
/// Tells this buffer that `amt` bytes have been consumed from the buffer,
10511068
/// so they should no longer be returned in calls to `fill` or `read`.
@@ -1116,7 +1133,7 @@ pub trait Buffer: Reader {
11161133
let mut used;
11171134
loop {
11181135
{
1119-
let available = match self.fill() {
1136+
let available = match self.fill_buf() {
11201137
Ok(n) => n,
11211138
Err(ref e) if res.len() > 0 && e.kind == EndOfFile => {
11221139
used = 0;

0 commit comments

Comments
 (0)