pub mod batch;
pub mod central_dir;
pub mod chunk;
pub mod deflate_scan;
pub mod entry;
pub mod parallel;
pub mod reader;
pub use entry::{ZipEntry, ZipError};
pub use reader::StreamingZipRead;
const SMALL_FILE_THRESHOLD: usize = 10 * 1024 * 1024;
use std::sync::OnceLock;
static POOL: OnceLock<rayon::ThreadPool> = OnceLock::new();
pub fn thread_pool() -> &'static rayon::ThreadPool {
POOL.get_or_init(|| {
let n = std::env::var("LZIP_THREADS")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or_else(|| {
std::thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(4)
});
rayon::ThreadPoolBuilder::new()
.num_threads(n)
.thread_name(|i| format!("lzip-{i}"))
.build()
.expect("failed to create lzip thread pool")
})
}
pub fn decompress_zip(data: &[u8]) -> Result<Vec<ZipEntry>, ZipError> {
if data.len() < SMALL_FILE_THRESHOLD {
parallel::decompress_parallel(data)
} else {
decompress_zip_stream(std::io::Cursor::new(data))
}
}
pub fn decompress_zip_filter(data: &[u8], needle: &str) -> Result<Vec<ZipEntry>, ZipError> {
if data.len() < SMALL_FILE_THRESHOLD {
parallel::decompress_parallel_filter(data, needle)
} else {
let reader = StreamingZipRead::with_filter(std::io::Cursor::new(data), needle)?;
reader.collect()
}
}
pub fn decompress_zip_filter_set(data: &[u8], names: &[&str]) -> Result<Vec<ZipEntry>, ZipError> {
if data.len() < SMALL_FILE_THRESHOLD {
parallel::decompress_parallel_filter_set(data, names)
} else {
let reader = StreamingZipRead::with_filter_set(std::io::Cursor::new(data), names)?;
reader.collect()
}
}
pub fn decompress_zip_filter_suffixes(data: &[u8], suffixes: &[&str]) -> Result<Vec<ZipEntry>, ZipError> {
if data.len() < SMALL_FILE_THRESHOLD {
parallel::decompress_parallel_filter_suffixes(data, suffixes)
} else {
let reader = StreamingZipRead::with_filter_suffixes(std::io::Cursor::new(data), suffixes)?;
reader.collect()
}
}
pub fn decompress_zip_stream<R: std::io::Read + std::io::Seek>(
source: R,
) -> Result<Vec<ZipEntry>, ZipError> {
StreamingZipRead::new(source)?.collect()
}