1 use std::io as std_io;
2 use bytes::BufMut;
3 use futures::{Async, Poll};
4 
5 use {framed, split, AsyncWrite};
6 #[allow(deprecated)]
7 use codec::{Decoder, Encoder, Framed};
8 use split::{ReadHalf, WriteHalf};
9 
10 /// Read bytes asynchronously.
11 ///
12 /// This trait inherits from `std::io::Read` and indicates that an I/O object is
13 /// **non-blocking**. All non-blocking I/O objects must return an error when
14 /// bytes are unavailable instead of blocking the current thread.
15 ///
16 /// Specifically, this means that the `read` function will return one of the
17 /// following:
18 ///
19 /// * `Ok(n)` means that `n` bytes of data was immediately read and placed into
20 ///   the output buffer, where `n` == 0 implies that EOF has been reached.
21 ///
22 /// * `Err(e) if e.kind() == ErrorKind::WouldBlock` means that no data was read
23 ///   into the buffer provided. The I/O object is not currently readable but may
24 ///   become readable in the future. Most importantly, **the current future's
25 ///   task is scheduled to get unparked when the object is readable**. This
26 ///   means that like `Future::poll` you'll receive a notification when the I/O
27 ///   object is readable again.
28 ///
29 /// * `Err(e)` for other errors are standard I/O errors coming from the
30 ///   underlying object.
31 ///
32 /// This trait importantly means that the `read` method only works in the
33 /// context of a future's task. The object may panic if used outside of a task.
34 pub trait AsyncRead: std_io::Read {
35     /// Prepares an uninitialized buffer to be safe to pass to `read`. Returns
36     /// `true` if the supplied buffer was zeroed out.
37     ///
38     /// While it would be highly unusual, implementations of [`io::Read`] are
39     /// able to read data from the buffer passed as an argument. Because of
40     /// this, the buffer passed to [`io::Read`] must be initialized memory. In
41     /// situations where large numbers of buffers are used, constantly having to
42     /// zero out buffers can be expensive.
43     ///
44     /// This function does any necessary work to prepare an uninitialized buffer
45     /// to be safe to pass to `read`. If `read` guarantees to never attempt read
46     /// data out of the supplied buffer, then `prepare_uninitialized_buffer`
47     /// doesn't need to do any work.
48     ///
49     /// If this function returns `true`, then the memory has been zeroed out.
50     /// This allows implementations of `AsyncRead` which are composed of
51     /// multiple sub implementations to efficiently implement
52     /// `prepare_uninitialized_buffer`.
53     ///
54     /// This function isn't actually `unsafe` to call but `unsafe` to implement.
55     /// The implementor must ensure that either the whole `buf` has been zeroed
56     /// or `read_buf()` overwrites the buffer without reading it and returns
57     /// correct value.
58     ///
59     /// This function is called from [`read_buf`].
60     ///
61     /// [`io::Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
62     /// [`read_buf`]: #method.read_buf
prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool63     unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
64         for i in 0..buf.len() {
65             buf[i] = 0;
66         }
67 
68         true
69     }
70 
71     /// Attempt to read from the `AsyncRead` into `buf`.
72     ///
73     /// On success, returns `Ok(Async::Ready(num_bytes_read))`.
74     ///
75     /// If no data is available for reading, the method returns
76     /// `Ok(Async::Pending)` and arranges for the current task (via
77     /// `cx.waker()`) to receive a notification when the object becomes
78     /// readable or is closed.
poll_read(&mut self, buf: &mut [u8]) -> Poll<usize, std_io::Error>79     fn poll_read(&mut self, buf: &mut [u8]) -> Poll<usize, std_io::Error> {
80         match self.read(buf) {
81             Ok(t) => Ok(Async::Ready(t)),
82             Err(ref e) if e.kind() == std_io::ErrorKind::WouldBlock => {
83                 return Ok(Async::NotReady)
84             }
85             Err(e) => return Err(e.into()),
86         }
87     }
88 
89     /// Pull some bytes from this source into the specified `Buf`, returning
90     /// how many bytes were read.
91     ///
92     /// The `buf` provided will have bytes read into it and the internal cursor
93     /// will be advanced if any bytes were read. Note that this method typically
94     /// will not reallocate the buffer provided.
read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, std_io::Error> where Self: Sized,95     fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, std_io::Error>
96         where Self: Sized,
97     {
98         if !buf.has_remaining_mut() {
99             return Ok(Async::Ready(0));
100         }
101 
102         unsafe {
103             let n = {
104                 let b = buf.bytes_mut();
105 
106                 self.prepare_uninitialized_buffer(b);
107 
108                 try_ready!(self.poll_read(b))
109             };
110 
111             buf.advance_mut(n);
112             Ok(Async::Ready(n))
113         }
114     }
115 
116     /// Provides a `Stream` and `Sink` interface for reading and writing to this
117     /// `Io` object, using `Decode` and `Encode` to read and write the raw data.
118     ///
119     /// Raw I/O objects work with byte sequences, but higher-level code usually
120     /// wants to batch these into meaningful chunks, called "frames". This
121     /// method layers framing on top of an I/O object, by using the `Codec`
122     /// traits to handle encoding and decoding of messages frames. Note that
123     /// the incoming and outgoing frame types may be distinct.
124     ///
125     /// This function returns a *single* object that is both `Stream` and
126     /// `Sink`; grouping this into a single object is often useful for layering
127     /// things like gzip or TLS, which require both read and write access to the
128     /// underlying object.
129     ///
130     /// If you want to work more directly with the streams and sink, consider
131     /// calling `split` on the `Framed` returned by this method, which will
132     /// break them into separate objects, allowing them to interact more easily.
133     #[deprecated(since = "0.1.7", note = "Use tokio_codec::Decoder::framed instead")]
134     #[allow(deprecated)]
framed<T: Encoder + Decoder>(self, codec: T) -> Framed<Self, T> where Self: AsyncWrite + Sized,135     fn framed<T: Encoder + Decoder>(self, codec: T) -> Framed<Self, T>
136         where Self: AsyncWrite + Sized,
137     {
138         framed::framed(self, codec)
139     }
140 
141     /// Helper method for splitting this read/write object into two halves.
142     ///
143     /// The two halves returned implement the `Read` and `Write` traits,
144     /// respectively.
split(self) -> (ReadHalf<Self>, WriteHalf<Self>) where Self: AsyncWrite + Sized,145     fn split(self) -> (ReadHalf<Self>, WriteHalf<Self>)
146         where Self: AsyncWrite + Sized,
147     {
148         split::split(self)
149     }
150 }
151 
152 impl<T: ?Sized + AsyncRead> AsyncRead for Box<T> {
prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool153     unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
154         (**self).prepare_uninitialized_buffer(buf)
155     }
156 }
157 
158 impl<'a, T: ?Sized + AsyncRead> AsyncRead for &'a mut T {
prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool159     unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
160         (**self).prepare_uninitialized_buffer(buf)
161     }
162 }
163 
164 impl<'a> AsyncRead for &'a [u8] {
prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool165     unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool {
166         false
167     }
168 }
169