lgz/examples/bitcheck.rs
//! Debug aid: are the split starts real block starts? `bitcheck <file.gz> <n>`
fn main() {
let a: Vec<String> = std::env::args().collect();
let gz = std::fs::read(&a[1]).unwrap();
let n: usize = a[2].parse().unwrap();
let s = lgz::parallel::deflate_offset(&gz).unwrap();
let d = &gz[s..gz.len() - 8];
let isz = u32::from_le_bytes(gz[gz.len() - 4..].try_into().unwrap()) as usize;
// every true block start, by decoding block by block
let mut out = vec![0u8; isz + linflate::OVERWRITE_HEADROOM];
let mut starts = std::collections::BTreeMap::new();
let (mut bit, mut done) = (0usize, 0usize);
loop {
let h = (u16::from_le_bytes([d[bit / 8], d[bit / 8 + 1]]) >> (bit % 8)) & 7;
starts.insert(bit, h);
let win = done.min(32768);
let mut buf = vec![0u8; win + isz - done + linflate::OVERWRITE_HEADROOM];
buf[..win].copy_from_slice(&out[done - win..done]);
let r = linflate::inflate_bits(d, bit, bit + 1, &mut buf, win).unwrap();
out[done..done + r.written].copy_from_slice(&buf[win..win + r.written]);
done += r.written;
if r.final_block {
break;
}
bit = r.end_bit;
}
let types: Vec<u16> = starts.values().copied().collect();
println!(
"blocks {} (dynamic {}, fixed {}, stored {})",
types.len(),
types.iter().filter(|&&h| h >> 1 == 2).count(),
types.iter().filter(|&&h| h >> 1 == 1).count(),
types.iter().filter(|&&h| h >> 1 == 0).count()
);
let sp = lgz::bitsplit::split_chunk_bits(d, 0, n);
for &b in &sp.starts {
let real = starts.contains_key(&b);
let next = starts.range(b..).next().map(|(k, _)| *k);
println!("start {b} real={real} next_true={next:?}");
}
}