use ldeflate::{
Config, ZipEntry as Entry, compress_objects, gzip_compress, gzip_compress_members,
gzip_members_of, jar_write, zip_write,
};
fn precompressed(magic: &[u8], n: usize) -> Vec<u8> {
let mut v = Vec::with_capacity(n);
v.extend_from_slice(magic);
v.extend(compressible(n.saturating_sub(magic.len())));
v
}
fn incompressible(n: usize) -> Vec<u8> {
let mut v = Vec::with_capacity(n);
let mut s: u64 = 0x2545_F491_4F6C_DD1D;
while v.len() < n {
s ^= s << 13;
s ^= s >> 7;
s ^= s << 17;
v.extend_from_slice(&s.to_le_bytes());
}
v.truncate(n);
v
}
fn compressible(n: usize) -> Vec<u8> {
b"the quick brown fox jumps over the lazy dog. "
.iter()
.copied()
.cycle()
.take(n)
.collect()
}
fn corpus() -> Vec<(&'static str, Vec<u8>)> {
vec![
("git packfile", precompressed(b"PACK\0\0\0\x02", 300_000)),
("png", precompressed(b"\x89PNG\r\n\x1a\n", 300_000)),
("jpeg", precompressed(b"\xff\xd8\xff\xe0", 300_000)),
("gzip", precompressed(b"\x1f\x8b\x08\x00", 300_000)),
("zstd", precompressed(b"\x28\xb5\x2f\xfd", 300_000)),
("zlib stream", precompressed(b"\x78\x9c", 300_000)),
]
}
fn is_stored_block(body: &[u8]) -> bool {
!body.is_empty() && (body[0] >> 1) & 0b11 == 0
}
#[test]
fn zlib_streams_store_already_compressed_objects_and_still_round_trip() {
for (label, src) in corpus() {
let objs: Vec<&[u8]> = vec![&src];
let skipped = compress_objects(&objs, &Config::default()).unwrap();
let forced = compress_objects(&objs, &Config::default().compress_everything()).unwrap();
assert!(
is_stored_block(&skipped[0][2..]),
"{label}: the probe did not store — first body byte {:#04x}",
skipped[0][2]
);
assert!(
!is_stored_block(&forced[0][2..]),
"{label}: the control stored too, so this comparison proves nothing — \
the fixture body must be compressible (see the module docs)"
);
assert!(
forced[0].len() < skipped[0].len() / 10,
"{label}: the control did not really compress ({} vs {}), so the skip is unproven",
forced[0].len(),
skipped[0].len()
);
assert!(
skipped[0].len() > src.len(),
"{label}: a stored stream is its input plus framing, got {} for {}",
skipped[0].len(),
src.len()
);
for (what, stream) in [("skipped", &skipped[0]), ("forced", &forced[0])] {
let out = linflate::inflate_to_vec(&stream[2..], src.len())
.unwrap_or_else(|e| panic!("{label} ({what}): did not inflate: {e}"));
assert_eq!(out, src, "{label} ({what}): did not round-trip");
}
}
}
#[test]
fn compressible_objects_are_still_compressed() {
let src = compressible(300_000);
let objs: Vec<&[u8]> = vec![&src];
let out = compress_objects(&objs, &Config::default()).unwrap();
assert!(
!is_stored_block(&out[0][2..]),
"ordinary text was stored — the probe is firing on everything"
);
assert!(
out[0].len() < src.len() / 10,
"ordinary text did not compress: {} -> {}",
src.len(),
out[0].len()
);
assert_eq!(
linflate::inflate_to_vec(&out[0][2..], src.len()).unwrap(),
src
);
}
#[test]
fn gzip_members_store_already_compressed_input_and_stock_gzip_reads_them() {
for (label, src) in corpus() {
let out = gzip_compress_members(&src, &Config::default(), 64 << 10).unwrap();
let forced =
gzip_compress_members(&src, &Config::default().compress_everything(), 64 << 10)
.unwrap();
assert_ne!(
out, forced,
"{label}: skip and no-skip produced the same bytes"
);
let members = gzip_members_of(&out)
.unwrap_or_else(|| panic!("{label}: output is not a clean member concatenation"));
assert!(
members.len() > 1,
"{label}: fixture must produce several members"
);
for (i, m) in members.iter().enumerate() {
assert!(
is_stored_block(&m[10..]),
"{label}: member {i} was deflated, not stored"
);
}
let back = decode_gzip_all(&out);
assert_eq!(
back, src,
"{label}: member concatenation did not round-trip"
);
}
}
#[test]
fn a_single_split_gzip_member_stores_every_segment() {
let src = precompressed(b"\x89PNG\r\n\x1a\n", 6 << 20);
let cfg = Config {
segment: 1 << 20,
..Config::default()
};
let out = gzip_compress(&src, &cfg).unwrap();
let forced = gzip_compress(&src, &cfg.compress_everything()).unwrap();
assert_ne!(out, forced, "skip and no-skip produced the same bytes");
assert!(
is_stored_block(&out[10..]),
"the first segment was deflated, not stored: {:#04x}",
out[10]
);
assert_eq!(decode_gzip_all(&out), src, "split gzip did not round-trip");
assert_eq!(decode_gzip_all(&forced), src, "control did not round-trip");
}
#[test]
fn zip_and_jar_store_already_compressed_entries_without_deflating_them() {
let items = corpus();
let entries: Vec<Entry<'_>> = items
.iter()
.map(|(label, data)| Entry::new(zip_name(label), data))
.collect();
let text = compressible(200_000);
let mut all = entries.clone();
all.push(Entry::new("readme.txt", &text));
for (what, archive, lead) in [
("zip", zip_write(&all, &Config::default()).unwrap(), 0usize),
(
"jar",
jar_write("Manifest-Version: 1.0", &all, &Config::default()).unwrap(),
1usize,
),
] {
let methods = local_header_methods(&archive);
assert_eq!(
methods.len(),
lead + items.len() + 1,
"{what}: wrong entry count"
);
for (i, &m) in methods.iter().skip(lead).take(items.len()).enumerate() {
assert_eq!(m, 0, "{what}: entry {} ({}) was deflated", i, items[i].0);
}
assert_eq!(
*methods.last().unwrap(),
8,
"{what}: readme.txt is compressible and must still deflate"
);
assert!(
methods.iter().any(|&m| m == 8),
"{what}: nothing was deflated, so the assertion above is vacuous"
);
}
let off = zip_write(&all, &Config::default().compress_everything()).unwrap();
let off_methods = local_header_methods(&off);
assert!(
off_methods.iter().all(|&m| m == 8),
"with the probe off every entry must deflate, got {off_methods:?}"
);
assert_eq!(off_methods.len(), items.len() + 1);
}
#[test]
fn incompressible_content_round_trips_in_every_container() {
let src = incompressible(400_000);
let z = compress_objects(&[&src[..]], &Config::default()).unwrap();
assert_eq!(
linflate::inflate_to_vec(&z[0][2..], src.len()).unwrap(),
src,
"zlib"
);
let g = gzip_compress_members(&src, &Config::default(), 64 << 10).unwrap();
assert_eq!(decode_gzip_all(&g), src, "gzip members");
let s = gzip_compress(
&src,
&Config {
segment: 64 << 10,
..Config::default()
},
)
.unwrap();
assert_eq!(decode_gzip_all(&s), src, "split gzip");
let entries = [Entry::new("a.bin", &src)];
let archive = zip_write(&entries, &Config::default()).unwrap();
assert_eq!(
local_header_methods(&archive).len(),
1,
"zip wrote one entry"
);
}
fn zip_name(label: &str) -> &'static str {
match label {
"git packfile" => "objects/pack/a.pack",
"png" => "img/a.png",
"jpeg" => "img/a.jpg",
"gzip" => "data/a.gz",
"zstd" => "data/a.zst",
_ => "obj/a.bin",
}
}
fn local_header_methods(archive: &[u8]) -> Vec<u16> {
let mut out = Vec::new();
let mut i = 0usize;
while i + 30 <= archive.len() && &archive[i..i + 4] == b"PK\x03\x04" {
let method = u16::from_le_bytes([archive[i + 8], archive[i + 9]]);
let csize = u32::from_le_bytes(archive[i + 18..i + 22].try_into().unwrap()) as usize;
let nlen = u16::from_le_bytes([archive[i + 26], archive[i + 27]]) as usize;
let elen = u16::from_le_bytes([archive[i + 28], archive[i + 29]]) as usize;
out.push(method);
i += 30 + nlen + elen + csize;
}
out
}
fn decode_gzip_all(data: &[u8]) -> Vec<u8> {
use std::io::Read;
let mut out = Vec::new();
flate2::read::MultiGzDecoder::new(data)
.read_to_end(&mut out)
.expect("gzip output did not decode");
out
}