use super::{SeqVec, iter::SeqVecBitReader};
use crate::common::codec_reader::{CodecReader, VarVecBitReader};
use crate::variable::traits::Storable;
use dsi_bitstream::{
dispatch::{CodesRead, StaticCodeRead},
prelude::{BitRead, BitSeek, Endianness},
};
use std::fmt;
pub struct SeqVecReader<'a, T: Storable, E: Endianness, B: AsRef<[u64]>>
where
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
seqvec: &'a SeqVec<T, E, B>,
reader: VarVecBitReader<'a, E>,
code_reader: CodecReader<'a, E>,
}
impl<T: Storable, E: Endianness, B: AsRef<[u64]>> fmt::Debug for SeqVecReader<'_, T, E, B>
where
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SeqVecReader").finish_non_exhaustive()
}
}
impl<'a, T: Storable, E: Endianness, B: AsRef<[u64]>> SeqVecReader<'a, T, E, B>
where
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
#[inline]
pub(super) fn new(seqvec: &'a SeqVec<T, E, B>) -> Self {
let reader = VarVecBitReader::new(dsi_bitstream::impls::MemWordReader::new_inf(
seqvec.data.as_ref(),
));
let code_reader = CodecReader::new(seqvec.encoding);
Self {
seqvec,
reader,
code_reader,
}
}
#[inline]
pub fn decode_vec(&mut self, index: usize) -> Option<Vec<T>> {
let mut buf = Vec::new();
self.decode_into(index, &mut buf).map(|_| buf)
}
#[inline]
pub fn decode_into(&mut self, index: usize, buf: &mut Vec<T>) -> Option<usize> {
if index >= self.seqvec.num_sequences() {
return None;
}
Some(unsafe { self.decode_into_unchecked(index, buf) })
}
#[inline]
pub unsafe fn decode_into_unchecked(&mut self, index: usize, buf: &mut Vec<T>) -> usize {
let start_bit = unsafe { self.seqvec.sequence_start_bit_unchecked(index) };
buf.clear();
let _ = self.reader.set_bit_pos(start_bit);
if let Some(lengths) = &self.seqvec.seq_lengths {
let count = unsafe { lengths.get_unchecked(index) as usize };
buf.reserve(count);
for _ in 0..count {
let word = self.code_reader.read(&mut self.reader).unwrap();
buf.push(T::from_word(word));
}
} else {
let end_bit = unsafe { self.seqvec.sequence_end_bit_unchecked(index) };
while self.reader.bit_pos().unwrap() < end_bit {
let word = self.code_reader.read(&mut self.reader).unwrap();
buf.push(T::from_word(word));
}
}
buf.len()
}
}