mirror of
https://github.com/Drop-OSS/droplet.git
synced 2026-06-22 04:11:40 +10:00
feat: add support for partially deflated zips
This commit is contained in:
@@ -200,3 +200,21 @@ test.skip("zip manifest test", async (t) => {
|
|||||||
|
|
||||||
t.pass();
|
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();
|
||||||
|
});
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@drop-oss/droplet",
|
"name": "@drop-oss/droplet",
|
||||||
"version": "2.3.0",
|
"version": "2.3.1",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"types": "index.d.ts",
|
"types": "index.d.ts",
|
||||||
"napi": {
|
"napi": {
|
||||||
|
|||||||
+28
-11
@@ -9,7 +9,8 @@ use std::{
|
|||||||
|
|
||||||
use flate2::read::DeflateDecoder;
|
use flate2::read::DeflateDecoder;
|
||||||
use rawzip::{
|
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};
|
use crate::version::types::{MinimumFileObject, VersionBackend, VersionFile};
|
||||||
@@ -116,15 +117,27 @@ impl ZipVersionBackend {
|
|||||||
pub fn new_entry<'archive>(
|
pub fn new_entry<'archive>(
|
||||||
&self,
|
&self,
|
||||||
entry: ZipEntry<'archive, FileReader>,
|
entry: ZipEntry<'archive, FileReader>,
|
||||||
|
compression_method: CompressionMethod,
|
||||||
start: u64,
|
start: u64,
|
||||||
end: u64,
|
end: u64,
|
||||||
) -> ZipFileWrapper<'archive> {
|
) -> ZipFileWrapper<'archive> {
|
||||||
let mut deflater = DeflateDecoder::new(entry.reader());
|
let deflater: Box<dyn Read + Send + 'archive> = 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 {
|
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 {
|
ZipFileWrapper {
|
||||||
reader: deflater,
|
reader: verifier,
|
||||||
limit: (end - start) as usize,
|
limit: (end - start) as usize,
|
||||||
current: 0,
|
current: 0,
|
||||||
}
|
}
|
||||||
@@ -132,7 +145,7 @@ impl ZipVersionBackend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct ZipFileWrapper<'archive> {
|
pub struct ZipFileWrapper<'archive> {
|
||||||
reader: DeflateDecoder<ZipReader<'archive, FileReader>>,
|
reader: ZipVerifier<'archive, Box<dyn Read + Send + 'archive>, FileReader>,
|
||||||
limit: usize,
|
limit: usize,
|
||||||
current: usize,
|
current: usize,
|
||||||
}
|
}
|
||||||
@@ -163,9 +176,13 @@ impl<'a> Read for ZipFileWrapper<'a> {
|
|||||||
return Ok(read);
|
return Ok(read);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//impl<'a> MinimumFileObject for ZipFileWrapper<'a> {}
|
||||||
|
|
||||||
impl ZipVersionBackend {
|
impl ZipVersionBackend {
|
||||||
fn find_wayfinder(&mut self, filename: &str) -> Option<ZipArchiveEntryWayfinder> {
|
fn find_wayfinder(
|
||||||
|
&mut self,
|
||||||
|
filename: &str,
|
||||||
|
) -> Option<(ZipArchiveEntryWayfinder, CompressionMethod)> {
|
||||||
let read_buffer = &mut [0u8; RECOMMENDED_BUFFER_SIZE];
|
let read_buffer = &mut [0u8; RECOMMENDED_BUFFER_SIZE];
|
||||||
let mut entries = self.archive.entries(read_buffer);
|
let mut entries = self.archive.entries(read_buffer);
|
||||||
let entry = loop {
|
let entry = loop {
|
||||||
@@ -180,7 +197,7 @@ impl ZipVersionBackend {
|
|||||||
|
|
||||||
let wayfinder = entry.wayfinder();
|
let wayfinder = entry.wayfinder();
|
||||||
|
|
||||||
Some(wayfinder)
|
Some((wayfinder, entry.compression_method()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl VersionBackend for ZipVersionBackend {
|
impl VersionBackend for ZipVersionBackend {
|
||||||
@@ -207,16 +224,16 @@ impl VersionBackend for ZipVersionBackend {
|
|||||||
start: u64,
|
start: u64,
|
||||||
end: u64,
|
end: u64,
|
||||||
) -> Option<Box<dyn MinimumFileObject + '_>> {
|
) -> Option<Box<dyn MinimumFileObject + '_>> {
|
||||||
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 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<dyn MinimumFileObject>)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn peek_file(&mut self, sub_path: String) -> Option<VersionFile> {
|
fn peek_file(&mut self, sub_path: String) -> Option<VersionFile> {
|
||||||
let entry = self.find_wayfinder(&sub_path)?;
|
let (entry, _) = self.find_wayfinder(&sub_path)?;
|
||||||
|
|
||||||
Some(VersionFile {
|
Some(VersionFile {
|
||||||
relative_filename: sub_path,
|
relative_filename: sub_path,
|
||||||
|
|||||||
Reference in New Issue
Block a user