1 //! Buffering wrappers for I/O traits
3 use crate::io::prelude::*;
9 self, Error, ErrorKind, Initializer, IoSlice, IoSliceMut, SeekFrom, DEFAULT_BUF_SIZE,
13 /// The `BufReader<R>` struct adds buffering to any reader.
15 /// It can be excessively inefficient to work directly with a [`Read`] instance.
16 /// For example, every call to [`read`][`TcpStream::read`] on [`TcpStream`]
17 /// results in a system call. A `BufReader<R>` performs large, infrequent reads on
18 /// the underlying [`Read`] and maintains an in-memory buffer of the results.
20 /// `BufReader<R>` can improve the speed of programs that make *small* and
21 /// *repeated* read calls to the same file or network socket. It does not
22 /// help when reading very large amounts at once, or reading just one or a few
23 /// times. It also provides no advantage when reading from a source that is
24 /// already in memory, like a [`Vec`]`<u8>`.
26 /// When the `BufReader<R>` is dropped, the contents of its buffer will be
27 /// discarded. Creating multiple instances of a `BufReader<R>` on the same
28 /// stream can cause data loss. Reading from the underlying reader after
29 /// unwrapping the `BufReader<R>` with [`BufReader::into_inner`] can also cause
32 /// [`TcpStream::read`]: Read::read
33 /// [`TcpStream`]: crate::net::TcpStream
38 /// use std::io::prelude::*;
39 /// use std::io::BufReader;
40 /// use std::fs::File;
42 /// fn main() -> std::io::Result<()> {
43 /// let f = File::open("log.txt")?;
44 /// let mut reader = BufReader::new(f);
46 /// let mut line = String::new();
47 /// let len = reader.read_line(&mut line)?;
48 /// println!("First line is {} bytes long", len);
52 #[stable(feature = "rust1", since = "1.0.0")]
53 pub struct BufReader<R> {
60 impl<R: Read> BufReader<R> {
61 /// Creates a new `BufReader<R>` with a default buffer capacity. The default is currently 8 KB,
62 /// but may change in the future.
67 /// use std::io::BufReader;
68 /// use std::fs::File;
70 /// fn main() -> std::io::Result<()> {
71 /// let f = File::open("log.txt")?;
72 /// let reader = BufReader::new(f);
76 #[stable(feature = "rust1", since = "1.0.0")]
77 pub fn new(inner: R) -> BufReader<R> {
78 BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
81 /// Creates a new `BufReader<R>` with the specified buffer capacity.
85 /// Creating a buffer with ten bytes of capacity:
88 /// use std::io::BufReader;
89 /// use std::fs::File;
91 /// fn main() -> std::io::Result<()> {
92 /// let f = File::open("log.txt")?;
93 /// let reader = BufReader::with_capacity(10, f);
97 #[stable(feature = "rust1", since = "1.0.0")]
98 pub fn with_capacity(capacity: usize, inner: R) -> BufReader<R> {
100 let mut buffer = Vec::with_capacity(capacity);
101 buffer.set_len(capacity);
102 inner.initializer().initialize(&mut buffer);
103 BufReader { inner, buf: buffer.into_boxed_slice(), pos: 0, cap: 0 }
108 impl<R> BufReader<R> {
109 /// Gets a reference to the underlying reader.
111 /// It is inadvisable to directly read from the underlying reader.
116 /// use std::io::BufReader;
117 /// use std::fs::File;
119 /// fn main() -> std::io::Result<()> {
120 /// let f1 = File::open("log.txt")?;
121 /// let reader = BufReader::new(f1);
123 /// let f2 = reader.get_ref();
127 #[stable(feature = "rust1", since = "1.0.0")]
128 pub fn get_ref(&self) -> &R {
132 /// Gets a mutable reference to the underlying reader.
134 /// It is inadvisable to directly read from the underlying reader.
139 /// use std::io::BufReader;
140 /// use std::fs::File;
142 /// fn main() -> std::io::Result<()> {
143 /// let f1 = File::open("log.txt")?;
144 /// let mut reader = BufReader::new(f1);
146 /// let f2 = reader.get_mut();
150 #[stable(feature = "rust1", since = "1.0.0")]
151 pub fn get_mut(&mut self) -> &mut R {
155 /// Returns a reference to the internally buffered data.
157 /// Unlike [`fill_buf`], this will not attempt to fill the buffer if it is empty.
159 /// [`fill_buf`]: BufRead::fill_buf
164 /// use std::io::{BufReader, BufRead};
165 /// use std::fs::File;
167 /// fn main() -> std::io::Result<()> {
168 /// let f = File::open("log.txt")?;
169 /// let mut reader = BufReader::new(f);
170 /// assert!(reader.buffer().is_empty());
172 /// if reader.fill_buf()?.len() > 0 {
173 /// assert!(!reader.buffer().is_empty());
178 #[stable(feature = "bufreader_buffer", since = "1.37.0")]
179 pub fn buffer(&self) -> &[u8] {
180 &self.buf[self.pos..self.cap]
183 /// Returns the number of bytes the internal buffer can hold at once.
188 /// use std::io::{BufReader, BufRead};
189 /// use std::fs::File;
191 /// fn main() -> std::io::Result<()> {
192 /// let f = File::open("log.txt")?;
193 /// let mut reader = BufReader::new(f);
195 /// let capacity = reader.capacity();
196 /// let buffer = reader.fill_buf()?;
197 /// assert!(buffer.len() <= capacity);
201 #[stable(feature = "buffered_io_capacity", since = "1.46.0")]
202 pub fn capacity(&self) -> usize {
206 /// Unwraps this `BufReader<R>`, returning the underlying reader.
208 /// Note that any leftover data in the internal buffer is lost. Therefore,
209 /// a following read from the underlying reader may lead to data loss.
214 /// use std::io::BufReader;
215 /// use std::fs::File;
217 /// fn main() -> std::io::Result<()> {
218 /// let f1 = File::open("log.txt")?;
219 /// let reader = BufReader::new(f1);
221 /// let f2 = reader.into_inner();
225 #[stable(feature = "rust1", since = "1.0.0")]
226 pub fn into_inner(self) -> R {
230 /// Invalidates all data in the internal buffer.
232 fn discard_buffer(&mut self) {
238 impl<R: Seek> BufReader<R> {
239 /// Seeks relative to the current position. If the new position lies within the buffer,
240 /// the buffer will not be flushed, allowing for more efficient seeks.
241 /// This method does not return the location of the underlying reader, so the caller
242 /// must track this information themselves if it is required.
243 #[unstable(feature = "bufreader_seek_relative", issue = "31100")]
244 pub fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
245 let pos = self.pos as u64;
247 if let Some(new_pos) = pos.checked_sub((-offset) as u64) {
248 self.pos = new_pos as usize;
252 if let Some(new_pos) = pos.checked_add(offset as u64) {
253 if new_pos <= self.cap as u64 {
254 self.pos = new_pos as usize;
259 self.seek(SeekFrom::Current(offset)).map(drop)
263 #[stable(feature = "rust1", since = "1.0.0")]
264 impl<R: Read> Read for BufReader<R> {
265 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
266 // If we don't have any buffered data and we're doing a massive read
267 // (larger than our internal buffer), bypass our internal buffer
269 if self.pos == self.cap && buf.len() >= self.buf.len() {
270 self.discard_buffer();
271 return self.inner.read(buf);
274 let mut rem = self.fill_buf()?;
281 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
282 let total_len = bufs.iter().map(|b| b.len()).sum::<usize>();
283 if self.pos == self.cap && total_len >= self.buf.len() {
284 self.discard_buffer();
285 return self.inner.read_vectored(bufs);
288 let mut rem = self.fill_buf()?;
289 rem.read_vectored(bufs)?
295 fn is_read_vectored(&self) -> bool {
296 self.inner.is_read_vectored()
299 // we can't skip unconditionally because of the large buffer case in read.
300 unsafe fn initializer(&self) -> Initializer {
301 self.inner.initializer()
305 #[stable(feature = "rust1", since = "1.0.0")]
306 impl<R: Read> BufRead for BufReader<R> {
307 fn fill_buf(&mut self) -> io::Result<&[u8]> {
308 // If we've reached the end of our internal buffer then we need to fetch
309 // some more data from the underlying reader.
310 // Branch using `>=` instead of the more correct `==`
311 // to tell the compiler that the pos..cap slice is always valid.
312 if self.pos >= self.cap {
313 debug_assert!(self.pos == self.cap);
314 self.cap = self.inner.read(&mut self.buf)?;
317 Ok(&self.buf[self.pos..self.cap])
320 fn consume(&mut self, amt: usize) {
321 self.pos = cmp::min(self.pos + amt, self.cap);
325 #[stable(feature = "rust1", since = "1.0.0")]
326 impl<R> fmt::Debug for BufReader<R>
330 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
331 fmt.debug_struct("BufReader")
332 .field("reader", &self.inner)
333 .field("buffer", &format_args!("{}/{}", self.cap - self.pos, self.buf.len()))
338 #[stable(feature = "rust1", since = "1.0.0")]
339 impl<R: Seek> Seek for BufReader<R> {
340 /// Seek to an offset, in bytes, in the underlying reader.
342 /// The position used for seeking with [`SeekFrom::Current`]`(_)` is the
343 /// position the underlying reader would be at if the `BufReader<R>` had no
346 /// Seeking always discards the internal buffer, even if the seek position
347 /// would otherwise fall within it. This guarantees that calling
348 /// [`BufReader::into_inner()`] immediately after a seek yields the underlying reader
349 /// at the same position.
351 /// To seek without discarding the internal buffer, use [`BufReader::seek_relative`].
353 /// See [`std::io::Seek`] for more details.
355 /// Note: In the edge case where you're seeking with [`SeekFrom::Current`]`(n)`
356 /// where `n` minus the internal buffer length overflows an `i64`, two
357 /// seeks will be performed instead of one. If the second seek returns
358 /// [`Err`], the underlying reader will be left at the same position it would
359 /// have if you called `seek` with [`SeekFrom::Current`]`(0)`.
361 /// [`std::io::Seek`]: Seek
362 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
364 if let SeekFrom::Current(n) = pos {
365 let remainder = (self.cap - self.pos) as i64;
366 // it should be safe to assume that remainder fits within an i64 as the alternative
367 // means we managed to allocate 8 exbibytes and that's absurd.
368 // But it's not out of the realm of possibility for some weird underlying reader to
369 // support seeking by i64::MIN so we need to handle underflow when subtracting
371 if let Some(offset) = n.checked_sub(remainder) {
372 result = self.inner.seek(SeekFrom::Current(offset))?;
374 // seek backwards by our remainder, and then by the offset
375 self.inner.seek(SeekFrom::Current(-remainder))?;
376 self.discard_buffer();
377 result = self.inner.seek(SeekFrom::Current(n))?;
380 // Seeking with Start/End doesn't care about our buffer length.
381 result = self.inner.seek(pos)?;
383 self.discard_buffer();
388 /// Wraps a writer and buffers its output.
390 /// It can be excessively inefficient to work directly with something that
391 /// implements [`Write`]. For example, every call to
392 /// [`write`][`TcpStream::write`] on [`TcpStream`] results in a system call. A
393 /// `BufWriter<W>` keeps an in-memory buffer of data and writes it to an underlying
394 /// writer in large, infrequent batches.
396 /// `BufWriter<W>` can improve the speed of programs that make *small* and
397 /// *repeated* write calls to the same file or network socket. It does not
398 /// help when writing very large amounts at once, or writing just one or a few
399 /// times. It also provides no advantage when writing to a destination that is
400 /// in memory, like a [`Vec`]<u8>`.
402 /// It is critical to call [`flush`] before `BufWriter<W>` is dropped. Though
403 /// dropping will attempt to flush the contents of the buffer, any errors
404 /// that happen in the process of dropping will be ignored. Calling [`flush`]
405 /// ensures that the buffer is empty and thus dropping will not even attempt
410 /// Let's write the numbers one through ten to a [`TcpStream`]:
413 /// use std::io::prelude::*;
414 /// use std::net::TcpStream;
416 /// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
419 /// stream.write(&[i+1]).unwrap();
423 /// Because we're not buffering, we write each one in turn, incurring the
424 /// overhead of a system call per byte written. We can fix this with a
428 /// use std::io::prelude::*;
429 /// use std::io::BufWriter;
430 /// use std::net::TcpStream;
432 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
435 /// stream.write(&[i+1]).unwrap();
437 /// stream.flush().unwrap();
440 /// By wrapping the stream with a `BufWriter<W>`, these ten writes are all grouped
441 /// together by the buffer and will all be written out in one system call when
442 /// the `stream` is flushed.
444 /// [`TcpStream::write`]: Write::write
445 /// [`TcpStream`]: crate::net::TcpStream
446 /// [`flush`]: Write::flush
447 #[stable(feature = "rust1", since = "1.0.0")]
448 pub struct BufWriter<W: Write> {
451 // #30888: If the inner writer panics in a call to write, we don't want to
452 // write the buffered data a second time in BufWriter's destructor. This
453 // flag tells the Drop impl if it should skip the flush.
457 /// An error returned by [`BufWriter::into_inner`] which combines an error that
458 /// happened while writing out the buffer, and the buffered writer object
459 /// which may be used to recover from the condition.
464 /// use std::io::BufWriter;
465 /// use std::net::TcpStream;
467 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
469 /// // do stuff with the stream
471 /// // we want to get our `TcpStream` back, so let's try:
473 /// let stream = match stream.into_inner() {
476 /// // Here, e is an IntoInnerError
477 /// panic!("An error occurred");
482 #[stable(feature = "rust1", since = "1.0.0")]
483 pub struct IntoInnerError<W>(W, Error);
485 impl<W: Write> BufWriter<W> {
486 /// Creates a new `BufWriter<W>` with a default buffer capacity. The default is currently 8 KB,
487 /// but may change in the future.
492 /// use std::io::BufWriter;
493 /// use std::net::TcpStream;
495 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
497 #[stable(feature = "rust1", since = "1.0.0")]
498 pub fn new(inner: W) -> BufWriter<W> {
499 BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
502 /// Creates a new `BufWriter<W>` with the specified buffer capacity.
506 /// Creating a buffer with a buffer of a hundred bytes.
509 /// use std::io::BufWriter;
510 /// use std::net::TcpStream;
512 /// let stream = TcpStream::connect("127.0.0.1:34254").unwrap();
513 /// let mut buffer = BufWriter::with_capacity(100, stream);
515 #[stable(feature = "rust1", since = "1.0.0")]
516 pub fn with_capacity(capacity: usize, inner: W) -> BufWriter<W> {
517 BufWriter { inner: Some(inner), buf: Vec::with_capacity(capacity), panicked: false }
520 fn flush_buf(&mut self) -> io::Result<()> {
522 let len = self.buf.len();
523 let mut ret = Ok(());
524 while written < len {
525 self.panicked = true;
526 let r = self.inner.as_mut().unwrap().write(&self.buf[written..]);
527 self.panicked = false;
532 Err(Error::new(ErrorKind::WriteZero, "failed to write the buffered data"));
535 Ok(n) => written += n,
536 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
544 self.buf.drain(..written);
549 /// Gets a reference to the underlying writer.
554 /// use std::io::BufWriter;
555 /// use std::net::TcpStream;
557 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
559 /// // we can use reference just like buffer
560 /// let reference = buffer.get_ref();
562 #[stable(feature = "rust1", since = "1.0.0")]
563 pub fn get_ref(&self) -> &W {
564 self.inner.as_ref().unwrap()
567 /// Gets a mutable reference to the underlying writer.
569 /// It is inadvisable to directly write to the underlying writer.
574 /// use std::io::BufWriter;
575 /// use std::net::TcpStream;
577 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
579 /// // we can use reference just like buffer
580 /// let reference = buffer.get_mut();
582 #[stable(feature = "rust1", since = "1.0.0")]
583 pub fn get_mut(&mut self) -> &mut W {
584 self.inner.as_mut().unwrap()
587 /// Returns a reference to the internally buffered data.
592 /// use std::io::BufWriter;
593 /// use std::net::TcpStream;
595 /// let buf_writer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
597 /// // See how many bytes are currently buffered
598 /// let bytes_buffered = buf_writer.buffer().len();
600 #[stable(feature = "bufreader_buffer", since = "1.37.0")]
601 pub fn buffer(&self) -> &[u8] {
605 /// Returns the number of bytes the internal buffer can hold without flushing.
610 /// use std::io::BufWriter;
611 /// use std::net::TcpStream;
613 /// let buf_writer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
615 /// // Check the capacity of the inner buffer
616 /// let capacity = buf_writer.capacity();
617 /// // Calculate how many bytes can be written without flushing
618 /// let without_flush = capacity - buf_writer.buffer().len();
620 #[stable(feature = "buffered_io_capacity", since = "1.46.0")]
621 pub fn capacity(&self) -> usize {
625 /// Unwraps this `BufWriter<W>`, returning the underlying writer.
627 /// The buffer is written out before returning the writer.
631 /// An [`Err`] will be returned if an error occurs while flushing the buffer.
636 /// use std::io::BufWriter;
637 /// use std::net::TcpStream;
639 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
641 /// // unwrap the TcpStream and flush the buffer
642 /// let stream = buffer.into_inner().unwrap();
644 #[stable(feature = "rust1", since = "1.0.0")]
645 pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
646 match self.flush_buf() {
647 Err(e) => Err(IntoInnerError(self, e)),
648 Ok(()) => Ok(self.inner.take().unwrap()),
653 #[stable(feature = "rust1", since = "1.0.0")]
654 impl<W: Write> Write for BufWriter<W> {
655 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
656 if self.buf.len() + buf.len() > self.buf.capacity() {
659 if buf.len() >= self.buf.capacity() {
660 self.panicked = true;
661 let r = self.get_mut().write(buf);
662 self.panicked = false;
669 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
670 let total_len = bufs.iter().map(|b| b.len()).sum::<usize>();
671 if self.buf.len() + total_len > self.buf.capacity() {
674 if total_len >= self.buf.capacity() {
675 self.panicked = true;
676 let r = self.get_mut().write_vectored(bufs);
677 self.panicked = false;
680 self.buf.write_vectored(bufs)
684 fn is_write_vectored(&self) -> bool {
685 self.get_ref().is_write_vectored()
688 fn flush(&mut self) -> io::Result<()> {
689 self.flush_buf().and_then(|()| self.get_mut().flush())
693 #[stable(feature = "rust1", since = "1.0.0")]
694 impl<W: Write> fmt::Debug for BufWriter<W>
698 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
699 fmt.debug_struct("BufWriter")
700 .field("writer", &self.inner.as_ref().unwrap())
701 .field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
706 #[stable(feature = "rust1", since = "1.0.0")]
707 impl<W: Write + Seek> Seek for BufWriter<W> {
708 /// Seek to the offset, in bytes, in the underlying writer.
710 /// Seeking always writes out the internal buffer before seeking.
711 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
712 self.flush_buf().and_then(|_| self.get_mut().seek(pos))
716 #[stable(feature = "rust1", since = "1.0.0")]
717 impl<W: Write> Drop for BufWriter<W> {
719 if self.inner.is_some() && !self.panicked {
720 // dtors should not panic, so we ignore a failed flush
721 let _r = self.flush_buf();
726 impl<W> IntoInnerError<W> {
727 /// Returns the error which caused the call to [`BufWriter::into_inner()`]
730 /// This error was returned when attempting to write the internal buffer.
735 /// use std::io::BufWriter;
736 /// use std::net::TcpStream;
738 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
740 /// // do stuff with the stream
742 /// // we want to get our `TcpStream` back, so let's try:
744 /// let stream = match stream.into_inner() {
747 /// // Here, e is an IntoInnerError, let's log the inner error.
749 /// // We'll just 'log' to stdout for this example.
750 /// println!("{}", e.error());
752 /// panic!("An unexpected error occurred.");
756 #[stable(feature = "rust1", since = "1.0.0")]
757 pub fn error(&self) -> &Error {
761 /// Returns the buffered writer instance which generated the error.
763 /// The returned object can be used for error recovery, such as
764 /// re-inspecting the buffer.
769 /// use std::io::BufWriter;
770 /// use std::net::TcpStream;
772 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
774 /// // do stuff with the stream
776 /// // we want to get our `TcpStream` back, so let's try:
778 /// let stream = match stream.into_inner() {
781 /// // Here, e is an IntoInnerError, let's re-examine the buffer:
782 /// let buffer = e.into_inner();
784 /// // do stuff to try to recover
786 /// // afterwards, let's just return the stream
787 /// buffer.into_inner().unwrap()
791 #[stable(feature = "rust1", since = "1.0.0")]
792 pub fn into_inner(self) -> W {
797 #[stable(feature = "rust1", since = "1.0.0")]
798 impl<W> From<IntoInnerError<W>> for Error {
799 fn from(iie: IntoInnerError<W>) -> Error {
804 #[stable(feature = "rust1", since = "1.0.0")]
805 impl<W: Send + fmt::Debug> error::Error for IntoInnerError<W> {
806 #[allow(deprecated, deprecated_in_future)]
807 fn description(&self) -> &str {
808 error::Error::description(self.error())
812 #[stable(feature = "rust1", since = "1.0.0")]
813 impl<W> fmt::Display for IntoInnerError<W> {
814 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
819 /// Wraps a writer and buffers output to it, flushing whenever a newline
820 /// (`0x0a`, `'\n'`) is detected.
822 /// The [`BufWriter`] struct wraps a writer and buffers its output.
823 /// But it only does this batched write when it goes out of scope, or when the
824 /// internal buffer is full. Sometimes, you'd prefer to write each line as it's
825 /// completed, rather than the entire buffer at once. Enter `LineWriter`. It
826 /// does exactly that.
828 /// Like [`BufWriter`], a `LineWriter`’s buffer will also be flushed when the
829 /// `LineWriter` goes out of scope or when its internal buffer is full.
831 /// If there's still a partial line in the buffer when the `LineWriter` is
832 /// dropped, it will flush those contents.
836 /// We can use `LineWriter` to write one line at a time, significantly
837 /// reducing the number of actual writes to the file.
840 /// use std::fs::{self, File};
841 /// use std::io::prelude::*;
842 /// use std::io::LineWriter;
844 /// fn main() -> std::io::Result<()> {
845 /// let road_not_taken = b"I shall be telling this with a sigh
846 /// Somewhere ages and ages hence:
847 /// Two roads diverged in a wood, and I -
848 /// I took the one less traveled by,
849 /// And that has made all the difference.";
851 /// let file = File::create("poem.txt")?;
852 /// let mut file = LineWriter::new(file);
854 /// file.write_all(b"I shall be telling this with a sigh")?;
856 /// // No bytes are written until a newline is encountered (or
857 /// // the internal buffer is filled).
858 /// assert_eq!(fs::read_to_string("poem.txt")?, "");
859 /// file.write_all(b"\n")?;
861 /// fs::read_to_string("poem.txt")?,
862 /// "I shall be telling this with a sigh\n",
865 /// // Write the rest of the poem.
866 /// file.write_all(b"Somewhere ages and ages hence:
867 /// Two roads diverged in a wood, and I -
868 /// I took the one less traveled by,
869 /// And that has made all the difference.")?;
871 /// // The last line of the poem doesn't end in a newline, so
872 /// // we have to flush or drop the `LineWriter` to finish
876 /// // Confirm the whole poem was written.
877 /// assert_eq!(fs::read("poem.txt")?, &road_not_taken[..]);
881 #[stable(feature = "rust1", since = "1.0.0")]
882 pub struct LineWriter<W: Write> {
887 impl<W: Write> LineWriter<W> {
888 /// Creates a new `LineWriter`.
893 /// use std::fs::File;
894 /// use std::io::LineWriter;
896 /// fn main() -> std::io::Result<()> {
897 /// let file = File::create("poem.txt")?;
898 /// let file = LineWriter::new(file);
902 #[stable(feature = "rust1", since = "1.0.0")]
903 pub fn new(inner: W) -> LineWriter<W> {
904 // Lines typically aren't that long, don't use a giant buffer
905 LineWriter::with_capacity(1024, inner)
908 /// Creates a new `LineWriter` with a specified capacity for the internal
914 /// use std::fs::File;
915 /// use std::io::LineWriter;
917 /// fn main() -> std::io::Result<()> {
918 /// let file = File::create("poem.txt")?;
919 /// let file = LineWriter::with_capacity(100, file);
923 #[stable(feature = "rust1", since = "1.0.0")]
924 pub fn with_capacity(capacity: usize, inner: W) -> LineWriter<W> {
925 LineWriter { inner: BufWriter::with_capacity(capacity, inner), need_flush: false }
928 /// Gets a reference to the underlying writer.
933 /// use std::fs::File;
934 /// use std::io::LineWriter;
936 /// fn main() -> std::io::Result<()> {
937 /// let file = File::create("poem.txt")?;
938 /// let file = LineWriter::new(file);
940 /// let reference = file.get_ref();
944 #[stable(feature = "rust1", since = "1.0.0")]
945 pub fn get_ref(&self) -> &W {
949 /// Gets a mutable reference to the underlying writer.
951 /// Caution must be taken when calling methods on the mutable reference
952 /// returned as extra writes could corrupt the output stream.
957 /// use std::fs::File;
958 /// use std::io::LineWriter;
960 /// fn main() -> std::io::Result<()> {
961 /// let file = File::create("poem.txt")?;
962 /// let mut file = LineWriter::new(file);
964 /// // we can use reference just like file
965 /// let reference = file.get_mut();
969 #[stable(feature = "rust1", since = "1.0.0")]
970 pub fn get_mut(&mut self) -> &mut W {
974 /// Unwraps this `LineWriter`, returning the underlying writer.
976 /// The internal buffer is written out before returning the writer.
980 /// An [`Err`] will be returned if an error occurs while flushing the buffer.
985 /// use std::fs::File;
986 /// use std::io::LineWriter;
988 /// fn main() -> std::io::Result<()> {
989 /// let file = File::create("poem.txt")?;
991 /// let writer: LineWriter<File> = LineWriter::new(file);
993 /// let file: File = writer.into_inner()?;
997 #[stable(feature = "rust1", since = "1.0.0")]
998 pub fn into_inner(self) -> Result<W, IntoInnerError<LineWriter<W>>> {
999 self.inner.into_inner().map_err(|IntoInnerError(buf, e)| {
1000 IntoInnerError(LineWriter { inner: buf, need_flush: false }, e)
1005 #[stable(feature = "rust1", since = "1.0.0")]
1006 impl<W: Write> Write for LineWriter<W> {
1007 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1008 if self.need_flush {
1012 // Find the last newline character in the buffer provided. If found then
1013 // we're going to write all the data up to that point and then flush,
1014 // otherwise we just write the whole block to the underlying writer.
1015 let i = match memchr::memrchr(b'\n', buf) {
1017 None => return self.inner.write(buf),
1020 // Ok, we're going to write a partial amount of the data given first
1021 // followed by flushing the newline. After we've successfully written
1022 // some data then we *must* report that we wrote that data, so future
1023 // errors are ignored. We set our internal `need_flush` flag, though, in
1024 // case flushing fails and we need to try it first next time.
1025 let n = self.inner.write(&buf[..=i])?;
1026 self.need_flush = true;
1027 if self.flush().is_err() || n != i + 1 {
1031 // At this point we successfully wrote `i + 1` bytes and flushed it out,
1032 // meaning that the entire line is now flushed out on the screen. While
1033 // we can attempt to finish writing the rest of the data provided.
1034 // Remember though that we ignore errors here as we've successfully
1035 // written data, so we need to report that.
1036 match self.inner.write(&buf[i + 1..]) {
1042 // Vectored writes are very similar to the writes above, but adjusted for
1043 // the list of buffers that we have to write.
1044 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
1045 if self.need_flush {
1049 // Find the last newline, and failing that write the whole buffer
1050 let last_newline = bufs.iter().enumerate().rev().find_map(|(i, buf)| {
1051 let pos = memchr::memrchr(b'\n', buf)?;
1054 let (i, j) = match last_newline {
1056 None => return self.inner.write_vectored(bufs),
1058 let (prefix, suffix) = bufs.split_at(i);
1059 let (buf, suffix) = suffix.split_at(1);
1062 // Write everything up to the last newline, flushing afterwards. Note
1063 // that only if we finished our entire `write_vectored` do we try the
1067 let prefix_amt = prefix.iter().map(|i| i.len()).sum();
1069 n += self.inner.write_vectored(prefix)?;
1070 self.need_flush = true;
1072 if n == prefix_amt {
1073 match self.inner.write(&buf[..=j]) {
1075 Err(e) if n == 0 => return Err(e),
1076 Err(_) => return Ok(n),
1078 self.need_flush = true;
1080 if self.flush().is_err() || n != j + 1 + prefix_amt {
1084 // ... and now write out everything remaining
1085 match self.inner.write(&buf[j + 1..]) {
1087 Err(_) => return Ok(n),
1090 if suffix.iter().map(|s| s.len()).sum::<usize>() == 0 {
1093 match self.inner.write_vectored(suffix) {
1099 fn flush(&mut self) -> io::Result<()> {
1100 self.inner.flush()?;
1101 self.need_flush = false;
1106 #[stable(feature = "rust1", since = "1.0.0")]
1107 impl<W: Write> fmt::Debug for LineWriter<W>
1111 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1112 fmt.debug_struct("LineWriter")
1113 .field("writer", &self.inner.inner)
1116 &format_args!("{}/{}", self.inner.buf.len(), self.inner.buf.capacity()),
1124 use crate::io::prelude::*;
1125 use crate::io::{self, BufReader, BufWriter, IoSlice, LineWriter, SeekFrom};
1126 use crate::sync::atomic::{AtomicUsize, Ordering};
1129 /// A dummy reader intended at testing short-reads propagation.
1130 pub struct ShortReader {
1131 lengths: Vec<usize>,
1134 impl Read for ShortReader {
1135 fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
1136 if self.lengths.is_empty() { Ok(0) } else { Ok(self.lengths.remove(0)) }
1141 fn test_buffered_reader() {
1142 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
1143 let mut reader = BufReader::with_capacity(2, inner);
1145 let mut buf = [0, 0, 0];
1146 let nread = reader.read(&mut buf);
1147 assert_eq!(nread.unwrap(), 3);
1148 assert_eq!(buf, [5, 6, 7]);
1149 assert_eq!(reader.buffer(), []);
1151 let mut buf = [0, 0];
1152 let nread = reader.read(&mut buf);
1153 assert_eq!(nread.unwrap(), 2);
1154 assert_eq!(buf, [0, 1]);
1155 assert_eq!(reader.buffer(), []);
1158 let nread = reader.read(&mut buf);
1159 assert_eq!(nread.unwrap(), 1);
1160 assert_eq!(buf, [2]);
1161 assert_eq!(reader.buffer(), [3]);
1163 let mut buf = [0, 0, 0];
1164 let nread = reader.read(&mut buf);
1165 assert_eq!(nread.unwrap(), 1);
1166 assert_eq!(buf, [3, 0, 0]);
1167 assert_eq!(reader.buffer(), []);
1169 let nread = reader.read(&mut buf);
1170 assert_eq!(nread.unwrap(), 1);
1171 assert_eq!(buf, [4, 0, 0]);
1172 assert_eq!(reader.buffer(), []);
1174 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1178 fn test_buffered_reader_seek() {
1179 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
1180 let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
1182 assert_eq!(reader.seek(SeekFrom::Start(3)).ok(), Some(3));
1183 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
1184 assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(3));
1185 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
1186 assert_eq!(reader.seek(SeekFrom::Current(1)).ok(), Some(4));
1187 assert_eq!(reader.fill_buf().ok(), Some(&[1, 2][..]));
1189 assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3));
1193 fn test_buffered_reader_seek_relative() {
1194 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
1195 let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
1197 assert!(reader.seek_relative(3).is_ok());
1198 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
1199 assert!(reader.seek_relative(0).is_ok());
1200 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
1201 assert!(reader.seek_relative(1).is_ok());
1202 assert_eq!(reader.fill_buf().ok(), Some(&[1][..]));
1203 assert!(reader.seek_relative(-1).is_ok());
1204 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
1205 assert!(reader.seek_relative(2).is_ok());
1206 assert_eq!(reader.fill_buf().ok(), Some(&[2, 3][..]));
1210 fn test_buffered_reader_invalidated_after_read() {
1211 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
1212 let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner));
1214 assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
1217 let mut buffer = [0, 0, 0, 0, 0];
1218 assert_eq!(reader.read(&mut buffer).ok(), Some(5));
1219 assert_eq!(buffer, [0, 1, 2, 3, 4]);
1221 assert!(reader.seek_relative(-2).is_ok());
1222 let mut buffer = [0, 0];
1223 assert_eq!(reader.read(&mut buffer).ok(), Some(2));
1224 assert_eq!(buffer, [3, 4]);
1228 fn test_buffered_reader_invalidated_after_seek() {
1229 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
1230 let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner));
1232 assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
1235 assert!(reader.seek(SeekFrom::Current(5)).is_ok());
1237 assert!(reader.seek_relative(-2).is_ok());
1238 let mut buffer = [0, 0];
1239 assert_eq!(reader.read(&mut buffer).ok(), Some(2));
1240 assert_eq!(buffer, [3, 4]);
1244 fn test_buffered_reader_seek_underflow() {
1245 // gimmick reader that yields its position modulo 256 for each byte
1246 struct PositionReader {
1249 impl Read for PositionReader {
1250 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1251 let len = buf.len();
1253 *x = self.pos as u8;
1254 self.pos = self.pos.wrapping_add(1);
1259 impl Seek for PositionReader {
1260 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
1262 SeekFrom::Start(n) => {
1265 SeekFrom::Current(n) => {
1266 self.pos = self.pos.wrapping_add(n as u64);
1268 SeekFrom::End(n) => {
1269 self.pos = u64::MAX.wrapping_add(n as u64);
1276 let mut reader = BufReader::with_capacity(5, PositionReader { pos: 0 });
1277 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1, 2, 3, 4][..]));
1278 assert_eq!(reader.seek(SeekFrom::End(-5)).ok(), Some(u64::MAX - 5));
1279 assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
1280 // the following seek will require two underlying seeks
1281 let expected = 9223372036854775802;
1282 assert_eq!(reader.seek(SeekFrom::Current(i64::MIN)).ok(), Some(expected));
1283 assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
1284 // seeking to 0 should empty the buffer.
1285 assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(expected));
1286 assert_eq!(reader.get_ref().pos, expected);
1290 fn test_buffered_reader_seek_underflow_discard_buffer_between_seeks() {
1291 // gimmick reader that returns Err after first seek
1292 struct ErrAfterFirstSeekReader {
1295 impl Read for ErrAfterFirstSeekReader {
1296 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1297 for x in &mut *buf {
1303 impl Seek for ErrAfterFirstSeekReader {
1304 fn seek(&mut self, _: SeekFrom) -> io::Result<u64> {
1305 if self.first_seek {
1306 self.first_seek = false;
1309 Err(io::Error::new(io::ErrorKind::Other, "oh no!"))
1314 let mut reader = BufReader::with_capacity(5, ErrAfterFirstSeekReader { first_seek: true });
1315 assert_eq!(reader.fill_buf().ok(), Some(&[0, 0, 0, 0, 0][..]));
1317 // The following seek will require two underlying seeks. The first will
1318 // succeed but the second will fail. This should still invalidate the
1320 assert!(reader.seek(SeekFrom::Current(i64::MIN)).is_err());
1321 assert_eq!(reader.buffer().len(), 0);
1325 fn test_buffered_writer() {
1326 let inner = Vec::new();
1327 let mut writer = BufWriter::with_capacity(2, inner);
1329 writer.write(&[0, 1]).unwrap();
1330 assert_eq!(writer.buffer(), []);
1331 assert_eq!(*writer.get_ref(), [0, 1]);
1333 writer.write(&[2]).unwrap();
1334 assert_eq!(writer.buffer(), [2]);
1335 assert_eq!(*writer.get_ref(), [0, 1]);
1337 writer.write(&[3]).unwrap();
1338 assert_eq!(writer.buffer(), [2, 3]);
1339 assert_eq!(*writer.get_ref(), [0, 1]);
1341 writer.flush().unwrap();
1342 assert_eq!(writer.buffer(), []);
1343 assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
1345 writer.write(&[4]).unwrap();
1346 writer.write(&[5]).unwrap();
1347 assert_eq!(writer.buffer(), [4, 5]);
1348 assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
1350 writer.write(&[6]).unwrap();
1351 assert_eq!(writer.buffer(), [6]);
1352 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]);
1354 writer.write(&[7, 8]).unwrap();
1355 assert_eq!(writer.buffer(), []);
1356 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]);
1358 writer.write(&[9, 10, 11]).unwrap();
1359 assert_eq!(writer.buffer(), []);
1360 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
1362 writer.flush().unwrap();
1363 assert_eq!(writer.buffer(), []);
1364 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
1368 fn test_buffered_writer_inner_flushes() {
1369 let mut w = BufWriter::with_capacity(3, Vec::new());
1370 w.write(&[0, 1]).unwrap();
1371 assert_eq!(*w.get_ref(), []);
1372 let w = w.into_inner().unwrap();
1373 assert_eq!(w, [0, 1]);
1377 fn test_buffered_writer_seek() {
1378 let mut w = BufWriter::with_capacity(3, io::Cursor::new(Vec::new()));
1379 w.write_all(&[0, 1, 2, 3, 4, 5]).unwrap();
1380 w.write_all(&[6, 7]).unwrap();
1381 assert_eq!(w.seek(SeekFrom::Current(0)).ok(), Some(8));
1382 assert_eq!(&w.get_ref().get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]);
1383 assert_eq!(w.seek(SeekFrom::Start(2)).ok(), Some(2));
1384 w.write_all(&[8, 9]).unwrap();
1385 assert_eq!(&w.into_inner().unwrap().into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]);
1389 fn test_read_until() {
1390 let inner: &[u8] = &[0, 1, 2, 1, 0];
1391 let mut reader = BufReader::with_capacity(2, inner);
1392 let mut v = Vec::new();
1393 reader.read_until(0, &mut v).unwrap();
1396 reader.read_until(2, &mut v).unwrap();
1397 assert_eq!(v, [1, 2]);
1399 reader.read_until(1, &mut v).unwrap();
1402 reader.read_until(8, &mut v).unwrap();
1405 reader.read_until(9, &mut v).unwrap();
1410 fn test_line_buffer_fail_flush() {
1412 struct FailFlushWriter<'a>(&'a mut Vec<u8>);
1414 impl Write for FailFlushWriter<'_> {
1415 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1416 self.0.extend_from_slice(buf);
1419 fn flush(&mut self) -> io::Result<()> {
1420 Err(io::Error::new(io::ErrorKind::Other, "flush failed"))
1424 let mut buf = Vec::new();
1426 let mut writer = LineWriter::new(FailFlushWriter(&mut buf));
1427 let to_write = b"abc\ndef";
1428 if let Ok(written) = writer.write(to_write) {
1429 assert!(written < to_write.len(), "didn't flush on new line");
1434 assert!(buf.is_empty(), "write returned an error but wrote data");
1438 fn test_line_buffer() {
1439 let mut writer = LineWriter::new(Vec::new());
1440 writer.write(&[0]).unwrap();
1441 assert_eq!(*writer.get_ref(), []);
1442 writer.write(&[1]).unwrap();
1443 assert_eq!(*writer.get_ref(), []);
1444 writer.flush().unwrap();
1445 assert_eq!(*writer.get_ref(), [0, 1]);
1446 writer.write(&[0, b'\n', 1, b'\n', 2]).unwrap();
1447 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n']);
1448 writer.flush().unwrap();
1449 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2]);
1450 writer.write(&[3, b'\n']).unwrap();
1451 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n']);
1455 fn test_read_line() {
1456 let in_buf: &[u8] = b"a\nb\nc";
1457 let mut reader = BufReader::with_capacity(2, in_buf);
1458 let mut s = String::new();
1459 reader.read_line(&mut s).unwrap();
1460 assert_eq!(s, "a\n");
1462 reader.read_line(&mut s).unwrap();
1463 assert_eq!(s, "b\n");
1465 reader.read_line(&mut s).unwrap();
1468 reader.read_line(&mut s).unwrap();
1474 let in_buf: &[u8] = b"a\nb\nc";
1475 let reader = BufReader::with_capacity(2, in_buf);
1476 let mut it = reader.lines();
1477 assert_eq!(it.next().unwrap().unwrap(), "a".to_string());
1478 assert_eq!(it.next().unwrap().unwrap(), "b".to_string());
1479 assert_eq!(it.next().unwrap().unwrap(), "c".to_string());
1480 assert!(it.next().is_none());
1484 fn test_short_reads() {
1485 let inner = ShortReader { lengths: vec![0, 1, 2, 0, 1, 0] };
1486 let mut reader = BufReader::new(inner);
1487 let mut buf = [0, 0];
1488 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1489 assert_eq!(reader.read(&mut buf).unwrap(), 1);
1490 assert_eq!(reader.read(&mut buf).unwrap(), 2);
1491 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1492 assert_eq!(reader.read(&mut buf).unwrap(), 1);
1493 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1494 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1499 fn dont_panic_in_drop_on_panicked_flush() {
1500 struct FailFlushWriter;
1502 impl Write for FailFlushWriter {
1503 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1506 fn flush(&mut self) -> io::Result<()> {
1507 Err(io::Error::last_os_error())
1511 let writer = FailFlushWriter;
1512 let _writer = BufWriter::new(writer);
1514 // If writer panics *again* due to the flush error then the process will
1520 #[cfg_attr(target_os = "emscripten", ignore)]
1521 fn panic_in_write_doesnt_flush_in_drop() {
1522 static WRITES: AtomicUsize = AtomicUsize::new(0);
1526 impl Write for PanicWriter {
1527 fn write(&mut self, _: &[u8]) -> io::Result<usize> {
1528 WRITES.fetch_add(1, Ordering::SeqCst);
1531 fn flush(&mut self) -> io::Result<()> {
1537 let mut writer = BufWriter::new(PanicWriter);
1538 let _ = writer.write(b"hello world");
1539 let _ = writer.flush();
1544 assert_eq!(WRITES.load(Ordering::SeqCst), 1);
1548 fn bench_buffered_reader(b: &mut test::Bencher) {
1549 b.iter(|| BufReader::new(io::empty()));
1553 fn bench_buffered_writer(b: &mut test::Bencher) {
1554 b.iter(|| BufWriter::new(io::sink()));
1557 struct AcceptOneThenFail {
1562 impl Write for AcceptOneThenFail {
1563 fn write(&mut self, data: &[u8]) -> io::Result<usize> {
1565 assert_eq!(data, b"a\nb\n");
1566 self.written = true;
1569 Err(io::Error::new(io::ErrorKind::NotFound, "test"))
1573 fn flush(&mut self) -> io::Result<()> {
1574 assert!(self.written);
1575 assert!(!self.flushed);
1576 self.flushed = true;
1577 Err(io::Error::new(io::ErrorKind::Other, "test"))
1582 fn erroneous_flush_retried() {
1583 let a = AcceptOneThenFail { written: false, flushed: false };
1585 let mut l = LineWriter::new(a);
1586 assert_eq!(l.write(b"a\nb\na").unwrap(), 4);
1587 assert!(l.get_ref().written);
1588 assert!(l.get_ref().flushed);
1589 l.get_mut().flushed = false;
1591 assert_eq!(l.write(b"a").unwrap_err().kind(), io::ErrorKind::Other)
1595 fn line_vectored() {
1596 let mut a = LineWriter::new(Vec::new());
1600 IoSlice::new(b"\n"),
1607 assert_eq!(a.get_ref(), b"\n");
1621 assert_eq!(a.get_ref(), b"\n");
1623 assert_eq!(a.get_ref(), b"\nabac");
1624 assert_eq!(a.write_vectored(&[]).unwrap(), 0);
1635 assert_eq!(a.write_vectored(&[IoSlice::new(b"a\nb"),]).unwrap(), 3);
1636 assert_eq!(a.get_ref(), b"\nabaca\n");
1640 fn line_vectored_partial_and_errors() {
1642 Write { inputs: Vec<&'static [u8]>, output: io::Result<usize> },
1643 Flush { output: io::Result<()> },
1649 impl Write for Writer {
1650 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1651 self.write_vectored(&[IoSlice::new(buf)])
1654 fn write_vectored(&mut self, buf: &[IoSlice<'_>]) -> io::Result<usize> {
1655 match self.calls.pop().unwrap() {
1656 Call::Write { inputs, output } => {
1657 assert_eq!(inputs, buf.iter().map(|b| &**b).collect::<Vec<_>>());
1660 _ => panic!("unexpected call to write"),
1664 fn flush(&mut self) -> io::Result<()> {
1665 match self.calls.pop().unwrap() {
1666 Call::Flush { output } => output,
1667 _ => panic!("unexpected call to flush"),
1672 impl Drop for Writer {
1673 fn drop(&mut self) {
1674 if !thread::panicking() {
1675 assert_eq!(self.calls.len(), 0);
1680 // partial writes keep going
1681 let mut a = LineWriter::new(Writer { calls: Vec::new() });
1682 a.write_vectored(&[IoSlice::new(&[]), IoSlice::new(b"abc")]).unwrap();
1683 a.get_mut().calls.push(Call::Flush { output: Ok(()) });
1684 a.get_mut().calls.push(Call::Write { inputs: vec![b"bcx\n"], output: Ok(4) });
1685 a.get_mut().calls.push(Call::Write { inputs: vec![b"abcx\n"], output: Ok(1) });
1686 a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\n")]).unwrap();
1687 a.get_mut().calls.push(Call::Flush { output: Ok(()) });
1690 // erroneous writes stop and don't write more
1691 a.get_mut().calls.push(Call::Write { inputs: vec![b"x\n"], output: Err(err()) });
1692 assert_eq!(a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\na")]).unwrap(), 2);
1693 a.get_mut().calls.push(Call::Flush { output: Ok(()) });
1694 a.get_mut().calls.push(Call::Write { inputs: vec![b"x\n"], output: Ok(2) });
1697 fn err() -> io::Error {
1698 io::Error::new(io::ErrorKind::Other, "x")