auto merge of #11022 : spaolacci/rust/0read, r=alexcrichton

Could prevent callers from catching the situation and lead to e.g early
iterator terminations (cf. `Reader::read_byte`) since `None` is only to
be returned only on EOF.
This commit is contained in:
bors 2013-12-23 11:26:34 -08:00
commit 619c4fce89

View File

@ -118,14 +118,14 @@ impl<R: Reader> Reader for BufferedReader<R> {
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
let nread = {
let available = self.fill();
if available.len() == 0 {
return None;
}
let nread = num::min(available.len(), buf.len());
vec::bytes::copy_memory(buf, available.slice_to(nread));
nread
};
self.pos += nread;
if nread == 0 && self.inner.eof() && buf.len() != 0 {
return None;
}
Some(nread)
}
@ -322,6 +322,21 @@ impl Writer for NullStream {
fn write(&mut self, _: &[u8]) { }
}
/// A dummy reader intended at testing short-reads propagation.
pub struct ShortReader {
priv lengths: ~[uint],
}
impl Reader for ShortReader {
fn read(&mut self, _: &mut [u8]) -> Option<uint> {
self.lengths.shift_opt()
}
fn eof(&mut self) -> bool {
self.lengths.len() == 0
}
}
#[test]
fn test_buffered_reader() {
let inner = MemReader::new(~[0, 1, 2, 3, 4]);
@ -475,6 +490,19 @@ fn test_lines() {
assert_eq!(it.next(), None);
}
#[test]
fn test_short_reads() {
let inner = ShortReader{lengths: ~[0, 1, 2, 0, 1, 0]};
let mut reader = BufferedReader::new(inner);
let mut buf = [0, 0];
assert_eq!(reader.read(buf), Some(0));
assert_eq!(reader.read(buf), Some(1));
assert_eq!(reader.read(buf), Some(2));
assert_eq!(reader.read(buf), Some(0));
assert_eq!(reader.read(buf), Some(1));
assert_eq!(reader.read(buf), None);
}
#[bench]
fn bench_buffered_reader(bh: &mut Harness) {