use crate::decode::tables::*;
use crate::dict::DictTables;
use crate::error::Result;
use crate::fse::ctable::CTable;
use crate::fse::Norm;
use crate::huf::ctable::HufCTable;
#[derive(Clone, Debug)]
pub struct SeqCTable {
pub norm: Norm,
pub ct: CTable,
}
impl SeqCTable {
pub fn new(norm: Norm) -> Result<SeqCTable> {
let ct = CTable::build(&norm)?;
Ok(SeqCTable { norm, ct })
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Held {
None,
Predefined,
Dict,
Local,
Rle(u8),
}
pub struct PredefinedC {
pub t: [SeqCTable; 3],
}
impl PredefinedC {
pub fn new() -> Result<PredefinedC> {
Ok(PredefinedC {
t: [
SeqCTable::new(Norm::from_slice(&LL_DEFAULT, LL_DEFAULT_LOG))?,
SeqCTable::new(Norm::from_slice(&OF_DEFAULT, OF_DEFAULT_LOG))?,
SeqCTable::new(Norm::from_slice(&ML_DEFAULT, ML_DEFAULT_LOG))?,
],
})
}
}
#[derive(Clone, Debug)]
pub struct DictCTables {
pub huf: HufCTable,
pub seq: [SeqCTable; 3],
}
impl DictCTables {
pub fn new(t: &DictTables) -> Result<DictCTables> {
Ok(DictCTables {
huf: HufCTable::new(&t.huf),
seq: [SeqCTable::new(t.ll.clone())?, SeqCTable::new(t.of.clone())?, SeqCTable::new(t.ml.clone())?],
})
}
}
pub struct EntropyState {
pub huf_held: Held,
pub huf_local: Option<HufCTable>,
pub seq_held: [Held; 3],
pub seq_local: [Option<SeqCTable>; 3],
}
impl EntropyState {
pub fn new() -> EntropyState {
EntropyState { huf_held: Held::None, huf_local: None, seq_held: [Held::None; 3], seq_local: [None, None, None] }
}
pub fn reset(&mut self, dict: Option<&DictCTables>) {
let h = if dict.is_some() { Held::Dict } else { Held::None };
self.huf_held = h;
self.seq_held = [h; 3];
}
pub fn huf<'a>(&'a self, dict: Option<&'a DictCTables>) -> Option<&'a HufCTable> {
match self.huf_held {
Held::Dict => dict.map(|d| &d.huf),
Held::Local => self.huf_local.as_ref(),
_ => None,
}
}
pub fn seq<'a>(&'a self, i: usize, pre: &'a PredefinedC, dict: Option<&'a DictCTables>) -> Option<&'a SeqCTable> {
match self.seq_held[i] {
Held::Predefined => Some(&pre.t[i]),
Held::Dict => dict.map(|d| &d.seq[i]),
Held::Local => self.seq_local[i].as_ref(),
_ => None,
}
}
}