2019-01-20 08:38:28 +00:00
|
|
|
use failure::*;
|
2019-01-20 09:28:51 +00:00
|
|
|
use tokio_threadpool;
|
2019-01-20 08:38:28 +00:00
|
|
|
use std::io::Read;
|
|
|
|
use futures::Async;
|
|
|
|
use futures::stream::Stream;
|
|
|
|
|
|
|
|
pub struct WrappedReaderStream<R: Read> {
|
|
|
|
reader: R,
|
2019-01-20 10:01:18 +00:00
|
|
|
buffer: Vec<u8>,
|
2019-01-20 08:38:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl <R: Read> WrappedReaderStream<R> {
|
|
|
|
|
|
|
|
pub fn new(reader: R) -> Self {
|
2019-01-20 10:01:18 +00:00
|
|
|
let mut buffer = Vec::with_capacity(64*1024);
|
|
|
|
unsafe { buffer.set_len(buffer.capacity()); }
|
|
|
|
Self { reader, buffer }
|
2019-01-20 08:38:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-20 09:41:21 +00:00
|
|
|
fn blocking_err() -> std::io::Error {
|
|
|
|
std::io::Error::new(
|
|
|
|
std::io::ErrorKind::Other,
|
|
|
|
"`blocking` annotated I/O must be called from the context of the Tokio runtime.")
|
2019-01-20 08:38:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl <R: Read> Stream for WrappedReaderStream<R> {
|
|
|
|
|
|
|
|
type Item = Vec<u8>;
|
|
|
|
type Error = std::io::Error;
|
|
|
|
|
|
|
|
fn poll(&mut self) -> Result<Async<Option<Vec<u8>>>, std::io::Error> {
|
2019-01-20 10:01:18 +00:00
|
|
|
match tokio_threadpool::blocking(|| self.reader.read(&mut self.buffer)) {
|
2019-01-20 09:41:21 +00:00
|
|
|
Ok(Async::Ready(Ok(n))) => {
|
|
|
|
if n == 0 { // EOF
|
2019-01-20 08:38:28 +00:00
|
|
|
Ok(Async::Ready(None))
|
|
|
|
} else {
|
2019-01-20 10:01:18 +00:00
|
|
|
Ok(Async::Ready(Some(self.buffer[..n].to_vec())))
|
2019-01-20 08:38:28 +00:00
|
|
|
}
|
|
|
|
},
|
2019-01-20 09:41:21 +00:00
|
|
|
Ok(Async::Ready(Err(err))) => Err(err),
|
2019-01-20 08:38:28 +00:00
|
|
|
Ok(Async::NotReady) => Ok(Async::NotReady),
|
2019-01-20 09:41:21 +00:00
|
|
|
Err(err) => Err(blocking_err()),
|
2019-01-20 08:38:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|