| use core::cmp; |
| |
| use crate::io::{ |
| self, BorrowedBuf, BorrowedCursor, 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 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 = "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() }; |
| } |
| |
| unsafe { |
| // SAFETY: filled bytes have been filled |
| 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 |
| } |
| } |
| } |
| |
| /// 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)] |
| #[doc(hidden)] |
| #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")] |
| pub fn uninlined_slow_read_byte<R: Read>(reader: &mut R) -> Option<Result<u8>> { |
| inlined_slow_read_byte(reader) |
| } |
| |
| #[doc(hidden)] |
| #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")] |
| pub const fn bytes<R>(inner: R) -> Bytes<R> { |
| Bytes { inner } |
| } |