|
| 1 | +mod lines; |
| 2 | +mod read_line; |
| 3 | +mod read_until; |
| 4 | + |
| 5 | +pub use lines::Lines; |
| 6 | +use read_line::ReadLineFuture; |
| 7 | +use read_until::ReadUntilFuture; |
| 8 | + |
1 | 9 | use std::mem;
|
2 | 10 | use std::pin::Pin;
|
3 |
| -use std::str; |
4 | 11 |
|
5 | 12 | use cfg_if::cfg_if;
|
6 | 13 | use futures_io::AsyncBufRead;
|
7 | 14 |
|
8 |
| -use crate::future::Future; |
9 | 15 | use crate::io;
|
10 | 16 | use crate::task::{Context, Poll};
|
11 | 17 |
|
@@ -191,134 +197,6 @@ pub trait BufRead {
|
191 | 197 |
|
192 | 198 | impl<T: AsyncBufRead + Unpin + ?Sized> BufRead for T {}
|
193 | 199 |
|
194 |
| -#[doc(hidden)] |
195 |
| -#[allow(missing_debug_implementations)] |
196 |
| -pub struct ReadUntilFuture<'a, T: Unpin + ?Sized> { |
197 |
| - reader: &'a mut T, |
198 |
| - byte: u8, |
199 |
| - buf: &'a mut Vec<u8>, |
200 |
| - read: usize, |
201 |
| -} |
202 |
| - |
203 |
| -impl<T: AsyncBufRead + Unpin + ?Sized> Future for ReadUntilFuture<'_, T> { |
204 |
| - type Output = io::Result<usize>; |
205 |
| - |
206 |
| - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
207 |
| - let Self { |
208 |
| - reader, |
209 |
| - byte, |
210 |
| - buf, |
211 |
| - read, |
212 |
| - } = &mut *self; |
213 |
| - read_until_internal(Pin::new(reader), cx, *byte, buf, read) |
214 |
| - } |
215 |
| -} |
216 |
| - |
217 |
| -#[doc(hidden)] |
218 |
| -#[allow(missing_debug_implementations)] |
219 |
| -pub struct ReadLineFuture<'a, T: Unpin + ?Sized> { |
220 |
| - reader: &'a mut T, |
221 |
| - buf: &'a mut String, |
222 |
| - bytes: Vec<u8>, |
223 |
| - read: usize, |
224 |
| -} |
225 |
| - |
226 |
| -impl<T: AsyncBufRead + Unpin + ?Sized> Future for ReadLineFuture<'_, T> { |
227 |
| - type Output = io::Result<usize>; |
228 |
| - |
229 |
| - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
230 |
| - let Self { |
231 |
| - reader, |
232 |
| - buf, |
233 |
| - bytes, |
234 |
| - read, |
235 |
| - } = &mut *self; |
236 |
| - let reader = Pin::new(reader); |
237 |
| - |
238 |
| - let ret = futures_core::ready!(read_until_internal(reader, cx, b'\n', bytes, read)); |
239 |
| - if str::from_utf8(&bytes).is_err() { |
240 |
| - Poll::Ready(ret.and_then(|_| { |
241 |
| - Err(io::Error::new( |
242 |
| - io::ErrorKind::InvalidData, |
243 |
| - "stream did not contain valid UTF-8", |
244 |
| - )) |
245 |
| - })) |
246 |
| - } else { |
247 |
| - debug_assert!(buf.is_empty()); |
248 |
| - debug_assert_eq!(*read, 0); |
249 |
| - // Safety: `bytes` is a valid UTF-8 because `str::from_utf8` returned `Ok`. |
250 |
| - mem::swap(unsafe { buf.as_mut_vec() }, bytes); |
251 |
| - Poll::Ready(ret) |
252 |
| - } |
253 |
| - } |
254 |
| -} |
255 |
| - |
256 |
| -/// A stream of lines in a byte stream. |
257 |
| -/// |
258 |
| -/// This stream is created by the [`lines`] method on types that implement [`BufRead`]. |
259 |
| -/// |
260 |
| -/// This type is an async version of [`std::io::Lines`]. |
261 |
| -/// |
262 |
| -/// [`lines`]: trait.BufRead.html#method.lines |
263 |
| -/// [`BufRead`]: trait.BufRead.html |
264 |
| -/// [`std::io::Lines`]: https://doc.rust-lang.org/nightly/std/io/struct.Lines.html |
265 |
| -#[derive(Debug)] |
266 |
| -pub struct Lines<R> { |
267 |
| - reader: R, |
268 |
| - buf: String, |
269 |
| - bytes: Vec<u8>, |
270 |
| - read: usize, |
271 |
| -} |
272 |
| - |
273 |
| -impl<R: AsyncBufRead> futures_core::stream::Stream for Lines<R> { |
274 |
| - type Item = io::Result<String>; |
275 |
| - |
276 |
| - fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { |
277 |
| - let Self { |
278 |
| - reader, |
279 |
| - buf, |
280 |
| - bytes, |
281 |
| - read, |
282 |
| - } = unsafe { self.get_unchecked_mut() }; |
283 |
| - let reader = unsafe { Pin::new_unchecked(reader) }; |
284 |
| - let n = futures_core::ready!(read_line_internal(reader, cx, buf, bytes, read))?; |
285 |
| - if n == 0 && buf.is_empty() { |
286 |
| - return Poll::Ready(None); |
287 |
| - } |
288 |
| - if buf.ends_with('\n') { |
289 |
| - buf.pop(); |
290 |
| - if buf.ends_with('\r') { |
291 |
| - buf.pop(); |
292 |
| - } |
293 |
| - } |
294 |
| - Poll::Ready(Some(Ok(mem::replace(buf, String::new())))) |
295 |
| - } |
296 |
| -} |
297 |
| - |
298 |
| -pub fn read_line_internal<R: AsyncBufRead + ?Sized>( |
299 |
| - reader: Pin<&mut R>, |
300 |
| - cx: &mut Context<'_>, |
301 |
| - buf: &mut String, |
302 |
| - bytes: &mut Vec<u8>, |
303 |
| - read: &mut usize, |
304 |
| -) -> Poll<io::Result<usize>> { |
305 |
| - let ret = futures_core::ready!(read_until_internal(reader, cx, b'\n', bytes, read)); |
306 |
| - if str::from_utf8(&bytes).is_err() { |
307 |
| - Poll::Ready(ret.and_then(|_| { |
308 |
| - Err(io::Error::new( |
309 |
| - io::ErrorKind::InvalidData, |
310 |
| - "stream did not contain valid UTF-8", |
311 |
| - )) |
312 |
| - })) |
313 |
| - } else { |
314 |
| - debug_assert!(buf.is_empty()); |
315 |
| - debug_assert_eq!(*read, 0); |
316 |
| - // Safety: `bytes` is a valid UTF-8 because `str::from_utf8` returned `Ok`. |
317 |
| - mem::swap(unsafe { buf.as_mut_vec() }, bytes); |
318 |
| - Poll::Ready(ret) |
319 |
| - } |
320 |
| -} |
321 |
| - |
322 | 200 | pub fn read_until_internal<R: AsyncBufRead + ?Sized>(
|
323 | 201 | mut reader: Pin<&mut R>,
|
324 | 202 | cx: &mut Context<'_>,
|
|
0 commit comments