use std::io::Write;
use crate::base_decompressor::{BaseDecompressor, Step};
use crate::bit_words::BitWords;
use crate::data_types::NumberLike;
use crate::errors::QCompressResult;
use crate::{ChunkMetadata, DecompressorConfig, Flags};
#[derive(Clone, Debug, Default)]
pub struct Decompressor<T: NumberLike>(BaseDecompressor<T>);
impl<T: NumberLike> Decompressor<T> {
pub fn from_config(config: DecompressorConfig) -> Self {
Self(BaseDecompressor::<T>::from_config(config))
}
pub fn header(&mut self) -> QCompressResult<Flags> {
self.0.header(true)
}
pub fn chunk_metadata(&mut self) -> QCompressResult<ChunkMetadata<T>> {
self.0.state.check_step_among(
&[Step::StartOfChunk, Step::StartOfDataPage, Step::MidDataPage],
"read chunk metadata",
)?;
self.0.with_reader(|reader, state, _| {
let meta = ChunkMetadata::<T>::parse_from(reader, state.flags.as_ref().unwrap())?;
state.chunk_meta = Some(meta.clone());
state.body_decompressor = None;
Ok(meta)
})
}
pub fn begin_data_page(&mut self, n: usize, compressed_page_size: usize) -> QCompressResult<()> {
self.0.state.check_step_among(
&[Step::StartOfDataPage, Step::MidDataPage],
"begin data page",
)?;
self.0.with_reader(|reader, state, _| {
state.body_decompressor =
Some(state.new_body_decompressor(reader, n, compressed_page_size)?);
Ok(())
})
}
pub fn next_batch(&mut self, limit: usize) -> QCompressResult<Vec<T>> {
self
.0
.state
.check_step(Step::MidDataPage, "read next batch")?;
self.0.with_reader(|reader, state, _| {
let bd = state.body_decompressor.as_mut().unwrap();
let numbers = bd.decompress_next_batch(reader, limit, true)?;
if numbers.finished_body {
state.body_decompressor = None;
}
Ok(numbers.nums)
})
}
pub fn data_page(&mut self, n: usize, compressed_page_size: usize) -> QCompressResult<Vec<T>> {
self.0.state.check_step_among(
&[Step::StartOfDataPage, Step::MidDataPage],
"data page",
)?;
self.0.data_page_internal(n, compressed_page_size)
}
pub fn free_compressed_memory(&mut self) {
self.0.free_compressed_memory()
}
pub fn clear_compressed_bytes(&mut self) {
self.0.words = BitWords::default();
self.0.state.bit_idx = 0;
}
pub fn bit_idx(&self) -> usize {
self.0.bit_idx()
}
}
impl<T: NumberLike> Write for Decompressor<T> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.0.write(buf)
}
fn flush(&mut self) -> std::io::Result<()> {
self.0.flush()
}
}