1 | mod bytes; |
2 | mod chain; |
3 | mod read; |
4 | mod read_exact; |
5 | mod read_to_end; |
6 | mod read_to_string; |
7 | mod read_vectored; |
8 | mod take; |
9 | |
10 | use read::ReadFuture; |
11 | use read_exact::ReadExactFuture; |
12 | use read_to_end::{read_to_end_internal, ReadToEndFuture}; |
13 | use read_to_string::ReadToStringFuture; |
14 | use read_vectored::ReadVectoredFuture; |
15 | |
16 | use std::mem; |
17 | |
18 | use crate::io::IoSliceMut; |
19 | |
20 | pub use bytes::Bytes; |
21 | pub use chain::Chain; |
22 | pub use take::Take; |
23 | |
24 | pub use futures_io::AsyncRead as Read; |
25 | |
26 | #[doc = r#" |
27 | Extension methods for [`Read`]. |
28 | |
29 | [`Read`]: ../trait.Read.html |
30 | "# ] |
31 | pub trait ReadExt: Read { |
32 | #[doc = r#" |
33 | Reads some bytes from the byte stream. |
34 | |
35 | Returns the number of bytes read from the start of the buffer. |
36 | |
37 | If the return value is `Ok(n)`, then it must be guaranteed that |
38 | `0 <= n <= buf.len()`. A nonzero `n` value indicates that the buffer has been |
39 | filled in with `n` bytes of data. If `n` is `0`, then it can indicate one of two |
40 | scenarios: |
41 | |
42 | 1. This reader has reached its "end of file" and will likely no longer be able to |
43 | produce bytes. Note that this does not mean that the reader will always no |
44 | longer be able to produce bytes. |
45 | 2. The buffer specified was 0 bytes in length. |
46 | |
47 | # Examples |
48 | |
49 | ```no_run |
50 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
51 | # |
52 | use async_std::fs::File; |
53 | use async_std::prelude::*; |
54 | |
55 | let mut file = File::open("a.txt" ).await?; |
56 | |
57 | let mut buf = vec![0; 1024]; |
58 | let n = file.read(&mut buf).await?; |
59 | # |
60 | # Ok(()) }) } |
61 | ``` |
62 | "# ] |
63 | fn read<'a>( |
64 | &'a mut self, |
65 | buf: &'a mut [u8], |
66 | ) -> ReadFuture<'a, Self> |
67 | where |
68 | Self: Unpin |
69 | { |
70 | ReadFuture { reader: self, buf } |
71 | } |
72 | |
73 | #[doc = r#" |
74 | Like [`read`], except that it reads into a slice of buffers. |
75 | |
76 | Data is copied to fill each buffer in order, with the final buffer written to |
77 | possibly being only partially filled. This method must behave as a single call to |
78 | [`read`] with the buffers concatenated would. |
79 | |
80 | The default implementation calls [`read`] with either the first nonempty buffer |
81 | provided, or an empty one if none exists. |
82 | |
83 | [`read`]: #tymethod.read |
84 | "# ] |
85 | fn read_vectored<'a>( |
86 | &'a mut self, |
87 | bufs: &'a mut [IoSliceMut<'a>], |
88 | ) -> ReadVectoredFuture<'a, Self> |
89 | where |
90 | Self: Unpin, |
91 | { |
92 | ReadVectoredFuture { reader: self, bufs } |
93 | } |
94 | |
95 | #[doc = r#" |
96 | Reads all bytes from the byte stream. |
97 | |
98 | All bytes read from this stream will be appended to the specified buffer `buf`. |
99 | This function will continuously call [`read`] to append more data to `buf` until |
100 | [`read`] returns either `Ok(0)` or an error. |
101 | |
102 | If successful, this function will return the total number of bytes read. |
103 | |
104 | [`read`]: #tymethod.read |
105 | |
106 | # Examples |
107 | |
108 | ```no_run |
109 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
110 | # |
111 | use async_std::fs::File; |
112 | use async_std::prelude::*; |
113 | |
114 | let mut file = File::open("a.txt" ).await?; |
115 | |
116 | let mut buf = Vec::new(); |
117 | file.read_to_end(&mut buf).await?; |
118 | # |
119 | # Ok(()) }) } |
120 | ``` |
121 | "# ] |
122 | fn read_to_end<'a>( |
123 | &'a mut self, |
124 | buf: &'a mut Vec<u8>, |
125 | ) -> ReadToEndFuture<'a, Self> |
126 | where |
127 | Self: Unpin, |
128 | { |
129 | let start_len = buf.len(); |
130 | ReadToEndFuture { |
131 | reader: self, |
132 | buf, |
133 | start_len, |
134 | } |
135 | } |
136 | |
137 | #[doc = r#" |
138 | Reads all bytes from the byte stream and appends them into a string. |
139 | |
140 | If successful, this function will return the number of bytes read. |
141 | |
142 | If the data in this stream is not valid UTF-8 then an error will be returned and |
143 | `buf` will be left unmodified. |
144 | |
145 | # Examples |
146 | |
147 | ```no_run |
148 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
149 | # |
150 | use async_std::fs::File; |
151 | use async_std::prelude::*; |
152 | |
153 | let mut file = File::open("a.txt" ).await?; |
154 | |
155 | let mut buf = String::new(); |
156 | file.read_to_string(&mut buf).await?; |
157 | # |
158 | # Ok(()) }) } |
159 | ``` |
160 | "# ] |
161 | fn read_to_string<'a>( |
162 | &'a mut self, |
163 | buf: &'a mut String, |
164 | ) -> ReadToStringFuture<'a, Self> |
165 | where |
166 | Self: Unpin, |
167 | { |
168 | let start_len = buf.len(); |
169 | ReadToStringFuture { |
170 | reader: self, |
171 | bytes: unsafe { mem::replace(buf.as_mut_vec(), Vec::new()) }, |
172 | buf, |
173 | start_len, |
174 | } |
175 | } |
176 | |
177 | #[doc = r#" |
178 | Reads the exact number of bytes required to fill `buf`. |
179 | |
180 | This function reads as many bytes as necessary to completely fill the specified |
181 | buffer `buf`. |
182 | |
183 | No guarantees are provided about the contents of `buf` when this function is |
184 | called, implementations cannot rely on any property of the contents of `buf` being |
185 | true. It is recommended that implementations only write data to `buf` instead of |
186 | reading its contents. |
187 | |
188 | If this function encounters an "end of file" before completely filling the buffer, |
189 | it returns an error of the kind [`ErrorKind::UnexpectedEof`]. The contents of |
190 | `buf` are unspecified in this case. |
191 | |
192 | If any other read error is encountered then this function immediately returns. The |
193 | contents of `buf` are unspecified in this case. |
194 | |
195 | If this function returns an error, it is unspecified how many bytes it has read, |
196 | but it will never read more than would be necessary to completely fill the buffer. |
197 | |
198 | [`ErrorKind::UnexpectedEof`]: enum.ErrorKind.html#variant.UnexpectedEof |
199 | |
200 | # Examples |
201 | |
202 | ```no_run |
203 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
204 | # |
205 | use async_std::fs::File; |
206 | use async_std::prelude::*; |
207 | |
208 | let mut file = File::open("a.txt" ).await?; |
209 | |
210 | let mut buf = vec![0; 10]; |
211 | file.read_exact(&mut buf).await?; |
212 | # |
213 | # Ok(()) }) } |
214 | ``` |
215 | "# ] |
216 | fn read_exact<'a>( |
217 | &'a mut self, |
218 | buf: &'a mut [u8], |
219 | ) -> ReadExactFuture<'a, Self> |
220 | where |
221 | Self: Unpin, |
222 | { |
223 | ReadExactFuture { reader: self, buf } |
224 | } |
225 | |
226 | #[doc = r#" |
227 | Creates an adaptor which will read at most `limit` bytes from it. |
228 | |
229 | This function returns a new instance of `Read` which will read at most |
230 | `limit` bytes, after which it will always return EOF ([`Ok(0)`]). Any |
231 | read errors will not count towards the number of bytes read and future |
232 | calls to [`read`] may succeed. |
233 | |
234 | # Examples |
235 | |
236 | [`File`]s implement `Read`: |
237 | |
238 | [`File`]: ../fs/struct.File.html |
239 | [`Ok(0)`]: ../../std/result/enum.Result.html#variant.Ok |
240 | [`read`]: tymethod.read |
241 | |
242 | ```no_run |
243 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
244 | # |
245 | use async_std::io::prelude::*; |
246 | use async_std::fs::File; |
247 | |
248 | let f = File::open("foo.txt" ).await?; |
249 | let mut buffer = [0; 5]; |
250 | |
251 | // read at most five bytes |
252 | let mut handle = f.take(5); |
253 | |
254 | handle.read(&mut buffer).await?; |
255 | # |
256 | # Ok(()) }) } |
257 | ``` |
258 | "# ] |
259 | fn take(self, limit: u64) -> Take<Self> |
260 | where |
261 | Self: Sized, |
262 | { |
263 | Take { inner: self, limit } |
264 | } |
265 | |
266 | #[doc = r#" |
267 | Creates a "by reference" adaptor for this instance of `Read`. |
268 | |
269 | The returned adaptor also implements `Read` and will simply borrow this |
270 | current reader. |
271 | |
272 | # Examples |
273 | |
274 | [`File`][file]s implement `Read`: |
275 | |
276 | [file]: ../fs/struct.File.html |
277 | |
278 | ```no_run |
279 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
280 | # |
281 | use async_std::prelude::*; |
282 | use async_std::fs::File; |
283 | |
284 | let mut f = File::open("foo.txt" ).await?; |
285 | let mut buffer = Vec::new(); |
286 | let mut other_buffer = Vec::new(); |
287 | |
288 | { |
289 | let reference = f.by_ref(); |
290 | |
291 | // read at most 5 bytes |
292 | reference.take(5).read_to_end(&mut buffer).await?; |
293 | |
294 | } // drop our &mut reference so we can use f again |
295 | |
296 | // original file still usable, read the rest |
297 | f.read_to_end(&mut other_buffer).await?; |
298 | # |
299 | # Ok(()) }) } |
300 | ``` |
301 | "# ] |
302 | fn by_ref(&mut self) -> &mut Self where Self: Sized { self } |
303 | |
304 | |
305 | #[doc = r#" |
306 | Transforms this `Read` instance to a `Stream` over its bytes. |
307 | |
308 | The returned type implements `Stream` where the `Item` is |
309 | `Result<u8, io::Error>`. |
310 | The yielded item is `Ok` if a byte was successfully read and `Err` |
311 | otherwise. EOF is mapped to returning `None` from this iterator. |
312 | |
313 | # Examples |
314 | |
315 | [`File`][file]s implement `Read`: |
316 | |
317 | [file]: ../fs/struct.File.html |
318 | |
319 | ```no_run |
320 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
321 | # |
322 | use async_std::prelude::*; |
323 | use async_std::fs::File; |
324 | |
325 | let f = File::open("foo.txt" ).await?; |
326 | let mut s = f.bytes(); |
327 | |
328 | while let Some(byte) = s.next().await { |
329 | println!("{}" , byte.unwrap()); |
330 | } |
331 | # |
332 | # Ok(()) }) } |
333 | ``` |
334 | "# ] |
335 | fn bytes(self) -> Bytes<Self> where Self: Sized { |
336 | Bytes { inner: self } |
337 | } |
338 | |
339 | #[doc = r#" |
340 | Creates an adaptor which will chain this stream with another. |
341 | |
342 | The returned `Read` instance will first read all bytes from this object |
343 | until EOF is encountered. Afterwards the output is equivalent to the |
344 | output of `next`. |
345 | |
346 | # Examples |
347 | |
348 | [`File`][file]s implement `Read`: |
349 | |
350 | [file]: ../fs/struct.File.html |
351 | |
352 | ```no_run |
353 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
354 | # |
355 | use async_std::prelude::*; |
356 | use async_std::fs::File; |
357 | |
358 | let f1 = File::open("foo.txt" ).await?; |
359 | let f2 = File::open("bar.txt" ).await?; |
360 | |
361 | let mut handle = f1.chain(f2); |
362 | let mut buffer = String::new(); |
363 | |
364 | // read the value into a String. We could use any Read method here, |
365 | // this is just one example. |
366 | handle.read_to_string(&mut buffer).await?; |
367 | # |
368 | # Ok(()) }) } |
369 | ``` |
370 | "# ] |
371 | fn chain<R: Read>(self, next: R) -> Chain<Self, R> where Self: Sized { |
372 | Chain { first: self, second: next, done_first: false } |
373 | } |
374 | } |
375 | |
376 | impl<T: Read + ?Sized> ReadExt for T {} |
377 | |
378 | /// Initializes a buffer if necessary. |
379 | /// |
380 | /// Currently, a buffer is always initialized because `read_initializer` |
381 | /// feature is not stable. |
382 | #[inline ] |
383 | unsafe fn initialize<R: futures_io::AsyncRead>(_reader: &R, buf: &mut [u8]) { |
384 | std::ptr::write_bytes(dst:buf.as_mut_ptr(), val:0, count:buf.len()) |
385 | } |
386 | |
387 | #[cfg (all(test, not(target_os = "unknown" )))] |
388 | mod tests { |
389 | use crate::io; |
390 | use crate::prelude::*; |
391 | |
392 | #[test ] |
393 | fn test_read_by_ref() { |
394 | crate::task::block_on(async { |
395 | let mut f = io::Cursor::new(vec![0u8, 1, 2, 3, 4, 5, 6, 7, 8]); |
396 | let mut buffer = Vec::new(); |
397 | let mut other_buffer = Vec::new(); |
398 | |
399 | { |
400 | let reference = f.by_ref(); |
401 | |
402 | // read at most 5 bytes |
403 | assert_eq!(reference.take(5).read_to_end(&mut buffer).await.unwrap(), 5); |
404 | assert_eq!(&buffer, &[0, 1, 2, 3, 4]) |
405 | } // drop our &mut reference so we can use f again |
406 | |
407 | // original file still usable, read the rest |
408 | assert_eq!(f.read_to_end(&mut other_buffer).await.unwrap(), 4); |
409 | assert_eq!(&other_buffer, &[5, 6, 7, 8]); |
410 | }); |
411 | } |
412 | } |
413 | |