unarc_rs/z/
mod.rs

1use std::io::{self, Read};
2mod lzw;
3pub struct ZArchieve<T: Read> {
4    block_mode: bool,
5    max_bits: u8,
6    reader: T,
7}
8
9const ID: [u8; 2] = [0x1F, 0x9D];
10const BLOCK_MODE: u8 = 0x80;
11const BIT_MASK: u8 = 0x1f;
12
13impl<T: Read> ZArchieve<T> {
14    pub fn new(mut reader: T) -> io::Result<Self> {
15        let mut header = [0; 3];
16        reader.read_exact(&mut header)?;
17        if header[0..2] != ID {
18            return Err(io::Error::new(
19                io::ErrorKind::InvalidData,
20                "Not a Z archive",
21            ));
22        }
23        let block_mode = header[2] & BLOCK_MODE != 0;
24        let max_bits = header[2] & BIT_MASK;
25        Ok(Self {
26            block_mode,
27            max_bits,
28            reader,
29        })
30    }
31
32    pub fn skip(&mut self) -> io::Result<()> {
33        // just 1 file in the archive
34        Ok(())
35    }
36
37    pub fn read(&mut self) -> io::Result<Vec<u8>> {
38        let mut compressed_buffer = Vec::new();
39        self.reader.read_to_end(&mut compressed_buffer)?;
40        let decompressed =
41            lzw::Lzw::new(self.max_bits, self.block_mode).decomp(&compressed_buffer)?;
42        Ok(decompressed)
43    }
44}