1use std::fs::File;
2use std::io;
3use std::io::Read;
4use zip::read::ZipFile;
5
6use log::*;
7
8pub trait LengthRead: Read {
10 fn input_size(&self) -> io::Result<u64>;
11
12 fn read_all_sized(&mut self) -> io::Result<Vec<u8>> {
14 let mut cap = self.input_size()? as usize;
15 let mut out = vec![0; cap + 1];
16 let mut pos = 0;
17 loop {
18 trace!("requesting {} bytes", cap - pos);
19 let ls = self.read(&mut out[pos..])?;
20 pos += ls;
21 if pos >= cap {
22 warn!("size was wrong, expanding");
24 cap += 16 * 1024;
25 out.resize(cap, 0);
26 }
27 if ls == 0 {
28 out.truncate(pos);
29 return Ok(out);
30 }
31 }
32 }
33}
34
35impl LengthRead for File {
36 fn input_size(&self) -> io::Result<u64> {
37 let meta = self.metadata()?;
38 Ok(meta.len())
39 }
40}
41
42impl<'a> LengthRead for ZipFile<'a> {
43 fn input_size(&self) -> io::Result<u64> {
44 Ok(self.size())
45 }
46}