• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use std::ops::DerefMut;
15 use std::pin::Pin;
16 use std::task::{Context, Poll};
17 use std::{cmp, io};
18 
19 use crate::io::read_buf::ReadBuf;
20 use crate::io::read_task::{ReadExactTask, ReadTask, ReadToEndTask, ReadToStringTask};
21 
22 /// An async version of the `std::io::Read` trait. Provides all necessary
23 /// reading methods in an asynchronous style.
24 pub trait AsyncRead {
25     /// Attempts to reads bytes from the an I/O source into the buffer passed
26     /// in.
27     ///
28     /// If succeeds, this method will return `Poll::Ready(Ok(n))` where `n`
29     /// indicates the number of bytes that have been successfully read. It's
30     /// guaranteed that `n <= buf.len()`.
31     ///
32     /// If returns `Poll::Ready(Ok(0))`, one of the two scenarios below might
33     /// have occurred
34     ///     1. The underlying stream has been shut down and no longer transfers
35     ///        any bytes.
36     ///     2. The buf passed in is empty
37     ///
38     /// If `Poll::Pending` is returned, it means that the input source is
39     /// currently not ready for reading. In this case, this task will be put
40     /// to sleep until the underlying stream becomes readable or closed.
poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<io::Result<()>>41     fn poll_read(
42         self: Pin<&mut Self>,
43         cx: &mut Context<'_>,
44         buf: &mut ReadBuf<'_>,
45     ) -> Poll<io::Result<()>>;
46 }
47 
48 // Auto-implementation for Box object
49 impl<T: AsyncRead + Unpin + ?Sized> AsyncRead for Box<T> {
poll_read( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<io::Result<()>>50     fn poll_read(
51         mut self: Pin<&mut Self>,
52         cx: &mut Context<'_>,
53         buf: &mut ReadBuf<'_>,
54     ) -> Poll<io::Result<()>> {
55         Pin::new(&mut **self).poll_read(cx, buf)
56     }
57 }
58 
59 // Auto-implementation for mutable reference.
60 impl<T: AsyncRead + Unpin + ?Sized> AsyncRead for &mut T {
poll_read( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<io::Result<()>>61     fn poll_read(
62         mut self: Pin<&mut Self>,
63         cx: &mut Context<'_>,
64         buf: &mut ReadBuf<'_>,
65     ) -> Poll<io::Result<()>> {
66         Pin::new(&mut **self).poll_read(cx, buf)
67     }
68 }
69 
70 // Auto-implementation for Pinned object.
71 impl<T> AsyncRead for Pin<T>
72 where
73     T: DerefMut + Unpin,
74     T::Target: AsyncRead,
75 {
poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<io::Result<()>>76     fn poll_read(
77         self: Pin<&mut Self>,
78         cx: &mut Context<'_>,
79         buf: &mut ReadBuf<'_>,
80     ) -> Poll<io::Result<()>> {
81         self.get_mut().as_mut().poll_read(cx, buf)
82     }
83 }
84 
85 /// An external trait that is automatically implemented for any object that has
86 /// the AsyncRead trait. Provides std-like reading methods such as `read`,
87 /// `read_exact`, `read_to_end`. Every method in this trait returns a future
88 /// object. Awaits on the future will complete the task, but it doesn't
89 /// guarantee whether the task will finished immediately or asynchronously.
90 pub trait AsyncReadExt: AsyncRead {
91     /// Reads data from the I/O source into the buffer.
92     ///
93     /// On success, `Ok(n)` will be returned, where `n` indicates the number of
94     /// bytes that have been successfully read into the buffer. It
95     /// guarantees `0 <= n < buf.len()`, and if `n == 0`, then one of the
96     /// two scenarios below might have been occurred.
97     ///     1. The reader has reaches `end of file` and no more bytes will be
98     ///        produced.
99     ///     2. The length of the buffer passed in is 0.
100     ///
101     /// `Err(e)` will be returned when encounters a fatal error during the read
102     /// procedure. This method should not read anything into the buffer if
103     /// an error has occurred.
104     ///
105     /// # Examples
106     /// ```no run
107     /// let mut io = File::open("foo.txt").await?;
108     /// let mut buf = [0; 3];
109     /// let n = io.read(&mut buf).await?;
110     /// ```
read<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadTask<'a, Self>111     fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadTask<'a, Self> {
112         ReadTask::new(self, buf)
113     }
114 
115     /// Reads data from the I/O source into the buffer until the buffer is
116     /// entirely filled.
117     ///
118     /// On success, `Ok(())` will be returned, indicating the `buf` has been
119     /// filled entirely. If the I/O connection closes before filling the
120     /// entire buffer, io::Error::UnexpectedEof will be returned.
121     /// If a read error occurs during the process, this method will finish
122     /// immediately, the number of bytes that has been read is unspecified.
123     ///
124     /// # Examples
125     /// ```no run
126     /// let mut io = File::open("foo.txt").await?;
127     /// let mut buf = [0; 16384];
128     /// let n = io.read_exact(&mut buf).await?;
129     /// ```
read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExactTask<'a, Self>130     fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExactTask<'a, Self> {
131         ReadExactTask::new(self, buf)
132     }
133 
134     /// Reads all data from the I/O source into the buffer until EOF.
135     ///
136     /// On success, `Ok(())` will be returned, indicating all data from the I/O
137     /// source has been append to the buffer.
138     ///
139     /// If a read error occurs during the read process, this method will finish
140     /// immediately, the number of bytes that has been read is unspecified.
141     ///
142     /// # Examples
143     /// ```no run
144     /// let mut io = File::open("foo.txt").await?;
145     /// let mut buf = Vec::new();
146     /// let n = io.read_to_end(&mut buf).await?;
147     /// ```
read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEndTask<'a, Self>148     fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEndTask<'a, Self> {
149         ReadToEndTask::new(self, buf)
150     }
151 
152     /// Reads all string data from the I/O source into the buffer until EOF.
153     ///
154     /// On success, `Ok(())` will be returned, indicating all data from the I/O
155     /// source has been append to the buffer.
156     ///
157     /// If a read error occurs during the read process, this method will finish
158     /// immediately, the number of bytes that has been read is unspecified.
159     ///
160     /// # Examples
161     /// ```no run
162     ///
163     /// let mut io = File::open("foo.txt").await?;
164     /// let mut buf = String::new();
165     /// let n = io.read_to_string(&mut buf).await?;
166     /// ```
read_to_string<'a>(&'a mut self, dst: &'a mut String) -> ReadToStringTask<'a, Self>167     fn read_to_string<'a>(&'a mut self, dst: &'a mut String) -> ReadToStringTask<'a, Self> {
168         ReadToStringTask::new(self, dst)
169     }
170 
171     /// Creates a "by reference" adaptor for this instance of `AsyncRead`.
172     ///
173     /// The returned adapter also implements `AsyncRead` and will simply borrow
174     /// this current reader.
175     ///
176     /// # Examples
177     ///
178     /// ```no run
179     /// use std::io;
180     ///
181     /// use ylong_runtime::fs::File;
182     /// use ylong_runtime::io::AsyncReadExt;
183     ///
184     /// async fn async_io() -> io::Result<()> {
185     ///     let mut f = File::open("foo.txt").await?;
186     ///     let mut other_buffer = Vec::new();
187     ///
188     ///     {
189     ///         let reference = f.by_ref();
190     ///     } // drop our &mut reference so we can use f again
191     ///
192     ///     // original file still usable, read the rest
193     ///     f.read_to_end(&mut other_buffer).await?;
194     ///     Ok(())
195     /// }
196     /// ```
by_ref(&mut self) -> &mut Self where Self: Sized,197     fn by_ref(&mut self) -> &mut Self
198     where
199         Self: Sized,
200     {
201         self
202     }
203 }
204 
205 /// AsyncRead is implemented for `&[u8]` by copying from the slice.
206 ///
207 /// Note that reading updates the slice to point to the yet unread part.
208 /// The slice will be empty when EOF is reached.
209 impl AsyncRead for &[u8] {
poll_read( mut self: Pin<&mut Self>, _cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<io::Result<()>>210     fn poll_read(
211         mut self: Pin<&mut Self>,
212         _cx: &mut Context<'_>,
213         buf: &mut ReadBuf<'_>,
214     ) -> Poll<io::Result<()>> {
215         let amt = cmp::min(buf.remaining(), self.len());
216         let (a, b) = self.split_at(amt);
217         buf.append(a);
218         *self = b;
219         Poll::Ready(Ok(()))
220     }
221 }
222 
223 impl<R: AsyncRead + ?Sized> AsyncReadExt for R {}
224