]> git.lizzy.rs Git - rust.git/blob - src/libstd/old_io/buffered.rs
check: Reword the warning to be more prescriptive
[rust.git] / src / libstd / old_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 fmt;
17 use old_io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
18 use iter::{IteratorExt, ExactSizeIterator, repeat};
19 use ops::Drop;
20 use option::Option;
21 use option::Option::{Some, None};
22 use result::Result::Ok;
23 use slice;
24 use vec::Vec;
25
26 /// Wraps a Reader and buffers input from it
27 ///
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.
32 ///
33 /// # Examples
34 ///
35 /// ```
36 /// # #![feature(old_io, old_path)]
37 /// use std::old_io::*;
38 /// use std::old_path::Path;
39 ///
40 /// let file = File::open(&Path::new("message.txt"));
41 /// let mut reader = BufferedReader::new(file);
42 ///
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)
47 /// }
48 /// ```
49 pub struct BufferedReader<R> {
50     inner: R,
51     buf: Vec<u8>,
52     pos: uint,
53     cap: uint,
54 }
55
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())
61     }
62 }
63
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> {
67         BufferedReader {
68             inner: inner,
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(),
72             pos: 0,
73             cap: 0,
74         }
75     }
76
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)
80     }
81
82     /// Gets a reference to the underlying reader.
83     pub fn get_ref<'a>(&self) -> &R { &self.inner }
84
85     /// Gets a mutable reference to the underlying reader.
86     ///
87     /// # Warning
88     ///
89     /// It is inadvisable to directly read from the underlying reader.
90     pub fn get_mut(&mut self) -> &mut R { &mut self.inner }
91
92     /// Unwraps this `BufferedReader`, returning the underlying reader.
93     ///
94     /// Note that any leftover data in the internal buffer is lost.
95     pub fn into_inner(self) -> R { self.inner }
96 }
97
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));
102             self.pos = 0;
103         }
104         Ok(&self.buf[self.pos..self.cap])
105     }
106
107     fn consume(&mut self, amt: uint) {
108         self.pos += amt;
109         assert!(self.pos <= self.cap);
110     }
111 }
112
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);
117         }
118         let nread = {
119             let available = try!(self.fill_buf());
120             let nread = cmp::min(available.len(), buf.len());
121             slice::bytes::copy_memory(buf, &available[..nread]);
122             nread
123         };
124         self.pos += nread;
125         Ok(nread)
126     }
127 }
128
129 /// Wraps a Writer and buffers output to it
130 ///
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.
135 ///
136 /// This writer will be flushed when it is dropped.
137 ///
138 /// # Examples
139 ///
140 /// ```
141 /// # #![feature(old_io, old_path)]
142 /// use std::old_io::*;
143 /// use std::old_path::Path;
144 ///
145 /// let file = File::create(&Path::new("message.txt")).unwrap();
146 /// let mut writer = BufferedWriter::new(file);
147 ///
148 /// writer.write_str("hello, world").unwrap();
149 /// writer.flush().unwrap();
150 /// ```
151 pub struct BufferedWriter<W: Writer> {
152     inner: Option<W>,
153     buf: Vec<u8>,
154     pos: uint
155 }
156
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())
162     }
163 }
164
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
173         // callocs).
174         let mut buf = Vec::with_capacity(cap);
175         unsafe { buf.set_len(cap); }
176         BufferedWriter {
177             inner: Some(inner),
178             buf: buf,
179             pos: 0
180         }
181     }
182
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)
186     }
187
188     fn flush_buf(&mut self) -> IoResult<()> {
189         if self.pos != 0 {
190             let ret = self.inner.as_mut().unwrap().write_all(&self.buf[..self.pos]);
191             self.pos = 0;
192             ret
193         } else {
194             Ok(())
195         }
196     }
197
198     /// Gets a reference to the underlying writer.
199     pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() }
200
201     /// Gets a mutable reference to the underlying write.
202     ///
203     /// # Warning
204     ///
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() }
207
208     /// Unwraps this `BufferedWriter`, returning the underlying writer.
209     ///
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()
215     }
216 }
217
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());
222         }
223
224         if buf.len() > self.buf.len() {
225             self.inner.as_mut().unwrap().write_all(buf)
226         } else {
227             let dst = &mut self.buf[self.pos..];
228             slice::bytes::copy_memory(dst, buf);
229             self.pos += buf.len();
230             Ok(())
231         }
232     }
233
234     fn flush(&mut self) -> IoResult<()> {
235         self.flush_buf().and_then(|()| self.inner.as_mut().unwrap().flush())
236     }
237 }
238
239 #[unsafe_destructor]
240 impl<W: Writer> Drop for BufferedWriter<W> {
241     fn drop(&mut self) {
242         if self.inner.is_some() {
243             // dtors should not panic, so we ignore a panicked flush
244             let _ = self.flush_buf();
245         }
246     }
247 }
248
249 /// Wraps a Writer and buffers output to it, flushing whenever a newline (`0x0a`,
250 /// `'\n'`) is detected.
251 ///
252 /// This writer will be flushed when it is dropped.
253 pub struct LineBufferedWriter<W: Writer> {
254     inner: BufferedWriter<W>,
255 }
256
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())
262     }
263 }
264
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
269         LineBufferedWriter {
270             inner: BufferedWriter::with_capacity(1024, inner)
271         }
272     }
273
274     /// Gets a reference to the underlying writer.
275     ///
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() }
279
280     /// Unwraps this `LineBufferedWriter`, returning the underlying writer.
281     ///
282     /// The internal buffer is flushed before returning the writer.
283     pub fn into_inner(self) -> W { self.inner.into_inner() }
284 }
285
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') {
289             Some(i) => {
290                 try!(self.inner.write_all(&buf[..i + 1]));
291                 try!(self.inner.flush());
292                 try!(self.inner.write_all(&buf[i + 1..]));
293                 Ok(())
294             }
295             None => self.inner.write_all(buf),
296         }
297     }
298
299     fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
300 }
301
302 struct InternalBufferedWriter<W: Writer>(BufferedWriter<W>);
303
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;
307         return w;
308     }
309 }
310
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)
314     }
315 }
316
317 /// Wraps a Stream and buffers input and output to and from it.
318 ///
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`.
323 ///
324 /// The output half will be flushed when this stream is dropped.
325 ///
326 /// # Examples
327 ///
328 /// ```
329 /// # #![feature(old_io, old_path)]
330 /// # #![allow(unused_must_use)]
331 /// use std::old_io::*;
332 /// use std::old_path::Path;
333 ///
334 /// let file = File::open(&Path::new("message.txt"));
335 /// let mut stream = BufferedStream::new(file);
336 ///
337 /// stream.write_all("hello, world".as_bytes());
338 /// stream.flush();
339 ///
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)
344 /// }
345 /// ```
346 pub struct BufferedStream<S: Writer> {
347     inner: BufferedReader<InternalBufferedWriter<S>>
348 }
349
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: {}/{} }}",
356                writer.inner,
357                writer.pos, writer.buf.len(),
358                reader.cap - reader.pos, reader.buf.len())
359     }
360 }
361
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,
370                                                    internal_writer);
371         BufferedStream { inner: reader }
372     }
373
374     /// Creates a new buffered stream with the default reader/writer buffer
375     /// capacities.
376     pub fn new(inner: S) -> BufferedStream<S> {
377         BufferedStream::with_capacities(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE,
378                                         inner)
379     }
380
381     /// Gets a reference to the underlying stream.
382     pub fn get_ref(&self) -> &S {
383         let InternalBufferedWriter(ref w) = self.inner.inner;
384         w.get_ref()
385     }
386
387     /// Gets a mutable reference to the underlying stream.
388     ///
389     /// # Warning
390     ///
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;
395         w.get_mut()
396     }
397
398     /// Unwraps this `BufferedStream`, returning the underlying stream.
399     ///
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;
404         w.into_inner()
405     }
406 }
407
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) }
411 }
412
413 impl<S: Stream> Reader for BufferedStream<S> {
414     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
415         self.inner.read(buf)
416     }
417 }
418
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)
422     }
423     fn flush(&mut self) -> IoResult<()> {
424         self.inner.inner.get_mut().flush()
425     }
426 }
427
428 #[cfg(test)]
429 mod test {
430     extern crate test;
431     use old_io::{self, Reader, Writer, Buffer, BufferPrelude};
432     use prelude::v1::*;
433     use super::*;
434     use super::super::{IoResult, EndOfFile};
435     use super::super::mem::MemReader;
436     use self::test::Bencher;
437
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;
443
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))
447         }
448     }
449
450     impl Writer for NullStream {
451         fn write_all(&mut self, _: &[u8]) -> old_io::IoResult<()> { Ok(()) }
452     }
453
454     /// A dummy reader intended at testing short-reads propagation.
455     pub struct ShortReader {
456         lengths: Vec<uint>,
457     }
458
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))
463             } else {
464                 Ok(self.lengths.remove(0))
465             }
466         }
467     }
468
469     #[test]
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);
473
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];
478         assert_eq!(buf, b);
479
480         let mut buf = [0, 0];
481         let nread = reader.read(&mut buf);
482         assert_eq!(Ok(2), nread);
483         let b: &[_] = &[0, 1];
484         assert_eq!(buf, b);
485
486         let mut buf = [0];
487         let nread = reader.read(&mut buf);
488         assert_eq!(Ok(1), nread);
489         let b: &[_] = &[2];
490         assert_eq!(buf, b);
491
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];
496         assert_eq!(buf, b);
497
498         let nread = reader.read(&mut buf);
499         assert_eq!(Ok(1), nread);
500         let b: &[_] = &[4, 0, 0];
501         assert_eq!(buf, b);
502
503         assert!(reader.read(&mut buf).is_err());
504     }
505
506     #[test]
507     fn test_buffered_writer() {
508         let inner = Vec::new();
509         let mut writer = BufferedWriter::with_capacity(2, inner);
510
511         writer.write_all(&[0, 1]).unwrap();
512         let b: &[_] = &[];
513         assert_eq!(&writer.get_ref()[], b);
514
515         writer.write_all(&[2]).unwrap();
516         let b: &[_] = &[0, 1];
517         assert_eq!(&writer.get_ref()[], b);
518
519         writer.write_all(&[3]).unwrap();
520         assert_eq!(&writer.get_ref()[], b);
521
522         writer.flush().unwrap();
523         let a: &[_] = &[0, 1, 2, 3];
524         assert_eq!(a, &writer.get_ref()[]);
525
526         writer.write_all(&[4]).unwrap();
527         writer.write_all(&[5]).unwrap();
528         assert_eq!(a, &writer.get_ref()[]);
529
530         writer.write_all(&[6]).unwrap();
531         let a: &[_] = &[0, 1, 2, 3, 4, 5];
532         assert_eq!(a, &writer.get_ref()[]);
533
534         writer.write_all(&[7, 8]).unwrap();
535         let a: &[_] = &[0, 1, 2, 3, 4, 5, 6];
536         assert_eq!(a, &writer.get_ref()[]);
537
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()[]);
541
542         writer.flush().unwrap();
543         assert_eq!(a, &writer.get_ref()[]);
544     }
545
546     #[test]
547     fn test_buffered_writer_inner_flushes() {
548         let mut w = BufferedWriter::with_capacity(3, Vec::new());
549         w.write_all(&[0, 1]).unwrap();
550         let a: &[_] = &[];
551         assert_eq!(a, &w.get_ref()[]);
552         let w = w.into_inner();
553         let a: &[_] = &[0, 1];
554         assert_eq!(a, &w[..]);
555     }
556
557     // This is just here to make sure that we don't infinite loop in the
558     // newtype struct autoderef weirdness
559     #[test]
560     fn test_buffered_stream() {
561         struct S;
562
563         impl old_io::Writer for S {
564             fn write_all(&mut self, _: &[u8]) -> old_io::IoResult<()> { Ok(()) }
565         }
566
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))
570             }
571         }
572
573         let mut stream = BufferedStream::new(S);
574         let mut buf = [];
575         assert!(stream.read(&mut buf).is_err());
576         stream.write_all(&buf).unwrap();
577         stream.flush().unwrap();
578     }
579
580     #[test]
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());
589     }
590
591     #[test]
592     fn test_line_buffer() {
593         let mut writer = LineBufferedWriter::new(Vec::new());
594         writer.write_all(&[0]).unwrap();
595         let b: &[_] = &[];
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);
611     }
612
613     #[test]
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());
621     }
622
623     #[test]
624     fn test_lines() {
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);
632     }
633
634     #[test]
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());
646     }
647
648     #[test]
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('ß'));
653     }
654
655     #[test]
656     fn test_chars() {
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);
663     }
664
665     #[test]
666     #[should_panic]
667     fn dont_panic_in_drop_on_panicked_flush() {
668         struct FailFlushWriter;
669
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)) }
673         }
674
675         let writer = FailFlushWriter;
676         let _writer = BufferedWriter::new(writer);
677
678         // If writer panics *again* due to the flush error then the process will abort.
679         panic!();
680     }
681
682     #[bench]
683     fn bench_buffered_reader(b: &mut Bencher) {
684         b.iter(|| {
685             BufferedReader::new(NullStream)
686         });
687     }
688
689     #[bench]
690     fn bench_buffered_writer(b: &mut Bencher) {
691         b.iter(|| {
692             BufferedWriter::new(NullStream)
693         });
694     }
695
696     #[bench]
697     fn bench_buffered_stream(b: &mut Bencher) {
698         b.iter(|| {
699             BufferedStream::new(NullStream);
700         });
701     }
702 }