unarc-rs 0.6.1

Universal archive extraction & decompression library for retro + modern formats (7z, ZIP, RAR, LHA/LZH, TAR, ARJ, ARC/PAK, ZOO, HA, UC2, SQ/SQ2, SQZ, HYP, gz, bz2, Z).
Documentation
use std::io::Read;

use crate::error::{ArchiveError, Result};

pub(crate) mod lzw;
pub struct ZArchive<T: Read> {
    block_mode: bool,
    max_bits: u8,
    reader: T,
}

const ID: [u8; 2] = [0x1F, 0x9D];
const BLOCK_MODE: u8 = 0x80;
const BIT_MASK: u8 = 0x1f;

impl<T: Read> ZArchive<T> {
    pub fn new(mut reader: T) -> Result<Self> {
        let mut header = [0; 3];
        reader.read_exact(&mut header)?;
        if header[0..2] != ID {
            return Err(ArchiveError::invalid_header("Z"));
        }
        let block_mode = header[2] & BLOCK_MODE != 0;
        let max_bits = header[2] & BIT_MASK;
        Ok(Self { block_mode, max_bits, reader })
    }

    pub fn skip(&mut self) -> Result<()> {
        // just 1 file in the archive
        Ok(())
    }

    pub fn read(&mut self) -> Result<Vec<u8>> {
        let mut compressed_buffer = Vec::new();
        self.reader.read_to_end(&mut compressed_buffer)?;
        let decompressed = lzw::Lzw::new(self.max_bits, self.block_mode).decomp(&compressed_buffer)?;
        Ok(decompressed)
    }
}