| use core::slice::memchr; |
| |
| use crate::io::{ErrorKind, Lines, Read, Result, Split, append_to_string, lines, split}; |
| use crate::string::String; |
| use crate::vec::Vec; |
| |
| /// A `BufRead` is a type of [`Read`]er which has an internal buffer, allowing it |
| /// to perform extra ways of reading. |
| /// |
| /// For example, reading line-by-line is inefficient without using a buffer, so |
| /// if you want to read by line, you'll need `BufRead`, which includes a |
| /// [`read_line`] method as well as a [`lines`] iterator. |
| /// |
| /// # Examples |
| /// |
| /// A locked standard input implements `BufRead`: |
| /// |
| /// ```no_run |
| /// use std::io; |
| /// use std::io::prelude::*; |
| /// |
| /// let stdin = io::stdin(); |
| /// for line in stdin.lock().lines() { |
| /// println!("{}", line?); |
| /// } |
| /// # std::io::Result::Ok(()) |
| /// ``` |
| /// |
| /// If you have something that implements [`Read`], you can use the `BufReader` |
| /// type to turn it into a `BufRead`. |
| /// |
| /// For example, `File` implements [`Read`], but not `BufRead`. |
| /// `BufReader` to the rescue! |
| /// |
| /// [`read_line`]: BufRead::read_line |
| /// [`lines`]: BufRead::lines |
| /// |
| /// ```no_run |
| /// use std::io::{self, BufReader}; |
| /// use std::io::prelude::*; |
| /// use std::fs::File; |
| /// |
| /// fn main() -> io::Result<()> { |
| /// let f = File::open("foo.txt")?; |
| /// let f = BufReader::new(f); |
| /// |
| /// for line in f.lines() { |
| /// let line = line?; |
| /// println!("{line}"); |
| /// } |
| /// |
| /// Ok(()) |
| /// } |
| /// ``` |
| #[stable(feature = "rust1", since = "1.0.0")] |
| #[cfg_attr(not(test), rustc_diagnostic_item = "IoBufRead")] |
| pub trait BufRead: Read { |
| /// Returns the contents of the internal buffer, filling it with more data, via [`Read`] methods, if empty. |
| /// |
| /// This is a lower-level method and is meant to be used together with [`consume`], |
| /// which can be used to mark bytes that should not be returned by subsequent calls to `read`. |
| /// |
| /// [`consume`]: BufRead::consume |
| /// |
| /// Returns an empty buffer when the stream has reached EOF. |
| /// |
| /// # Errors |
| /// |
| /// This function will return an I/O error if a [`Read`] method was called, but returned an error. |
| /// |
| /// # Examples |
| /// |
| /// A locked standard input implements `BufRead`: |
| /// |
| /// ```no_run |
| /// use std::io; |
| /// use std::io::prelude::*; |
| /// |
| /// let stdin = io::stdin(); |
| /// let mut stdin = stdin.lock(); |
| /// |
| /// let buffer = stdin.fill_buf()?; |
| /// |
| /// // work with buffer |
| /// println!("{buffer:?}"); |
| /// |
| /// // mark the bytes we worked with as read |
| /// let length = buffer.len(); |
| /// stdin.consume(length); |
| /// # std::io::Result::Ok(()) |
| /// ``` |
| #[stable(feature = "rust1", since = "1.0.0")] |
| fn fill_buf(&mut self) -> Result<&[u8]>; |
| |
| /// Marks the given `amount` of additional bytes from the internal buffer as having been read. |
| /// Subsequent calls to `read` only return bytes that have not been marked as read. |
| /// |
| /// This is a lower-level method and is meant to be used together with [`fill_buf`], |
| /// which can be used to fill the internal buffer via [`Read`] methods. |
| /// |
| /// It is a logic error if `amount` exceeds the number of unread bytes in the internal buffer, which is returned by [`fill_buf`]. |
| /// |
| /// # Examples |
| /// |
| /// Since `consume()` is meant to be used with [`fill_buf`], |
| /// that method's example includes an example of `consume()`. |
| /// |
| /// [`fill_buf`]: BufRead::fill_buf |
| #[stable(feature = "rust1", since = "1.0.0")] |
| fn consume(&mut self, amount: usize); |
| |
| /// Checks if there is any data left to be `read`. |
| /// |
| /// This function may fill the buffer to check for data, |
| /// so this function returns `Result<bool>`, not `bool`. |
| /// |
| /// The default implementation calls `fill_buf` and checks that the |
| /// returned slice is empty (which means that there is no data left, |
| /// since EOF is reached). |
| /// |
| /// # Errors |
| /// |
| /// This function will return an I/O error if a [`Read`] method was called, but returned an error. |
| /// |
| /// Examples |
| /// |
| /// ``` |
| /// #![feature(buf_read_has_data_left)] |
| /// use std::io; |
| /// use std::io::prelude::*; |
| /// |
| /// let stdin = io::stdin(); |
| /// let mut stdin = stdin.lock(); |
| /// |
| /// while stdin.has_data_left()? { |
| /// let mut line = String::new(); |
| /// stdin.read_line(&mut line)?; |
| /// // work with line |
| /// println!("{line:?}"); |
| /// } |
| /// # std::io::Result::Ok(()) |
| /// ``` |
| #[unstable(feature = "buf_read_has_data_left", issue = "86423")] |
| fn has_data_left(&mut self) -> Result<bool> { |
| self.fill_buf().map(|b| !b.is_empty()) |
| } |
| |
| /// Reads all bytes into `buf` until the delimiter `byte` or EOF is reached. |
| /// |
| /// This function will read bytes from the underlying stream until the |
| /// delimiter or EOF is found. Once found, all bytes up to, and including, |
| /// the delimiter (if found) will be appended to `buf`. |
| /// |
| /// If successful, this function will return the total number of bytes read. |
| /// |
| /// This function is blocking and should be used carefully: it is possible for |
| /// an attacker to continuously send bytes without ever sending the delimiter |
| /// or EOF. |
| /// |
| /// # Errors |
| /// |
| /// This function will ignore all instances of [`ErrorKind::Interrupted`] and |
| /// will otherwise return any errors returned by [`fill_buf`]. |
| /// |
| /// If an I/O error is encountered then all bytes read so far will be |
| /// present in `buf` and its length will have been adjusted appropriately. |
| /// |
| /// [`fill_buf`]: BufRead::fill_buf |
| /// |
| /// # Examples |
| /// |
| /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In |
| /// this example, we use [`Cursor`] to read all the bytes in a byte slice |
| /// in hyphen delimited segments: |
| /// |
| /// [`Cursor`]: crate::io::Cursor |
| /// |
| /// ``` |
| /// use std::io::{self, BufRead}; |
| /// |
| /// let mut cursor = io::Cursor::new(b"lorem-ipsum"); |
| /// let mut buf = vec![]; |
| /// |
| /// // cursor is at 'l' |
| /// let num_bytes = cursor.read_until(b'-', &mut buf) |
| /// .expect("reading from cursor won't fail"); |
| /// assert_eq!(num_bytes, 6); |
| /// assert_eq!(buf, b"lorem-"); |
| /// buf.clear(); |
| /// |
| /// // cursor is at 'i' |
| /// let num_bytes = cursor.read_until(b'-', &mut buf) |
| /// .expect("reading from cursor won't fail"); |
| /// assert_eq!(num_bytes, 5); |
| /// assert_eq!(buf, b"ipsum"); |
| /// buf.clear(); |
| /// |
| /// // cursor is at EOF |
| /// let num_bytes = cursor.read_until(b'-', &mut buf) |
| /// .expect("reading from cursor won't fail"); |
| /// assert_eq!(num_bytes, 0); |
| /// assert_eq!(buf, b""); |
| /// ``` |
| #[stable(feature = "rust1", since = "1.0.0")] |
| fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> { |
| default_read_until(self, byte, buf) |
| } |
| |
| /// Skips all bytes until the delimiter `byte` or EOF is reached. |
| /// |
| /// This function will read (and discard) bytes from the underlying stream until the |
| /// delimiter or EOF is found. |
| /// |
| /// If successful, this function will return the total number of bytes read, |
| /// including the delimiter byte if found. |
| /// |
| /// This is useful for efficiently skipping data such as NUL-terminated strings |
| /// in binary file formats without buffering. |
| /// |
| /// This function is blocking and should be used carefully: it is possible for |
| /// an attacker to continuously send bytes without ever sending the delimiter |
| /// or EOF. |
| /// |
| /// # Errors |
| /// |
| /// This function will ignore all instances of [`ErrorKind::Interrupted`] and |
| /// will otherwise return any errors returned by [`fill_buf`]. |
| /// |
| /// If an I/O error is encountered then all bytes read so far will be |
| /// present in `buf` and its length will have been adjusted appropriately. |
| /// |
| /// [`fill_buf`]: BufRead::fill_buf |
| /// |
| /// # Examples |
| /// |
| /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In |
| /// this example, we use [`Cursor`] to read some NUL-terminated information |
| /// about Ferris from a binary string, skipping the fun fact: |
| /// |
| /// [`Cursor`]: crate::io::Cursor |
| /// |
| /// ``` |
| /// use std::io::{self, BufRead}; |
| /// |
| /// let mut cursor = io::Cursor::new(b"Ferris\0Likes long walks on the beach\0Crustacean\0!"); |
| /// |
| /// // read name |
| /// let mut name = Vec::new(); |
| /// let num_bytes = cursor.read_until(b'\0', &mut name) |
| /// .expect("reading from cursor won't fail"); |
| /// assert_eq!(num_bytes, 7); |
| /// assert_eq!(name, b"Ferris\0"); |
| /// |
| /// // skip fun fact |
| /// let num_bytes = cursor.skip_until(b'\0') |
| /// .expect("reading from cursor won't fail"); |
| /// assert_eq!(num_bytes, 30); |
| /// |
| /// // read animal type |
| /// let mut animal = Vec::new(); |
| /// let num_bytes = cursor.read_until(b'\0', &mut animal) |
| /// .expect("reading from cursor won't fail"); |
| /// assert_eq!(num_bytes, 11); |
| /// assert_eq!(animal, b"Crustacean\0"); |
| /// |
| /// // reach EOF |
| /// let num_bytes = cursor.skip_until(b'\0') |
| /// .expect("reading from cursor won't fail"); |
| /// assert_eq!(num_bytes, 1); |
| /// ``` |
| #[stable(feature = "bufread_skip_until", since = "1.83.0")] |
| fn skip_until(&mut self, byte: u8) -> Result<usize> { |
| default_skip_until(self, byte) |
| } |
| |
| /// Reads all bytes until a newline (the `0xA` byte) is reached, and append |
| /// them to the provided [`String`] buffer. |
| /// |
| /// Previous content of the buffer will be preserved. To avoid appending to |
| /// the buffer, you need to [`clear`] it first. |
| /// |
| /// This function will read bytes from the underlying stream until the |
| /// newline delimiter (the `0xA` byte) or EOF is found. Once found, all bytes |
| /// up to, and including, the delimiter (if found) will be appended to |
| /// `buf`. |
| /// |
| /// If successful, this function will return the total number of bytes read. |
| /// |
| /// If this function returns [`Ok(0)`], the stream has reached EOF. |
| /// |
| /// This function is blocking and should be used carefully: it is possible for |
| /// an attacker to continuously send bytes without ever sending a newline |
| /// or EOF. You can use [`take`] to limit the maximum number of bytes read. |
| /// |
| /// [`Ok(0)`]: Ok |
| /// [`clear`]: String::clear |
| /// [`take`]: crate::io::Read::take |
| /// |
| /// # Errors |
| /// |
| /// This function has the same error semantics as [`read_until`] and will |
| /// also return an error if the read bytes are not valid UTF-8. If an I/O |
| /// error is encountered then `buf` may contain some bytes already read in |
| /// the event that all data read so far was valid UTF-8. |
| /// |
| /// [`read_until`]: BufRead::read_until |
| /// |
| /// # Examples |
| /// |
| /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In |
| /// this example, we use [`Cursor`] to read all the lines in a byte slice: |
| /// |
| /// [`Cursor`]: crate::io::Cursor |
| /// |
| /// ``` |
| /// use std::io::{self, BufRead}; |
| /// |
| /// let mut cursor = io::Cursor::new(b"foo\nbar"); |
| /// let mut buf = String::new(); |
| /// |
| /// // cursor is at 'f' |
| /// let num_bytes = cursor.read_line(&mut buf) |
| /// .expect("reading from cursor won't fail"); |
| /// assert_eq!(num_bytes, 4); |
| /// assert_eq!(buf, "foo\n"); |
| /// buf.clear(); |
| /// |
| /// // cursor is at 'b' |
| /// let num_bytes = cursor.read_line(&mut buf) |
| /// .expect("reading from cursor won't fail"); |
| /// assert_eq!(num_bytes, 3); |
| /// assert_eq!(buf, "bar"); |
| /// buf.clear(); |
| /// |
| /// // cursor is at EOF |
| /// let num_bytes = cursor.read_line(&mut buf) |
| /// .expect("reading from cursor won't fail"); |
| /// assert_eq!(num_bytes, 0); |
| /// assert_eq!(buf, ""); |
| /// ``` |
| #[stable(feature = "rust1", since = "1.0.0")] |
| fn read_line(&mut self, buf: &mut String) -> Result<usize> { |
| // Note that we are not calling the `.read_until` method here, but |
| // rather our hardcoded implementation. For more details as to why, see |
| // the comments in `default_read_to_string`. |
| unsafe { append_to_string(buf, |b| default_read_until(self, b'\n', b)) } |
| } |
| |
| /// Returns an iterator over the contents of this reader split on the byte |
| /// `byte`. |
| /// |
| /// The iterator returned from this function will return instances of |
| /// <code>[io::Result]<[Vec]\<u8>></code>. Each vector returned will *not* have |
| /// the delimiter byte at the end. |
| /// |
| /// This function will yield errors whenever [`read_until`] would have |
| /// also yielded an error. |
| /// |
| /// [io::Result]: self::Result "io::Result" |
| /// [`read_until`]: BufRead::read_until |
| /// |
| /// # Examples |
| /// |
| /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In |
| /// this example, we use [`Cursor`] to iterate over all hyphen delimited |
| /// segments in a byte slice |
| /// |
| /// [`Cursor`]: crate::io::Cursor |
| /// |
| /// ``` |
| /// use std::io::{self, BufRead}; |
| /// |
| /// let cursor = io::Cursor::new(b"lorem-ipsum-dolor"); |
| /// |
| /// let mut split_iter = cursor.split(b'-').map(|l| l.unwrap()); |
| /// assert_eq!(split_iter.next(), Some(b"lorem".to_vec())); |
| /// assert_eq!(split_iter.next(), Some(b"ipsum".to_vec())); |
| /// assert_eq!(split_iter.next(), Some(b"dolor".to_vec())); |
| /// assert_eq!(split_iter.next(), None); |
| /// ``` |
| #[stable(feature = "rust1", since = "1.0.0")] |
| fn split(self, byte: u8) -> Split<Self> |
| where |
| Self: Sized, |
| { |
| split(self, byte) |
| } |
| |
| /// Returns an iterator over the lines of this reader. |
| /// |
| /// The iterator returned from this function will yield instances of |
| /// <code>[io::Result]<[String]></code>. Each string returned will *not* have a newline |
| /// byte (the `0xA` byte) or `CRLF` (`0xD`, `0xA` bytes) at the end. |
| /// |
| /// [io::Result]: crate::io::Result "io::Result" |
| /// |
| /// # Examples |
| /// |
| /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In |
| /// this example, we use [`Cursor`] to iterate over all the lines in a byte |
| /// slice. |
| /// |
| /// [`Cursor`]: crate::io::Cursor |
| /// |
| /// ``` |
| /// use std::io::{self, BufRead}; |
| /// |
| /// let cursor = io::Cursor::new(b"lorem\nipsum\r\ndolor"); |
| /// |
| /// let mut lines_iter = cursor.lines().map(|l| l.unwrap()); |
| /// assert_eq!(lines_iter.next(), Some(String::from("lorem"))); |
| /// assert_eq!(lines_iter.next(), Some(String::from("ipsum"))); |
| /// assert_eq!(lines_iter.next(), Some(String::from("dolor"))); |
| /// assert_eq!(lines_iter.next(), None); |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// Each line of the iterator has the same error semantics as [`BufRead::read_line`]. |
| #[stable(feature = "rust1", since = "1.0.0")] |
| fn lines(self) -> Lines<Self> |
| where |
| Self: Sized, |
| { |
| lines(self) |
| } |
| } |
| |
| fn default_read_until<R: BufRead + ?Sized>( |
| r: &mut R, |
| delim: u8, |
| buf: &mut Vec<u8>, |
| ) -> Result<usize> { |
| let mut read = 0; |
| loop { |
| let (done, used) = { |
| let available = match r.fill_buf() { |
| Ok(n) => n, |
| Err(ref e) if e.is_interrupted() => continue, |
| Err(e) => return Err(e), |
| }; |
| let (done, available) = match memchr::memchr(delim, available) { |
| Some(i) => (true, &available[..=i]), |
| None => (false, available), |
| }; |
| |
| cfg_select! { |
| no_global_oom_handling => { |
| let count = available.len(); |
| buf.try_reserve(count)?; |
| |
| // SAFETY: |
| // * self and buf are non-overlapping |
| // * buf[..len] is already initialized |
| // * buf[len..len + count] is initialized by copy_nonoverlapping |
| // * len + count is within the capacity of buf based on the reservation completed above |
| unsafe { |
| let len = buf.len(); |
| let src = available.as_ptr(); |
| let dst = buf.as_mut_ptr().add(len); |
| core::ptr::copy_nonoverlapping(src, dst, count); |
| buf.set_len(len + count); |
| } |
| } |
| _ => { |
| buf.extend_from_slice(available); |
| } |
| } |
| |
| (done, available.len()) |
| }; |
| r.consume(used); |
| read += used; |
| if done || used == 0 { |
| return Ok(read); |
| } |
| } |
| } |
| |
| fn default_skip_until<R: BufRead + ?Sized>(r: &mut R, delim: u8) -> Result<usize> { |
| let mut read = 0; |
| loop { |
| let (done, used) = { |
| let available = match r.fill_buf() { |
| Ok(n) => n, |
| Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, |
| Err(e) => return Err(e), |
| }; |
| match memchr::memchr(delim, available) { |
| Some(i) => (true, i + 1), |
| None => (false, available.len()), |
| } |
| }; |
| r.consume(used); |
| read += used; |
| if done || used == 0 { |
| return Ok(read); |
| } |
| } |
| } |