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 //! Buffering wrappers for I/O traits
18 use io::{self, Initializer, DEFAULT_BUF_SIZE, Error, ErrorKind, SeekFrom};
21 /// The `BufReader` struct adds buffering to any reader.
23 /// It can be excessively inefficient to work directly with a [`Read`] instance.
24 /// For example, every call to [`read`][`TcpStream::read`] on [`TcpStream`]
25 /// results in a system call. A `BufReader` performs large, infrequent reads on
26 /// the underlying [`Read`] and maintains an in-memory buffer of the results.
28 /// [`Read`]: ../../std/io/trait.Read.html
29 /// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read
30 /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
35 /// use std::io::prelude::*;
36 /// use std::io::BufReader;
37 /// use std::fs::File;
39 /// # fn foo() -> std::io::Result<()> {
40 /// let f = File::open("log.txt")?;
41 /// let mut reader = BufReader::new(f);
43 /// let mut line = String::new();
44 /// let len = reader.read_line(&mut line)?;
45 /// println!("First line is {} bytes long", len);
49 #[stable(feature = "rust1", since = "1.0.0")]
50 pub struct BufReader<R> {
57 impl<R: Read> BufReader<R> {
58 /// Creates a new `BufReader` with a default buffer capacity.
63 /// use std::io::BufReader;
64 /// use std::fs::File;
66 /// # fn foo() -> std::io::Result<()> {
67 /// let f = File::open("log.txt")?;
68 /// let reader = BufReader::new(f);
72 #[stable(feature = "rust1", since = "1.0.0")]
73 pub fn new(inner: R) -> BufReader<R> {
74 BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
77 /// Creates a new `BufReader` with the specified buffer capacity.
81 /// Creating a buffer with ten bytes of capacity:
84 /// use std::io::BufReader;
85 /// use std::fs::File;
87 /// # fn foo() -> std::io::Result<()> {
88 /// let f = File::open("log.txt")?;
89 /// let reader = BufReader::with_capacity(10, f);
93 #[stable(feature = "rust1", since = "1.0.0")]
94 pub fn with_capacity(cap: usize, inner: R) -> BufReader<R> {
96 let mut buffer = Vec::with_capacity(cap);
98 inner.initializer().initialize(&mut buffer);
101 buf: buffer.into_boxed_slice(),
108 /// Gets a reference to the underlying reader.
110 /// It is inadvisable to directly read from the underlying reader.
115 /// use std::io::BufReader;
116 /// use std::fs::File;
118 /// # fn foo() -> std::io::Result<()> {
119 /// let f1 = File::open("log.txt")?;
120 /// let reader = BufReader::new(f1);
122 /// let f2 = reader.get_ref();
126 #[stable(feature = "rust1", since = "1.0.0")]
127 pub fn get_ref(&self) -> &R { &self.inner }
129 /// Gets a mutable reference to the underlying reader.
131 /// It is inadvisable to directly read from the underlying reader.
136 /// use std::io::BufReader;
137 /// use std::fs::File;
139 /// # fn foo() -> std::io::Result<()> {
140 /// let f1 = File::open("log.txt")?;
141 /// let mut reader = BufReader::new(f1);
143 /// let f2 = reader.get_mut();
147 #[stable(feature = "rust1", since = "1.0.0")]
148 pub fn get_mut(&mut self) -> &mut R { &mut self.inner }
150 /// Returns `true` if there are no bytes in the internal buffer.
154 /// # #![feature(bufreader_is_empty)]
155 /// use std::io::BufReader;
156 /// use std::io::BufRead;
157 /// use std::fs::File;
159 /// # fn foo() -> std::io::Result<()> {
160 /// let f1 = File::open("log.txt")?;
161 /// let mut reader = BufReader::new(f1);
162 /// assert!(reader.is_empty());
164 /// if reader.fill_buf()?.len() > 0 {
165 /// assert!(!reader.is_empty());
170 #[unstable(feature = "bufreader_is_empty", issue = "45323", reason = "recently added")]
171 pub fn is_empty(&self) -> bool {
175 /// Unwraps this `BufReader`, returning the underlying reader.
177 /// Note that any leftover data in the internal buffer is lost.
182 /// use std::io::BufReader;
183 /// use std::fs::File;
185 /// # fn foo() -> std::io::Result<()> {
186 /// let f1 = File::open("log.txt")?;
187 /// let reader = BufReader::new(f1);
189 /// let f2 = reader.into_inner();
193 #[stable(feature = "rust1", since = "1.0.0")]
194 pub fn into_inner(self) -> R { self.inner }
197 impl<R: Seek> BufReader<R> {
198 /// Seeks relative to the current position. If the new position lies within the buffer,
199 /// the buffer will not be flushed, allowing for more efficient seeks.
200 /// This method does not return the location of the underlying reader, so the caller
201 /// must track this information themselves if it is required.
202 #[unstable(feature = "bufreader_seek_relative", issue = "31100")]
203 pub fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
204 let pos = self.pos as u64;
206 if let Some(new_pos) = pos.checked_sub((-offset) as u64) {
207 self.pos = new_pos as usize;
211 if let Some(new_pos) = pos.checked_add(offset as u64) {
212 if new_pos <= self.cap as u64 {
213 self.pos = new_pos as usize;
218 self.seek(SeekFrom::Current(offset)).map(|_|())
222 #[stable(feature = "rust1", since = "1.0.0")]
223 impl<R: Read> Read for BufReader<R> {
224 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
225 // If we don't have any buffered data and we're doing a massive read
226 // (larger than our internal buffer), bypass our internal buffer
228 if self.pos == self.cap && buf.len() >= self.buf.len() {
229 return self.inner.read(buf);
232 let mut rem = self.fill_buf()?;
239 // we can't skip unconditionally because of the large buffer case in read.
240 unsafe fn initializer(&self) -> Initializer {
241 self.inner.initializer()
245 #[stable(feature = "rust1", since = "1.0.0")]
246 impl<R: Read> BufRead for BufReader<R> {
247 fn fill_buf(&mut self) -> io::Result<&[u8]> {
248 // If we've reached the end of our internal buffer then we need to fetch
249 // some more data from the underlying reader.
250 // Branch using `>=` instead of the more correct `==`
251 // to tell the compiler that the pos..cap slice is always valid.
252 if self.pos >= self.cap {
253 debug_assert!(self.pos == self.cap);
254 self.cap = self.inner.read(&mut self.buf)?;
257 Ok(&self.buf[self.pos..self.cap])
260 fn consume(&mut self, amt: usize) {
261 self.pos = cmp::min(self.pos + amt, self.cap);
265 #[stable(feature = "rust1", since = "1.0.0")]
266 impl<R> fmt::Debug for BufReader<R> where R: fmt::Debug {
267 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
268 fmt.debug_struct("BufReader")
269 .field("reader", &self.inner)
270 .field("buffer", &format_args!("{}/{}", self.cap - self.pos, self.buf.len()))
275 #[stable(feature = "rust1", since = "1.0.0")]
276 impl<R: Seek> Seek for BufReader<R> {
277 /// Seek to an offset, in bytes, in the underlying reader.
279 /// The position used for seeking with `SeekFrom::Current(_)` is the
280 /// position the underlying reader would be at if the `BufReader` had no
283 /// Seeking always discards the internal buffer, even if the seek position
284 /// would otherwise fall within it. This guarantees that calling
285 /// `.into_inner()` immediately after a seek yields the underlying reader
286 /// at the same position.
288 /// To seek without discarding the internal buffer, use [`seek_relative`].
290 /// See `std::io::Seek` for more details.
292 /// Note: In the edge case where you're seeking with `SeekFrom::Current(n)`
293 /// where `n` minus the internal buffer length overflows an `i64`, two
294 /// seeks will be performed instead of one. If the second seek returns
295 /// `Err`, the underlying reader will be left at the same position it would
296 /// have if you seeked to `SeekFrom::Current(0)`.
298 /// [`seek_relative`]: #method.seek_relative
299 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
301 if let SeekFrom::Current(n) = pos {
302 let remainder = (self.cap - self.pos) as i64;
303 // it should be safe to assume that remainder fits within an i64 as the alternative
304 // means we managed to allocate 8 exbibytes and that's absurd.
305 // But it's not out of the realm of possibility for some weird underlying reader to
306 // support seeking by i64::min_value() so we need to handle underflow when subtracting
308 if let Some(offset) = n.checked_sub(remainder) {
309 result = self.inner.seek(SeekFrom::Current(offset))?;
311 // seek backwards by our remainder, and then by the offset
312 self.inner.seek(SeekFrom::Current(-remainder))?;
313 self.pos = self.cap; // empty the buffer
314 result = self.inner.seek(SeekFrom::Current(n))?;
317 // Seeking with Start/End doesn't care about our buffer length.
318 result = self.inner.seek(pos)?;
320 self.pos = self.cap; // empty the buffer
325 /// Wraps a writer and buffers its output.
327 /// It can be excessively inefficient to work directly with something that
328 /// implements [`Write`]. For example, every call to
329 /// [`write`][`Tcpstream::write`] on [`TcpStream`] results in a system call. A
330 /// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying
331 /// writer in large, infrequent batches.
333 /// When the `BufWriter` is dropped, the contents of its buffer will be written
334 /// out. However, any errors that happen in the process of flushing the buffer
335 /// when the writer is dropped will be ignored. Code that wishes to handle such
336 /// errors must manually call [`flush`] before the writer is dropped.
340 /// Let's write the numbers one through ten to a [`TcpStream`]:
343 /// use std::io::prelude::*;
344 /// use std::net::TcpStream;
346 /// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
349 /// stream.write(&[i+1]).unwrap();
353 /// Because we're not buffering, we write each one in turn, incurring the
354 /// overhead of a system call per byte written. We can fix this with a
358 /// use std::io::prelude::*;
359 /// use std::io::BufWriter;
360 /// use std::net::TcpStream;
362 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
365 /// stream.write(&[i+1]).unwrap();
369 /// By wrapping the stream with a `BufWriter`, these ten writes are all grouped
370 /// together by the buffer, and will all be written out in one system call when
371 /// the `stream` is dropped.
373 /// [`Write`]: ../../std/io/trait.Write.html
374 /// [`Tcpstream::write`]: ../../std/net/struct.TcpStream.html#method.write
375 /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
376 /// [`flush`]: #method.flush
377 #[stable(feature = "rust1", since = "1.0.0")]
378 pub struct BufWriter<W: Write> {
381 // #30888: If the inner writer panics in a call to write, we don't want to
382 // write the buffered data a second time in BufWriter's destructor. This
383 // flag tells the Drop impl if it should skip the flush.
387 /// An error returned by `into_inner` which combines an error that
388 /// happened while writing out the buffer, and the buffered writer object
389 /// which may be used to recover from the condition.
394 /// use std::io::BufWriter;
395 /// use std::net::TcpStream;
397 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
399 /// // do stuff with the stream
401 /// // we want to get our `TcpStream` back, so let's try:
403 /// let stream = match stream.into_inner() {
406 /// // Here, e is an IntoInnerError
407 /// panic!("An error occurred");
412 #[stable(feature = "rust1", since = "1.0.0")]
413 pub struct IntoInnerError<W>(W, Error);
415 impl<W: Write> BufWriter<W> {
416 /// Creates a new `BufWriter` with a default buffer capacity.
421 /// use std::io::BufWriter;
422 /// use std::net::TcpStream;
424 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
426 #[stable(feature = "rust1", since = "1.0.0")]
427 pub fn new(inner: W) -> BufWriter<W> {
428 BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
431 /// Creates a new `BufWriter` with the specified buffer capacity.
435 /// Creating a buffer with a buffer of a hundred bytes.
438 /// use std::io::BufWriter;
439 /// use std::net::TcpStream;
441 /// let stream = TcpStream::connect("127.0.0.1:34254").unwrap();
442 /// let mut buffer = BufWriter::with_capacity(100, stream);
444 #[stable(feature = "rust1", since = "1.0.0")]
445 pub fn with_capacity(cap: usize, inner: W) -> BufWriter<W> {
448 buf: Vec::with_capacity(cap),
453 fn flush_buf(&mut self) -> io::Result<()> {
455 let len = self.buf.len();
456 let mut ret = Ok(());
457 while written < len {
458 self.panicked = true;
459 let r = self.inner.as_mut().unwrap().write(&self.buf[written..]);
460 self.panicked = false;
464 ret = Err(Error::new(ErrorKind::WriteZero,
465 "failed to write the buffered data"));
468 Ok(n) => written += n,
469 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
470 Err(e) => { ret = Err(e); break }
475 self.buf.drain(..written);
480 /// Gets a reference to the underlying writer.
485 /// use std::io::BufWriter;
486 /// use std::net::TcpStream;
488 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
490 /// // we can use reference just like buffer
491 /// let reference = buffer.get_ref();
493 #[stable(feature = "rust1", since = "1.0.0")]
494 pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() }
496 /// Gets a mutable reference to the underlying writer.
498 /// It is inadvisable to directly write to the underlying writer.
503 /// use std::io::BufWriter;
504 /// use std::net::TcpStream;
506 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
508 /// // we can use reference just like buffer
509 /// let reference = buffer.get_mut();
511 #[stable(feature = "rust1", since = "1.0.0")]
512 pub fn get_mut(&mut self) -> &mut W { self.inner.as_mut().unwrap() }
514 /// Unwraps this `BufWriter`, returning the underlying writer.
516 /// The buffer is written out before returning the writer.
520 /// An `Err` will be returned if an error occurs while flushing the buffer.
525 /// use std::io::BufWriter;
526 /// use std::net::TcpStream;
528 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
530 /// // unwrap the TcpStream and flush the buffer
531 /// let stream = buffer.into_inner().unwrap();
533 #[stable(feature = "rust1", since = "1.0.0")]
534 pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
535 match self.flush_buf() {
536 Err(e) => Err(IntoInnerError(self, e)),
537 Ok(()) => Ok(self.inner.take().unwrap())
542 #[stable(feature = "rust1", since = "1.0.0")]
543 impl<W: Write> Write for BufWriter<W> {
544 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
545 if self.buf.len() + buf.len() > self.buf.capacity() {
548 if buf.len() >= self.buf.capacity() {
549 self.panicked = true;
550 let r = self.inner.as_mut().unwrap().write(buf);
551 self.panicked = false;
554 Write::write(&mut self.buf, buf)
557 fn flush(&mut self) -> io::Result<()> {
558 self.flush_buf().and_then(|()| self.get_mut().flush())
562 #[stable(feature = "rust1", since = "1.0.0")]
563 impl<W: Write> fmt::Debug for BufWriter<W> where W: fmt::Debug {
564 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
565 fmt.debug_struct("BufWriter")
566 .field("writer", &self.inner.as_ref().unwrap())
567 .field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
572 #[stable(feature = "rust1", since = "1.0.0")]
573 impl<W: Write + Seek> Seek for BufWriter<W> {
574 /// Seek to the offset, in bytes, in the underlying writer.
576 /// Seeking always writes out the internal buffer before seeking.
577 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
578 self.flush_buf().and_then(|_| self.get_mut().seek(pos))
582 #[stable(feature = "rust1", since = "1.0.0")]
583 impl<W: Write> Drop for BufWriter<W> {
585 if self.inner.is_some() && !self.panicked {
586 // dtors should not panic, so we ignore a failed flush
587 let _r = self.flush_buf();
592 impl<W> IntoInnerError<W> {
593 /// Returns the error which caused the call to `into_inner()` to fail.
595 /// This error was returned when attempting to write the internal buffer.
600 /// use std::io::BufWriter;
601 /// use std::net::TcpStream;
603 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
605 /// // do stuff with the stream
607 /// // we want to get our `TcpStream` back, so let's try:
609 /// let stream = match stream.into_inner() {
612 /// // Here, e is an IntoInnerError, let's log the inner error.
614 /// // We'll just 'log' to stdout for this example.
615 /// println!("{}", e.error());
617 /// panic!("An unexpected error occurred.");
621 #[stable(feature = "rust1", since = "1.0.0")]
622 pub fn error(&self) -> &Error { &self.1 }
624 /// Returns the buffered writer instance which generated the error.
626 /// The returned object can be used for error recovery, such as
627 /// re-inspecting the buffer.
632 /// use std::io::BufWriter;
633 /// use std::net::TcpStream;
635 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
637 /// // do stuff with the stream
639 /// // we want to get our `TcpStream` back, so let's try:
641 /// let stream = match stream.into_inner() {
644 /// // Here, e is an IntoInnerError, let's re-examine the buffer:
645 /// let buffer = e.into_inner();
647 /// // do stuff to try to recover
649 /// // afterwards, let's just return the stream
650 /// buffer.into_inner().unwrap()
654 #[stable(feature = "rust1", since = "1.0.0")]
655 pub fn into_inner(self) -> W { self.0 }
658 #[stable(feature = "rust1", since = "1.0.0")]
659 impl<W> From<IntoInnerError<W>> for Error {
660 fn from(iie: IntoInnerError<W>) -> Error { iie.1 }
663 #[stable(feature = "rust1", since = "1.0.0")]
664 impl<W: Send + fmt::Debug> error::Error for IntoInnerError<W> {
665 fn description(&self) -> &str {
666 error::Error::description(self.error())
670 #[stable(feature = "rust1", since = "1.0.0")]
671 impl<W> fmt::Display for IntoInnerError<W> {
672 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
677 /// Wraps a writer and buffers output to it, flushing whenever a newline
678 /// (`0x0a`, `'\n'`) is detected.
680 /// The [`BufWriter`][bufwriter] struct wraps a writer and buffers its output.
681 /// But it only does this batched write when it goes out of scope, or when the
682 /// internal buffer is full. Sometimes, you'd prefer to write each line as it's
683 /// completed, rather than the entire buffer at once. Enter `LineWriter`. It
684 /// does exactly that.
686 /// Like [`BufWriter`], a `LineWriter`’s buffer will also be flushed when the
687 /// `LineWriter` goes out of scope or when its internal buffer is full.
689 /// [bufwriter]: struct.BufWriter.html
691 /// If there's still a partial line in the buffer when the `LineWriter` is
692 /// dropped, it will flush those contents.
696 /// We can use `LineWriter` to write one line at a time, significantly
697 /// reducing the number of actual writes to the file.
700 /// use std::fs::File;
701 /// use std::io::prelude::*;
702 /// use std::io::LineWriter;
704 /// # fn foo() -> std::io::Result<()> {
705 /// let road_not_taken = b"I shall be telling this with a sigh
706 /// Somewhere ages and ages hence:
707 /// Two roads diverged in a wood, and I -
708 /// I took the one less traveled by,
709 /// And that has made all the difference.";
711 /// let file = File::create("poem.txt")?;
712 /// let mut file = LineWriter::new(file);
714 /// for &byte in road_not_taken.iter() {
715 /// file.write(&[byte]).unwrap();
718 /// // let's check we did the right thing.
719 /// let mut file = File::open("poem.txt")?;
720 /// let mut contents = String::new();
722 /// file.read_to_string(&mut contents)?;
724 /// assert_eq!(contents.as_bytes(), &road_not_taken[..]);
728 #[stable(feature = "rust1", since = "1.0.0")]
729 pub struct LineWriter<W: Write> {
734 impl<W: Write> LineWriter<W> {
735 /// Creates a new `LineWriter`.
740 /// use std::fs::File;
741 /// use std::io::LineWriter;
743 /// # fn foo() -> std::io::Result<()> {
744 /// let file = File::create("poem.txt")?;
745 /// let file = LineWriter::new(file);
749 #[stable(feature = "rust1", since = "1.0.0")]
750 pub fn new(inner: W) -> LineWriter<W> {
751 // Lines typically aren't that long, don't use a giant buffer
752 LineWriter::with_capacity(1024, inner)
755 /// Creates a new `LineWriter` with a specified capacity for the internal
761 /// use std::fs::File;
762 /// use std::io::LineWriter;
764 /// # fn foo() -> std::io::Result<()> {
765 /// let file = File::create("poem.txt")?;
766 /// let file = LineWriter::with_capacity(100, file);
770 #[stable(feature = "rust1", since = "1.0.0")]
771 pub fn with_capacity(cap: usize, inner: W) -> LineWriter<W> {
773 inner: BufWriter::with_capacity(cap, inner),
778 /// Gets a reference to the underlying writer.
783 /// use std::fs::File;
784 /// use std::io::LineWriter;
786 /// # fn foo() -> std::io::Result<()> {
787 /// let file = File::create("poem.txt")?;
788 /// let file = LineWriter::new(file);
790 /// let reference = file.get_ref();
794 #[stable(feature = "rust1", since = "1.0.0")]
795 pub fn get_ref(&self) -> &W { self.inner.get_ref() }
797 /// Gets a mutable reference to the underlying writer.
799 /// Caution must be taken when calling methods on the mutable reference
800 /// returned as extra writes could corrupt the output stream.
805 /// use std::fs::File;
806 /// use std::io::LineWriter;
808 /// # fn foo() -> std::io::Result<()> {
809 /// let file = File::create("poem.txt")?;
810 /// let mut file = LineWriter::new(file);
812 /// // we can use reference just like file
813 /// let reference = file.get_mut();
817 #[stable(feature = "rust1", since = "1.0.0")]
818 pub fn get_mut(&mut self) -> &mut W { self.inner.get_mut() }
820 /// Unwraps this `LineWriter`, returning the underlying writer.
822 /// The internal buffer is written out before returning the writer.
826 /// An `Err` will be returned if an error occurs while flushing the buffer.
831 /// use std::fs::File;
832 /// use std::io::LineWriter;
834 /// # fn foo() -> std::io::Result<()> {
835 /// let file = File::create("poem.txt")?;
837 /// let writer: LineWriter<File> = LineWriter::new(file);
839 /// let file: File = writer.into_inner()?;
843 #[stable(feature = "rust1", since = "1.0.0")]
844 pub fn into_inner(self) -> Result<W, IntoInnerError<LineWriter<W>>> {
845 self.inner.into_inner().map_err(|IntoInnerError(buf, e)| {
846 IntoInnerError(LineWriter {
854 #[stable(feature = "rust1", since = "1.0.0")]
855 impl<W: Write> Write for LineWriter<W> {
856 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
861 // Find the last newline character in the buffer provided. If found then
862 // we're going to write all the data up to that point and then flush,
863 // otherewise we just write the whole block to the underlying writer.
864 let i = match memchr::memrchr(b'\n', buf) {
866 None => return self.inner.write(buf),
870 // Ok, we're going to write a partial amount of the data given first
871 // followed by flushing the newline. After we've successfully written
872 // some data then we *must* report that we wrote that data, so future
873 // errors are ignored. We set our internal `need_flush` flag, though, in
874 // case flushing fails and we need to try it first next time.
875 let n = self.inner.write(&buf[..i + 1])?;
876 self.need_flush = true;
877 if self.flush().is_err() || n != i + 1 {
881 // At this point we successfully wrote `i + 1` bytes and flushed it out,
882 // meaning that the entire line is now flushed out on the screen. While
883 // we can attempt to finish writing the rest of the data provided.
884 // Remember though that we ignore errors here as we've successfully
885 // written data, so we need to report that.
886 match self.inner.write(&buf[i + 1..]) {
892 fn flush(&mut self) -> io::Result<()> {
894 self.need_flush = false;
899 #[stable(feature = "rust1", since = "1.0.0")]
900 impl<W: Write> fmt::Debug for LineWriter<W> where W: fmt::Debug {
901 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
902 fmt.debug_struct("LineWriter")
903 .field("writer", &self.inner.inner)
905 &format_args!("{}/{}", self.inner.buf.len(), self.inner.buf.capacity()))
913 use io::{self, BufReader, BufWriter, LineWriter, SeekFrom};
914 use sync::atomic::{AtomicUsize, Ordering};
918 /// A dummy reader intended at testing short-reads propagation.
919 pub struct ShortReader {
923 impl Read for ShortReader {
924 fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
925 if self.lengths.is_empty() {
928 Ok(self.lengths.remove(0))
934 fn test_buffered_reader() {
935 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
936 let mut reader = BufReader::with_capacity(2, inner);
938 let mut buf = [0, 0, 0];
939 let nread = reader.read(&mut buf);
940 assert_eq!(nread.unwrap(), 3);
941 let b: &[_] = &[5, 6, 7];
944 let mut buf = [0, 0];
945 let nread = reader.read(&mut buf);
946 assert_eq!(nread.unwrap(), 2);
947 let b: &[_] = &[0, 1];
951 let nread = reader.read(&mut buf);
952 assert_eq!(nread.unwrap(), 1);
956 let mut buf = [0, 0, 0];
957 let nread = reader.read(&mut buf);
958 assert_eq!(nread.unwrap(), 1);
959 let b: &[_] = &[3, 0, 0];
962 let nread = reader.read(&mut buf);
963 assert_eq!(nread.unwrap(), 1);
964 let b: &[_] = &[4, 0, 0];
967 assert_eq!(reader.read(&mut buf).unwrap(), 0);
971 fn test_buffered_reader_seek() {
972 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
973 let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
975 assert_eq!(reader.seek(SeekFrom::Start(3)).ok(), Some(3));
976 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
977 assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(3));
978 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
979 assert_eq!(reader.seek(SeekFrom::Current(1)).ok(), Some(4));
980 assert_eq!(reader.fill_buf().ok(), Some(&[1, 2][..]));
982 assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3));
986 fn test_buffered_reader_seek_relative() {
987 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
988 let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
990 assert!(reader.seek_relative(3).is_ok());
991 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
992 assert!(reader.seek_relative(0).is_ok());
993 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
994 assert!(reader.seek_relative(1).is_ok());
995 assert_eq!(reader.fill_buf().ok(), Some(&[1][..]));
996 assert!(reader.seek_relative(-1).is_ok());
997 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
998 assert!(reader.seek_relative(2).is_ok());
999 assert_eq!(reader.fill_buf().ok(), Some(&[2, 3][..]));
1003 fn test_buffered_reader_seek_underflow() {
1004 // gimmick reader that yields its position modulo 256 for each byte
1005 struct PositionReader {
1008 impl Read for PositionReader {
1009 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1010 let len = buf.len();
1012 *x = self.pos as u8;
1013 self.pos = self.pos.wrapping_add(1);
1018 impl Seek for PositionReader {
1019 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
1021 SeekFrom::Start(n) => {
1024 SeekFrom::Current(n) => {
1025 self.pos = self.pos.wrapping_add(n as u64);
1027 SeekFrom::End(n) => {
1028 self.pos = u64::max_value().wrapping_add(n as u64);
1035 let mut reader = BufReader::with_capacity(5, PositionReader { pos: 0 });
1036 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1, 2, 3, 4][..]));
1037 assert_eq!(reader.seek(SeekFrom::End(-5)).ok(), Some(u64::max_value()-5));
1038 assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
1039 // the following seek will require two underlying seeks
1040 let expected = 9223372036854775802;
1041 assert_eq!(reader.seek(SeekFrom::Current(i64::min_value())).ok(), Some(expected));
1042 assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
1043 // seeking to 0 should empty the buffer.
1044 assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(expected));
1045 assert_eq!(reader.get_ref().pos, expected);
1049 fn test_buffered_writer() {
1050 let inner = Vec::new();
1051 let mut writer = BufWriter::with_capacity(2, inner);
1053 writer.write(&[0, 1]).unwrap();
1054 assert_eq!(*writer.get_ref(), [0, 1]);
1056 writer.write(&[2]).unwrap();
1057 assert_eq!(*writer.get_ref(), [0, 1]);
1059 writer.write(&[3]).unwrap();
1060 assert_eq!(*writer.get_ref(), [0, 1]);
1062 writer.flush().unwrap();
1063 assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
1065 writer.write(&[4]).unwrap();
1066 writer.write(&[5]).unwrap();
1067 assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
1069 writer.write(&[6]).unwrap();
1070 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]);
1072 writer.write(&[7, 8]).unwrap();
1073 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]);
1075 writer.write(&[9, 10, 11]).unwrap();
1076 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
1078 writer.flush().unwrap();
1079 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
1083 fn test_buffered_writer_inner_flushes() {
1084 let mut w = BufWriter::with_capacity(3, Vec::new());
1085 w.write(&[0, 1]).unwrap();
1086 assert_eq!(*w.get_ref(), []);
1087 let w = w.into_inner().unwrap();
1088 assert_eq!(w, [0, 1]);
1092 fn test_buffered_writer_seek() {
1093 let mut w = BufWriter::with_capacity(3, io::Cursor::new(Vec::new()));
1094 w.write_all(&[0, 1, 2, 3, 4, 5]).unwrap();
1095 w.write_all(&[6, 7]).unwrap();
1096 assert_eq!(w.seek(SeekFrom::Current(0)).ok(), Some(8));
1097 assert_eq!(&w.get_ref().get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]);
1098 assert_eq!(w.seek(SeekFrom::Start(2)).ok(), Some(2));
1099 w.write_all(&[8, 9]).unwrap();
1100 assert_eq!(&w.into_inner().unwrap().into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]);
1104 fn test_read_until() {
1105 let inner: &[u8] = &[0, 1, 2, 1, 0];
1106 let mut reader = BufReader::with_capacity(2, inner);
1107 let mut v = Vec::new();
1108 reader.read_until(0, &mut v).unwrap();
1111 reader.read_until(2, &mut v).unwrap();
1112 assert_eq!(v, [1, 2]);
1114 reader.read_until(1, &mut v).unwrap();
1117 reader.read_until(8, &mut v).unwrap();
1120 reader.read_until(9, &mut v).unwrap();
1125 fn test_line_buffer_fail_flush() {
1127 struct FailFlushWriter<'a>(&'a mut Vec<u8>);
1129 impl<'a> Write for FailFlushWriter<'a> {
1130 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1131 self.0.extend_from_slice(buf);
1134 fn flush(&mut self) -> io::Result<()> {
1135 Err(io::Error::new(io::ErrorKind::Other, "flush failed"))
1139 let mut buf = Vec::new();
1141 let mut writer = LineWriter::new(FailFlushWriter(&mut buf));
1142 let to_write = b"abc\ndef";
1143 if let Ok(written) = writer.write(to_write) {
1144 assert!(written < to_write.len(), "didn't flush on new line");
1149 assert!(buf.is_empty(), "write returned an error but wrote data");
1153 fn test_line_buffer() {
1154 let mut writer = LineWriter::new(Vec::new());
1155 writer.write(&[0]).unwrap();
1156 assert_eq!(*writer.get_ref(), []);
1157 writer.write(&[1]).unwrap();
1158 assert_eq!(*writer.get_ref(), []);
1159 writer.flush().unwrap();
1160 assert_eq!(*writer.get_ref(), [0, 1]);
1161 writer.write(&[0, b'\n', 1, b'\n', 2]).unwrap();
1162 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n']);
1163 writer.flush().unwrap();
1164 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2]);
1165 writer.write(&[3, b'\n']).unwrap();
1166 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n']);
1170 fn test_read_line() {
1171 let in_buf: &[u8] = b"a\nb\nc";
1172 let mut reader = BufReader::with_capacity(2, in_buf);
1173 let mut s = String::new();
1174 reader.read_line(&mut s).unwrap();
1175 assert_eq!(s, "a\n");
1177 reader.read_line(&mut s).unwrap();
1178 assert_eq!(s, "b\n");
1180 reader.read_line(&mut s).unwrap();
1183 reader.read_line(&mut s).unwrap();
1189 let in_buf: &[u8] = b"a\nb\nc";
1190 let reader = BufReader::with_capacity(2, in_buf);
1191 let mut it = reader.lines();
1192 assert_eq!(it.next().unwrap().unwrap(), "a".to_string());
1193 assert_eq!(it.next().unwrap().unwrap(), "b".to_string());
1194 assert_eq!(it.next().unwrap().unwrap(), "c".to_string());
1195 assert!(it.next().is_none());
1199 fn test_short_reads() {
1200 let inner = ShortReader{lengths: vec![0, 1, 2, 0, 1, 0]};
1201 let mut reader = BufReader::new(inner);
1202 let mut buf = [0, 0];
1203 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1204 assert_eq!(reader.read(&mut buf).unwrap(), 1);
1205 assert_eq!(reader.read(&mut buf).unwrap(), 2);
1206 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1207 assert_eq!(reader.read(&mut buf).unwrap(), 1);
1208 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1209 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1213 fn read_char_buffered() {
1214 let buf = [195, 159];
1215 let reader = BufReader::with_capacity(1, &buf[..]);
1216 assert_eq!(reader.chars().next().unwrap().unwrap(), 'ß');
1221 let buf = [195, 159, b'a'];
1222 let reader = BufReader::with_capacity(1, &buf[..]);
1223 let mut it = reader.chars();
1224 assert_eq!(it.next().unwrap().unwrap(), 'ß');
1225 assert_eq!(it.next().unwrap().unwrap(), 'a');
1226 assert!(it.next().is_none());
1231 fn dont_panic_in_drop_on_panicked_flush() {
1232 struct FailFlushWriter;
1234 impl Write for FailFlushWriter {
1235 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
1236 fn flush(&mut self) -> io::Result<()> {
1237 Err(io::Error::last_os_error())
1241 let writer = FailFlushWriter;
1242 let _writer = BufWriter::new(writer);
1244 // If writer panics *again* due to the flush error then the process will
1250 #[cfg_attr(target_os = "emscripten", ignore)]
1251 fn panic_in_write_doesnt_flush_in_drop() {
1252 static WRITES: AtomicUsize = AtomicUsize::new(0);
1256 impl Write for PanicWriter {
1257 fn write(&mut self, _: &[u8]) -> io::Result<usize> {
1258 WRITES.fetch_add(1, Ordering::SeqCst);
1261 fn flush(&mut self) -> io::Result<()> { Ok(()) }
1265 let mut writer = BufWriter::new(PanicWriter);
1266 let _ = writer.write(b"hello world");
1267 let _ = writer.flush();
1268 }).join().unwrap_err();
1270 assert_eq!(WRITES.load(Ordering::SeqCst), 1);
1274 fn bench_buffered_reader(b: &mut test::Bencher) {
1276 BufReader::new(io::empty())
1281 fn bench_buffered_writer(b: &mut test::Bencher) {
1283 BufWriter::new(io::sink())
1287 struct AcceptOneThenFail {
1292 impl Write for AcceptOneThenFail {
1293 fn write(&mut self, data: &[u8]) -> io::Result<usize> {
1295 assert_eq!(data, b"a\nb\n");
1296 self.written = true;
1299 Err(io::Error::new(io::ErrorKind::NotFound, "test"))
1303 fn flush(&mut self) -> io::Result<()> {
1304 assert!(self.written);
1305 assert!(!self.flushed);
1306 self.flushed = true;
1307 Err(io::Error::new(io::ErrorKind::Other, "test"))
1312 fn erroneous_flush_retried() {
1313 let a = AcceptOneThenFail {
1318 let mut l = LineWriter::new(a);
1319 assert_eq!(l.write(b"a\nb\na").unwrap(), 4);
1320 assert!(l.get_ref().written);
1321 assert!(l.get_ref().flushed);
1322 l.get_mut().flushed = false;
1324 assert_eq!(l.write(b"a").unwrap_err().kind(), io::ErrorKind::Other)