| mod bytes; |
| mod chain; |
| mod read; |
| mod read_exact; |
| mod read_to_end; |
| mod read_to_string; |
| mod read_vectored; |
| mod take; |
| |
| use read::ReadFuture; |
| use read_exact::ReadExactFuture; |
| use read_to_end::{read_to_end_internal, ReadToEndFuture}; |
| use read_to_string::ReadToStringFuture; |
| use read_vectored::ReadVectoredFuture; |
| |
| use std::mem; |
| |
| use crate::io::IoSliceMut; |
| |
| pub use bytes::Bytes; |
| pub use chain::Chain; |
| pub use take::Take; |
| |
| extension_trait! { |
| use std::pin::Pin; |
| use std::ops::{Deref, DerefMut}; |
| |
| use crate::io; |
| use crate::task::{Context, Poll}; |
| |
| #[doc = r#" |
| Allows reading from a byte stream. |
| |
| This trait is a re-export of [`futures::io::AsyncRead`] and is an async version of |
| [`std::io::Read`]. |
| |
| Methods other than [`poll_read`] and [`poll_read_vectored`] do not really exist in the |
| trait itself, but they become available when [`ReadExt`] from the [prelude] is imported: |
| |
| ``` |
| # #[allow(unused_imports)] |
| use async_std::prelude::*; |
| ``` |
| |
| [`std::io::Read`]: https://doc.rust-lang.org/std/io/trait.Read.html |
| [`futures::io::AsyncRead`]: |
| https://docs.rs/futures/0.3/futures/io/trait.AsyncRead.html |
| [`poll_read`]: #tymethod.poll_read |
| [`poll_read_vectored`]: #method.poll_read_vectored |
| [`ReadExt`]: ../io/prelude/trait.ReadExt.html |
| [prelude]: ../prelude/index.html |
| "#] |
| pub trait Read { |
| #[doc = r#" |
| Attempt to read from the `AsyncRead` into `buf`. |
| "#] |
| fn poll_read( |
| self: Pin<&mut Self>, |
| cx: &mut Context<'_>, |
| buf: &mut [u8], |
| ) -> Poll<io::Result<usize>>; |
| |
| #[doc = r#" |
| Attempt to read from the `AsyncRead` into `bufs` using vectored IO operations. |
| "#] |
| fn poll_read_vectored( |
| self: Pin<&mut Self>, |
| cx: &mut Context<'_>, |
| bufs: &mut [IoSliceMut<'_>], |
| ) -> Poll<io::Result<usize>> { |
| unreachable!("this impl only appears in the rendered docs") |
| } |
| } |
| |
| #[doc = r#" |
| Extension methods for [`Read`]. |
| |
| [`Read`]: ../trait.Read.html |
| "#] |
| pub trait ReadExt: futures_io::AsyncRead { |
| #[doc = r#" |
| Reads some bytes from the byte stream. |
| |
| Returns the number of bytes read from the start of the buffer. |
| |
| If the return value is `Ok(n)`, then it must be guaranteed that |
| `0 <= n <= buf.len()`. A nonzero `n` value indicates that the buffer has been |
| filled in with `n` bytes of data. If `n` is `0`, then it can indicate one of two |
| scenarios: |
| |
| 1. This reader has reached its "end of file" and will likely no longer be able to |
| produce bytes. Note that this does not mean that the reader will always no |
| longer be able to produce bytes. |
| 2. The buffer specified was 0 bytes in length. |
| |
| # Examples |
| |
| ```no_run |
| # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
| # |
| use async_std::fs::File; |
| use async_std::prelude::*; |
| |
| let mut file = File::open("a.txt").await?; |
| |
| let mut buf = vec![0; 1024]; |
| let n = file.read(&mut buf).await?; |
| # |
| # Ok(()) }) } |
| ``` |
| "#] |
| fn read<'a>( |
| &'a mut self, |
| buf: &'a mut [u8], |
| ) -> impl Future<Output = io::Result<usize>> + 'a [ReadFuture<'a, Self>] |
| where |
| Self: Unpin |
| { |
| ReadFuture { reader: self, buf } |
| } |
| |
| #[doc = r#" |
| Like [`read`], except that it reads into a slice of buffers. |
| |
| Data is copied to fill each buffer in order, with the final buffer written to |
| possibly being only partially filled. This method must behave as a single call to |
| [`read`] with the buffers concatenated would. |
| |
| The default implementation calls [`read`] with either the first nonempty buffer |
| provided, or an empty one if none exists. |
| |
| [`read`]: #tymethod.read |
| "#] |
| fn read_vectored<'a>( |
| &'a mut self, |
| bufs: &'a mut [IoSliceMut<'a>], |
| ) -> impl Future<Output = io::Result<usize>> + 'a [ReadVectoredFuture<'a, Self>] |
| where |
| Self: Unpin, |
| { |
| ReadVectoredFuture { reader: self, bufs } |
| } |
| |
| #[doc = r#" |
| Reads all bytes from the byte stream. |
| |
| All bytes read from this stream will be appended to the specified buffer `buf`. |
| This function will continuously call [`read`] to append more data to `buf` until |
| [`read`] returns either `Ok(0)` or an error. |
| |
| If successful, this function will return the total number of bytes read. |
| |
| [`read`]: #tymethod.read |
| |
| # Examples |
| |
| ```no_run |
| # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
| # |
| use async_std::fs::File; |
| use async_std::prelude::*; |
| |
| let mut file = File::open("a.txt").await?; |
| |
| let mut buf = Vec::new(); |
| file.read_to_end(&mut buf).await?; |
| # |
| # Ok(()) }) } |
| ``` |
| "#] |
| fn read_to_end<'a>( |
| &'a mut self, |
| buf: &'a mut Vec<u8>, |
| ) -> impl Future<Output = io::Result<usize>> + 'a [ReadToEndFuture<'a, Self>] |
| where |
| Self: Unpin, |
| { |
| let start_len = buf.len(); |
| ReadToEndFuture { |
| reader: self, |
| buf, |
| start_len, |
| } |
| } |
| |
| #[doc = r#" |
| Reads all bytes from the byte stream and appends them into a string. |
| |
| If successful, this function will return the number of bytes read. |
| |
| If the data in this stream is not valid UTF-8 then an error will be returned and |
| `buf` will be left unmodified. |
| |
| # Examples |
| |
| ```no_run |
| # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
| # |
| use async_std::fs::File; |
| use async_std::prelude::*; |
| |
| let mut file = File::open("a.txt").await?; |
| |
| let mut buf = String::new(); |
| file.read_to_string(&mut buf).await?; |
| # |
| # Ok(()) }) } |
| ``` |
| "#] |
| fn read_to_string<'a>( |
| &'a mut self, |
| buf: &'a mut String, |
| ) -> impl Future<Output = io::Result<usize>> + 'a [ReadToStringFuture<'a, Self>] |
| where |
| Self: Unpin, |
| { |
| let start_len = buf.len(); |
| ReadToStringFuture { |
| reader: self, |
| bytes: unsafe { mem::replace(buf.as_mut_vec(), Vec::new()) }, |
| buf, |
| start_len, |
| } |
| } |
| |
| #[doc = r#" |
| Reads the exact number of bytes required to fill `buf`. |
| |
| This function reads as many bytes as necessary to completely fill the specified |
| buffer `buf`. |
| |
| No guarantees are provided about the contents of `buf` when this function is |
| called, implementations cannot rely on any property of the contents of `buf` being |
| true. It is recommended that implementations only write data to `buf` instead of |
| reading its contents. |
| |
| If this function encounters an "end of file" before completely filling the buffer, |
| it returns an error of the kind [`ErrorKind::UnexpectedEof`]. The contents of |
| `buf` are unspecified in this case. |
| |
| If any other read error is encountered then this function immediately returns. The |
| contents of `buf` are unspecified in this case. |
| |
| If this function returns an error, it is unspecified how many bytes it has read, |
| but it will never read more than would be necessary to completely fill the buffer. |
| |
| [`ErrorKind::UnexpectedEof`]: enum.ErrorKind.html#variant.UnexpectedEof |
| |
| # Examples |
| |
| ```no_run |
| # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
| # |
| use async_std::fs::File; |
| use async_std::prelude::*; |
| |
| let mut file = File::open("a.txt").await?; |
| |
| let mut buf = vec![0; 10]; |
| file.read_exact(&mut buf).await?; |
| # |
| # Ok(()) }) } |
| ``` |
| "#] |
| fn read_exact<'a>( |
| &'a mut self, |
| buf: &'a mut [u8], |
| ) -> impl Future<Output = io::Result<()>> + 'a [ReadExactFuture<'a, Self>] |
| where |
| Self: Unpin, |
| { |
| ReadExactFuture { reader: self, buf } |
| } |
| |
| #[doc = r#" |
| Creates an adaptor which will read at most `limit` bytes from it. |
| |
| This function returns a new instance of `Read` which will read at most |
| `limit` bytes, after which it will always return EOF ([`Ok(0)`]). Any |
| read errors will not count towards the number of bytes read and future |
| calls to [`read`] may succeed. |
| |
| # Examples |
| |
| [`File`]s implement `Read`: |
| |
| [`File`]: ../fs/struct.File.html |
| [`Ok(0)`]: ../../std/result/enum.Result.html#variant.Ok |
| [`read`]: tymethod.read |
| |
| ```no_run |
| # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
| # |
| use async_std::io::prelude::*; |
| use async_std::fs::File; |
| |
| let f = File::open("foo.txt").await?; |
| let mut buffer = [0; 5]; |
| |
| // read at most five bytes |
| let mut handle = f.take(5); |
| |
| handle.read(&mut buffer).await?; |
| # |
| # Ok(()) }) } |
| ``` |
| "#] |
| fn take(self, limit: u64) -> Take<Self> |
| where |
| Self: Sized, |
| { |
| Take { inner: self, limit } |
| } |
| |
| #[doc = r#" |
| Creates a "by reference" adaptor for this instance of `Read`. |
| |
| The returned adaptor also implements `Read` and will simply borrow this |
| current reader. |
| |
| # Examples |
| |
| [`File`][file]s implement `Read`: |
| |
| [file]: ../fs/struct.File.html |
| |
| ```no_run |
| # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
| # |
| use async_std::prelude::*; |
| use async_std::fs::File; |
| |
| let mut f = File::open("foo.txt").await?; |
| let mut buffer = Vec::new(); |
| let mut other_buffer = Vec::new(); |
| |
| { |
| let reference = f.by_ref(); |
| |
| // read at most 5 bytes |
| reference.take(5).read_to_end(&mut buffer).await?; |
| |
| } // drop our &mut reference so we can use f again |
| |
| // original file still usable, read the rest |
| f.read_to_end(&mut other_buffer).await?; |
| # |
| # Ok(()) }) } |
| ``` |
| "#] |
| fn by_ref(&mut self) -> &mut Self where Self: Sized { self } |
| |
| |
| #[doc = r#" |
| Transforms this `Read` instance to a `Stream` over its bytes. |
| |
| The returned type implements `Stream` where the `Item` is |
| `Result<u8, io::Error>`. |
| The yielded item is `Ok` if a byte was successfully read and `Err` |
| otherwise. EOF is mapped to returning `None` from this iterator. |
| |
| # Examples |
| |
| [`File`][file]s implement `Read`: |
| |
| [file]: ../fs/struct.File.html |
| |
| ```no_run |
| # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
| # |
| use async_std::prelude::*; |
| use async_std::fs::File; |
| |
| let f = File::open("foo.txt").await?; |
| let mut s = f.bytes(); |
| |
| while let Some(byte) = s.next().await { |
| println!("{}", byte.unwrap()); |
| } |
| # |
| # Ok(()) }) } |
| ``` |
| "#] |
| fn bytes(self) -> Bytes<Self> where Self: Sized { |
| Bytes { inner: self } |
| } |
| |
| #[doc = r#" |
| Creates an adaptor which will chain this stream with another. |
| |
| The returned `Read` instance will first read all bytes from this object |
| until EOF is encountered. Afterwards the output is equivalent to the |
| output of `next`. |
| |
| # Examples |
| |
| [`File`][file]s implement `Read`: |
| |
| [file]: ../fs/struct.File.html |
| |
| ```no_run |
| # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
| # |
| use async_std::prelude::*; |
| use async_std::fs::File; |
| |
| let f1 = File::open("foo.txt").await?; |
| let f2 = File::open("bar.txt").await?; |
| |
| let mut handle = f1.chain(f2); |
| let mut buffer = String::new(); |
| |
| // read the value into a String. We could use any Read method here, |
| // this is just one example. |
| handle.read_to_string(&mut buffer).await?; |
| # |
| # Ok(()) }) } |
| ``` |
| "#] |
| fn chain<R: Read>(self, next: R) -> Chain<Self, R> where Self: Sized { |
| Chain { first: self, second: next, done_first: false } |
| } |
| |
| } |
| |
| impl<T: Read + Unpin + ?Sized> Read for Box<T> { |
| fn poll_read( |
| self: Pin<&mut Self>, |
| cx: &mut Context<'_>, |
| buf: &mut [u8], |
| ) -> Poll<io::Result<usize>> { |
| unreachable!("this impl only appears in the rendered docs") |
| } |
| } |
| |
| impl<T: Read + Unpin + ?Sized> Read for &mut T { |
| fn poll_read( |
| self: Pin<&mut Self>, |
| cx: &mut Context<'_>, |
| buf: &mut [u8], |
| ) -> Poll<io::Result<usize>> { |
| unreachable!("this impl only appears in the rendered docs") |
| } |
| } |
| |
| impl<P> Read for Pin<P> |
| where |
| P: DerefMut + Unpin, |
| <P as Deref>::Target: Read, |
| { |
| fn poll_read( |
| self: Pin<&mut Self>, |
| cx: &mut Context<'_>, |
| buf: &mut [u8], |
| ) -> Poll<io::Result<usize>> { |
| unreachable!("this impl only appears in the rendered docs") |
| } |
| } |
| |
| impl Read for &[u8] { |
| fn poll_read( |
| self: Pin<&mut Self>, |
| cx: &mut Context<'_>, |
| buf: &mut [u8], |
| ) -> Poll<io::Result<usize>> { |
| unreachable!("this impl only appears in the rendered docs") |
| } |
| } |
| } |
| |
| /// Initializes a buffer if necessary. |
| /// |
| /// Currently, a buffer is always initialized because `read_initializer` |
| /// feature is not stable. |
| #[inline] |
| unsafe fn initialize<R: futures_io::AsyncRead>(_reader: &R, buf: &mut [u8]) { |
| std::ptr::write_bytes(buf.as_mut_ptr(), 0, buf.len()) |
| } |
| |
| #[cfg(all(test, not(target_os = "unknown")))] |
| mod tests { |
| use crate::io; |
| use crate::prelude::*; |
| |
| #[test] |
| fn test_read_by_ref() { |
| crate::task::block_on(async { |
| let mut f = io::Cursor::new(vec![0u8, 1, 2, 3, 4, 5, 6, 7, 8]); |
| let mut buffer = Vec::new(); |
| let mut other_buffer = Vec::new(); |
| |
| { |
| let reference = f.by_ref(); |
| |
| // read at most 5 bytes |
| assert_eq!(reference.take(5).read_to_end(&mut buffer).await.unwrap(), 5); |
| assert_eq!(&buffer, &[0, 1, 2, 3, 4]) |
| } // drop our &mut reference so we can use f again |
| |
| // original file still usable, read the rest |
| assert_eq!(f.read_to_end(&mut other_buffer).await.unwrap(), 4); |
| assert_eq!(&other_buffer, &[5, 6, 7, 8]); |
| }); |
| } |
| } |