diff --git a/__test__/utils.spec.mjs b/__test__/utils.spec.mjs index 4621ee3..10a7687 100644 --- a/__test__/utils.spec.mjs +++ b/__test__/utils.spec.mjs @@ -200,3 +200,21 @@ test.skip("zip manifest test", async (t) => { t.pass(); }); + +test.skip("partially compress zip test", async (t) => { + const dropletHandler = new DropletHandler(); + + const manifest = JSON.parse( + await new Promise((r, e) => + generateManifest( + dropletHandler, + "./assets/my horror game.zip", + (_, __) => {}, + (_, __) => {}, + (err, manifest) => (err ? e(err) : r(manifest)) + ) + ) + ); + + return t.pass(); +}); diff --git a/package.json b/package.json index e05a212..6cc24c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@drop-oss/droplet", - "version": "2.3.0", + "version": "2.3.1", "main": "index.js", "types": "index.d.ts", "napi": { diff --git a/src/version/backends.rs b/src/version/backends.rs index ef11ea0..e921ca3 100644 --- a/src/version/backends.rs +++ b/src/version/backends.rs @@ -9,7 +9,8 @@ use std::{ use flate2::read::DeflateDecoder; use rawzip::{ - FileReader, ZipArchive, ZipArchiveEntryWayfinder, ZipEntry, ZipReader, RECOMMENDED_BUFFER_SIZE, + CompressionMethod, FileReader, ZipArchive, ZipArchiveEntryWayfinder, ZipEntry, + ZipVerifier, RECOMMENDED_BUFFER_SIZE, }; use crate::version::types::{MinimumFileObject, VersionBackend, VersionFile}; @@ -116,15 +117,27 @@ impl ZipVersionBackend { pub fn new_entry<'archive>( &self, entry: ZipEntry<'archive, FileReader>, + compression_method: CompressionMethod, start: u64, end: u64, ) -> ZipFileWrapper<'archive> { - let mut deflater = DeflateDecoder::new(entry.reader()); + let deflater: Box = match compression_method { + CompressionMethod::Store => Box::new(entry.reader()), + CompressionMethod::Deflate => Box::new(DeflateDecoder::new(entry.reader())), + CompressionMethod::Deflate64 => Box::new(DeflateDecoder::new(entry.reader())), + _ => panic!( + "unsupported decompression algorithm: {:?}", + compression_method + ), + }; + + let mut verifier = entry.verifying_reader(deflater); if start != 0 { - io::copy(&mut (&mut deflater).take(start), &mut Sink::default()).unwrap(); + io::copy(&mut (&mut verifier).take(start), &mut Sink::default()).unwrap(); } + ZipFileWrapper { - reader: deflater, + reader: verifier, limit: (end - start) as usize, current: 0, } @@ -132,7 +145,7 @@ impl ZipVersionBackend { } pub struct ZipFileWrapper<'archive> { - reader: DeflateDecoder>, + reader: ZipVerifier<'archive, Box, FileReader>, limit: usize, current: usize, } @@ -163,9 +176,13 @@ impl<'a> Read for ZipFileWrapper<'a> { return Ok(read); } } +//impl<'a> MinimumFileObject for ZipFileWrapper<'a> {} impl ZipVersionBackend { - fn find_wayfinder(&mut self, filename: &str) -> Option { + fn find_wayfinder( + &mut self, + filename: &str, + ) -> Option<(ZipArchiveEntryWayfinder, CompressionMethod)> { let read_buffer = &mut [0u8; RECOMMENDED_BUFFER_SIZE]; let mut entries = self.archive.entries(read_buffer); let entry = loop { @@ -180,7 +197,7 @@ impl ZipVersionBackend { let wayfinder = entry.wayfinder(); - Some(wayfinder) + Some((wayfinder, entry.compression_method())) } } impl VersionBackend for ZipVersionBackend { @@ -207,16 +224,16 @@ impl VersionBackend for ZipVersionBackend { start: u64, end: u64, ) -> Option> { - let wayfinder = self.find_wayfinder(&file.relative_filename)?; + let (wayfinder, compression_method) = self.find_wayfinder(&file.relative_filename)?; let local_entry = self.archive.get_entry(wayfinder).unwrap(); - let wrapper = self.new_entry(local_entry, start, end); + let wrapper = self.new_entry(local_entry, compression_method, start, end); - Some(Box::new(wrapper)) + Some(Box::new(wrapper) as Box) } fn peek_file(&mut self, sub_path: String) -> Option { - let entry = self.find_wayfinder(&sub_path)?; + let (entry, _) = self.find_wayfinder(&sub_path)?; Some(VersionFile { relative_filename: sub_path,