]> git.lizzy.rs Git - rust.git/blob - src/libstd/io/buffered.rs
d590aa8419453d6de9ce3ed35c62fba98b719052
[rust.git] / src / libstd / io / buffered.rs
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.
4 //
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.
10 //
11 // ignore-lexer-test FIXME #15883
12
13 //! Buffering wrappers for I/O traits
14
15 use cmp;
16 use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
17 use iter::{IteratorExt, ExactSizeIterator};
18 use ops::Drop;
19 use option::Option;
20 use option::Option::{Some, None};
21 use result::Result::Ok;
22 use slice::{SliceExt};
23 use slice;
24 use vec::Vec;
25
26 // NOTE: for old macros; remove after the next snapshot
27 #[cfg(stage0)] use result::Result::Err;
28
29 /// Wraps a Reader and buffers input from it
30 ///
31 /// It can be excessively inefficient to work directly with a `Reader`. For
32 /// example, every call to `read` on `TcpStream` results in a system call. A
33 /// `BufferedReader` performs large, infrequent reads on the underlying
34 /// `Reader` and maintains an in-memory buffer of the results.
35 ///
36 /// # Example
37 ///
38 /// ```rust
39 /// use std::io::{BufferedReader, File};
40 ///
41 /// let file = File::open(&Path::new("message.txt"));
42 /// let mut reader = BufferedReader::new(file);
43 ///
44 /// let mut buf = [0; 100];
45 /// match reader.read(&mut buf) {
46 ///     Ok(nread) => println!("Read {} bytes", nread),
47 ///     Err(e) => println!("error reading: {}", e)
48 /// }
49 /// ```
50 pub struct BufferedReader<R> {
51     inner: R,
52     buf: Vec<u8>,
53     pos: uint,
54     cap: uint,
55 }
56
57 impl<R: Reader> BufferedReader<R> {
58     /// Creates a new `BufferedReader` with the specified buffer capacity
59     pub fn with_capacity(cap: uint, inner: R) -> BufferedReader<R> {
60         // It's *much* faster to create an uninitialized buffer than it is to
61         // fill everything in with 0. This buffer is entirely an implementation
62         // detail and is never exposed, so we're safe to not initialize
63         // everything up-front. This allows creation of BufferedReader instances
64         // to be very cheap (large mallocs are not nearly as expensive as large
65         // callocs).
66         let mut buf = Vec::with_capacity(cap);
67         unsafe { buf.set_len(cap); }
68         BufferedReader {
69             inner: inner,
70             buf: buf,
71             pos: 0,
72             cap: 0,
73         }
74     }
75
76     /// Creates a new `BufferedReader` with a default buffer capacity
77     pub fn new(inner: R) -> BufferedReader<R> {
78         BufferedReader::with_capacity(DEFAULT_BUF_SIZE, inner)
79     }
80
81     /// Gets a reference to the underlying reader.
82     pub fn get_ref<'a>(&self) -> &R { &self.inner }
83
84     /// Gets a mutable reference to the underlying reader.
85     ///
86     /// # Warning
87     ///
88     /// It is inadvisable to directly read from the underlying reader.
89     pub fn get_mut(&mut self) -> &mut R { &mut self.inner }
90
91     /// Unwraps this `BufferedReader`, returning the underlying reader.
92     ///
93     /// Note that any leftover data in the internal buffer is lost.
94     pub fn into_inner(self) -> R { self.inner }
95 }
96
97 impl<R: Reader> Buffer for BufferedReader<R> {
98     fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
99         if self.pos == self.cap {
100             self.cap = try!(self.inner.read(self.buf.as_mut_slice()));
101             self.pos = 0;
102         }
103         Ok(self.buf[self.pos..self.cap])
104     }
105
106     fn consume(&mut self, amt: uint) {
107         self.pos += amt;
108         assert!(self.pos <= self.cap);
109     }
110 }
111
112 impl<R: Reader> Reader for BufferedReader<R> {
113     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
114         if self.pos == self.cap && buf.len() >= self.buf.capacity() {
115             return self.inner.read(buf);
116         }
117         let nread = {
118             let available = try!(self.fill_buf());
119             let nread = cmp::min(available.len(), buf.len());
120             slice::bytes::copy_memory(buf, available[..nread]);
121             nread
122         };
123         self.pos += nread;
124         Ok(nread)
125     }
126 }
127
128 /// Wraps a Writer and buffers output to it
129 ///
130 /// It can be excessively inefficient to work directly with a `Writer`. For
131 /// example, every call to `write` on `TcpStream` results in a system call. A
132 /// `BufferedWriter` keeps an in memory buffer of data and writes it to the
133 /// underlying `Writer` in large, infrequent batches.
134 ///
135 /// This writer will be flushed when it is dropped.
136 ///
137 /// # Example
138 ///
139 /// ```rust
140 /// use std::io::{BufferedWriter, File};
141 ///
142 /// let file = File::create(&Path::new("message.txt")).unwrap();
143 /// let mut writer = BufferedWriter::new(file);
144 ///
145 /// writer.write_str("hello, world").unwrap();
146 /// writer.flush().unwrap();
147 /// ```
148 pub struct BufferedWriter<W> {
149     inner: Option<W>,
150     buf: Vec<u8>,
151     pos: uint
152 }
153
154 impl<W: Writer> BufferedWriter<W> {
155     /// Creates a new `BufferedWriter` with the specified buffer capacity
156     pub fn with_capacity(cap: uint, inner: W) -> BufferedWriter<W> {
157         // See comments in BufferedReader for why this uses unsafe code.
158         let mut buf = Vec::with_capacity(cap);
159         unsafe { buf.set_len(cap); }
160         BufferedWriter {
161             inner: Some(inner),
162             buf: buf,
163             pos: 0
164         }
165     }
166
167     /// Creates a new `BufferedWriter` with a default buffer capacity
168     pub fn new(inner: W) -> BufferedWriter<W> {
169         BufferedWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
170     }
171
172     fn flush_buf(&mut self) -> IoResult<()> {
173         if self.pos != 0 {
174             let ret = self.inner.as_mut().unwrap().write(self.buf[..self.pos]);
175             self.pos = 0;
176             ret
177         } else {
178             Ok(())
179         }
180     }
181
182     /// Gets a reference to the underlying writer.
183     pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() }
184
185     /// Gets a mutable reference to the underlying write.
186     ///
187     /// # Warning
188     ///
189     /// It is inadvisable to directly read from the underlying writer.
190     pub fn get_mut(&mut self) -> &mut W { self.inner.as_mut().unwrap() }
191
192     /// Unwraps this `BufferedWriter`, returning the underlying writer.
193     ///
194     /// The buffer is flushed before returning the writer.
195     pub fn into_inner(mut self) -> W {
196         // FIXME(#12628): is panicking the right thing to do if flushing panicks?
197         self.flush_buf().unwrap();
198         self.inner.take().unwrap()
199     }
200 }
201
202 impl<W: Writer> Writer for BufferedWriter<W> {
203     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
204         if self.pos + buf.len() > self.buf.len() {
205             try!(self.flush_buf());
206         }
207
208         if buf.len() > self.buf.len() {
209             self.inner.as_mut().unwrap().write(buf)
210         } else {
211             let dst = self.buf.slice_from_mut(self.pos);
212             slice::bytes::copy_memory(dst, buf);
213             self.pos += buf.len();
214             Ok(())
215         }
216     }
217
218     fn flush(&mut self) -> IoResult<()> {
219         self.flush_buf().and_then(|()| self.inner.as_mut().unwrap().flush())
220     }
221 }
222
223 #[unsafe_destructor]
224 impl<W: Writer> Drop for BufferedWriter<W> {
225     fn drop(&mut self) {
226         if self.inner.is_some() {
227             // dtors should not panic, so we ignore a panicked flush
228             let _ = self.flush_buf();
229         }
230     }
231 }
232
233 /// Wraps a Writer and buffers output to it, flushing whenever a newline (`0x0a`,
234 /// `'\n'`) is detected.
235 ///
236 /// This writer will be flushed when it is dropped.
237 pub struct LineBufferedWriter<W> {
238     inner: BufferedWriter<W>,
239 }
240
241 impl<W: Writer> LineBufferedWriter<W> {
242     /// Creates a new `LineBufferedWriter`
243     pub fn new(inner: W) -> LineBufferedWriter<W> {
244         // Lines typically aren't that long, don't use a giant buffer
245         LineBufferedWriter {
246             inner: BufferedWriter::with_capacity(1024, inner)
247         }
248     }
249
250     /// Gets a reference to the underlying writer.
251     ///
252     /// This type does not expose the ability to get a mutable reference to the
253     /// underlying reader because that could possibly corrupt the buffer.
254     pub fn get_ref<'a>(&'a self) -> &'a W { self.inner.get_ref() }
255
256     /// Unwraps this `LineBufferedWriter`, returning the underlying writer.
257     ///
258     /// The internal buffer is flushed before returning the writer.
259     pub fn into_inner(self) -> W { self.inner.into_inner() }
260 }
261
262 impl<W: Writer> Writer for LineBufferedWriter<W> {
263     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
264         match buf.iter().rposition(|&b| b == b'\n') {
265             Some(i) => {
266                 try!(self.inner.write(buf[..i + 1]));
267                 try!(self.inner.flush());
268                 try!(self.inner.write(buf[i + 1..]));
269                 Ok(())
270             }
271             None => self.inner.write(buf),
272         }
273     }
274
275     fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
276 }
277
278 struct InternalBufferedWriter<W>(BufferedWriter<W>);
279
280 impl<W> InternalBufferedWriter<W> {
281     fn get_mut<'a>(&'a mut self) -> &'a mut BufferedWriter<W> {
282         let InternalBufferedWriter(ref mut w) = *self;
283         return w;
284     }
285 }
286
287 impl<W: Reader> Reader for InternalBufferedWriter<W> {
288     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
289         self.get_mut().inner.as_mut().unwrap().read(buf)
290     }
291 }
292
293 /// Wraps a Stream and buffers input and output to and from it.
294 ///
295 /// It can be excessively inefficient to work directly with a `Stream`. For
296 /// example, every call to `read` or `write` on `TcpStream` results in a system
297 /// call. A `BufferedStream` keeps in memory buffers of data, making large,
298 /// infrequent calls to `read` and `write` on the underlying `Stream`.
299 ///
300 /// The output half will be flushed when this stream is dropped.
301 ///
302 /// # Example
303 ///
304 /// ```rust
305 /// # #![allow(unused_must_use)]
306 /// use std::io::{BufferedStream, File};
307 ///
308 /// let file = File::open(&Path::new("message.txt"));
309 /// let mut stream = BufferedStream::new(file);
310 ///
311 /// stream.write("hello, world".as_bytes());
312 /// stream.flush();
313 ///
314 /// let mut buf = [0; 100];
315 /// match stream.read(&mut buf) {
316 ///     Ok(nread) => println!("Read {} bytes", nread),
317 ///     Err(e) => println!("error reading: {}", e)
318 /// }
319 /// ```
320 pub struct BufferedStream<S> {
321     inner: BufferedReader<InternalBufferedWriter<S>>
322 }
323
324 impl<S: Stream> BufferedStream<S> {
325     /// Creates a new buffered stream with explicitly listed capacities for the
326     /// reader/writer buffer.
327     pub fn with_capacities(reader_cap: uint, writer_cap: uint, inner: S)
328                            -> BufferedStream<S> {
329         let writer = BufferedWriter::with_capacity(writer_cap, inner);
330         let internal_writer = InternalBufferedWriter(writer);
331         let reader = BufferedReader::with_capacity(reader_cap,
332                                                    internal_writer);
333         BufferedStream { inner: reader }
334     }
335
336     /// Creates a new buffered stream with the default reader/writer buffer
337     /// capacities.
338     pub fn new(inner: S) -> BufferedStream<S> {
339         BufferedStream::with_capacities(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE,
340                                         inner)
341     }
342
343     /// Gets a reference to the underlying stream.
344     pub fn get_ref(&self) -> &S {
345         let InternalBufferedWriter(ref w) = self.inner.inner;
346         w.get_ref()
347     }
348
349     /// Gets a mutable reference to the underlying stream.
350     ///
351     /// # Warning
352     ///
353     /// It is inadvisable to read directly from or write directly to the
354     /// underlying stream.
355     pub fn get_mut(&mut self) -> &mut S {
356         let InternalBufferedWriter(ref mut w) = self.inner.inner;
357         w.get_mut()
358     }
359
360     /// Unwraps this `BufferedStream`, returning the underlying stream.
361     ///
362     /// The internal buffer is flushed before returning the stream. Any leftover
363     /// data in the read buffer is lost.
364     pub fn into_inner(self) -> S {
365         let InternalBufferedWriter(w) = self.inner.inner;
366         w.into_inner()
367     }
368 }
369
370 impl<S: Stream> Buffer for BufferedStream<S> {
371     fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
372     fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
373 }
374
375 impl<S: Stream> Reader for BufferedStream<S> {
376     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
377         self.inner.read(buf)
378     }
379 }
380
381 impl<S: Stream> Writer for BufferedStream<S> {
382     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
383         self.inner.inner.get_mut().write(buf)
384     }
385     fn flush(&mut self) -> IoResult<()> {
386         self.inner.inner.get_mut().flush()
387     }
388 }
389
390 #[cfg(test)]
391 mod test {
392     extern crate test;
393     use io;
394     use prelude::v1::*;
395     use super::*;
396     use super::super::{IoResult, EndOfFile};
397     use super::super::mem::MemReader;
398     use self::test::Bencher;
399
400     /// A type, free to create, primarily intended for benchmarking creation of
401     /// wrappers that, just for construction, don't need a Reader/Writer that
402     /// does anything useful. Is equivalent to `/dev/null` in semantics.
403     #[derive(Clone,PartialEq,PartialOrd)]
404     pub struct NullStream;
405
406     impl Reader for NullStream {
407         fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
408             Err(io::standard_error(io::EndOfFile))
409         }
410     }
411
412     impl Writer for NullStream {
413         fn write(&mut self, _: &[u8]) -> io::IoResult<()> { Ok(()) }
414     }
415
416     /// A dummy reader intended at testing short-reads propagation.
417     pub struct ShortReader {
418         lengths: Vec<uint>,
419     }
420
421     impl Reader for ShortReader {
422         fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
423             if self.lengths.is_empty() {
424                 Err(io::standard_error(io::EndOfFile))
425             } else {
426                 Ok(self.lengths.remove(0))
427             }
428         }
429     }
430
431     #[test]
432     fn test_buffered_reader() {
433         let inner = MemReader::new(vec!(5, 6, 7, 0, 1, 2, 3, 4));
434         let mut reader = BufferedReader::with_capacity(2, inner);
435
436         let mut buf = [0, 0, 0];
437         let nread = reader.read(&mut buf);
438         assert_eq!(Ok(3), nread);
439         let b: &[_] = &[5, 6, 7];
440         assert_eq!(buf, b);
441
442         let mut buf = [0, 0];
443         let nread = reader.read(&mut buf);
444         assert_eq!(Ok(2), nread);
445         let b: &[_] = &[0, 1];
446         assert_eq!(buf, b);
447
448         let mut buf = [0];
449         let nread = reader.read(&mut buf);
450         assert_eq!(Ok(1), nread);
451         let b: &[_] = &[2];
452         assert_eq!(buf, b);
453
454         let mut buf = [0, 0, 0];
455         let nread = reader.read(&mut buf);
456         assert_eq!(Ok(1), nread);
457         let b: &[_] = &[3, 0, 0];
458         assert_eq!(buf, b);
459
460         let nread = reader.read(&mut buf);
461         assert_eq!(Ok(1), nread);
462         let b: &[_] = &[4, 0, 0];
463         assert_eq!(buf, b);
464
465         assert!(reader.read(&mut buf).is_err());
466     }
467
468     #[test]
469     fn test_buffered_writer() {
470         let inner = Vec::new();
471         let mut writer = BufferedWriter::with_capacity(2, inner);
472
473         writer.write(&[0, 1]).unwrap();
474         let b: &[_] = &[];
475         assert_eq!(writer.get_ref()[], b);
476
477         writer.write(&[2]).unwrap();
478         let b: &[_] = &[0, 1];
479         assert_eq!(writer.get_ref()[], b);
480
481         writer.write(&[3]).unwrap();
482         assert_eq!(writer.get_ref()[], b);
483
484         writer.flush().unwrap();
485         let a: &[_] = &[0, 1, 2, 3];
486         assert_eq!(a, writer.get_ref()[]);
487
488         writer.write(&[4]).unwrap();
489         writer.write(&[5]).unwrap();
490         assert_eq!(a, writer.get_ref()[]);
491
492         writer.write(&[6]).unwrap();
493         let a: &[_] = &[0, 1, 2, 3, 4, 5];
494         assert_eq!(a,
495                    writer.get_ref()[]);
496
497         writer.write(&[7, 8]).unwrap();
498         let a: &[_] = &[0, 1, 2, 3, 4, 5, 6];
499         assert_eq!(a,
500                    writer.get_ref()[]);
501
502         writer.write(&[9, 10, 11]).unwrap();
503         let a: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
504         assert_eq!(a,
505                    writer.get_ref()[]);
506
507         writer.flush().unwrap();
508         assert_eq!(a,
509                    writer.get_ref()[]);
510     }
511
512     #[test]
513     fn test_buffered_writer_inner_flushes() {
514         let mut w = BufferedWriter::with_capacity(3, Vec::new());
515         w.write(&[0, 1]).unwrap();
516         let a: &[_] = &[];
517         assert_eq!(a, w.get_ref()[]);
518         let w = w.into_inner();
519         let a: &[_] = &[0, 1];
520         assert_eq!(a, w[]);
521     }
522
523     // This is just here to make sure that we don't infinite loop in the
524     // newtype struct autoderef weirdness
525     #[test]
526     fn test_buffered_stream() {
527         struct S;
528
529         impl io::Writer for S {
530             fn write(&mut self, _: &[u8]) -> io::IoResult<()> { Ok(()) }
531         }
532
533         impl io::Reader for S {
534             fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
535                 Err(io::standard_error(io::EndOfFile))
536             }
537         }
538
539         let mut stream = BufferedStream::new(S);
540         let mut buf = [];
541         assert!(stream.read(&mut buf).is_err());
542         stream.write(&buf).unwrap();
543         stream.flush().unwrap();
544     }
545
546     #[test]
547     fn test_read_until() {
548         let inner = MemReader::new(vec!(0, 1, 2, 1, 0));
549         let mut reader = BufferedReader::with_capacity(2, inner);
550         assert_eq!(reader.read_until(0), Ok(vec!(0)));
551         assert_eq!(reader.read_until(2), Ok(vec!(1, 2)));
552         assert_eq!(reader.read_until(1), Ok(vec!(1)));
553         assert_eq!(reader.read_until(8), Ok(vec!(0)));
554         assert!(reader.read_until(9).is_err());
555     }
556
557     #[test]
558     fn test_line_buffer() {
559         let mut writer = LineBufferedWriter::new(Vec::new());
560         writer.write(&[0]).unwrap();
561         let b: &[_] = &[];
562         assert_eq!(writer.get_ref()[], b);
563         writer.write(&[1]).unwrap();
564         assert_eq!(writer.get_ref()[], b);
565         writer.flush().unwrap();
566         let b: &[_] = &[0, 1];
567         assert_eq!(writer.get_ref()[], b);
568         writer.write(&[0, b'\n', 1, b'\n', 2]).unwrap();
569         let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n'];
570         assert_eq!(writer.get_ref()[], b);
571         writer.flush().unwrap();
572         let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n', 2];
573         assert_eq!(writer.get_ref()[], b);
574         writer.write(&[3, b'\n']).unwrap();
575         let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n'];
576         assert_eq!(writer.get_ref()[], b);
577     }
578
579     #[test]
580     fn test_read_line() {
581         let in_buf = MemReader::new(b"a\nb\nc".to_vec());
582         let mut reader = BufferedReader::with_capacity(2, in_buf);
583         assert_eq!(reader.read_line(), Ok("a\n".to_string()));
584         assert_eq!(reader.read_line(), Ok("b\n".to_string()));
585         assert_eq!(reader.read_line(), Ok("c".to_string()));
586         assert!(reader.read_line().is_err());
587     }
588
589     #[test]
590     fn test_lines() {
591         let in_buf = MemReader::new(b"a\nb\nc".to_vec());
592         let mut reader = BufferedReader::with_capacity(2, in_buf);
593         let mut it = reader.lines();
594         assert_eq!(it.next(), Some(Ok("a\n".to_string())));
595         assert_eq!(it.next(), Some(Ok("b\n".to_string())));
596         assert_eq!(it.next(), Some(Ok("c".to_string())));
597         assert_eq!(it.next(), None);
598     }
599
600     #[test]
601     fn test_short_reads() {
602         let inner = ShortReader{lengths: vec![0, 1, 2, 0, 1, 0]};
603         let mut reader = BufferedReader::new(inner);
604         let mut buf = [0, 0];
605         assert_eq!(reader.read(&mut buf), Ok(0));
606         assert_eq!(reader.read(&mut buf), Ok(1));
607         assert_eq!(reader.read(&mut buf), Ok(2));
608         assert_eq!(reader.read(&mut buf), Ok(0));
609         assert_eq!(reader.read(&mut buf), Ok(1));
610         assert_eq!(reader.read(&mut buf), Ok(0));
611         assert!(reader.read(&mut buf).is_err());
612     }
613
614     #[test]
615     fn read_char_buffered() {
616         let buf = [195u8, 159u8];
617         let mut reader = BufferedReader::with_capacity(1, buf[]);
618         assert_eq!(reader.read_char(), Ok('ß'));
619     }
620
621     #[test]
622     fn test_chars() {
623         let buf = [195u8, 159u8, b'a'];
624         let mut reader = BufferedReader::with_capacity(1, buf[]);
625         let mut it = reader.chars();
626         assert_eq!(it.next(), Some(Ok('ß')));
627         assert_eq!(it.next(), Some(Ok('a')));
628         assert_eq!(it.next(), None);
629     }
630
631     #[test]
632     #[should_fail]
633     fn dont_panic_in_drop_on_panicked_flush() {
634         struct FailFlushWriter;
635
636         impl Writer for FailFlushWriter {
637             fn write(&mut self, _buf: &[u8]) -> IoResult<()> { Ok(()) }
638             fn flush(&mut self) -> IoResult<()> { Err(io::standard_error(EndOfFile)) }
639         }
640
641         let writer = FailFlushWriter;
642         let _writer = BufferedWriter::new(writer);
643
644         // If writer panics *again* due to the flush error then the process will abort.
645         panic!();
646     }
647
648     #[bench]
649     fn bench_buffered_reader(b: &mut Bencher) {
650         b.iter(|| {
651             BufferedReader::new(NullStream)
652         });
653     }
654
655     #[bench]
656     fn bench_buffered_writer(b: &mut Bencher) {
657         b.iter(|| {
658             BufferedWriter::new(NullStream)
659         });
660     }
661
662     #[bench]
663     fn bench_buffered_stream(b: &mut Bencher) {
664         b.iter(|| {
665             BufferedStream::new(NullStream);
666         });
667     }
668 }