1 extern crate flate2;
2 extern crate futures;
3 extern crate tokio_io;
4
5 use flate2::read::{GzDecoder, MultiGzDecoder};
6 use futures::prelude::*;
7 use futures::task;
8 use std::cmp;
9 use std::fs::File;
10 use std::io::{self, Read};
11 use tokio_io::io::read_to_end;
12 use tokio_io::AsyncRead;
13
14 struct BadReader<T> {
15 reader: T,
16 x: bool,
17 }
18
19 impl<T> BadReader<T> {
new(reader: T) -> BadReader<T>20 fn new(reader: T) -> BadReader<T> {
21 BadReader { reader, x: true }
22 }
23 }
24
25 impl<T: Read> Read for BadReader<T> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>26 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
27 if self.x {
28 self.x = false;
29 let len = cmp::min(buf.len(), 1);
30 self.reader.read(&mut buf[..len])
31 } else {
32 self.x = true;
33 Err(io::ErrorKind::WouldBlock.into())
34 }
35 }
36 }
37
38 struct AssertAsync<T>(T);
39
40 impl<T: Read> Read for AssertAsync<T> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>41 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
42 self.0.read(buf)
43 }
44 }
45
46 impl<T: Read> AsyncRead for AssertAsync<T> {}
47
48 struct AlwaysNotify<T>(T);
49
50 impl<T: Future> Future for AlwaysNotify<T> {
51 type Item = T::Item;
52 type Error = T::Error;
53
poll(&mut self) -> Poll<Self::Item, Self::Error>54 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
55 let ret = self.0.poll();
56 if let Ok(Async::NotReady) = &ret {
57 task::current().notify();
58 }
59 ret
60 }
61 }
62
63 #[test]
test_gz_asyncread()64 fn test_gz_asyncread() {
65 let f = File::open("tests/good-file.gz").unwrap();
66
67 let fut = read_to_end(AssertAsync(GzDecoder::new(BadReader::new(f))), Vec::new());
68 let (_, content) = AlwaysNotify(fut).wait().unwrap();
69
70 let mut expected = Vec::new();
71 File::open("tests/good-file.txt")
72 .unwrap()
73 .read_to_end(&mut expected)
74 .unwrap();
75
76 assert_eq!(content, expected);
77 }
78
79 #[test]
test_multi_gz_asyncread()80 fn test_multi_gz_asyncread() {
81 let f = File::open("tests/multi.gz").unwrap();
82
83 let fut = read_to_end(
84 AssertAsync(MultiGzDecoder::new(BadReader::new(f))),
85 Vec::new(),
86 );
87 let (_, content) = AlwaysNotify(fut).wait().unwrap();
88
89 let mut expected = Vec::new();
90 File::open("tests/multi.txt")
91 .unwrap()
92 .read_to_end(&mut expected)
93 .unwrap();
94
95 assert_eq!(content, expected);
96 }
97