1 use bytes::BufMut; 2 use futures::{Async, Poll}; 3 use std::io as std_io; 4 5 #[allow(deprecated)] 6 use codec::{Decoder, Encoder, Framed}; 7 use split::{ReadHalf, WriteHalf}; 8 use {framed, split, AsyncWrite}; 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 `poll_read` function will return one of 17 /// the following: 18 /// 19 /// * `Ok(Async::Ready(n))` means that `n` bytes of data was immediately read 20 /// and placed into the output buffer, where `n` == 0 implies that EOF has 21 /// been reached. 22 /// 23 /// * `Ok(Async::NotReady)` means that no data was read into the buffer 24 /// provided. The I/O object is not currently readable but may become readable 25 /// in the future. Most importantly, **the current future's task is scheduled 26 /// to get unparked when the object is readable**. This means that like 27 /// `Future::poll` you'll receive a notification when the I/O object is 28 /// readable again. 29 /// 30 /// * `Err(e)` for other errors are standard I/O errors coming from the 31 /// underlying object. 32 /// 33 /// This trait importantly means that the `read` method only works in the 34 /// context of a future's task. The object may panic if used outside of a task. 35 pub trait AsyncRead: std_io::Read { 36 /// Prepares an uninitialized buffer to be safe to pass to `read`. Returns 37 /// `true` if the supplied buffer was zeroed out. 38 /// 39 /// While it would be highly unusual, implementations of [`io::Read`] are 40 /// able to read data from the buffer passed as an argument. Because of 41 /// this, the buffer passed to [`io::Read`] must be initialized memory. In 42 /// situations where large numbers of buffers are used, constantly having to 43 /// zero out buffers can be expensive. 44 /// 45 /// This function does any necessary work to prepare an uninitialized buffer 46 /// to be safe to pass to `read`. If `read` guarantees to never attempt to 47 /// read data out of the supplied buffer, then `prepare_uninitialized_buffer` 48 /// doesn't need to do any work. 49 /// 50 /// If this function returns `true`, then the memory has been zeroed out. 51 /// This allows implementations of `AsyncRead` which are composed of 52 /// multiple subimplementations to efficiently implement 53 /// `prepare_uninitialized_buffer`. 54 /// 55 /// This function isn't actually `unsafe` to call but `unsafe` to implement. 56 /// The implementer must ensure that either the whole `buf` has been zeroed 57 /// or `read_buf()` overwrites the buffer without reading it and returns 58 /// correct value. 59 /// 60 /// This function is called from [`read_buf`]. 61 /// 62 /// [`io::Read`]: https://doc.rust-lang.org/std/io/trait.Read.html 63 /// [`read_buf`]: #method.read_buf prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool64 unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool { 65 for i in 0..buf.len() { 66 buf[i] = 0; 67 } 68 69 true 70 } 71 72 /// Attempt to read from the `AsyncRead` into `buf`. 73 /// 74 /// On success, returns `Ok(Async::Ready(num_bytes_read))`. 75 /// 76 /// If no data is available for reading, the method returns 77 /// `Ok(Async::NotReady)` and arranges for the current task (via 78 /// `cx.waker()`) to receive a notification when the object becomes 79 /// readable or is closed. poll_read(&mut self, buf: &mut [u8]) -> Poll<usize, std_io::Error>80 fn poll_read(&mut self, buf: &mut [u8]) -> Poll<usize, std_io::Error> { 81 match self.read(buf) { 82 Ok(t) => Ok(Async::Ready(t)), 83 Err(ref e) if e.kind() == std_io::ErrorKind::WouldBlock => return Ok(Async::NotReady), 84 Err(e) => return Err(e.into()), 85 } 86 } 87 88 /// Pull some bytes from this source into the specified `BufMut`, returning 89 /// how many bytes were read. 90 /// 91 /// The `buf` provided will have bytes read into it and the internal cursor 92 /// will be advanced if any bytes were read. Note that this method typically 93 /// will not reallocate the buffer provided. read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, std_io::Error> where Self: Sized,94 fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, std_io::Error> 95 where 96 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 /// I/O 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 137 Self: AsyncWrite + Sized, 138 { 139 framed::framed(self, codec) 140 } 141 142 /// Helper method for splitting this read/write object into two halves. 143 /// 144 /// The two halves returned implement the `Read` and `Write` traits, 145 /// respectively. 146 /// 147 /// To restore this read/write object from its `ReadHalf` and `WriteHalf` 148 /// use `unsplit`. split(self) -> (ReadHalf<Self>, WriteHalf<Self>) where Self: AsyncWrite + Sized,149 fn split(self) -> (ReadHalf<Self>, WriteHalf<Self>) 150 where 151 Self: AsyncWrite + Sized, 152 { 153 split::split(self) 154 } 155 } 156 157 impl<T: ?Sized + AsyncRead> AsyncRead for Box<T> { prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool158 unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool { 159 (**self).prepare_uninitialized_buffer(buf) 160 } 161 } 162 163 impl<'a, T: ?Sized + AsyncRead> AsyncRead for &'a mut T { prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool164 unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool { 165 (**self).prepare_uninitialized_buffer(buf) 166 } 167 } 168 169 impl<'a> AsyncRead for &'a [u8] { prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool170 unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool { 171 false 172 } 173 } 174