Skip to content

Commit

Permalink
Auto merge of #32541 - troplin:chain-bufread, r=alexcrichton
Browse files Browse the repository at this point in the history
Implement BufRead for Chain

Addresses #32536
  • Loading branch information
bors committed Mar 29, 2016
2 parents 21a4d80 + f611e44 commit 161c541
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions src/libstd/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,27 @@ impl<T: Read, U: Read> Read for Chain<T, U> {
}
}

#[stable(feature = "chain_bufread", since = "1.9.0")]
impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
fn fill_buf(&mut self) -> Result<&[u8]> {
if !self.done_first {
match self.first.fill_buf()? {
buf if buf.len() == 0 => { self.done_first = true; }
buf => return Ok(buf),
}
}
self.second.fill_buf()
}

fn consume(&mut self, amt: usize) {
if !self.done_first {
self.first.consume(amt)
} else {
self.second.consume(amt)
}
}
}

/// Reader adaptor which limits the bytes read from an underlying reader.
///
/// This struct is generally created by calling [`take()`][take] on a reader.
Expand Down Expand Up @@ -1844,6 +1865,39 @@ mod tests {
assert_eq!(0, R.take(0).read(&mut buf).unwrap());
}

fn cmp_bufread<Br1: BufRead, Br2: BufRead>(mut br1: Br1, mut br2: Br2, exp: &[u8]) {
let mut cat = Vec::new();
loop {
let consume = {
let buf1 = br1.fill_buf().unwrap();
let buf2 = br2.fill_buf().unwrap();
let minlen = if buf1.len() < buf2.len() { buf1.len() } else { buf2.len() };
assert_eq!(buf1[..minlen], buf2[..minlen]);
cat.extend_from_slice(&buf1[..minlen]);
minlen
};
if consume == 0 {
break;
}
br1.consume(consume);
br2.consume(consume);
}
assert_eq!(br1.fill_buf().unwrap().len(), 0);
assert_eq!(br2.fill_buf().unwrap().len(), 0);
assert_eq!(&cat[..], &exp[..])
}

#[test]
fn chain_bufread() {
let testdata = b"ABCDEFGHIJKL";
let chain1 = (&testdata[..3]).chain(&testdata[3..6])
.chain(&testdata[6..9])
.chain(&testdata[9..]);
let chain2 = (&testdata[..4]).chain(&testdata[4..8])
.chain(&testdata[8..]);
cmp_bufread(chain1, chain2, &testdata[..]);
}

#[bench]
fn bench_read_to_end(b: &mut test::Bencher) {
b.iter(|| {
Expand Down

0 comments on commit 161c541

Please sign in to comment.