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 /// [`Read`]: ../../std/io/trait.Read.html
33 /// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read
34 /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
39 /// use std::io::prelude::*;
40 /// use std::io::BufReader;
41 /// use std::fs::File;
43 /// fn main() -> std::io::Result<()> {
44 /// let f = File::open("log.txt")?;
45 /// let mut reader = BufReader::new(f);
47 /// let mut line = String::new();
48 /// let len = reader.read_line(&mut line)?;
49 /// println!("First line is {} bytes long", len);
53 #[stable(feature = "rust1", since = "1.0.0")]
54 pub struct BufReader<R> {
61 impl<R: Read> BufReader<R> {
62 /// Creates a new `BufReader<R>` with a default buffer capacity. The default is currently 8 KB,
63 /// but may change in the future.
68 /// use std::io::BufReader;
69 /// use std::fs::File;
71 /// fn main() -> std::io::Result<()> {
72 /// let f = File::open("log.txt")?;
73 /// let reader = BufReader::new(f);
77 #[stable(feature = "rust1", since = "1.0.0")]
78 pub fn new(inner: R) -> BufReader<R> {
79 BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
82 /// Creates a new `BufReader<R>` with the specified buffer capacity.
86 /// Creating a buffer with ten bytes of capacity:
89 /// use std::io::BufReader;
90 /// use std::fs::File;
92 /// fn main() -> std::io::Result<()> {
93 /// let f = File::open("log.txt")?;
94 /// let reader = BufReader::with_capacity(10, f);
98 #[stable(feature = "rust1", since = "1.0.0")]
99 pub fn with_capacity(capacity: usize, inner: R) -> BufReader<R> {
101 let mut buffer = Vec::with_capacity(capacity);
102 buffer.set_len(capacity);
103 inner.initializer().initialize(&mut buffer);
104 BufReader { inner, buf: buffer.into_boxed_slice(), pos: 0, cap: 0 }
109 impl<R> BufReader<R> {
110 /// Gets a reference to the underlying reader.
112 /// It is inadvisable to directly read from the underlying reader.
117 /// use std::io::BufReader;
118 /// use std::fs::File;
120 /// fn main() -> std::io::Result<()> {
121 /// let f1 = File::open("log.txt")?;
122 /// let reader = BufReader::new(f1);
124 /// let f2 = reader.get_ref();
128 #[stable(feature = "rust1", since = "1.0.0")]
129 pub fn get_ref(&self) -> &R {
133 /// Gets a mutable reference to the underlying reader.
135 /// It is inadvisable to directly read from the underlying reader.
140 /// use std::io::BufReader;
141 /// use std::fs::File;
143 /// fn main() -> std::io::Result<()> {
144 /// let f1 = File::open("log.txt")?;
145 /// let mut reader = BufReader::new(f1);
147 /// let f2 = reader.get_mut();
151 #[stable(feature = "rust1", since = "1.0.0")]
152 pub fn get_mut(&mut self) -> &mut R {
156 /// Returns a reference to the internally buffered data.
158 /// Unlike `fill_buf`, this will not attempt to fill the buffer if it is empty.
163 /// use std::io::{BufReader, BufRead};
164 /// use std::fs::File;
166 /// fn main() -> std::io::Result<()> {
167 /// let f = File::open("log.txt")?;
168 /// let mut reader = BufReader::new(f);
169 /// assert!(reader.buffer().is_empty());
171 /// if reader.fill_buf()?.len() > 0 {
172 /// assert!(!reader.buffer().is_empty());
177 #[stable(feature = "bufreader_buffer", since = "1.37.0")]
178 pub fn buffer(&self) -> &[u8] {
179 &self.buf[self.pos..self.cap]
182 /// Returns the number of bytes the internal buffer can hold at once.
187 /// use std::io::{BufReader, BufRead};
188 /// use std::fs::File;
190 /// fn main() -> std::io::Result<()> {
191 /// let f = File::open("log.txt")?;
192 /// let mut reader = BufReader::new(f);
194 /// let capacity = reader.capacity();
195 /// let buffer = reader.fill_buf()?;
196 /// assert!(buffer.len() <= capacity);
200 #[stable(feature = "buffered_io_capacity", since = "1.46.0")]
201 pub fn capacity(&self) -> usize {
205 /// Unwraps this `BufReader<R>`, returning the underlying reader.
207 /// Note that any leftover data in the internal buffer is lost. Therefore,
208 /// a following read from the underlying reader may lead to data loss.
213 /// use std::io::BufReader;
214 /// use std::fs::File;
216 /// fn main() -> std::io::Result<()> {
217 /// let f1 = File::open("log.txt")?;
218 /// let reader = BufReader::new(f1);
220 /// let f2 = reader.into_inner();
224 #[stable(feature = "rust1", since = "1.0.0")]
225 pub fn into_inner(self) -> R {
229 /// Invalidates all data in the internal buffer.
231 fn discard_buffer(&mut self) {
237 impl<R: Seek> BufReader<R> {
238 /// Seeks relative to the current position. If the new position lies within the buffer,
239 /// the buffer will not be flushed, allowing for more efficient seeks.
240 /// This method does not return the location of the underlying reader, so the caller
241 /// must track this information themselves if it is required.
242 #[unstable(feature = "bufreader_seek_relative", issue = "31100")]
243 pub fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
244 let pos = self.pos as u64;
246 if let Some(new_pos) = pos.checked_sub((-offset) as u64) {
247 self.pos = new_pos as usize;
251 if let Some(new_pos) = pos.checked_add(offset as u64) {
252 if new_pos <= self.cap as u64 {
253 self.pos = new_pos as usize;
258 self.seek(SeekFrom::Current(offset)).map(drop)
262 #[stable(feature = "rust1", since = "1.0.0")]
263 impl<R: Read> Read for BufReader<R> {
264 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
265 // If we don't have any buffered data and we're doing a massive read
266 // (larger than our internal buffer), bypass our internal buffer
268 if self.pos == self.cap && buf.len() >= self.buf.len() {
269 self.discard_buffer();
270 return self.inner.read(buf);
273 let mut rem = self.fill_buf()?;
280 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
281 let total_len = bufs.iter().map(|b| b.len()).sum::<usize>();
282 if self.pos == self.cap && total_len >= self.buf.len() {
283 self.discard_buffer();
284 return self.inner.read_vectored(bufs);
287 let mut rem = self.fill_buf()?;
288 rem.read_vectored(bufs)?
294 fn is_read_vectored(&self) -> bool {
295 self.inner.is_read_vectored()
298 // we can't skip unconditionally because of the large buffer case in read.
299 unsafe fn initializer(&self) -> Initializer {
300 self.inner.initializer()
304 #[stable(feature = "rust1", since = "1.0.0")]
305 impl<R: Read> BufRead for BufReader<R> {
306 fn fill_buf(&mut self) -> io::Result<&[u8]> {
307 // If we've reached the end of our internal buffer then we need to fetch
308 // some more data from the underlying reader.
309 // Branch using `>=` instead of the more correct `==`
310 // to tell the compiler that the pos..cap slice is always valid.
311 if self.pos >= self.cap {
312 debug_assert!(self.pos == self.cap);
313 self.cap = self.inner.read(&mut self.buf)?;
316 Ok(&self.buf[self.pos..self.cap])
319 fn consume(&mut self, amt: usize) {
320 self.pos = cmp::min(self.pos + amt, self.cap);
324 #[stable(feature = "rust1", since = "1.0.0")]
325 impl<R> fmt::Debug for BufReader<R>
329 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
330 fmt.debug_struct("BufReader")
331 .field("reader", &self.inner)
332 .field("buffer", &format_args!("{}/{}", self.cap - self.pos, self.buf.len()))
337 #[stable(feature = "rust1", since = "1.0.0")]
338 impl<R: Seek> Seek for BufReader<R> {
339 /// Seek to an offset, in bytes, in the underlying reader.
341 /// The position used for seeking with `SeekFrom::Current(_)` is the
342 /// position the underlying reader would be at if the `BufReader<R>` had no
345 /// Seeking always discards the internal buffer, even if the seek position
346 /// would otherwise fall within it. This guarantees that calling
347 /// `.into_inner()` immediately after a seek yields the underlying reader
348 /// at the same position.
350 /// To seek without discarding the internal buffer, use [`BufReader::seek_relative`].
352 /// See [`std::io::Seek`] for more details.
354 /// Note: In the edge case where you're seeking with `SeekFrom::Current(n)`
355 /// where `n` minus the internal buffer length overflows an `i64`, two
356 /// seeks will be performed instead of one. If the second seek returns
357 /// `Err`, the underlying reader will be left at the same position it would
358 /// have if you called `seek` with `SeekFrom::Current(0)`.
360 /// [`BufReader::seek_relative`]: struct.BufReader.html#method.seek_relative
361 /// [`std::io::Seek`]: trait.Seek.html
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 /// [`Write`]: ../../std/io/trait.Write.html
445 /// [`TcpStream::write`]: ../../std/net/struct.TcpStream.html#method.write
446 /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
447 /// [`flush`]: #method.flush
448 #[stable(feature = "rust1", since = "1.0.0")]
449 pub struct BufWriter<W: Write> {
452 // #30888: If the inner writer panics in a call to write, we don't want to
453 // write the buffered data a second time in BufWriter's destructor. This
454 // flag tells the Drop impl if it should skip the flush.
458 /// An error returned by `into_inner` which combines an error that
459 /// happened while writing out the buffer, and the buffered writer object
460 /// which may be used to recover from the condition.
465 /// use std::io::BufWriter;
466 /// use std::net::TcpStream;
468 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
470 /// // do stuff with the stream
472 /// // we want to get our `TcpStream` back, so let's try:
474 /// let stream = match stream.into_inner() {
477 /// // Here, e is an IntoInnerError
478 /// panic!("An error occurred");
483 #[stable(feature = "rust1", since = "1.0.0")]
484 pub struct IntoInnerError<W>(W, Error);
486 impl<W: Write> BufWriter<W> {
487 /// Creates a new `BufWriter<W>` with a default buffer capacity. The default is currently 8 KB,
488 /// but may change in the future.
493 /// use std::io::BufWriter;
494 /// use std::net::TcpStream;
496 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
498 #[stable(feature = "rust1", since = "1.0.0")]
499 pub fn new(inner: W) -> BufWriter<W> {
500 BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
503 /// Creates a new `BufWriter<W>` with the specified buffer capacity.
507 /// Creating a buffer with a buffer of a hundred bytes.
510 /// use std::io::BufWriter;
511 /// use std::net::TcpStream;
513 /// let stream = TcpStream::connect("127.0.0.1:34254").unwrap();
514 /// let mut buffer = BufWriter::with_capacity(100, stream);
516 #[stable(feature = "rust1", since = "1.0.0")]
517 pub fn with_capacity(capacity: usize, inner: W) -> BufWriter<W> {
518 BufWriter { inner: Some(inner), buf: Vec::with_capacity(capacity), panicked: false }
521 fn flush_buf(&mut self) -> io::Result<()> {
523 let len = self.buf.len();
524 let mut ret = Ok(());
525 while written < len {
526 self.panicked = true;
527 let r = self.inner.as_mut().unwrap().write(&self.buf[written..]);
528 self.panicked = false;
533 Err(Error::new(ErrorKind::WriteZero, "failed to write the buffered data"));
536 Ok(n) => written += n,
537 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
545 self.buf.drain(..written);
550 /// Gets a reference to the underlying writer.
555 /// use std::io::BufWriter;
556 /// use std::net::TcpStream;
558 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
560 /// // we can use reference just like buffer
561 /// let reference = buffer.get_ref();
563 #[stable(feature = "rust1", since = "1.0.0")]
564 pub fn get_ref(&self) -> &W {
565 self.inner.as_ref().unwrap()
568 /// Gets a mutable reference to the underlying writer.
570 /// It is inadvisable to directly write to the underlying writer.
575 /// use std::io::BufWriter;
576 /// use std::net::TcpStream;
578 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
580 /// // we can use reference just like buffer
581 /// let reference = buffer.get_mut();
583 #[stable(feature = "rust1", since = "1.0.0")]
584 pub fn get_mut(&mut self) -> &mut W {
585 self.inner.as_mut().unwrap()
588 /// Returns a reference to the internally buffered data.
593 /// use std::io::BufWriter;
594 /// use std::net::TcpStream;
596 /// let buf_writer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
598 /// // See how many bytes are currently buffered
599 /// let bytes_buffered = buf_writer.buffer().len();
601 #[stable(feature = "bufreader_buffer", since = "1.37.0")]
602 pub fn buffer(&self) -> &[u8] {
606 /// Returns the number of bytes the internal buffer can hold without flushing.
611 /// use std::io::BufWriter;
612 /// use std::net::TcpStream;
614 /// let buf_writer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
616 /// // Check the capacity of the inner buffer
617 /// let capacity = buf_writer.capacity();
618 /// // Calculate how many bytes can be written without flushing
619 /// let without_flush = capacity - buf_writer.buffer().len();
621 #[stable(feature = "buffered_io_capacity", since = "1.46.0")]
622 pub fn capacity(&self) -> usize {
626 /// Unwraps this `BufWriter<W>`, returning the underlying writer.
628 /// The buffer is written out before returning the writer.
632 /// An `Err` will be returned if an error occurs while flushing the buffer.
637 /// use std::io::BufWriter;
638 /// use std::net::TcpStream;
640 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
642 /// // unwrap the TcpStream and flush the buffer
643 /// let stream = buffer.into_inner().unwrap();
645 #[stable(feature = "rust1", since = "1.0.0")]
646 pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
647 match self.flush_buf() {
648 Err(e) => Err(IntoInnerError(self, e)),
649 Ok(()) => Ok(self.inner.take().unwrap()),
654 #[stable(feature = "rust1", since = "1.0.0")]
655 impl<W: Write> Write for BufWriter<W> {
656 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
657 if self.buf.len() + buf.len() > self.buf.capacity() {
660 if buf.len() >= self.buf.capacity() {
661 self.panicked = true;
662 let r = self.get_mut().write(buf);
663 self.panicked = false;
670 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
671 let total_len = bufs.iter().map(|b| b.len()).sum::<usize>();
672 if self.buf.len() + total_len > self.buf.capacity() {
675 if total_len >= self.buf.capacity() {
676 self.panicked = true;
677 let r = self.get_mut().write_vectored(bufs);
678 self.panicked = false;
681 self.buf.write_vectored(bufs)
685 fn is_write_vectored(&self) -> bool {
686 self.get_ref().is_write_vectored()
689 fn flush(&mut self) -> io::Result<()> {
690 self.flush_buf().and_then(|()| self.get_mut().flush())
694 #[stable(feature = "rust1", since = "1.0.0")]
695 impl<W: Write> fmt::Debug for BufWriter<W>
699 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
700 fmt.debug_struct("BufWriter")
701 .field("writer", &self.inner.as_ref().unwrap())
702 .field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
707 #[stable(feature = "rust1", since = "1.0.0")]
708 impl<W: Write + Seek> Seek for BufWriter<W> {
709 /// Seek to the offset, in bytes, in the underlying writer.
711 /// Seeking always writes out the internal buffer before seeking.
712 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
713 self.flush_buf().and_then(|_| self.get_mut().seek(pos))
717 #[stable(feature = "rust1", since = "1.0.0")]
718 impl<W: Write> Drop for BufWriter<W> {
720 if self.inner.is_some() && !self.panicked {
721 // dtors should not panic, so we ignore a failed flush
722 let _r = self.flush_buf();
727 impl<W> IntoInnerError<W> {
728 /// Returns the error which caused the call to `into_inner()` to fail.
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`][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`][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 /// [bufwriter]: struct.BufWriter.html
833 /// If there's still a partial line in the buffer when the `LineWriter` is
834 /// dropped, it will flush those contents.
838 /// We can use `LineWriter` to write one line at a time, significantly
839 /// reducing the number of actual writes to the file.
842 /// use std::fs::{self, File};
843 /// use std::io::prelude::*;
844 /// use std::io::LineWriter;
846 /// fn main() -> std::io::Result<()> {
847 /// let road_not_taken = b"I shall be telling this with a sigh
848 /// Somewhere ages and ages hence:
849 /// Two roads diverged in a wood, and I -
850 /// I took the one less traveled by,
851 /// And that has made all the difference.";
853 /// let file = File::create("poem.txt")?;
854 /// let mut file = LineWriter::new(file);
856 /// file.write_all(b"I shall be telling this with a sigh")?;
858 /// // No bytes are written until a newline is encountered (or
859 /// // the internal buffer is filled).
860 /// assert_eq!(fs::read_to_string("poem.txt")?, "");
861 /// file.write_all(b"\n")?;
863 /// fs::read_to_string("poem.txt")?,
864 /// "I shall be telling this with a sigh\n",
867 /// // Write the rest of the poem.
868 /// file.write_all(b"Somewhere ages and ages hence:
869 /// Two roads diverged in a wood, and I -
870 /// I took the one less traveled by,
871 /// And that has made all the difference.")?;
873 /// // The last line of the poem doesn't end in a newline, so
874 /// // we have to flush or drop the `LineWriter` to finish
878 /// // Confirm the whole poem was written.
879 /// assert_eq!(fs::read("poem.txt")?, &road_not_taken[..]);
883 #[stable(feature = "rust1", since = "1.0.0")]
884 pub struct LineWriter<W: Write> {
889 impl<W: Write> LineWriter<W> {
890 /// Creates a new `LineWriter`.
895 /// use std::fs::File;
896 /// use std::io::LineWriter;
898 /// fn main() -> std::io::Result<()> {
899 /// let file = File::create("poem.txt")?;
900 /// let file = LineWriter::new(file);
904 #[stable(feature = "rust1", since = "1.0.0")]
905 pub fn new(inner: W) -> LineWriter<W> {
906 // Lines typically aren't that long, don't use a giant buffer
907 LineWriter::with_capacity(1024, inner)
910 /// Creates a new `LineWriter` with a specified capacity for the internal
916 /// use std::fs::File;
917 /// use std::io::LineWriter;
919 /// fn main() -> std::io::Result<()> {
920 /// let file = File::create("poem.txt")?;
921 /// let file = LineWriter::with_capacity(100, file);
925 #[stable(feature = "rust1", since = "1.0.0")]
926 pub fn with_capacity(capacity: usize, inner: W) -> LineWriter<W> {
927 LineWriter { inner: BufWriter::with_capacity(capacity, inner), need_flush: false }
930 /// Gets a reference to the underlying writer.
935 /// use std::fs::File;
936 /// use std::io::LineWriter;
938 /// fn main() -> std::io::Result<()> {
939 /// let file = File::create("poem.txt")?;
940 /// let file = LineWriter::new(file);
942 /// let reference = file.get_ref();
946 #[stable(feature = "rust1", since = "1.0.0")]
947 pub fn get_ref(&self) -> &W {
951 /// Gets a mutable reference to the underlying writer.
953 /// Caution must be taken when calling methods on the mutable reference
954 /// returned as extra writes could corrupt the output stream.
959 /// use std::fs::File;
960 /// use std::io::LineWriter;
962 /// fn main() -> std::io::Result<()> {
963 /// let file = File::create("poem.txt")?;
964 /// let mut file = LineWriter::new(file);
966 /// // we can use reference just like file
967 /// let reference = file.get_mut();
971 #[stable(feature = "rust1", since = "1.0.0")]
972 pub fn get_mut(&mut self) -> &mut W {
976 /// Unwraps this `LineWriter`, returning the underlying writer.
978 /// The internal buffer is written out before returning the writer.
982 /// An `Err` will be returned if an error occurs while flushing the buffer.
987 /// use std::fs::File;
988 /// use std::io::LineWriter;
990 /// fn main() -> std::io::Result<()> {
991 /// let file = File::create("poem.txt")?;
993 /// let writer: LineWriter<File> = LineWriter::new(file);
995 /// let file: File = writer.into_inner()?;
999 #[stable(feature = "rust1", since = "1.0.0")]
1000 pub fn into_inner(self) -> Result<W, IntoInnerError<LineWriter<W>>> {
1001 self.inner.into_inner().map_err(|IntoInnerError(buf, e)| {
1002 IntoInnerError(LineWriter { inner: buf, need_flush: false }, e)
1007 #[stable(feature = "rust1", since = "1.0.0")]
1008 impl<W: Write> Write for LineWriter<W> {
1009 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1010 if self.need_flush {
1014 // Find the last newline character in the buffer provided. If found then
1015 // we're going to write all the data up to that point and then flush,
1016 // otherwise we just write the whole block to the underlying writer.
1017 let i = match memchr::memrchr(b'\n', buf) {
1019 None => return self.inner.write(buf),
1022 // Ok, we're going to write a partial amount of the data given first
1023 // followed by flushing the newline. After we've successfully written
1024 // some data then we *must* report that we wrote that data, so future
1025 // errors are ignored. We set our internal `need_flush` flag, though, in
1026 // case flushing fails and we need to try it first next time.
1027 let n = self.inner.write(&buf[..=i])?;
1028 self.need_flush = true;
1029 if self.flush().is_err() || n != i + 1 {
1033 // At this point we successfully wrote `i + 1` bytes and flushed it out,
1034 // meaning that the entire line is now flushed out on the screen. While
1035 // we can attempt to finish writing the rest of the data provided.
1036 // Remember though that we ignore errors here as we've successfully
1037 // written data, so we need to report that.
1038 match self.inner.write(&buf[i + 1..]) {
1044 // Vectored writes are very similar to the writes above, but adjusted for
1045 // the list of buffers that we have to write.
1046 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
1047 if self.need_flush {
1051 // Find the last newline, and failing that write the whole buffer
1052 let last_newline = bufs.iter().enumerate().rev().find_map(|(i, buf)| {
1053 let pos = memchr::memrchr(b'\n', buf)?;
1056 let (i, j) = match last_newline {
1058 None => return self.inner.write_vectored(bufs),
1060 let (prefix, suffix) = bufs.split_at(i);
1061 let (buf, suffix) = suffix.split_at(1);
1064 // Write everything up to the last newline, flushing afterwards. Note
1065 // that only if we finished our entire `write_vectored` do we try the
1069 let prefix_amt = prefix.iter().map(|i| i.len()).sum();
1071 n += self.inner.write_vectored(prefix)?;
1072 self.need_flush = true;
1074 if n == prefix_amt {
1075 match self.inner.write(&buf[..=j]) {
1077 Err(e) if n == 0 => return Err(e),
1078 Err(_) => return Ok(n),
1080 self.need_flush = true;
1082 if self.flush().is_err() || n != j + 1 + prefix_amt {
1086 // ... and now write out everything remaining
1087 match self.inner.write(&buf[j + 1..]) {
1089 Err(_) => return Ok(n),
1092 if suffix.iter().map(|s| s.len()).sum::<usize>() == 0 {
1095 match self.inner.write_vectored(suffix) {
1101 fn flush(&mut self) -> io::Result<()> {
1102 self.inner.flush()?;
1103 self.need_flush = false;
1108 #[stable(feature = "rust1", since = "1.0.0")]
1109 impl<W: Write> fmt::Debug for LineWriter<W>
1113 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1114 fmt.debug_struct("LineWriter")
1115 .field("writer", &self.inner.inner)
1118 &format_args!("{}/{}", self.inner.buf.len(), self.inner.buf.capacity()),
1126 use crate::io::prelude::*;
1127 use crate::io::{self, BufReader, BufWriter, IoSlice, LineWriter, SeekFrom};
1128 use crate::sync::atomic::{AtomicUsize, Ordering};
1131 /// A dummy reader intended at testing short-reads propagation.
1132 pub struct ShortReader {
1133 lengths: Vec<usize>,
1136 impl Read for ShortReader {
1137 fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
1138 if self.lengths.is_empty() { Ok(0) } else { Ok(self.lengths.remove(0)) }
1143 fn test_buffered_reader() {
1144 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
1145 let mut reader = BufReader::with_capacity(2, inner);
1147 let mut buf = [0, 0, 0];
1148 let nread = reader.read(&mut buf);
1149 assert_eq!(nread.unwrap(), 3);
1150 assert_eq!(buf, [5, 6, 7]);
1151 assert_eq!(reader.buffer(), []);
1153 let mut buf = [0, 0];
1154 let nread = reader.read(&mut buf);
1155 assert_eq!(nread.unwrap(), 2);
1156 assert_eq!(buf, [0, 1]);
1157 assert_eq!(reader.buffer(), []);
1160 let nread = reader.read(&mut buf);
1161 assert_eq!(nread.unwrap(), 1);
1162 assert_eq!(buf, [2]);
1163 assert_eq!(reader.buffer(), [3]);
1165 let mut buf = [0, 0, 0];
1166 let nread = reader.read(&mut buf);
1167 assert_eq!(nread.unwrap(), 1);
1168 assert_eq!(buf, [3, 0, 0]);
1169 assert_eq!(reader.buffer(), []);
1171 let nread = reader.read(&mut buf);
1172 assert_eq!(nread.unwrap(), 1);
1173 assert_eq!(buf, [4, 0, 0]);
1174 assert_eq!(reader.buffer(), []);
1176 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1180 fn test_buffered_reader_seek() {
1181 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
1182 let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
1184 assert_eq!(reader.seek(SeekFrom::Start(3)).ok(), Some(3));
1185 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
1186 assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(3));
1187 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
1188 assert_eq!(reader.seek(SeekFrom::Current(1)).ok(), Some(4));
1189 assert_eq!(reader.fill_buf().ok(), Some(&[1, 2][..]));
1191 assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3));
1195 fn test_buffered_reader_seek_relative() {
1196 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
1197 let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
1199 assert!(reader.seek_relative(3).is_ok());
1200 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
1201 assert!(reader.seek_relative(0).is_ok());
1202 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
1203 assert!(reader.seek_relative(1).is_ok());
1204 assert_eq!(reader.fill_buf().ok(), Some(&[1][..]));
1205 assert!(reader.seek_relative(-1).is_ok());
1206 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
1207 assert!(reader.seek_relative(2).is_ok());
1208 assert_eq!(reader.fill_buf().ok(), Some(&[2, 3][..]));
1212 fn test_buffered_reader_invalidated_after_read() {
1213 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
1214 let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner));
1216 assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
1219 let mut buffer = [0, 0, 0, 0, 0];
1220 assert_eq!(reader.read(&mut buffer).ok(), Some(5));
1221 assert_eq!(buffer, [0, 1, 2, 3, 4]);
1223 assert!(reader.seek_relative(-2).is_ok());
1224 let mut buffer = [0, 0];
1225 assert_eq!(reader.read(&mut buffer).ok(), Some(2));
1226 assert_eq!(buffer, [3, 4]);
1230 fn test_buffered_reader_invalidated_after_seek() {
1231 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
1232 let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner));
1234 assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
1237 assert!(reader.seek(SeekFrom::Current(5)).is_ok());
1239 assert!(reader.seek_relative(-2).is_ok());
1240 let mut buffer = [0, 0];
1241 assert_eq!(reader.read(&mut buffer).ok(), Some(2));
1242 assert_eq!(buffer, [3, 4]);
1246 fn test_buffered_reader_seek_underflow() {
1247 // gimmick reader that yields its position modulo 256 for each byte
1248 struct PositionReader {
1251 impl Read for PositionReader {
1252 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1253 let len = buf.len();
1255 *x = self.pos as u8;
1256 self.pos = self.pos.wrapping_add(1);
1261 impl Seek for PositionReader {
1262 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
1264 SeekFrom::Start(n) => {
1267 SeekFrom::Current(n) => {
1268 self.pos = self.pos.wrapping_add(n as u64);
1270 SeekFrom::End(n) => {
1271 self.pos = u64::MAX.wrapping_add(n as u64);
1278 let mut reader = BufReader::with_capacity(5, PositionReader { pos: 0 });
1279 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1, 2, 3, 4][..]));
1280 assert_eq!(reader.seek(SeekFrom::End(-5)).ok(), Some(u64::MAX - 5));
1281 assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
1282 // the following seek will require two underlying seeks
1283 let expected = 9223372036854775802;
1284 assert_eq!(reader.seek(SeekFrom::Current(i64::MIN)).ok(), Some(expected));
1285 assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
1286 // seeking to 0 should empty the buffer.
1287 assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(expected));
1288 assert_eq!(reader.get_ref().pos, expected);
1292 fn test_buffered_reader_seek_underflow_discard_buffer_between_seeks() {
1293 // gimmick reader that returns Err after first seek
1294 struct ErrAfterFirstSeekReader {
1297 impl Read for ErrAfterFirstSeekReader {
1298 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1299 for x in &mut *buf {
1305 impl Seek for ErrAfterFirstSeekReader {
1306 fn seek(&mut self, _: SeekFrom) -> io::Result<u64> {
1307 if self.first_seek {
1308 self.first_seek = false;
1311 Err(io::Error::new(io::ErrorKind::Other, "oh no!"))
1316 let mut reader = BufReader::with_capacity(5, ErrAfterFirstSeekReader { first_seek: true });
1317 assert_eq!(reader.fill_buf().ok(), Some(&[0, 0, 0, 0, 0][..]));
1319 // The following seek will require two underlying seeks. The first will
1320 // succeed but the second will fail. This should still invalidate the
1322 assert!(reader.seek(SeekFrom::Current(i64::MIN)).is_err());
1323 assert_eq!(reader.buffer().len(), 0);
1327 fn test_buffered_writer() {
1328 let inner = Vec::new();
1329 let mut writer = BufWriter::with_capacity(2, inner);
1331 writer.write(&[0, 1]).unwrap();
1332 assert_eq!(writer.buffer(), []);
1333 assert_eq!(*writer.get_ref(), [0, 1]);
1335 writer.write(&[2]).unwrap();
1336 assert_eq!(writer.buffer(), [2]);
1337 assert_eq!(*writer.get_ref(), [0, 1]);
1339 writer.write(&[3]).unwrap();
1340 assert_eq!(writer.buffer(), [2, 3]);
1341 assert_eq!(*writer.get_ref(), [0, 1]);
1343 writer.flush().unwrap();
1344 assert_eq!(writer.buffer(), []);
1345 assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
1347 writer.write(&[4]).unwrap();
1348 writer.write(&[5]).unwrap();
1349 assert_eq!(writer.buffer(), [4, 5]);
1350 assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
1352 writer.write(&[6]).unwrap();
1353 assert_eq!(writer.buffer(), [6]);
1354 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]);
1356 writer.write(&[7, 8]).unwrap();
1357 assert_eq!(writer.buffer(), []);
1358 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]);
1360 writer.write(&[9, 10, 11]).unwrap();
1361 assert_eq!(writer.buffer(), []);
1362 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
1364 writer.flush().unwrap();
1365 assert_eq!(writer.buffer(), []);
1366 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
1370 fn test_buffered_writer_inner_flushes() {
1371 let mut w = BufWriter::with_capacity(3, Vec::new());
1372 w.write(&[0, 1]).unwrap();
1373 assert_eq!(*w.get_ref(), []);
1374 let w = w.into_inner().unwrap();
1375 assert_eq!(w, [0, 1]);
1379 fn test_buffered_writer_seek() {
1380 let mut w = BufWriter::with_capacity(3, io::Cursor::new(Vec::new()));
1381 w.write_all(&[0, 1, 2, 3, 4, 5]).unwrap();
1382 w.write_all(&[6, 7]).unwrap();
1383 assert_eq!(w.seek(SeekFrom::Current(0)).ok(), Some(8));
1384 assert_eq!(&w.get_ref().get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]);
1385 assert_eq!(w.seek(SeekFrom::Start(2)).ok(), Some(2));
1386 w.write_all(&[8, 9]).unwrap();
1387 assert_eq!(&w.into_inner().unwrap().into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]);
1391 fn test_read_until() {
1392 let inner: &[u8] = &[0, 1, 2, 1, 0];
1393 let mut reader = BufReader::with_capacity(2, inner);
1394 let mut v = Vec::new();
1395 reader.read_until(0, &mut v).unwrap();
1398 reader.read_until(2, &mut v).unwrap();
1399 assert_eq!(v, [1, 2]);
1401 reader.read_until(1, &mut v).unwrap();
1404 reader.read_until(8, &mut v).unwrap();
1407 reader.read_until(9, &mut v).unwrap();
1412 fn test_line_buffer_fail_flush() {
1414 struct FailFlushWriter<'a>(&'a mut Vec<u8>);
1416 impl Write for FailFlushWriter<'_> {
1417 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1418 self.0.extend_from_slice(buf);
1421 fn flush(&mut self) -> io::Result<()> {
1422 Err(io::Error::new(io::ErrorKind::Other, "flush failed"))
1426 let mut buf = Vec::new();
1428 let mut writer = LineWriter::new(FailFlushWriter(&mut buf));
1429 let to_write = b"abc\ndef";
1430 if let Ok(written) = writer.write(to_write) {
1431 assert!(written < to_write.len(), "didn't flush on new line");
1436 assert!(buf.is_empty(), "write returned an error but wrote data");
1440 fn test_line_buffer() {
1441 let mut writer = LineWriter::new(Vec::new());
1442 writer.write(&[0]).unwrap();
1443 assert_eq!(*writer.get_ref(), []);
1444 writer.write(&[1]).unwrap();
1445 assert_eq!(*writer.get_ref(), []);
1446 writer.flush().unwrap();
1447 assert_eq!(*writer.get_ref(), [0, 1]);
1448 writer.write(&[0, b'\n', 1, b'\n', 2]).unwrap();
1449 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n']);
1450 writer.flush().unwrap();
1451 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2]);
1452 writer.write(&[3, b'\n']).unwrap();
1453 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n']);
1457 fn test_read_line() {
1458 let in_buf: &[u8] = b"a\nb\nc";
1459 let mut reader = BufReader::with_capacity(2, in_buf);
1460 let mut s = String::new();
1461 reader.read_line(&mut s).unwrap();
1462 assert_eq!(s, "a\n");
1464 reader.read_line(&mut s).unwrap();
1465 assert_eq!(s, "b\n");
1467 reader.read_line(&mut s).unwrap();
1470 reader.read_line(&mut s).unwrap();
1476 let in_buf: &[u8] = b"a\nb\nc";
1477 let reader = BufReader::with_capacity(2, in_buf);
1478 let mut it = reader.lines();
1479 assert_eq!(it.next().unwrap().unwrap(), "a".to_string());
1480 assert_eq!(it.next().unwrap().unwrap(), "b".to_string());
1481 assert_eq!(it.next().unwrap().unwrap(), "c".to_string());
1482 assert!(it.next().is_none());
1486 fn test_short_reads() {
1487 let inner = ShortReader { lengths: vec![0, 1, 2, 0, 1, 0] };
1488 let mut reader = BufReader::new(inner);
1489 let mut buf = [0, 0];
1490 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1491 assert_eq!(reader.read(&mut buf).unwrap(), 1);
1492 assert_eq!(reader.read(&mut buf).unwrap(), 2);
1493 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1494 assert_eq!(reader.read(&mut buf).unwrap(), 1);
1495 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1496 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1501 fn dont_panic_in_drop_on_panicked_flush() {
1502 struct FailFlushWriter;
1504 impl Write for FailFlushWriter {
1505 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1508 fn flush(&mut self) -> io::Result<()> {
1509 Err(io::Error::last_os_error())
1513 let writer = FailFlushWriter;
1514 let _writer = BufWriter::new(writer);
1516 // If writer panics *again* due to the flush error then the process will
1522 #[cfg_attr(target_os = "emscripten", ignore)]
1523 fn panic_in_write_doesnt_flush_in_drop() {
1524 static WRITES: AtomicUsize = AtomicUsize::new(0);
1528 impl Write for PanicWriter {
1529 fn write(&mut self, _: &[u8]) -> io::Result<usize> {
1530 WRITES.fetch_add(1, Ordering::SeqCst);
1533 fn flush(&mut self) -> io::Result<()> {
1539 let mut writer = BufWriter::new(PanicWriter);
1540 let _ = writer.write(b"hello world");
1541 let _ = writer.flush();
1546 assert_eq!(WRITES.load(Ordering::SeqCst), 1);
1550 fn bench_buffered_reader(b: &mut test::Bencher) {
1551 b.iter(|| BufReader::new(io::empty()));
1555 fn bench_buffered_writer(b: &mut test::Bencher) {
1556 b.iter(|| BufWriter::new(io::sink()));
1559 struct AcceptOneThenFail {
1564 impl Write for AcceptOneThenFail {
1565 fn write(&mut self, data: &[u8]) -> io::Result<usize> {
1567 assert_eq!(data, b"a\nb\n");
1568 self.written = true;
1571 Err(io::Error::new(io::ErrorKind::NotFound, "test"))
1575 fn flush(&mut self) -> io::Result<()> {
1576 assert!(self.written);
1577 assert!(!self.flushed);
1578 self.flushed = true;
1579 Err(io::Error::new(io::ErrorKind::Other, "test"))
1584 fn erroneous_flush_retried() {
1585 let a = AcceptOneThenFail { written: false, flushed: false };
1587 let mut l = LineWriter::new(a);
1588 assert_eq!(l.write(b"a\nb\na").unwrap(), 4);
1589 assert!(l.get_ref().written);
1590 assert!(l.get_ref().flushed);
1591 l.get_mut().flushed = false;
1593 assert_eq!(l.write(b"a").unwrap_err().kind(), io::ErrorKind::Other)
1597 fn line_vectored() {
1598 let mut a = LineWriter::new(Vec::new());
1602 IoSlice::new(b"\n"),
1609 assert_eq!(a.get_ref(), b"\n");
1623 assert_eq!(a.get_ref(), b"\n");
1625 assert_eq!(a.get_ref(), b"\nabac");
1626 assert_eq!(a.write_vectored(&[]).unwrap(), 0);
1637 assert_eq!(a.write_vectored(&[IoSlice::new(b"a\nb"),]).unwrap(), 3);
1638 assert_eq!(a.get_ref(), b"\nabaca\n");
1642 fn line_vectored_partial_and_errors() {
1644 Write { inputs: Vec<&'static [u8]>, output: io::Result<usize> },
1645 Flush { output: io::Result<()> },
1651 impl Write for Writer {
1652 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1653 self.write_vectored(&[IoSlice::new(buf)])
1656 fn write_vectored(&mut self, buf: &[IoSlice<'_>]) -> io::Result<usize> {
1657 match self.calls.pop().unwrap() {
1658 Call::Write { inputs, output } => {
1659 assert_eq!(inputs, buf.iter().map(|b| &**b).collect::<Vec<_>>());
1662 _ => panic!("unexpected call to write"),
1666 fn flush(&mut self) -> io::Result<()> {
1667 match self.calls.pop().unwrap() {
1668 Call::Flush { output } => output,
1669 _ => panic!("unexpected call to flush"),
1674 impl Drop for Writer {
1675 fn drop(&mut self) {
1676 if !thread::panicking() {
1677 assert_eq!(self.calls.len(), 0);
1682 // partial writes keep going
1683 let mut a = LineWriter::new(Writer { calls: Vec::new() });
1684 a.write_vectored(&[IoSlice::new(&[]), IoSlice::new(b"abc")]).unwrap();
1685 a.get_mut().calls.push(Call::Flush { output: Ok(()) });
1686 a.get_mut().calls.push(Call::Write { inputs: vec![b"bcx\n"], output: Ok(4) });
1687 a.get_mut().calls.push(Call::Write { inputs: vec![b"abcx\n"], output: Ok(1) });
1688 a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\n")]).unwrap();
1689 a.get_mut().calls.push(Call::Flush { output: Ok(()) });
1692 // erroneous writes stop and don't write more
1693 a.get_mut().calls.push(Call::Write { inputs: vec![b"x\n"], output: Err(err()) });
1694 assert_eq!(a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\na")]).unwrap(), 2);
1695 a.get_mut().calls.push(Call::Flush { output: Ok(()) });
1696 a.get_mut().calls.push(Call::Write { inputs: vec![b"x\n"], output: Ok(2) });
1699 fn err() -> io::Error {
1700 io::Error::new(io::ErrorKind::Other, "x")