| 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`. | |
| // ignore-tidy-undocumented-unsafe | |
| 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); | |
| } | |
| } | |
| } |