1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // ignore-lexer-test FIXME #15883
13 //! Buffering wrappers for I/O traits
17 use old_io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
18 use iter::{IteratorExt, ExactSizeIterator, repeat};
21 use option::Option::{Some, None};
22 use result::Result::Ok;
26 /// Wraps a Reader and buffers input from it
28 /// It can be excessively inefficient to work directly with a `Reader`. For
29 /// example, every call to `read` on `TcpStream` results in a system call. A
30 /// `BufferedReader` performs large, infrequent reads on the underlying
31 /// `Reader` and maintains an in-memory buffer of the results.
36 /// # #![feature(old_io, old_path)]
37 /// use std::old_io::*;
38 /// use std::old_path::Path;
40 /// let file = File::open(&Path::new("message.txt"));
41 /// let mut reader = BufferedReader::new(file);
43 /// let mut buf = [0; 100];
44 /// match reader.read(&mut buf) {
45 /// Ok(nread) => println!("Read {} bytes", nread),
46 /// Err(e) => println!("error reading: {}", e)
49 pub struct BufferedReader<R> {
56 #[stable(feature = "rust1", since = "1.0.0")]
57 impl<R> fmt::Debug for BufferedReader<R> where R: fmt::Debug {
58 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
59 write!(fmt, "BufferedReader {{ reader: {:?}, buffer: {}/{} }}",
60 self.inner, self.cap - self.pos, self.buf.len())
64 impl<R: Reader> BufferedReader<R> {
65 /// Creates a new `BufferedReader` with the specified buffer capacity
66 pub fn with_capacity(cap: uint, inner: R) -> BufferedReader<R> {
69 // We can't use the same trick here as we do for BufferedWriter,
70 // since this memory is visible to the inner Reader.
71 buf: repeat(0).take(cap).collect(),
77 /// Creates a new `BufferedReader` with a default buffer capacity
78 pub fn new(inner: R) -> BufferedReader<R> {
79 BufferedReader::with_capacity(DEFAULT_BUF_SIZE, inner)
82 /// Gets a reference to the underlying reader.
83 pub fn get_ref<'a>(&self) -> &R { &self.inner }
85 /// Gets a mutable reference to the underlying reader.
89 /// It is inadvisable to directly read from the underlying reader.
90 pub fn get_mut(&mut self) -> &mut R { &mut self.inner }
92 /// Unwraps this `BufferedReader`, returning the underlying reader.
94 /// Note that any leftover data in the internal buffer is lost.
95 pub fn into_inner(self) -> R { self.inner }
98 impl<R: Reader> Buffer for BufferedReader<R> {
99 fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
100 if self.pos == self.cap {
101 self.cap = try!(self.inner.read(&mut self.buf));
104 Ok(&self.buf[self.pos..self.cap])
107 fn consume(&mut self, amt: uint) {
109 assert!(self.pos <= self.cap);
113 impl<R: Reader> Reader for BufferedReader<R> {
114 fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
115 if self.pos == self.cap && buf.len() >= self.buf.len() {
116 return self.inner.read(buf);
119 let available = try!(self.fill_buf());
120 let nread = cmp::min(available.len(), buf.len());
121 slice::bytes::copy_memory(buf, &available[..nread]);
129 /// Wraps a Writer and buffers output to it
131 /// It can be excessively inefficient to work directly with a `Writer`. For
132 /// example, every call to `write` on `TcpStream` results in a system call. A
133 /// `BufferedWriter` keeps an in memory buffer of data and writes it to the
134 /// underlying `Writer` in large, infrequent batches.
136 /// This writer will be flushed when it is dropped.
141 /// # #![feature(old_io, old_path)]
142 /// use std::old_io::*;
143 /// use std::old_path::Path;
145 /// let file = File::create(&Path::new("message.txt")).unwrap();
146 /// let mut writer = BufferedWriter::new(file);
148 /// writer.write_str("hello, world").unwrap();
149 /// writer.flush().unwrap();
151 pub struct BufferedWriter<W: Writer> {
157 #[stable(feature = "rust1", since = "1.0.0")]
158 impl<W: Writer> fmt::Debug for BufferedWriter<W> where W: fmt::Debug {
159 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
160 write!(fmt, "BufferedWriter {{ writer: {:?}, buffer: {}/{} }}",
161 self.inner.as_ref().unwrap(), self.pos, self.buf.len())
165 impl<W: Writer> BufferedWriter<W> {
166 /// Creates a new `BufferedWriter` with the specified buffer capacity
167 pub fn with_capacity(cap: uint, inner: W) -> BufferedWriter<W> {
168 // It's *much* faster to create an uninitialized buffer than it is to
169 // fill everything in with 0. This buffer is entirely an implementation
170 // detail and is never exposed, so we're safe to not initialize
171 // everything up-front. This allows creation of BufferedWriter instances
172 // to be very cheap (large mallocs are not nearly as expensive as large
174 let mut buf = Vec::with_capacity(cap);
175 unsafe { buf.set_len(cap); }
183 /// Creates a new `BufferedWriter` with a default buffer capacity
184 pub fn new(inner: W) -> BufferedWriter<W> {
185 BufferedWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
188 fn flush_buf(&mut self) -> IoResult<()> {
190 let ret = self.inner.as_mut().unwrap().write_all(&self.buf[..self.pos]);
198 /// Gets a reference to the underlying writer.
199 pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() }
201 /// Gets a mutable reference to the underlying write.
205 /// It is inadvisable to directly read from the underlying writer.
206 pub fn get_mut(&mut self) -> &mut W { self.inner.as_mut().unwrap() }
208 /// Unwraps this `BufferedWriter`, returning the underlying writer.
210 /// The buffer is flushed before returning the writer.
211 pub fn into_inner(mut self) -> W {
212 // FIXME(#12628): is panicking the right thing to do if flushing panicks?
213 self.flush_buf().unwrap();
214 self.inner.take().unwrap()
218 impl<W: Writer> Writer for BufferedWriter<W> {
219 fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
220 if self.pos + buf.len() > self.buf.len() {
221 try!(self.flush_buf());
224 if buf.len() > self.buf.len() {
225 self.inner.as_mut().unwrap().write_all(buf)
227 let dst = &mut self.buf[self.pos..];
228 slice::bytes::copy_memory(dst, buf);
229 self.pos += buf.len();
234 fn flush(&mut self) -> IoResult<()> {
235 self.flush_buf().and_then(|()| self.inner.as_mut().unwrap().flush())
240 impl<W: Writer> Drop for BufferedWriter<W> {
242 if self.inner.is_some() {
243 // dtors should not panic, so we ignore a panicked flush
244 let _ = self.flush_buf();
249 /// Wraps a Writer and buffers output to it, flushing whenever a newline (`0x0a`,
250 /// `'\n'`) is detected.
252 /// This writer will be flushed when it is dropped.
253 pub struct LineBufferedWriter<W: Writer> {
254 inner: BufferedWriter<W>,
257 #[stable(feature = "rust1", since = "1.0.0")]
258 impl<W: Writer> fmt::Debug for LineBufferedWriter<W> where W: fmt::Debug {
259 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
260 write!(fmt, "LineBufferedWriter {{ writer: {:?}, buffer: {}/{} }}",
261 self.inner.inner, self.inner.pos, self.inner.buf.len())
265 impl<W: Writer> LineBufferedWriter<W> {
266 /// Creates a new `LineBufferedWriter`
267 pub fn new(inner: W) -> LineBufferedWriter<W> {
268 // Lines typically aren't that long, don't use a giant buffer
270 inner: BufferedWriter::with_capacity(1024, inner)
274 /// Gets a reference to the underlying writer.
276 /// This type does not expose the ability to get a mutable reference to the
277 /// underlying reader because that could possibly corrupt the buffer.
278 pub fn get_ref<'a>(&'a self) -> &'a W { self.inner.get_ref() }
280 /// Unwraps this `LineBufferedWriter`, returning the underlying writer.
282 /// The internal buffer is flushed before returning the writer.
283 pub fn into_inner(self) -> W { self.inner.into_inner() }
286 impl<W: Writer> Writer for LineBufferedWriter<W> {
287 fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
288 match buf.iter().rposition(|&b| b == b'\n') {
290 try!(self.inner.write_all(&buf[..i + 1]));
291 try!(self.inner.flush());
292 try!(self.inner.write_all(&buf[i + 1..]));
295 None => self.inner.write_all(buf),
299 fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
302 struct InternalBufferedWriter<W: Writer>(BufferedWriter<W>);
304 impl<W: Writer> InternalBufferedWriter<W> {
305 fn get_mut<'a>(&'a mut self) -> &'a mut BufferedWriter<W> {
306 let InternalBufferedWriter(ref mut w) = *self;
311 impl<W: Reader + Writer> Reader for InternalBufferedWriter<W> {
312 fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
313 self.get_mut().inner.as_mut().unwrap().read(buf)
317 /// Wraps a Stream and buffers input and output to and from it.
319 /// It can be excessively inefficient to work directly with a `Stream`. For
320 /// example, every call to `read` or `write` on `TcpStream` results in a system
321 /// call. A `BufferedStream` keeps in memory buffers of data, making large,
322 /// infrequent calls to `read` and `write` on the underlying `Stream`.
324 /// The output half will be flushed when this stream is dropped.
329 /// # #![feature(old_io, old_path)]
330 /// # #![allow(unused_must_use)]
331 /// use std::old_io::*;
332 /// use std::old_path::Path;
334 /// let file = File::open(&Path::new("message.txt"));
335 /// let mut stream = BufferedStream::new(file);
337 /// stream.write_all("hello, world".as_bytes());
340 /// let mut buf = [0; 100];
341 /// match stream.read(&mut buf) {
342 /// Ok(nread) => println!("Read {} bytes", nread),
343 /// Err(e) => println!("error reading: {}", e)
346 pub struct BufferedStream<S: Writer> {
347 inner: BufferedReader<InternalBufferedWriter<S>>
350 #[stable(feature = "rust1", since = "1.0.0")]
351 impl<S: Writer> fmt::Debug for BufferedStream<S> where S: fmt::Debug {
352 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
353 let reader = &self.inner;
354 let writer = &self.inner.inner.0;
355 write!(fmt, "BufferedStream {{ stream: {:?}, write_buffer: {}/{}, read_buffer: {}/{} }}",
357 writer.pos, writer.buf.len(),
358 reader.cap - reader.pos, reader.buf.len())
362 impl<S: Stream> BufferedStream<S> {
363 /// Creates a new buffered stream with explicitly listed capacities for the
364 /// reader/writer buffer.
365 pub fn with_capacities(reader_cap: uint, writer_cap: uint, inner: S)
366 -> BufferedStream<S> {
367 let writer = BufferedWriter::with_capacity(writer_cap, inner);
368 let internal_writer = InternalBufferedWriter(writer);
369 let reader = BufferedReader::with_capacity(reader_cap,
371 BufferedStream { inner: reader }
374 /// Creates a new buffered stream with the default reader/writer buffer
376 pub fn new(inner: S) -> BufferedStream<S> {
377 BufferedStream::with_capacities(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE,
381 /// Gets a reference to the underlying stream.
382 pub fn get_ref(&self) -> &S {
383 let InternalBufferedWriter(ref w) = self.inner.inner;
387 /// Gets a mutable reference to the underlying stream.
391 /// It is inadvisable to read directly from or write directly to the
392 /// underlying stream.
393 pub fn get_mut(&mut self) -> &mut S {
394 let InternalBufferedWriter(ref mut w) = self.inner.inner;
398 /// Unwraps this `BufferedStream`, returning the underlying stream.
400 /// The internal buffer is flushed before returning the stream. Any leftover
401 /// data in the read buffer is lost.
402 pub fn into_inner(self) -> S {
403 let InternalBufferedWriter(w) = self.inner.inner;
408 impl<S: Stream> Buffer for BufferedStream<S> {
409 fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
410 fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
413 impl<S: Stream> Reader for BufferedStream<S> {
414 fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
419 impl<S: Stream> Writer for BufferedStream<S> {
420 fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
421 self.inner.inner.get_mut().write_all(buf)
423 fn flush(&mut self) -> IoResult<()> {
424 self.inner.inner.get_mut().flush()
431 use old_io::{self, Reader, Writer, Buffer, BufferPrelude};
434 use super::super::{IoResult, EndOfFile};
435 use super::super::mem::MemReader;
436 use self::test::Bencher;
438 /// A type, free to create, primarily intended for benchmarking creation of
439 /// wrappers that, just for construction, don't need a Reader/Writer that
440 /// does anything useful. Is equivalent to `/dev/null` in semantics.
441 #[derive(Clone,PartialEq,PartialOrd)]
442 pub struct NullStream;
444 impl Reader for NullStream {
445 fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<uint> {
446 Err(old_io::standard_error(old_io::EndOfFile))
450 impl Writer for NullStream {
451 fn write_all(&mut self, _: &[u8]) -> old_io::IoResult<()> { Ok(()) }
454 /// A dummy reader intended at testing short-reads propagation.
455 pub struct ShortReader {
459 impl Reader for ShortReader {
460 fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<uint> {
461 if self.lengths.is_empty() {
462 Err(old_io::standard_error(old_io::EndOfFile))
464 Ok(self.lengths.remove(0))
470 fn test_buffered_reader() {
471 let inner = MemReader::new(vec!(5, 6, 7, 0, 1, 2, 3, 4));
472 let mut reader = BufferedReader::with_capacity(2, inner);
474 let mut buf = [0, 0, 0];
475 let nread = reader.read(&mut buf);
476 assert_eq!(Ok(3), nread);
477 let b: &[_] = &[5, 6, 7];
480 let mut buf = [0, 0];
481 let nread = reader.read(&mut buf);
482 assert_eq!(Ok(2), nread);
483 let b: &[_] = &[0, 1];
487 let nread = reader.read(&mut buf);
488 assert_eq!(Ok(1), nread);
492 let mut buf = [0, 0, 0];
493 let nread = reader.read(&mut buf);
494 assert_eq!(Ok(1), nread);
495 let b: &[_] = &[3, 0, 0];
498 let nread = reader.read(&mut buf);
499 assert_eq!(Ok(1), nread);
500 let b: &[_] = &[4, 0, 0];
503 assert!(reader.read(&mut buf).is_err());
507 fn test_buffered_writer() {
508 let inner = Vec::new();
509 let mut writer = BufferedWriter::with_capacity(2, inner);
511 writer.write_all(&[0, 1]).unwrap();
513 assert_eq!(&writer.get_ref()[], b);
515 writer.write_all(&[2]).unwrap();
516 let b: &[_] = &[0, 1];
517 assert_eq!(&writer.get_ref()[], b);
519 writer.write_all(&[3]).unwrap();
520 assert_eq!(&writer.get_ref()[], b);
522 writer.flush().unwrap();
523 let a: &[_] = &[0, 1, 2, 3];
524 assert_eq!(a, &writer.get_ref()[]);
526 writer.write_all(&[4]).unwrap();
527 writer.write_all(&[5]).unwrap();
528 assert_eq!(a, &writer.get_ref()[]);
530 writer.write_all(&[6]).unwrap();
531 let a: &[_] = &[0, 1, 2, 3, 4, 5];
532 assert_eq!(a, &writer.get_ref()[]);
534 writer.write_all(&[7, 8]).unwrap();
535 let a: &[_] = &[0, 1, 2, 3, 4, 5, 6];
536 assert_eq!(a, &writer.get_ref()[]);
538 writer.write_all(&[9, 10, 11]).unwrap();
539 let a: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
540 assert_eq!(a, &writer.get_ref()[]);
542 writer.flush().unwrap();
543 assert_eq!(a, &writer.get_ref()[]);
547 fn test_buffered_writer_inner_flushes() {
548 let mut w = BufferedWriter::with_capacity(3, Vec::new());
549 w.write_all(&[0, 1]).unwrap();
551 assert_eq!(a, &w.get_ref()[]);
552 let w = w.into_inner();
553 let a: &[_] = &[0, 1];
554 assert_eq!(a, &w[..]);
557 // This is just here to make sure that we don't infinite loop in the
558 // newtype struct autoderef weirdness
560 fn test_buffered_stream() {
563 impl old_io::Writer for S {
564 fn write_all(&mut self, _: &[u8]) -> old_io::IoResult<()> { Ok(()) }
567 impl old_io::Reader for S {
568 fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<uint> {
569 Err(old_io::standard_error(old_io::EndOfFile))
573 let mut stream = BufferedStream::new(S);
575 assert!(stream.read(&mut buf).is_err());
576 stream.write_all(&buf).unwrap();
577 stream.flush().unwrap();
581 fn test_read_until() {
582 let inner = MemReader::new(vec!(0, 1, 2, 1, 0));
583 let mut reader = BufferedReader::with_capacity(2, inner);
584 assert_eq!(reader.read_until(0), Ok(vec!(0)));
585 assert_eq!(reader.read_until(2), Ok(vec!(1, 2)));
586 assert_eq!(reader.read_until(1), Ok(vec!(1)));
587 assert_eq!(reader.read_until(8), Ok(vec!(0)));
588 assert!(reader.read_until(9).is_err());
592 fn test_line_buffer() {
593 let mut writer = LineBufferedWriter::new(Vec::new());
594 writer.write_all(&[0]).unwrap();
596 assert_eq!(&writer.get_ref()[], b);
597 writer.write_all(&[1]).unwrap();
598 assert_eq!(&writer.get_ref()[], b);
599 writer.flush().unwrap();
600 let b: &[_] = &[0, 1];
601 assert_eq!(&writer.get_ref()[], b);
602 writer.write_all(&[0, b'\n', 1, b'\n', 2]).unwrap();
603 let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n'];
604 assert_eq!(&writer.get_ref()[], b);
605 writer.flush().unwrap();
606 let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n', 2];
607 assert_eq!(&writer.get_ref()[], b);
608 writer.write_all(&[3, b'\n']).unwrap();
609 let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n'];
610 assert_eq!(&writer.get_ref()[], b);
614 fn test_read_line() {
615 let in_buf = MemReader::new(b"a\nb\nc".to_vec());
616 let mut reader = BufferedReader::with_capacity(2, in_buf);
617 assert_eq!(reader.read_line(), Ok("a\n".to_string()));
618 assert_eq!(reader.read_line(), Ok("b\n".to_string()));
619 assert_eq!(reader.read_line(), Ok("c".to_string()));
620 assert!(reader.read_line().is_err());
625 let in_buf = MemReader::new(b"a\nb\nc".to_vec());
626 let mut reader = BufferedReader::with_capacity(2, in_buf);
627 let mut it = reader.lines();
628 assert_eq!(it.next(), Some(Ok("a\n".to_string())));
629 assert_eq!(it.next(), Some(Ok("b\n".to_string())));
630 assert_eq!(it.next(), Some(Ok("c".to_string())));
631 assert_eq!(it.next(), None);
635 fn test_short_reads() {
636 let inner = ShortReader{lengths: vec![0, 1, 2, 0, 1, 0]};
637 let mut reader = BufferedReader::new(inner);
638 let mut buf = [0, 0];
639 assert_eq!(reader.read(&mut buf), Ok(0));
640 assert_eq!(reader.read(&mut buf), Ok(1));
641 assert_eq!(reader.read(&mut buf), Ok(2));
642 assert_eq!(reader.read(&mut buf), Ok(0));
643 assert_eq!(reader.read(&mut buf), Ok(1));
644 assert_eq!(reader.read(&mut buf), Ok(0));
645 assert!(reader.read(&mut buf).is_err());
649 fn read_char_buffered() {
650 let buf = [195, 159];
651 let mut reader = BufferedReader::with_capacity(1, &buf[..]);
652 assert_eq!(reader.read_char(), Ok('ß'));
657 let buf = [195, 159, b'a'];
658 let mut reader = BufferedReader::with_capacity(1, &buf[..]);
659 let mut it = reader.chars();
660 assert_eq!(it.next(), Some(Ok('ß')));
661 assert_eq!(it.next(), Some(Ok('a')));
662 assert_eq!(it.next(), None);
667 fn dont_panic_in_drop_on_panicked_flush() {
668 struct FailFlushWriter;
670 impl Writer for FailFlushWriter {
671 fn write_all(&mut self, _buf: &[u8]) -> IoResult<()> { Ok(()) }
672 fn flush(&mut self) -> IoResult<()> { Err(old_io::standard_error(EndOfFile)) }
675 let writer = FailFlushWriter;
676 let _writer = BufferedWriter::new(writer);
678 // If writer panics *again* due to the flush error then the process will abort.
683 fn bench_buffered_reader(b: &mut Bencher) {
685 BufferedReader::new(NullStream)
690 fn bench_buffered_writer(b: &mut Bencher) {
692 BufferedWriter::new(NullStream)
697 fn bench_buffered_stream(b: &mut Bencher) {
699 BufferedStream::new(NullStream);