| use core::cmp; | |
| use crate::io::{ | |
| self, BorrowedBuf, BorrowedCursor, BufRead, Chain, Empty, IoSliceMut, Read, Repeat, Result, | |
| SizeHint, Take, | |
| }; | |
| use crate::slice; | |
| use crate::string::String; | |
| use crate::vec::Vec; | |
| #[stable(feature = "rust1", since = "1.0.0")] | |
| impl Read for Empty { | |
| #[inline] | |
| fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { | |
| Ok(0) | |
| } | |
| #[inline] | |
| fn read_buf(&mut self, _cursor: BorrowedCursor<'_, u8>) -> io::Result<()> { | |
| Ok(()) | |
| } | |
| #[inline] | |
| fn read_vectored(&mut self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { | |
| Ok(0) | |
| } | |
| #[inline] | |
| fn is_read_vectored(&self) -> bool { | |
| // Do not force `Chain<Empty, T>` or `Chain<T, Empty>` to use vectored | |
| // reads, unless the other reader is vectored. | |
| false | |
| } | |
| #[inline] | |
| fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { | |
| if !buf.is_empty() { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) } | |
| } | |
| #[inline] | |
| fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_, u8>) -> io::Result<()> { | |
| if cursor.capacity() != 0 { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) } | |
| } | |
| #[inline] | |
| fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> { | |
| Ok(0) | |
| } | |
| #[inline] | |
| fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> { | |
| Ok(0) | |
| } | |
| } | |
| #[stable(feature = "rust1", since = "1.0.0")] | |
| impl BufRead for Empty { | |
| #[inline] | |
| fn fill_buf(&mut self) -> io::Result<&[u8]> { | |
| Ok(&[]) | |
| } | |
| #[inline] | |
| fn consume(&mut self, _n: usize) {} | |
| #[inline] | |
| fn has_data_left(&mut self) -> io::Result<bool> { | |
| Ok(false) | |
| } | |
| #[inline] | |
| fn read_until(&mut self, _byte: u8, _buf: &mut Vec<u8>) -> io::Result<usize> { | |
| Ok(0) | |
| } | |
| #[inline] | |
| fn skip_until(&mut self, _byte: u8) -> io::Result<usize> { | |
| Ok(0) | |
| } | |
| #[inline] | |
| fn read_line(&mut self, _buf: &mut String) -> io::Result<usize> { | |
| Ok(0) | |
| } | |
| } | |
| #[stable(feature = "rust1", since = "1.0.0")] | |
| impl Read for Repeat { | |
| #[inline] | |
| fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | |
| buf.fill(self.byte); | |
| Ok(buf.len()) | |
| } | |
| #[inline] | |
| fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { | |
| buf.fill(self.byte); | |
| Ok(()) | |
| } | |
| #[inline] | |
| fn read_buf(&mut self, mut buf: BorrowedCursor<'_, u8>) -> io::Result<()> { | |
| // SAFETY: No uninit bytes are being written. | |
| unsafe { buf.as_mut() }.write_filled(self.byte); | |
| // SAFETY: the entire unfilled portion of buf has been initialized. | |
| unsafe { buf.advance(buf.capacity()) }; | |
| Ok(()) | |
| } | |
| #[inline] | |
| fn read_buf_exact(&mut self, buf: BorrowedCursor<'_, u8>) -> io::Result<()> { | |
| self.read_buf(buf) | |
| } | |
| /// This function is not supported by `io::Repeat`, because there's no end of its data | |
| fn read_to_end(&mut self, _: &mut Vec<u8>) -> io::Result<usize> { | |
| Err(io::Error::from(io::ErrorKind::OutOfMemory)) | |
| } | |
| /// This function is not supported by `io::Repeat`, because there's no end of its data | |
| fn read_to_string(&mut self, _: &mut String) -> io::Result<usize> { | |
| Err(io::Error::from(io::ErrorKind::OutOfMemory)) | |
| } | |
| #[inline] | |
| fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { | |
| let mut nwritten = 0; | |
| for buf in bufs { | |
| nwritten += self.read(buf)?; | |
| } | |
| Ok(nwritten) | |
| } | |
| #[inline] | |
| fn is_read_vectored(&self) -> bool { | |
| true | |
| } | |
| } | |
| #[stable(feature = "rust1", since = "1.0.0")] | |
| impl<T: Read, U: Read> Read for Chain<T, U> { | |
| fn read(&mut self, buf: &mut [u8]) -> Result<usize> { | |
| if !self.done_first { | |
| match self.first.read(buf)? { | |
| 0 if !buf.is_empty() => self.done_first = true, | |
| n => return Ok(n), | |
| } | |
| } | |
| self.second.read(buf) | |
| } | |
| fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> { | |
| if !self.done_first { | |
| match self.first.read_vectored(bufs)? { | |
| 0 if bufs.iter().any(|b| !b.is_empty()) => self.done_first = true, | |
| n => return Ok(n), | |
| } | |
| } | |
| self.second.read_vectored(bufs) | |
| } | |
| #[inline] | |
| fn is_read_vectored(&self) -> bool { | |
| self.first.is_read_vectored() || self.second.is_read_vectored() | |
| } | |
| fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> { | |
| let mut read = 0; | |
| if !self.done_first { | |
| read += self.first.read_to_end(buf)?; | |
| self.done_first = true; | |
| } | |
| read += self.second.read_to_end(buf)?; | |
| Ok(read) | |
| } | |
| // We don't override `read_to_string` here because an UTF-8 sequence could | |
| // be split between the two parts of the chain | |
| fn read_buf(&mut self, mut buf: BorrowedCursor<'_, u8>) -> Result<()> { | |
| if buf.capacity() == 0 { | |
| return Ok(()); | |
| } | |
| if !self.done_first { | |
| let old_len = buf.written(); | |
| self.first.read_buf(buf.reborrow())?; | |
| if buf.written() != old_len { | |
| return Ok(()); | |
| } else { | |
| self.done_first = true; | |
| } | |
| } | |
| self.second.read_buf(buf) | |
| } | |
| } | |
| #[stable(feature = "chain_bufread", since = "1.9.0")] | |
| impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> { | |
| fn fill_buf(&mut self) -> Result<&[u8]> { | |
| if !self.done_first { | |
| match self.first.fill_buf()? { | |
| buf if buf.is_empty() => self.done_first = true, | |
| buf => return Ok(buf), | |
| } | |
| } | |
| self.second.fill_buf() | |
| } | |
| fn consume(&mut self, amt: usize) { | |
| if !self.done_first { self.first.consume(amt) } else { self.second.consume(amt) } | |
| } | |
| fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> { | |
| let mut read = 0; | |
| if !self.done_first { | |
| let n = self.first.read_until(byte, buf)?; | |
| read += n; | |
| match buf.last() { | |
| Some(b) if *b == byte && n != 0 => return Ok(read), | |
| _ => self.done_first = true, | |
| } | |
| } | |
| read += self.second.read_until(byte, buf)?; | |
| Ok(read) | |
| } | |
| // We don't override `read_line` here because an UTF-8 sequence could be | |
| // split between the two parts of the chain | |
| } | |
| #[stable(feature = "rust1", since = "1.0.0")] | |
| impl<T: Read> Read for Take<T> { | |
| fn read(&mut self, buf: &mut [u8]) -> Result<usize> { | |
| // Don't call into inner reader at all at EOF because it may still block | |
| if self.limit == 0 { | |
| return Ok(0); | |
| } | |
| let max = cmp::min(buf.len() as u64, self.limit) as usize; | |
| let n = self.inner.read(&mut buf[..max])?; | |
| assert!(n as u64 <= self.limit, "number of read bytes exceeds limit"); | |
| self.limit -= n as u64; | |
| Ok(n) | |
| } | |
| fn read_buf(&mut self, mut buf: BorrowedCursor<'_, u8>) -> Result<()> { | |
| // Don't call into inner reader at all at EOF because it may still block | |
| if self.limit == 0 { | |
| return Ok(()); | |
| } | |
| if self.limit < buf.capacity() as u64 { | |
| // The condition above guarantees that `self.limit` fits in `usize`. | |
| let limit = self.limit as usize; | |
| let is_init = buf.is_init(); | |
| // SAFETY: no uninit data is written to ibuf | |
| let mut sliced_buf = BorrowedBuf::from(unsafe { &mut buf.as_mut()[..limit] }); | |
| if is_init { | |
| // SAFETY: `sliced_buf` is a subslice of `buf`, so if `buf` was initialized then | |
| // `sliced_buf` is. | |
| unsafe { sliced_buf.set_init() }; | |
| } | |
| let result = self.inner.read_buf(sliced_buf.unfilled()); | |
| let did_init_up_to_limit = sliced_buf.is_init(); | |
| let filled = sliced_buf.len(); | |
| // sliced_buf must drop here | |
| // Avoid accidentally quadratic behaviour by initializing the whole | |
| // cursor if only part of it was initialized. | |
| if did_init_up_to_limit && !is_init { | |
| // SAFETY: No uninit data will be written. | |
| let unfilled_before_advance = unsafe { buf.as_mut() }; | |
| unfilled_before_advance[limit..].write_filled(0); | |
| // SAFETY: `unfilled_before_advance[..limit]` was initialized by `T::read_buf`, and | |
| // `unfilled_before_advance[limit..]` was just initialized. | |
| unsafe { buf.set_init() }; | |
| } | |
| // SAFETY: filled bytes have been filled | |
| unsafe { | |
| buf.advance(filled); | |
| } | |
| self.limit -= filled as u64; | |
| result | |
| } else { | |
| let written = buf.written(); | |
| let result = self.inner.read_buf(buf.reborrow()); | |
| self.limit -= (buf.written() - written) as u64; | |
| result | |
| } | |
| } | |
| } | |
| #[stable(feature = "rust1", since = "1.0.0")] | |
| impl<T: BufRead> BufRead for Take<T> { | |
| fn fill_buf(&mut self) -> Result<&[u8]> { | |
| // Don't call into inner reader at all at EOF because it may still block | |
| if self.limit == 0 { | |
| return Ok(&[]); | |
| } | |
| let buf = self.inner.fill_buf()?; | |
| let cap = cmp::min(buf.len() as u64, self.limit) as usize; | |
| Ok(&buf[..cap]) | |
| } | |
| fn consume(&mut self, amt: usize) { | |
| // Don't let callers reset the limit by passing an overlarge value | |
| let amt = cmp::min(amt as u64, self.limit) as usize; | |
| self.limit -= amt as u64; | |
| self.inner.consume(amt); | |
| } | |
| } | |
| /// An iterator over `u8` values of a reader. | |
| /// | |
| /// This struct is generally created by calling [`bytes`] on a reader. | |
| /// Please see the documentation of [`bytes`] for more details. | |
| /// | |
| /// [`bytes`]: Read::bytes | |
| #[stable(feature = "rust1", since = "1.0.0")] | |
| #[derive(Debug)] | |
| pub struct Bytes<R> { | |
| inner: R, | |
| } | |
| #[stable(feature = "rust1", since = "1.0.0")] | |
| impl<R: Read> Iterator for Bytes<R> { | |
| type Item = Result<u8>; | |
| // Not `#[inline]`. This function gets inlined even without it, but having | |
| // the inline annotation can result in worse code generation. See #116785. | |
| fn next(&mut self) -> Option<Result<u8>> { | |
| SpecReadByte::spec_read_byte(&mut self.inner) | |
| } | |
| #[inline] | |
| fn size_hint(&self) -> (usize, Option<usize>) { | |
| SizeHint::size_hint(&self.inner) | |
| } | |
| } | |
| /// For the specialization of `Bytes::next`. | |
| #[doc(hidden)] | |
| #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")] | |
| pub trait SpecReadByte { | |
| fn spec_read_byte(&mut self) -> Option<Result<u8>>; | |
| } | |
| impl<R> SpecReadByte for R | |
| where | |
| Self: Read, | |
| { | |
| #[inline] | |
| default fn spec_read_byte(&mut self) -> Option<Result<u8>> { | |
| inlined_slow_read_byte(self) | |
| } | |
| } | |
| /// Reads a single byte in a slow, generic way. This is used by the default | |
| /// `spec_read_byte`. | |
| #[inline] | |
| fn inlined_slow_read_byte<R: Read>(reader: &mut R) -> Option<Result<u8>> { | |
| let mut byte = 0; | |
| loop { | |
| return match reader.read(slice::from_mut(&mut byte)) { | |
| Ok(0) => None, | |
| Ok(..) => Some(Ok(byte)), | |
| Err(ref e) if e.is_interrupted() => continue, | |
| Err(e) => Some(Err(e)), | |
| }; | |
| } | |
| } | |
| // Used by `BufReader::spec_read_byte`, for which the `inline(never)` is | |
| // important. | |
| #[inline(never)] | |
| pub(super) fn uninlined_slow_read_byte<R: Read>(reader: &mut R) -> Option<Result<u8>> { | |
| inlined_slow_read_byte(reader) | |
| } | |
| pub(super) const fn bytes<R>(inner: R) -> Bytes<R> { | |
| Bytes { inner } | |
| } | |
| /// An iterator over the contents of an instance of `BufRead` split on a | |
| /// particular byte. | |
| /// | |
| /// This struct is generally created by calling [`split`] on a `BufRead`. | |
| /// Please see the documentation of [`split`] for more details. | |
| /// | |
| /// [`split`]: BufRead::split | |
| #[stable(feature = "rust1", since = "1.0.0")] | |
| #[derive(Debug)] | |
| #[cfg_attr(not(test), rustc_diagnostic_item = "IoSplit")] | |
| pub struct Split<B> { | |
| buf: B, | |
| delim: u8, | |
| } | |
| #[stable(feature = "rust1", since = "1.0.0")] | |
| impl<B: BufRead> Iterator for Split<B> { | |
| type Item = Result<Vec<u8>>; | |
| fn next(&mut self) -> Option<Result<Vec<u8>>> { | |
| let mut buf = Vec::new(); | |
| match self.buf.read_until(self.delim, &mut buf) { | |
| Ok(0) => None, | |
| Ok(_n) => { | |
| if buf[buf.len() - 1] == self.delim { | |
| buf.pop(); | |
| } | |
| Some(Ok(buf)) | |
| } | |
| Err(e) => Some(Err(e)), | |
| } | |
| } | |
| } | |
| pub(super) const fn split<B>(buf: B, delim: u8) -> Split<B> { | |
| Split { buf, delim } | |
| } | |
| /// An iterator over the lines of an instance of [`BufRead`]. | |
| /// | |
| /// This struct is generally created by calling [`lines`] on a [`BufRead`]. | |
| /// Please see the documentation of [`lines`] for more details. | |
| /// | |
| /// [`lines`]: BufRead::lines | |
| #[stable(feature = "rust1", since = "1.0.0")] | |
| #[derive(Debug)] | |
| #[cfg_attr(not(test), rustc_diagnostic_item = "IoLines")] | |
| pub struct Lines<B> { | |
| buf: B, | |
| } | |
| #[stable(feature = "rust1", since = "1.0.0")] | |
| impl<B: BufRead> Iterator for Lines<B> { | |
| type Item = Result<String>; | |
| fn next(&mut self) -> Option<Result<String>> { | |
| let mut buf = String::new(); | |
| match self.buf.read_line(&mut buf) { | |
| Ok(0) => None, | |
| Ok(_n) => { | |
| if buf.ends_with('\n') { | |
| buf.pop(); | |
| if buf.ends_with('\r') { | |
| buf.pop(); | |
| } | |
| } | |
| Some(Ok(buf)) | |
| } | |
| Err(e) => Some(Err(e)), | |
| } | |
| } | |
| } | |
| pub(super) const fn lines<B>(buf: B) -> Lines<B> { | |
| Lines { buf } | |
| } |