From 373f93a629313dccd1858e403e99fb25709947a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Mu=CC=88ller?= Date: Mon, 28 Mar 2016 01:28:03 +0200 Subject: [PATCH 1/3] Implement BufRead for Chain --- src/libstd/io/mod.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 28492b30e0f88..ce14e5de90a6b 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1442,6 +1442,27 @@ impl Read for Chain { } } +#[stable(feature = "chain_bufread", since = "1.9.0")] +impl BufRead for Chain { + fn fill_buf(&mut self) -> Result<&[u8]> { + if !self.done_first { + match try!(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. From 6489fb40deeb7ac62ca11439f96fdb4124c6b94f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Mu=CC=88ller?= Date: Mon, 28 Mar 2016 21:37:36 +0200 Subject: [PATCH 2/3] Use ? instead of try!, add some basic tests --- src/libstd/io/mod.rs | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index ce14e5de90a6b..c329fb3bfa50e 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1446,7 +1446,7 @@ impl Read for Chain { impl BufRead for Chain { fn fill_buf(&mut self) -> Result<&[u8]> { if !self.done_first { - match try!(self.first.fill_buf()) { + match self.first.fill_buf()? { buf if buf.len() == 0 => { self.done_first = true; } buf => return Ok(buf), } @@ -1865,6 +1865,36 @@ mod tests { assert_eq!(0, R.take(0).read(&mut buf).unwrap()); } + fn cmp_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(|| { From f611e446624d288da7def4ad175405579c8bc310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Mu=CC=88ller?= Date: Mon, 28 Mar 2016 22:40:46 +0200 Subject: [PATCH 3/3] Fix formatting --- src/libstd/io/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index c329fb3bfa50e..d4f30e8a99b9a 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1890,8 +1890,11 @@ mod tests { #[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..]); + 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[..]); }