relibc/io/buffered.rs
1// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11//! Buffering wrappers for I/O traits
12
13use core::{cmp, fmt};
14
15use crate::io::{
16 self, DEFAULT_BUF_SIZE, Error, ErrorKind, Initializer, SeekFrom, Write, prelude::*,
17};
18
19/// The `BufReader` struct adds buffering to any reader.
20///
21/// It can be excessively inefficient to work directly with a [`Read`] instance.
22/// For example, every call to [`read`][`TcpStream::read`] on [`TcpStream`]
23/// results in a system call. A `BufReader` performs large, infrequent reads on
24/// the underlying [`Read`] and maintains an in-memory buffer of the results.
25///
26/// `BufReader` can improve the speed of programs that make *small* and
27/// *repeated* read calls to the same file or network socket. It does not
28/// help when reading very large amounts at once, or reading just one or a few
29/// times. It also provides no advantage when reading from a source that is
30/// already in memory, like a `Vec<u8>`.
31///
32/// [`Read`]: ../../std/io/trait.Read.html
33/// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read
34/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
35///
36/// # Examples
37///
38/// ```no_run
39/// use std::io::prelude::*;
40/// use std::io::BufReader;
41/// use std::fs::File;
42///
43/// fn main() -> std::io::Result<()> {
44/// let f = File::open("log.txt")?;
45/// let mut reader = BufReader::new(f);
46///
47/// let mut line = String::new();
48/// let len = reader.read_line(&mut line)?;
49/// println!("First line is {} bytes long", len);
50/// Ok(())
51/// }
52/// ```
53pub struct BufReader<R> {
54 inner: R,
55 buf: Box<[u8]>,
56 pos: usize,
57 cap: usize,
58}
59
60impl<R: Read> BufReader<R> {
61 /// Creates a new `BufReader` with a default buffer capacity. The default is currently 8 KB,
62 /// but may change in the future.
63 ///
64 /// # Examples
65 ///
66 /// ```no_run
67 /// use std::io::BufReader;
68 /// use std::fs::File;
69 ///
70 /// fn main() -> std::io::Result<()> {
71 /// let f = File::open("log.txt")?;
72 /// let reader = BufReader::new(f);
73 /// Ok(())
74 /// }
75 /// ```
76 pub fn new(inner: R) -> BufReader<R> {
77 BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
78 }
79
80 /// Creates a new `BufReader` with the specified buffer capacity.
81 ///
82 /// # Examples
83 ///
84 /// Creating a buffer with ten bytes of capacity:
85 ///
86 /// ```no_run
87 /// use std::io::BufReader;
88 /// use std::fs::File;
89 ///
90 /// fn main() -> std::io::Result<()> {
91 /// let f = File::open("log.txt")?;
92 /// let reader = BufReader::with_capacity(10, f);
93 /// Ok(())
94 /// }
95 /// ```
96 #[allow(clippy::uninit_vec)] // buffer initialized after set_len
97 pub fn with_capacity(cap: usize, inner: R) -> BufReader<R> {
98 unsafe {
99 let mut buffer = Vec::with_capacity(cap);
100 buffer.set_len(cap);
101 inner.initializer().initialize(&mut buffer);
102 BufReader {
103 inner,
104 buf: buffer.into_boxed_slice(),
105 pos: 0,
106 cap: 0,
107 }
108 }
109 }
110
111 /// Gets a reference to the underlying reader.
112 ///
113 /// It is inadvisable to directly read from the underlying reader.
114 ///
115 /// # Examples
116 ///
117 /// ```no_run
118 /// use std::io::BufReader;
119 /// use std::fs::File;
120 ///
121 /// fn main() -> std::io::Result<()> {
122 /// let f1 = File::open("log.txt")?;
123 /// let reader = BufReader::new(f1);
124 ///
125 /// let f2 = reader.get_ref();
126 /// Ok(())
127 /// }
128 /// ```
129 pub fn get_ref(&self) -> &R {
130 &self.inner
131 }
132}
133
134impl<R: Seek> BufReader<R> {
135 /// Seeks relative to the current position. If the new position lies within the buffer,
136 /// the buffer will not be flushed, allowing for more efficient seeks.
137 /// This method does not return the location of the underlying reader, so the caller
138 /// must track this information themselves if it is required.
139 pub fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
140 let pos = self.pos as u64;
141 if offset < 0 {
142 if let Some(new_pos) = pos.checked_sub((-offset) as u64) {
143 self.pos = new_pos as usize;
144 return Ok(());
145 }
146 } else if let Some(new_pos) = pos.checked_add(offset as u64)
147 && new_pos <= self.cap as u64
148 {
149 self.pos = new_pos as usize;
150 return Ok(());
151 }
152 self.seek(SeekFrom::Current(offset)).map(|_| ())
153 }
154}
155
156impl<R: Read> Read for BufReader<R> {
157 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
158 // If we don't have any buffered data and we're doing a massive read
159 // (larger than our internal buffer), bypass our internal buffer
160 // entirely.
161 if self.pos == self.cap && buf.len() >= self.buf.len() {
162 return self.inner.read(buf);
163 }
164 let nread = {
165 let mut rem = self.fill_buf()?;
166 rem.read(buf)?
167 };
168 self.consume(nread);
169 Ok(nread)
170 }
171
172 // we can't skip unconditionally because of the large buffer case in read.
173 unsafe fn initializer(&self) -> Initializer {
174 unsafe { self.inner.initializer() }
175 }
176}
177
178impl<R: Read> BufRead for BufReader<R> {
179 fn fill_buf(&mut self) -> io::Result<&[u8]> {
180 // If we've reached the end of our internal buffer then we need to fetch
181 // some more data from the underlying reader.
182 // Branch using `>=` instead of the more correct `==`
183 // to tell the compiler that the pos..cap slice is always valid.
184 if self.pos >= self.cap {
185 debug_assert!(self.pos == self.cap);
186 self.cap = self.inner.read(&mut self.buf)?;
187 self.pos = 0;
188 }
189 Ok(&self.buf[self.pos..self.cap])
190 }
191
192 fn consume(&mut self, amt: usize) {
193 self.pos = cmp::min(self.pos + amt, self.cap);
194 }
195}
196
197impl<R: Seek> Seek for BufReader<R> {
198 /// Seek to an offset, in bytes, in the underlying reader.
199 ///
200 /// The position used for seeking with `SeekFrom::Current(_)` is the
201 /// position the underlying reader would be at if the `BufReader` had no
202 /// internal buffer.
203 ///
204 /// Seeking always discards the internal buffer, even if the seek position
205 /// would otherwise fall within it. This guarantees that calling
206 /// `.into_inner()` immediately after a seek yields the underlying reader
207 /// at the same position.
208 ///
209 /// To seek without discarding the internal buffer, use [`seek_relative`](crate::io::BufReader::seek_relative).
210 ///
211 /// See [`std::io::Seek`](https://doc.rust-lang.org/std/io/trait.Seek.html) for more details.
212 ///
213 /// Note: In the edge case where you're seeking with `SeekFrom::Current(n)`
214 /// where `n` minus the internal buffer length overflows an `i64`, two
215 /// seeks will be performed instead of one. If the second seek returns
216 /// `Err`, the underlying reader will be left at the same position it would
217 /// have if you called `seek` with `SeekFrom::Current(0)`.
218 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
219 let result: u64;
220 if let SeekFrom::Current(n) = pos {
221 let remainder = (self.cap - self.pos) as i64;
222 // it should be safe to assume that remainder fits within an i64 as the alternative
223 // means we managed to allocate 8 exbibytes and that's absurd.
224 // But it's not out of the realm of possibility for some weird underlying reader to
225 // support seeking by i64::min_value() so we need to handle underflow when subtracting
226 // remainder.
227 if let Some(offset) = n.checked_sub(remainder) {
228 result = self.inner.seek(SeekFrom::Current(offset))?;
229 } else {
230 // seek backwards by our remainder, and then by the offset
231 self.inner.seek(SeekFrom::Current(-remainder))?;
232 self.pos = self.cap; // empty the buffer
233 result = self.inner.seek(SeekFrom::Current(n))?;
234 }
235 } else {
236 // Seeking with Start/End doesn't care about our buffer length.
237 result = self.inner.seek(pos)?;
238 }
239 self.pos = self.cap; // empty the buffer
240 Ok(result)
241 }
242}
243
244/// Wraps a writer and buffers its output.
245///
246/// It can be excessively inefficient to work directly with something that
247/// implements [`Write`]. For example, every call to
248/// [`write`][`Tcpstream::write`] on [`TcpStream`] results in a system call. A
249/// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying
250/// writer in large, infrequent batches.
251///
252/// `BufWriter` can improve the speed of programs that make *small* and
253/// *repeated* write calls to the same file or network socket. It does not
254/// help when writing very large amounts at once, or writing just one or a few
255/// times. It also provides no advantage when writing to a destination that is
256/// in memory, like a `Vec<u8>`.
257///
258/// When the `BufWriter` is dropped, the contents of its buffer will be written
259/// out. However, any errors that happen in the process of flushing the buffer
260/// when the writer is dropped will be ignored. Code that wishes to handle such
261/// errors must manually call [`flush`] before the writer is dropped.
262///
263/// # Examples
264///
265/// Let's write the numbers one through ten to a [`TcpStream`]:
266///
267/// ```no_run
268/// use std::io::prelude::*;
269/// use std::net::TcpStream;
270///
271/// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
272///
273/// for i in 0..10 {
274/// stream.write(&[i+1]).unwrap();
275/// }
276/// ```
277///
278/// Because we're not buffering, we write each one in turn, incurring the
279/// overhead of a system call per byte written. We can fix this with a
280/// `BufWriter`:
281///
282/// ```no_run
283/// use std::io::prelude::*;
284/// use std::io::BufWriter;
285/// use std::net::TcpStream;
286///
287/// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
288///
289/// for i in 0..10 {
290/// stream.write(&[i+1]).unwrap();
291/// }
292/// ```
293///
294/// By wrapping the stream with a `BufWriter`, these ten writes are all grouped
295/// together by the buffer, and will all be written out in one system call when
296/// the `stream` is dropped.
297///
298/// [`Write`]: ../../std/io/trait.Write.html
299/// [`Tcpstream::write`]: ../../std/net/struct.TcpStream.html#method.write
300/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
301/// [`flush`]: #method.flush
302pub struct BufWriter<W: Write> {
303 inner: Option<W>,
304 pub buf: Vec<u8>,
305 // #30888: If the inner writer panics in a call to write, we don't want to
306 // write the buffered data a second time in BufWriter's destructor. This
307 // flag tells the Drop impl if it should skip the flush.
308 panicked: bool,
309}
310
311/// An error returned by `into_inner` which combines an error that
312/// happened while writing out the buffer, and the buffered writer object
313/// which may be used to recover from the condition.
314///
315/// # Examples
316///
317/// ```no_run
318/// use std::io::BufWriter;
319/// use std::net::TcpStream;
320///
321/// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
322///
323/// // do stuff with the stream
324///
325/// // we want to get our `TcpStream` back, so let's try:
326///
327/// let stream = match stream.into_inner() {
328/// Ok(s) => s,
329/// Err(e) => {
330/// // Here, e is an IntoInnerError
331/// panic!("An error occurred");
332/// }
333/// };
334/// ```
335#[derive(Debug)]
336pub struct IntoInnerError<W>(W, Error);
337
338impl<W: Write> BufWriter<W> {
339 /// Creates a new `BufWriter` with a default buffer capacity. The default is currently 8 KB,
340 /// but may change in the future.
341 ///
342 /// # Examples
343 ///
344 /// ```no_run
345 /// use std::io::BufWriter;
346 /// use std::net::TcpStream;
347 ///
348 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
349 /// ```
350 pub fn new(inner: W) -> BufWriter<W> {
351 BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
352 }
353
354 /// Creates a new `BufWriter` with the specified buffer capacity.
355 ///
356 /// # Examples
357 ///
358 /// Creating a buffer with a buffer of a hundred bytes.
359 ///
360 /// ```no_run
361 /// use std::io::BufWriter;
362 /// use std::net::TcpStream;
363 ///
364 /// let stream = TcpStream::connect("127.0.0.1:34254").unwrap();
365 /// let mut buffer = BufWriter::with_capacity(100, stream);
366 /// ```
367 pub fn with_capacity(cap: usize, inner: W) -> BufWriter<W> {
368 BufWriter {
369 inner: Some(inner),
370 buf: Vec::with_capacity(cap),
371 panicked: false,
372 }
373 }
374
375 /// Gets a reference to the underlying writer.
376 ///
377 /// # Examples
378 ///
379 /// ```no_run
380 /// use std::io::BufWriter;
381 /// use std::net::TcpStream;
382 ///
383 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
384 ///
385 /// // we can use reference just like buffer
386 /// let reference = buffer.get_ref();
387 /// ```
388 pub fn get_ref(&self) -> &W {
389 self.inner.as_ref().unwrap()
390 }
391
392 fn flush_buf(&mut self) -> io::Result<()> {
393 let mut written = 0;
394 let len = self.buf.len();
395 let mut ret = Ok(());
396 while written < len {
397 self.panicked = true;
398 let r = self.inner.as_mut().unwrap().write(&self.buf[written..]);
399 self.panicked = false;
400
401 match r {
402 Ok(0) => {
403 ret = Err(Error::new(
404 ErrorKind::WriteZero,
405 "failed to write the buffered data",
406 ));
407 break;
408 }
409 Ok(n) => written += n,
410 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
411 Err(e) => {
412 ret = Err(e);
413 break;
414 }
415 }
416 }
417 if written > 0 {
418 self.buf.drain(..written);
419 }
420 ret
421 }
422
423 /// Gets a mutable reference to the underlying writer.
424 ///
425 /// It is inadvisable to directly write to the underlying writer.
426 ///
427 /// # Examples
428 ///
429 /// ```no_run
430 /// use std::io::BufWriter;
431 /// use std::net::TcpStream;
432 ///
433 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
434 ///
435 /// // we can use reference just like buffer
436 /// let reference = buffer.get_mut();
437 /// ```
438 pub fn get_mut(&mut self) -> &mut W {
439 self.inner.as_mut().unwrap()
440 }
441
442 /// Unwraps this `BufWriter`, returning the underlying writer.
443 ///
444 /// The buffer is written out before returning the writer.
445 ///
446 /// # Errors
447 ///
448 /// An `Err` will be returned if an error occurs while flushing the buffer.
449 ///
450 /// # Examples
451 ///
452 /// ```no_run
453 /// use std::io::BufWriter;
454 /// use std::net::TcpStream;
455 ///
456 /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
457 ///
458 /// // unwrap the TcpStream and flush the buffer
459 /// let stream = buffer.into_inner().unwrap();
460 /// ```
461 pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
462 match self.flush_buf() {
463 Err(e) => Err(IntoInnerError(self, e)),
464 Ok(()) => Ok(self.inner.take().unwrap()),
465 }
466 }
467}
468
469impl<W: Write> Write for BufWriter<W> {
470 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
471 if self.buf.len() + buf.len() > self.buf.capacity() {
472 self.flush_buf()?;
473 }
474 if buf.len() >= self.buf.capacity() {
475 self.panicked = true;
476 let r = self.inner.as_mut().unwrap().write(buf);
477 self.panicked = false;
478 r
479 } else {
480 Write::write(&mut self.buf, buf)
481 }
482 }
483 fn flush(&mut self) -> io::Result<()> {
484 self.flush_buf().and_then(|()| self.get_mut().flush())
485 }
486}
487
488impl<W: Write> fmt::Debug for BufWriter<W>
489where
490 W: fmt::Debug,
491{
492 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
493 fmt.debug_struct("BufWriter")
494 .field("writer", &self.inner.as_ref().unwrap())
495 .field(
496 "buffer",
497 &format_args!("{}/{}", self.buf.len(), self.buf.capacity()),
498 )
499 .finish()
500 }
501}
502
503impl<W: Write + Seek> Seek for BufWriter<W> {
504 /// Seek to the offset, in bytes, in the underlying writer.
505 ///
506 /// Seeking always writes out the internal buffer before seeking.
507 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
508 self.flush_buf().and_then(|()| self.get_mut().seek(pos))
509 }
510}
511
512/// Wraps a writer and buffers output to it, flushing whenever a newline
513/// (`0x0a`, `'\n'`) is detected.
514///
515/// The [`BufWriter`][bufwriter] struct wraps a writer and buffers its output.
516/// But it only does this batched write when it goes out of scope, or when the
517/// internal buffer is full. Sometimes, you'd prefer to write each line as it's
518/// completed, rather than the entire buffer at once. Enter `LineWriter`. It
519/// does exactly that.
520///
521/// Like [`BufWriter`], a `LineWriter`’s buffer will also be flushed when the
522/// `LineWriter` goes out of scope or when its internal buffer is full.
523///
524/// [bufwriter]: struct.BufWriter.html
525///
526/// If there's still a partial line in the buffer when the `LineWriter` is
527/// dropped, it will flush those contents.
528///
529/// # Examples
530///
531/// We can use `LineWriter` to write one line at a time, significantly
532/// reducing the number of actual writes to the file.
533///
534/// ```no_run
535/// use std::fs::{self, File};
536/// use std::io::prelude::*;
537/// use std::io::LineWriter;
538///
539/// fn main() -> std::io::Result<()> {
540/// let road_not_taken = b"I shall be telling this with a sigh
541/// Somewhere ages and ages hence:
542/// Two roads diverged in a wood, and I -
543/// I took the one less traveled by,
544/// And that has made all the difference.";
545///
546/// let file = File::create("poem.txt")?;
547/// let mut file = LineWriter::new(file);
548///
549/// file.write_all(b"I shall be telling this with a sigh")?;
550///
551/// // No bytes are written until a newline is encountered (or
552/// // the internal buffer is filled).
553/// assert_eq!(fs::read_to_string("poem.txt")?, "");
554/// file.write_all(b"\n")?;
555/// assert_eq!(
556/// fs::read_to_string("poem.txt")?,
557/// "I shall be telling this with a sigh\n",
558/// );
559///
560/// // Write the rest of the poem.
561/// file.write_all(b"Somewhere ages and ages hence:
562/// Two roads diverged in a wood, and I -
563/// I took the one less traveled by,
564/// And that has made all the difference.")?;
565///
566/// // The last line of the poem doesn't end in a newline, so
567/// // we have to flush or drop the `LineWriter` to finish
568/// // writing.
569/// file.flush()?;
570///
571/// // Confirm the whole poem was written.
572/// assert_eq!(fs::read("poem.txt")?, &road_not_taken[..]);
573/// Ok(())
574/// }
575/// ```
576pub struct LineWriter<W: Write> {
577 pub inner: BufWriter<W>,
578 need_flush: bool,
579}
580
581impl<W: Write> LineWriter<W> {
582 /// Creates a new `LineWriter`.
583 ///
584 /// # Examples
585 ///
586 /// ```no_run
587 /// use std::fs::File;
588 /// use std::io::LineWriter;
589 ///
590 /// fn main() -> std::io::Result<()> {
591 /// let file = File::create("poem.txt")?;
592 /// let file = LineWriter::new(file);
593 /// Ok(())
594 /// }
595 /// ```
596 pub fn new(inner: W) -> LineWriter<W> {
597 // Lines typically aren't that long, don't use a giant buffer
598 LineWriter::with_capacity(1024, inner)
599 }
600
601 /// Creates a new `LineWriter` with a specified capacity for the internal
602 /// buffer.
603 ///
604 /// # Examples
605 ///
606 /// ```no_run
607 /// use std::fs::File;
608 /// use std::io::LineWriter;
609 ///
610 /// fn main() -> std::io::Result<()> {
611 /// let file = File::create("poem.txt")?;
612 /// let file = LineWriter::with_capacity(100, file);
613 /// Ok(())
614 /// }
615 /// ```
616 pub fn with_capacity(cap: usize, inner: W) -> LineWriter<W> {
617 LineWriter {
618 inner: BufWriter::with_capacity(cap, inner),
619 need_flush: false,
620 }
621 }
622
623 /// Gets a reference to the underlying writer.
624 ///
625 /// # Examples
626 ///
627 /// ```no_run
628 /// use std::fs::File;
629 /// use std::io::LineWriter;
630 ///
631 /// fn main() -> std::io::Result<()> {
632 /// let file = File::create("poem.txt")?;
633 /// let file = LineWriter::new(file);
634 ///
635 /// let reference = file.get_ref();
636 /// Ok(())
637 /// }
638 /// ```
639 pub fn get_ref(&self) -> &W {
640 self.inner.get_ref()
641 }
642
643 /// Gets a mutable reference to the underlying writer.
644 ///
645 /// Caution must be taken when calling methods on the mutable reference
646 /// returned as extra writes could corrupt the output stream.
647 ///
648 /// # Examples
649 ///
650 /// ```no_run
651 /// use std::fs::File;
652 /// use std::io::LineWriter;
653 ///
654 /// fn main() -> std::io::Result<()> {
655 /// let file = File::create("poem.txt")?;
656 /// let mut file = LineWriter::new(file);
657 ///
658 /// // we can use reference just like file
659 /// let reference = file.get_mut();
660 /// Ok(())
661 /// }
662 /// ```
663 pub fn get_mut(&mut self) -> &mut W {
664 self.inner.get_mut()
665 }
666}
667
668impl<W: Write> Write for LineWriter<W> {
669 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
670 if self.need_flush {
671 self.flush()?;
672 }
673
674 // Find the last newline character in the buffer provided. If found then
675 // we're going to write all the data up to that point and then flush,
676 // otherwise we just write the whole block to the underlying writer.
677 let i = match memchr::memrchr(b'\n', buf) {
678 Some(i) => i,
679 None => return self.inner.write(buf),
680 };
681
682 // Ok, we're going to write a partial amount of the data given first
683 // followed by flushing the newline. After we've successfully written
684 // some data then we *must* report that we wrote that data, so future
685 // errors are ignored. We set our internal `need_flush` flag, though, in
686 // case flushing fails and we need to try it first next time.
687 let n = self.inner.write(&buf[..i + 1])?;
688 self.need_flush = true;
689 if self.flush().is_err() || n != i + 1 {
690 return Ok(n);
691 }
692
693 // At this point we successfully wrote `i + 1` bytes and flushed it out,
694 // meaning that the entire line is now flushed out on the screen. While
695 // we can attempt to finish writing the rest of the data provided.
696 // Remember though that we ignore errors here as we've successfully
697 // written data, so we need to report that.
698 match self.inner.write(&buf[i + 1..]) {
699 Ok(i) => Ok(n + i),
700 Err(_) => Ok(n),
701 }
702 }
703
704 fn flush(&mut self) -> io::Result<()> {
705 self.inner.flush()?;
706 self.need_flush = false;
707 Ok(())
708 }
709}
710
711#[cfg(test)]
712mod tests {
713 use alloc::string::String;
714
715 use crate::io::{self, BufReader, BufWriter, LineWriter, SeekFrom, prelude::*};
716 use test;
717 // use crate::sync::atomic::{AtomicUsize, Ordering};
718
719 /// A dummy reader intended at testing short-reads propagation.
720 pub struct ShortReader {
721 lengths: Vec<usize>,
722 }
723
724 impl Read for ShortReader {
725 fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
726 if self.lengths.is_empty() {
727 Ok(0)
728 } else {
729 Ok(self.lengths.remove(0))
730 }
731 }
732 }
733
734 #[test]
735 fn test_buffered_reader() {
736 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
737 let mut reader = BufReader::with_capacity(2, inner);
738
739 let mut buf = [0, 0, 0];
740 let nread = reader.read(&mut buf);
741 assert_eq!(nread.unwrap(), 3);
742 let b: &[_] = &[5, 6, 7];
743 assert_eq!(buf, b);
744
745 let mut buf = [0, 0];
746 let nread = reader.read(&mut buf);
747 assert_eq!(nread.unwrap(), 2);
748 let b: &[_] = &[0, 1];
749 assert_eq!(buf, b);
750
751 let mut buf = [0];
752 let nread = reader.read(&mut buf);
753 assert_eq!(nread.unwrap(), 1);
754 let b: &[_] = &[2];
755 assert_eq!(buf, b);
756
757 let mut buf = [0, 0, 0];
758 let nread = reader.read(&mut buf);
759 assert_eq!(nread.unwrap(), 1);
760 let b: &[_] = &[3, 0, 0];
761 assert_eq!(buf, b);
762
763 let nread = reader.read(&mut buf);
764 assert_eq!(nread.unwrap(), 1);
765 let b: &[_] = &[4, 0, 0];
766 assert_eq!(buf, b);
767
768 assert_eq!(reader.read(&mut buf).unwrap(), 0);
769 }
770
771 #[test]
772 fn test_buffered_reader_seek() {
773 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
774 let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
775
776 assert_eq!(reader.seek(SeekFrom::Start(3)).ok(), Some(3));
777 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
778 assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(3));
779 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
780 assert_eq!(reader.seek(SeekFrom::Current(1)).ok(), Some(4));
781 assert_eq!(reader.fill_buf().ok(), Some(&[1, 2][..]));
782 reader.consume(1);
783 assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3));
784 }
785
786 #[test]
787 fn test_buffered_reader_seek_relative() {
788 let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
789 let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
790
791 assert!(reader.seek_relative(3).is_ok());
792 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
793 assert!(reader.seek_relative(0).is_ok());
794 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
795 assert!(reader.seek_relative(1).is_ok());
796 assert_eq!(reader.fill_buf().ok(), Some(&[1][..]));
797 assert!(reader.seek_relative(-1).is_ok());
798 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
799 assert!(reader.seek_relative(2).is_ok());
800 assert_eq!(reader.fill_buf().ok(), Some(&[2, 3][..]));
801 }
802
803 #[test]
804 fn test_buffered_reader_seek_underflow() {
805 // gimmick reader that yields its position modulo 256 for each byte
806 struct PositionReader {
807 pos: u64,
808 }
809 impl Read for PositionReader {
810 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
811 let len = buf.len();
812 for x in buf {
813 *x = self.pos as u8;
814 self.pos = self.pos.wrapping_add(1);
815 }
816 Ok(len)
817 }
818 }
819 impl Seek for PositionReader {
820 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
821 match pos {
822 SeekFrom::Start(n) => {
823 self.pos = n;
824 }
825 SeekFrom::Current(n) => {
826 self.pos = self.pos.wrapping_add(n as u64);
827 }
828 SeekFrom::End(n) => {
829 self.pos = u64::MAX.wrapping_add(n as u64);
830 }
831 }
832 Ok(self.pos)
833 }
834 }
835
836 let mut reader = BufReader::with_capacity(5, PositionReader { pos: 0 });
837 assert_eq!(reader.fill_buf().ok(), Some(&[0, 1, 2, 3, 4][..]));
838 assert_eq!(reader.seek(SeekFrom::End(-5)).ok(), Some(u64::MAX - 5));
839 assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
840 // the following seek will require two underlying seeks
841 let expected = 9223372036854775802;
842 assert_eq!(
843 reader.seek(SeekFrom::Current(i64::MIN)).ok(),
844 Some(expected)
845 );
846 assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
847 // seeking to 0 should empty the buffer.
848 assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(expected));
849 assert_eq!(reader.get_ref().pos, expected);
850 }
851
852 #[test]
853 fn test_buffered_writer() {
854 let inner = Vec::new();
855 let mut writer = BufWriter::with_capacity(2, inner);
856
857 writer.write(&[0, 1]).unwrap();
858 assert_eq!(*writer.get_ref(), [0, 1]);
859
860 writer.write(&[2]).unwrap();
861 assert_eq!(*writer.get_ref(), [0, 1]);
862
863 writer.write(&[3]).unwrap();
864 assert_eq!(*writer.get_ref(), [0, 1]);
865
866 writer.flush().unwrap();
867 assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
868
869 writer.write(&[4]).unwrap();
870 writer.write(&[5]).unwrap();
871 assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
872
873 writer.write(&[6]).unwrap();
874 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]);
875
876 writer.write(&[7, 8]).unwrap();
877 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]);
878
879 writer.write(&[9, 10, 11]).unwrap();
880 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
881
882 writer.flush().unwrap();
883 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
884 }
885
886 #[test]
887 fn test_buffered_writer_inner_flushes() {
888 let mut w = BufWriter::with_capacity(3, Vec::new());
889 w.write(&[0, 1]).unwrap();
890 assert_eq!(*w.get_ref(), []);
891 let w = w.into_inner().unwrap();
892 assert_eq!(w, [0, 1]);
893 }
894
895 #[test]
896 fn test_buffered_writer_seek() {
897 let mut w = BufWriter::with_capacity(3, io::Cursor::new(Vec::new()));
898 w.write_all(&[0, 1, 2, 3, 4, 5]).unwrap();
899 w.write_all(&[6, 7]).unwrap();
900 assert_eq!(w.seek(SeekFrom::Current(0)).ok(), Some(8));
901 assert_eq!(&w.get_ref().get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]);
902 assert_eq!(w.seek(SeekFrom::Start(2)).ok(), Some(2));
903 w.write_all(&[8, 9]).unwrap();
904 assert_eq!(
905 &w.into_inner().unwrap().into_inner()[..],
906 &[0, 1, 8, 9, 4, 5, 6, 7]
907 );
908 }
909
910 #[test]
911 fn test_read_until() {
912 let inner: &[u8] = &[0, 1, 2, 1, 0];
913 let mut reader = BufReader::with_capacity(2, inner);
914 let mut v = Vec::new();
915 reader.read_until(0, &mut v).unwrap();
916 assert_eq!(v, [0]);
917 v.truncate(0);
918 reader.read_until(2, &mut v).unwrap();
919 assert_eq!(v, [1, 2]);
920 v.truncate(0);
921 reader.read_until(1, &mut v).unwrap();
922 assert_eq!(v, [1]);
923 v.truncate(0);
924 reader.read_until(8, &mut v).unwrap();
925 assert_eq!(v, [0]);
926 v.truncate(0);
927 reader.read_until(9, &mut v).unwrap();
928 assert_eq!(v, []);
929 }
930
931 #[test]
932 fn test_line_buffer_fail_flush() {
933 // Issue #32085
934 struct FailFlushWriter<'a>(&'a mut Vec<u8>);
935
936 impl<'a> Write for FailFlushWriter<'a> {
937 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
938 self.0.extend_from_slice(buf);
939 Ok(buf.len())
940 }
941 fn flush(&mut self) -> io::Result<()> {
942 Err(io::Error::new(io::ErrorKind::Other, "flush failed"))
943 }
944 }
945
946 let mut buf = Vec::new();
947 {
948 let mut writer = LineWriter::new(FailFlushWriter(&mut buf));
949 let to_write = b"abc\ndef";
950 if let Ok(written) = writer.write(to_write) {
951 assert!(written < to_write.len(), "didn't flush on new line");
952 // PASS
953 return;
954 }
955 }
956 assert!(buf.is_empty(), "write returned an error but wrote data");
957 }
958
959 #[test]
960 fn test_line_buffer() {
961 let mut writer = LineWriter::new(Vec::new());
962 writer.write(&[0]).unwrap();
963 assert_eq!(*writer.get_ref(), []);
964 writer.write(&[1]).unwrap();
965 assert_eq!(*writer.get_ref(), []);
966 writer.flush().unwrap();
967 assert_eq!(*writer.get_ref(), [0, 1]);
968 writer.write(&[0, b'\n', 1, b'\n', 2]).unwrap();
969 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n']);
970 writer.flush().unwrap();
971 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2]);
972 writer.write(&[3, b'\n']).unwrap();
973 assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n']);
974 }
975
976 #[test]
977 fn test_read_line() {
978 let in_buf: &[u8] = b"a\nb\nc";
979 let mut reader = BufReader::with_capacity(2, in_buf);
980 let mut s = String::new();
981 reader.read_line(&mut s).unwrap();
982 assert_eq!(s, "a\n");
983 s.truncate(0);
984 reader.read_line(&mut s).unwrap();
985 assert_eq!(s, "b\n");
986 s.truncate(0);
987 reader.read_line(&mut s).unwrap();
988 assert_eq!(s, "c");
989 s.truncate(0);
990 reader.read_line(&mut s).unwrap();
991 assert_eq!(s, "");
992 }
993
994 // #[test]
995 // fn test_lines() {
996 // let in_buf: &[u8] = b"a\nb\nc";
997 // let reader = BufReader::with_capacity(2, in_buf);
998 // let mut it = reader.lines();
999 // assert_eq!(it.next().unwrap().unwrap(), "a".to_string());
1000 // assert_eq!(it.next().unwrap().unwrap(), "b".to_string());
1001 // assert_eq!(it.next().unwrap().unwrap(), "c".to_string());
1002 // assert!(it.next().is_none());
1003 // }
1004
1005 #[test]
1006 fn test_short_reads() {
1007 let inner = ShortReader {
1008 lengths: vec![0, 1, 2, 0, 1, 0],
1009 };
1010 let mut reader = BufReader::new(inner);
1011 let mut buf = [0, 0];
1012 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1013 assert_eq!(reader.read(&mut buf).unwrap(), 1);
1014 assert_eq!(reader.read(&mut buf).unwrap(), 2);
1015 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1016 assert_eq!(reader.read(&mut buf).unwrap(), 1);
1017 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1018 assert_eq!(reader.read(&mut buf).unwrap(), 0);
1019 }
1020
1021 #[test]
1022 #[should_panic]
1023 fn dont_panic_in_drop_on_panicked_flush() {
1024 struct FailFlushWriter;
1025
1026 impl Write for FailFlushWriter {
1027 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1028 Ok(buf.len())
1029 }
1030 fn flush(&mut self) -> io::Result<()> {
1031 Err(io::Error::last_os_error())
1032 }
1033 }
1034
1035 let writer = FailFlushWriter;
1036 let _writer = BufWriter::new(writer);
1037
1038 // If writer panics *again* due to the flush error then the process will
1039 // abort.
1040 panic!();
1041 }
1042
1043 // #[test]
1044 // #[cfg_attr(target_os = "emscripten", ignore)]
1045 // fn panic_in_write_doesnt_flush_in_drop() {
1046 // static WRITES: AtomicUsize = AtomicUsize::new(0);
1047
1048 // struct PanicWriter;
1049
1050 // impl Write for PanicWriter {
1051 // fn write(&mut self, _: &[u8]) -> io::Result<usize> {
1052 // WRITES.fetch_add(1, Ordering::SeqCst);
1053 // panic!();
1054 // }
1055 // fn flush(&mut self) -> io::Result<()> { Ok(()) }
1056 // }
1057
1058 // thread::spawn(|| {
1059 // let mut writer = BufWriter::new(PanicWriter);
1060 // let _ = writer.write(b"hello world");
1061 // let _ = writer.flush();
1062 // }).join().unwrap_err();
1063
1064 // assert_eq!(WRITES.load(Ordering::SeqCst), 1);
1065 // }
1066
1067 // #[bench]
1068 // fn bench_buffered_reader(b: &mut test::Bencher) {
1069 // b.iter(|| {
1070 // BufReader::new(io::empty())
1071 // });
1072 // }
1073
1074 // #[bench]
1075 // fn bench_buffered_writer(b: &mut test::Bencher) {
1076 // b.iter(|| {
1077 // BufWriter::new(io::sink())
1078 // });
1079 // }
1080
1081 struct AcceptOneThenFail {
1082 written: bool,
1083 flushed: bool,
1084 }
1085
1086 impl Write for AcceptOneThenFail {
1087 fn write(&mut self, data: &[u8]) -> io::Result<usize> {
1088 if !self.written {
1089 assert_eq!(data, b"a\nb\n");
1090 self.written = true;
1091 Ok(data.len())
1092 } else {
1093 Err(io::Error::new(io::ErrorKind::NotFound, "test"))
1094 }
1095 }
1096
1097 fn flush(&mut self) -> io::Result<()> {
1098 assert!(self.written);
1099 assert!(!self.flushed);
1100 self.flushed = true;
1101 Err(io::Error::new(io::ErrorKind::Other, "test"))
1102 }
1103 }
1104
1105 #[test]
1106 fn erroneous_flush_retried() {
1107 let a = AcceptOneThenFail {
1108 written: false,
1109 flushed: false,
1110 };
1111
1112 let mut l = LineWriter::new(a);
1113 assert_eq!(l.write(b"a\nb\na").unwrap(), 4);
1114 assert!(l.get_ref().written);
1115 assert!(l.get_ref().flushed);
1116 l.get_mut().flushed = false;
1117
1118 assert_eq!(l.write(b"a").unwrap_err().kind(), io::ErrorKind::Other)
1119 }
1120}