]> git.proxmox.com Git - rustc.git/blame - src/libstd/old_io/buffered.rs
Imported Upstream version 1.0.0~beta
[rustc.git] / src / libstd / old_io / buffered.rs
CommitLineData
85aaf69f
SL
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
15use cmp;
16use fmt;
17use old_io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
c34b1796 18use iter::{Iterator, ExactSizeIterator, repeat};
85aaf69f
SL
19use ops::Drop;
20use option::Option;
21use option::Option::{Some, None};
22use result::Result::Ok;
85aaf69f
SL
23use slice;
24use 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///
c34b1796 33/// # Examples
85aaf69f 34///
c34b1796
AL
35/// ```
36/// # #![feature(old_io, old_path)]
37/// use std::old_io::*;
38/// use std::old_path::Path;
85aaf69f
SL
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/// ```
49pub struct BufferedReader<R> {
50 inner: R,
51 buf: Vec<u8>,
c34b1796
AL
52 pos: usize,
53 cap: usize,
85aaf69f
SL
54}
55
56#[stable(feature = "rust1", since = "1.0.0")]
57impl<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
64impl<R: Reader> BufferedReader<R> {
65 /// Creates a new `BufferedReader` with the specified buffer capacity
c34b1796 66 pub fn with_capacity(cap: usize, inner: R) -> BufferedReader<R> {
85aaf69f
SL
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
98impl<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
c34b1796 107 fn consume(&mut self, amt: usize) {
85aaf69f
SL
108 self.pos += amt;
109 assert!(self.pos <= self.cap);
110 }
111}
112
113impl<R: Reader> Reader for BufferedReader<R> {
c34b1796 114 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
85aaf69f
SL
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());
c34b1796 121 slice::bytes::copy_memory(&available[..nread], buf);
85aaf69f
SL
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///
c34b1796 138/// # Examples
85aaf69f 139///
c34b1796
AL
140/// ```
141/// # #![feature(old_io, old_path)]
142/// use std::old_io::*;
143/// use std::old_path::Path;
85aaf69f
SL
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/// ```
c34b1796 151pub struct BufferedWriter<W: Writer> {
85aaf69f
SL
152 inner: Option<W>,
153 buf: Vec<u8>,
c34b1796 154 pos: usize
85aaf69f
SL
155}
156
157#[stable(feature = "rust1", since = "1.0.0")]
c34b1796 158impl<W: Writer> fmt::Debug for BufferedWriter<W> where W: fmt::Debug {
85aaf69f
SL
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
165impl<W: Writer> BufferedWriter<W> {
166 /// Creates a new `BufferedWriter` with the specified buffer capacity
c34b1796 167 pub fn with_capacity(cap: usize, inner: W) -> BufferedWriter<W> {
85aaf69f
SL
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
218impl<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..];
c34b1796 228 slice::bytes::copy_memory(buf, dst);
85aaf69f
SL
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]
240impl<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.
c34b1796 253pub struct LineBufferedWriter<W: Writer> {
85aaf69f
SL
254 inner: BufferedWriter<W>,
255}
256
257#[stable(feature = "rust1", since = "1.0.0")]
c34b1796 258impl<W: Writer> fmt::Debug for LineBufferedWriter<W> where W: fmt::Debug {
85aaf69f
SL
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
265impl<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
286impl<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
c34b1796 302struct InternalBufferedWriter<W: Writer>(BufferedWriter<W>);
85aaf69f 303
c34b1796 304impl<W: Writer> InternalBufferedWriter<W> {
85aaf69f
SL
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
c34b1796
AL
311impl<W: Reader + Writer> Reader for InternalBufferedWriter<W> {
312 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
85aaf69f
SL
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///
c34b1796 326/// # Examples
85aaf69f 327///
c34b1796
AL
328/// ```
329/// # #![feature(old_io, old_path)]
85aaf69f 330/// # #![allow(unused_must_use)]
c34b1796
AL
331/// use std::old_io::*;
332/// use std::old_path::Path;
85aaf69f
SL
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/// ```
c34b1796 346pub struct BufferedStream<S: Writer> {
85aaf69f
SL
347 inner: BufferedReader<InternalBufferedWriter<S>>
348}
349
350#[stable(feature = "rust1", since = "1.0.0")]
c34b1796 351impl<S: Writer> fmt::Debug for BufferedStream<S> where S: fmt::Debug {
85aaf69f
SL
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
362impl<S: Stream> BufferedStream<S> {
363 /// Creates a new buffered stream with explicitly listed capacities for the
364 /// reader/writer buffer.
c34b1796 365 pub fn with_capacities(reader_cap: usize, writer_cap: usize, inner: S)
85aaf69f
SL
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
408impl<S: Stream> Buffer for BufferedStream<S> {
409 fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
c34b1796 410 fn consume(&mut self, amt: usize) { self.inner.consume(amt) }
85aaf69f
SL
411}
412
413impl<S: Stream> Reader for BufferedStream<S> {
c34b1796 414 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
85aaf69f
SL
415 self.inner.read(buf)
416 }
417}
418
419impl<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)]
429mod test {
430 extern crate test;
c34b1796 431 use old_io::{self, Reader, Writer, Buffer, BufferPrelude};
85aaf69f
SL
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 {
c34b1796 445 fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
85aaf69f
SL
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 {
c34b1796 456 lengths: Vec<usize>,
85aaf69f
SL
457 }
458
459 impl Reader for ShortReader {
c34b1796 460 fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
85aaf69f
SL
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: &[_] = &[];
c34b1796 513 assert_eq!(&writer.get_ref()[..], b);
85aaf69f
SL
514
515 writer.write_all(&[2]).unwrap();
516 let b: &[_] = &[0, 1];
c34b1796 517 assert_eq!(&writer.get_ref()[..], b);
85aaf69f
SL
518
519 writer.write_all(&[3]).unwrap();
c34b1796 520 assert_eq!(&writer.get_ref()[..], b);
85aaf69f
SL
521
522 writer.flush().unwrap();
523 let a: &[_] = &[0, 1, 2, 3];
c34b1796 524 assert_eq!(a, &writer.get_ref()[..]);
85aaf69f
SL
525
526 writer.write_all(&[4]).unwrap();
527 writer.write_all(&[5]).unwrap();
c34b1796 528 assert_eq!(a, &writer.get_ref()[..]);
85aaf69f
SL
529
530 writer.write_all(&[6]).unwrap();
531 let a: &[_] = &[0, 1, 2, 3, 4, 5];
c34b1796 532 assert_eq!(a, &writer.get_ref()[..]);
85aaf69f
SL
533
534 writer.write_all(&[7, 8]).unwrap();
535 let a: &[_] = &[0, 1, 2, 3, 4, 5, 6];
c34b1796 536 assert_eq!(a, &writer.get_ref()[..]);
85aaf69f
SL
537
538 writer.write_all(&[9, 10, 11]).unwrap();
539 let a: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
c34b1796 540 assert_eq!(a, &writer.get_ref()[..]);
85aaf69f
SL
541
542 writer.flush().unwrap();
c34b1796 543 assert_eq!(a, &writer.get_ref()[..]);
85aaf69f
SL
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: &[_] = &[];
c34b1796 551 assert_eq!(&w.get_ref()[..], a);
85aaf69f
SL
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 {
c34b1796 568 fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
85aaf69f
SL
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: &[_] = &[];
c34b1796 596 assert_eq!(&writer.get_ref()[..], b);
85aaf69f 597 writer.write_all(&[1]).unwrap();
c34b1796 598 assert_eq!(&writer.get_ref()[..], b);
85aaf69f
SL
599 writer.flush().unwrap();
600 let b: &[_] = &[0, 1];
c34b1796 601 assert_eq!(&writer.get_ref()[..], b);
85aaf69f
SL
602 writer.write_all(&[0, b'\n', 1, b'\n', 2]).unwrap();
603 let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n'];
c34b1796 604 assert_eq!(&writer.get_ref()[..], b);
85aaf69f
SL
605 writer.flush().unwrap();
606 let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n', 2];
c34b1796 607 assert_eq!(&writer.get_ref()[..], b);
85aaf69f
SL
608 writer.write_all(&[3, b'\n']).unwrap();
609 let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n'];
c34b1796 610 assert_eq!(&writer.get_ref()[..], b);
85aaf69f
SL
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() {
c34b1796 650 let buf = [195, 159];
85aaf69f
SL
651 let mut reader = BufferedReader::with_capacity(1, &buf[..]);
652 assert_eq!(reader.read_char(), Ok('ß'));
653 }
654
655 #[test]
656 fn test_chars() {
c34b1796 657 let buf = [195, 159, b'a'];
85aaf69f
SL
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]
c34b1796 666 #[should_panic]
85aaf69f
SL
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}