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