Files
addr2line
adler
aho_corasick
ansi_term
arraydeque
as_slice
atty
backtrace
base64
bincode_core
bitflags
byteorder
bytes
capnp
capnp_futures
capnp_rpc
cfg_if
chrono
clap
ctrlc
derivative
dlib
downcast_rs
enumflags2
enumflags2_derive
evdev_rs
evdev_sys
failure
failure_derive
flexi_logger
futures
futures_channel
futures_core
futures_executor
futures_io
futures_macro
futures_sink
futures_task
futures_util
async_await
future
io
lock
sink
stream
task
generic_array
getrandom
gimli
glob
hash32
heapless
hid_io_core
hid_io_protocol
hidapi
install_service
lazy_static
libc
libloading
libudev_sys
log
memchr
memmap
miniz_oxide
mio
nanoid
nix
num_cpus
num_enum
num_enum_derive
num_integer
num_traits
object
once_cell
open
pem
pin_project_lite
pin_utils
ppv_lite86
proc_macro2
proc_macro_hack
proc_macro_nested
quote
rand
rand_chacha
rand_core
rcgen
regex
regex_syntax
remove_dir_all
ring
rustc_demangle
rustls
scoped_tls
sct
serde
serde_derive
slab
smallvec
spin
stable_deref_trait
strsim
syn
synstructure
sys_info
tempfile
textwrap
thiserror
thiserror_impl
time
tokio
future
io
loom
macros
net
park
runtime
stream
sync
task
time
util
tokio_macros
tokio_rustls
tokio_util
typenum
udev
uhid_virt
uhidrs_sys
unicode_width
unicode_xid
untrusted
vec_map
wayland_client
wayland_commons
wayland_sys
webpki
which
x11
xcb
xkbcommon
yansi
yasna
zwp_virtual_keyboard
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use futures_core::future::Future;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::AsyncRead;
use std::io;
use std::pin::Pin;
use std::vec::Vec;

/// Future for the [`read_to_end`](super::AsyncReadExt::read_to_end) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct ReadToEnd<'a, R: ?Sized> {
    reader: &'a mut R,
    buf: &'a mut Vec<u8>,
    start_len: usize,
}

impl<R: ?Sized + Unpin> Unpin for ReadToEnd<'_, R> {}

impl<'a, R: AsyncRead + ?Sized + Unpin> ReadToEnd<'a, R> {
    pub(super) fn new(reader: &'a mut R, buf: &'a mut Vec<u8>) -> Self {
        let start_len = buf.len();
        Self {
            reader,
            buf,
            start_len,
        }
    }
}

struct Guard<'a> {
    buf: &'a mut Vec<u8>,
    len: usize,
}

impl Drop for Guard<'_> {
    fn drop(&mut self) {
        unsafe {
            self.buf.set_len(self.len);
        }
    }
}

// This uses an adaptive system to extend the vector when it fills. We want to
// avoid paying to allocate and zero a huge chunk of memory if the reader only
// has 4 bytes while still making large reads if the reader does have a ton
// of data to return. Simply tacking on an extra DEFAULT_BUF_SIZE space every
// time is 4,500 times (!) slower than this if the reader has a very small
// amount of data to return.
//
// Because we're extending the buffer with uninitialized data for trusted
// readers, we need to make sure to truncate that if any of this panics.
pub(super) fn read_to_end_internal<R: AsyncRead + ?Sized>(
    mut rd: Pin<&mut R>,
    cx: &mut Context<'_>,
    buf: &mut Vec<u8>,
    start_len: usize,
) -> Poll<io::Result<usize>> {
    let mut g = Guard {
        len: buf.len(),
        buf,
    };
    loop {
        if g.len == g.buf.len() {
            unsafe {
                g.buf.reserve(32);
                let capacity = g.buf.capacity();
                g.buf.set_len(capacity);
                super::initialize(&rd, &mut g.buf[g.len..]);
            }
        }

        let buf = &mut g.buf[g.len..];
        match ready!(rd.as_mut().poll_read(cx, buf)) {
            Ok(0) => return Poll::Ready(Ok(g.len - start_len)),
            Ok(n) => {
                // We can't allow bogus values from read. If it is too large, the returned vec could have its length
                // set past its capacity, or if it overflows the vec could be shortened which could create an invalid
                // string if this is called via read_to_string.
                assert!(n <= buf.len());
                g.len += n;
            }
            Err(e) => return Poll::Ready(Err(e)),
        }
    }
}

impl<A> Future for ReadToEnd<'_, A>
where
    A: AsyncRead + ?Sized + Unpin,
{
    type Output = io::Result<usize>;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let this = &mut *self;
        read_to_end_internal(Pin::new(&mut this.reader), cx, this.buf, this.start_len)
    }
}