I'm building a git clone implementation in Rust. I've gotten to the part where I need to parse the packfile to create the index, and I'm almost done parsing it.
Each object in the packfile consists of a header (Which I'm already parsing correctly) followed by the contents which are zlib compressed.
Notably the size stored in the header is the decompressed size, and is therefore larger than the actual data we have to skip to get to the next header.
Crates.io shows 2 crates that do zlib decompression and have more than a few downloads:
libz-sys
: Is practically a hello world and has been like that for monthsflate2
: This correctly deflates the data with ease:print!("Object type {} size {}", obj_type as u8, obj_size); println!(" data:\n{}", String::from_utf8( ZlibDecoder::new(data).read_exact(obj_size as usize).unwrap() ).unwrap() );
Here's the problem. After this I need to start reading the next object's header, but ZlibDecoder
doesn't give any way to detect how large the input was.
It takes ownership of a reader as it's input, rather than a reference.
Because of this, even though I have the output size of the object (and indeed all the object's data) since I don't know the input size I can't start reading the next object header.
How do I get the amount of compressed input bytes needed to reach the expected output size? If possible, I'd like to avoid using FFI to call native zlib.
PS: the flate2
docs suggest a helper trait but I have no idea how or if this would help me