diff options
| author | Steven Fackler <sfackler@gmail.com> | 2013-11-30 11:27:39 -0500 |
|---|---|---|
| committer | Steven Fackler <sfackler@gmail.com> | 2013-11-30 11:33:11 -0500 |
| commit | 26e57bbdb5180134ec604c9561e05e68bab2b023 (patch) | |
| tree | 6be36014a83e84ee885c2f5dd687d82349e9680c /src/libstd | |
| parent | 6c672ee094a1a8e72c100100f43c73a9741f08a7 (diff) | |
| download | rust-26e57bbdb5180134ec604c9561e05e68bab2b023.tar.gz rust-26e57bbdb5180134ec604c9561e05e68bab2b023.zip | |
Fixes for BufferedWriter and LineBufferedWriter
BufferedWriter::inner flushes before returning the underlying writer. BufferedWriter::write no longer flushes the underlying writer. LineBufferedWriter::write flushes up to the *last* newline in the input string, not the first.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/io/buffered.rs | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 8c1897339cb..9c5927f8639 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -166,12 +166,19 @@ impl<W: Writer> BufferedWriter<W> { pub fn new(inner: W) -> BufferedWriter<W> { BufferedWriter::with_capacity(DEFAULT_CAPACITY, inner) } + + fn flush_buf(&mut self) { + if self.pos != 0 { + self.inner.write(self.buf.slice_to(self.pos)); + self.pos = 0; + } + } } impl<W: Writer> Writer for BufferedWriter<W> { fn write(&mut self, buf: &[u8]) { if self.pos + buf.len() > self.buf.len() { - self.flush(); + self.flush_buf(); } if buf.len() > self.buf.len() { @@ -184,16 +191,13 @@ impl<W: Writer> Writer for BufferedWriter<W> { } fn flush(&mut self) { - if self.pos != 0 { - self.inner.write(self.buf.slice_to(self.pos)); - self.pos = 0; - } + self.flush_buf(); self.inner.flush(); } } impl<W: Writer> Decorator<W> for BufferedWriter<W> { - fn inner(self) -> W { self.inner } + fn inner(mut self) -> W { self.flush_buf(); self.inner } fn inner_ref<'a>(&'a self) -> &'a W { &self.inner } fn inner_mut_ref<'a>(&'a mut self) -> &'a mut W { &mut self.inner } } @@ -218,7 +222,7 @@ impl<W: Writer> LineBufferedWriter<W> { impl<W: Writer> Writer for LineBufferedWriter<W> { fn write(&mut self, buf: &[u8]) { - match buf.iter().position(|&b| b == '\n' as u8) { + match buf.iter().rposition(|&b| b == '\n' as u8) { Some(i) => { self.inner.write(buf.slice_to(i + 1)); self.inner.flush(); @@ -387,6 +391,15 @@ mod test { writer.inner_ref().inner_ref().as_slice()); } + #[test] + fn test_buffered_writer_inner_flushes() { + let mut w = BufferedWriter::with_capacity(3, MemWriter::new()); + w.write([0, 1]); + assert_eq!([], w.inner_ref().inner_ref().as_slice()); + let w = w.inner(); + assert_eq!([0, 1], w.inner_ref().as_slice()); + } + // This is just here to make sure that we don't infinite loop in the // newtype struct autoderef weirdness #[test] @@ -430,10 +443,15 @@ mod test { assert_eq!(*writer.inner_ref().inner_ref(), ~[]); writer.flush(); assert_eq!(*writer.inner_ref().inner_ref(), ~[0, 1]); - writer.write([0, '\n' as u8, 1]); - assert_eq!(*writer.inner_ref().inner_ref(), ~[0, 1, 0, '\n' as u8]); + writer.write([0, '\n' as u8, 1, '\n' as u8, 2]); + assert_eq!(*writer.inner_ref().inner_ref(), + ~[0, 1, 0, '\n' as u8, 1, '\n' as u8]); writer.flush(); - assert_eq!(*writer.inner_ref().inner_ref(), ~[0, 1, 0, '\n' as u8, 1]); + assert_eq!(*writer.inner_ref().inner_ref(), + ~[0, 1, 0, '\n' as u8, 1, '\n' as u8, 2]); + writer.write([3, '\n' as u8]); + assert_eq!(*writer.inner_ref().inner_ref(), + ~[0, 1, 0, '\n' as u8, 1, '\n' as u8, 2, 3, '\n' as u8]); } #[bench] |
