use super::*;
use std::io::{Read, Result};
use futures::*;
#[derive(Clone)]
struct ImageStreamIterator {
bytes: Arc<Vec<u8>>,
pos: usize
}
impl Iterator for ImageStreamIterator {
type Item=u8;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.pos < self.bytes.len() {
let res = (*self.bytes)[self.pos];
self.pos += 1;
Some(res)
} else {
None
}
}
}
impl Stream for ImageStreamIterator {
type Item = u8;
type Error = ();
fn poll(&mut self) -> Poll<Option<u8>, ()> {
use self::Async::*;
Ok(Ready(self.next()))
}
}
impl Read for ImageStreamIterator {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let mut num_to_read = buf.len();
if self.pos+num_to_read > self.bytes.len() {
num_to_read = self.bytes.len()-self.pos;
}
buf[..num_to_read].copy_from_slice(&self.bytes[self.pos..(self.pos+num_to_read)]);
self.pos += num_to_read;
Ok(num_to_read)
}
}
pub struct InMemoryImageData {
bytes: Arc<Vec<u8>>
}
impl InMemoryImageData {
pub fn new(bytes: Vec<u8>) -> InMemoryImageData {
InMemoryImageData {
bytes: Arc::new(bytes)
}
}
}
impl From<Vec<u8>> for InMemoryImageData {
fn from(bytes: Vec<u8>) -> InMemoryImageData {
InMemoryImageData::new(bytes)
}
}
impl From<Arc<Vec<u8>>> for InMemoryImageData {
fn from(bytes: Arc<Vec<u8>>) -> InMemoryImageData {
InMemoryImageData {
bytes: bytes
}
}
}
impl<'a> From<&'a Arc<Vec<u8>>> for InMemoryImageData {
fn from(bytes: &'a Arc<Vec<u8>>) -> InMemoryImageData {
InMemoryImageData {
bytes: Arc::clone(bytes)
}
}
}
impl ImageData for InMemoryImageData {
fn read(&self) -> Box<Read+Send> {
Box::new(ImageStreamIterator { bytes: self.bytes.clone(), pos: 0 })
}
fn read_future(&self) -> Box<Stream<Item=u8, Error=()>> {
Box::new(ImageStreamIterator { bytes: self.bytes.clone(), pos: 0 })
}
}
#[cfg(test)]
mod test {
use super::*;
use futures::executor;
#[test]
fn can_read_all_image_data() {
let data_test = InMemoryImageData::new(vec![1,2,3,4,5,6]);
let read_data = data_test.read_future();
let read_collect = read_data.collect();
let bytes_back = executor::spawn(read_collect).wait_future().unwrap();
assert!(bytes_back == vec![1,2,3,4,5,6]);
}
}