use crate::{lzh::LzhReader, rle::RleReader, Error};
use std::{io, rc::Rc};
#[derive(Debug, Default, Copy, Clone)]
pub(crate) enum CompressionMethod {
#[default]
Rle,
Lzh,
}
#[derive(Debug, Default, Copy, Clone)]
pub(crate) struct StreamDescription {
pub(crate) method: CompressionMethod,
pub(crate) _compressed_len: usize,
pub(crate) uncompressed_len: usize,
pub(crate) offset: u64,
}
pub enum EntryReader<'a, R: io::Read + std::io::Seek> {
RleReader(RleReader<&'a mut R>),
LzhReader(LzhReader<'a, R>),
}
impl<'a, R: io::Read + std::io::Seek> EntryReader<'a, R> {
pub(crate) fn try_new(reader: &'a mut Rc<R>, spec: StreamDescription) -> Result<Self, Error> {
let StreamDescription {
method,
uncompressed_len,
offset,
..
} = spec;
let reader = unsafe { Rc::get_mut_unchecked(reader) };
reader.seek(io::SeekFrom::Start(offset))?;
Ok(match method {
CompressionMethod::Rle => Self::RleReader(RleReader::new(reader, uncompressed_len)),
CompressionMethod::Lzh => {
Self::LzhReader(LzhReader::try_new(reader, uncompressed_len)?)
}
})
}
}
impl<R: io::Read + std::io::Seek> std::io::Read for EntryReader<'_, R> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match self {
EntryReader::RleReader(reader) => reader.read(buf),
EntryReader::LzhReader(reader) => reader.read(buf),
}
}
}