| @@ -1,15 +1,11 @@ |
| 1 | use object::{Id, Kind}; | 1 | use object::{Id, Kind}; |
| 2 | | 2 | |
| 3 | use std::path::PathBuf; | | |
| 4 | | | |
| 5 | use walkdir::WalkDir; | 3 | use walkdir::WalkDir; |
| 6 | use failure::{Error, ResultExt}; | 4 | use failure::{Error, ResultExt}; |
| 7 | use hex::{FromHex, ToHex}; | 5 | use hex::{FromHex, ToHex}; |
| 8 | use miniz_oxide::inflate::core::{decompress, DecompressorOxide, | | |
| 9 | inflate_flags::{TINFL_FLAG_PARSE_ZLIB_HEADER, | | |
| 10 | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF}}; | | |
| 11 | use smallvec::SmallVec; | 6 | use smallvec::SmallVec; |
| 12 | use std::{fs::File, io::{Cursor, Read}}; | 7 | use std::{fs::File, io::{Cursor, Read}, path::PathBuf}; |
| | 8 | use deflate; |
| 13 | | 9 | |
| 14 | const HEADER_READ_COMPRESSED_BYTES: usize = 512; | 10 | const HEADER_READ_COMPRESSED_BYTES: usize = 512; |
| 15 | | 11 | |
| @@ -21,57 +17,7 @@ pub struct Object { · 5 unmodified lines |
| 21 | pub kind: Kind, | 17 | pub kind: Kind, |
| 22 | pub size: usize, | 18 | pub size: usize, |
| 23 | data: SmallVec<[u8; HEADER_READ_COMPRESSED_BYTES]>, | 19 | data: SmallVec<[u8; HEADER_READ_COMPRESSED_BYTES]>, |
| 24 | } | 20 | deflate: deflate::State, |
| 25 | | | |
| 26 | mod deflate { | | |
| 27 | use failure::Error; | | |
| 28 | use miniz_oxide::inflate::core::DecompressorOxide; | | |
| 29 | use std::io::Cursor; | | |
| 30 | use miniz_oxide::inflate::core::{decompress, | | |
| 31 | inflate_flags::{TINFL_FLAG_PARSE_ZLIB_HEADER, | | |
| 32 | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF}}; | | |
| 33 | | | |
| 34 | pub struct State { | | |
| 35 | inner: DecompressorOxide, | | |
| 36 | pub read_in: usize, | | |
| 37 | pub read_out: usize, | | |
| 38 | } | | |
| 39 | | | |
| 40 | impl Default for State { | | |
| 41 | fn default() -> Self { | | |
| 42 | State { | | |
| 43 | inner: DecompressorOxide::default(), | | |
| 44 | read_in: 0, | | |
| 45 | read_out: 0, | | |
| 46 | } | | |
| 47 | } | | |
| 48 | } | | |
| 49 | | | |
| 50 | impl State { | | |
| 51 | pub fn once(&mut self, rbuf: &[u8], out: &mut Cursor<&mut [u8]>) -> Result<usize, Error> { | | |
| 52 | let (status, read_in, read_out) = decompress( | | |
| 53 | &mut self.inner, | | |
| 54 | rbuf, | | |
| 55 | out, | | |
| 56 | TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF, | | |
| 57 | ); | | |
| 58 | | | |
| 59 | self.read_in = read_in; | | |
| 60 | self.read_out = read_out; | | |
| 61 | | | |
| 62 | use miniz_oxide::inflate::TINFLStatus::*; | | |
| 63 | match status { | | |
| 64 | Failed | FailedCannotMakeProgress | BadParam | Adler32Mismatch | NeedsMoreInput => { | | |
| 65 | bail!( | | |
| 66 | "Could not decode zip stream for reading header, status was '{:?}'", | | |
| 67 | status | | |
| 68 | ) | | |
| 69 | } | | |
| 70 | Done | HasMoreOutput => {} | | |
| 71 | }; | | |
| 72 | Ok(read_out) | | |
| 73 | } | | |
| 74 | } | | |
| 75 | } | 21 | } |
| 76 | | 22 | |
| 77 | impl Db { | 23 | impl Db { |
| @@ -125,31 +71,21 @@ impl Db { · 47 unmodified lines |
| 125 | path | 71 | path |
| 126 | }; | 72 | }; |
| 127 | | 73 | |
| | 74 | let mut deflate = deflate::State::default(); |
| 128 | let mut out = [0; HEADER_READ_COMPRESSED_BYTES]; | 75 | let mut out = [0; HEADER_READ_COMPRESSED_BYTES]; |
| 129 | let read_out = { | 76 | let mut rbuf = [0; HEADER_READ_COMPRESSED_BYTES]; |
| 130 | let mut rbuf = [0; HEADER_READ_COMPRESSED_BYTES]; | 77 | let (_read_in, read_out) = { |
| 131 | let bytes_read = File::open(&path)?.read(&mut rbuf[..])?; | 78 | let bytes_read = File::open(&path)?.read(&mut rbuf[..])?; |
| 132 | let mut state = DecompressorOxide::default(); | | |
| 133 | let mut out = Cursor::new(&mut out[..]); | 79 | let mut out = Cursor::new(&mut out[..]); |
| 134 | | 80 | |
| 135 | let (status, _read_in, read_out) = decompress( | 81 | deflate |
| 136 | &mut state, | 82 | .once(&rbuf[..bytes_read], &mut out) |
| 137 | &rbuf[..bytes_read], | 83 | .with_context(|_| { |
| 138 | &mut out, | 84 | format!( |
| 139 | TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF, | 85 | "Could not decode zip stream for reading header in '{}'", |
| 140 | ); | 86 | path.display() |
| 141 | use miniz_oxide::inflate::TINFLStatus::*; | 87 | ) |
| 142 | match status { | 88 | })? |
| 143 | Failed | FailedCannotMakeProgress | BadParam | Adler32Mismatch | NeedsMoreInput => { | | |
| 144 | bail!( | | |
| 145 | "Could not decode zip stream for reading header in '{}', zip status was '{:?}'", | | |
| 146 | path.display(), | | |
| 147 | status | | |
| 148 | ) | | |
| 149 | } | | |
| 150 | Done | HasMoreOutput => {} | | |
| 151 | }; | | |
| 152 | read_out | | |
| 153 | }; | 89 | }; |
| 154 | | 90 | |
| 155 | parse::header(&out[..read_out]) | 91 | parse::header(&out[..read_out]) |
| @@ -157,6 +93,7 @@ impl Db { · 1 unmodified line |
| 157 | kind, | 93 | kind, |
| 158 | size, | 94 | size, |
| 159 | data: SmallVec::from_buf(out), | 95 | data: SmallVec::from_buf(out), |
| | 96 | deflate, |
| 160 | }) | 97 | }) |
| 161 | .with_context(|_| { | 98 | .with_context(|_| { |
| 162 | format!( | 99 | format!( |