use crate::prelude::*;
use core::convert::Infallible;
#[cfg(feature = "mem_dbg")]
use mem_dbg::{MemDbg, MemSize};
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "mem_dbg", derive(MemDbg, MemSize))]
pub struct MemWordReader<W: Word, B, const INF: bool = false> {
data: B,
word_index: usize,
_marker: core::marker::PhantomData<W>,
}
impl<W: Word, B, const INF: bool> MemWordReader<W, B, INF> {
#[must_use]
pub fn into_inner(self) -> B {
self.data
}
}
impl<W: Word, B: AsRef<[W]>> MemWordReader<W, B> {
#[must_use]
pub const fn new(data: B) -> Self {
Self {
data,
word_index: 0,
_marker: core::marker::PhantomData,
}
}
}
impl<W: Word, B: AsRef<[W]>> MemWordReader<W, B, true> {
#[must_use]
pub const fn new_inf(data: B) -> Self {
Self {
data,
word_index: 0,
_marker: core::marker::PhantomData,
}
}
}
impl<W: Word, B: AsRef<[W]>> WordRead for MemWordReader<W, B, true> {
type Error = Infallible;
type Word = W;
#[inline(always)]
fn read_word(&mut self) -> Result<W, Infallible> {
let res = self
.data
.as_ref()
.get(self.word_index)
.copied()
.unwrap_or(Self::Word::ZERO);
self.word_index += 1;
Ok(res)
}
}
impl<W: Word, B: AsRef<[W]>> WordRead for MemWordReader<W, B, false> {
type Error = WordError;
type Word = W;
#[inline(always)]
fn read_word(&mut self) -> Result<W, WordError> {
let res = self
.data
.as_ref()
.get(self.word_index)
.ok_or(WordError::UnexpectedEof {
word_pos: self.word_index,
})?;
self.word_index += 1;
Ok(*res)
}
}
impl<W: Word, B: AsRef<[W]>> WordSeek for MemWordReader<W, B, true> {
type Error = Infallible;
#[inline(always)]
fn word_pos(&mut self) -> Result<u64, Infallible> {
Ok(self.word_index as u64)
}
#[inline(always)]
fn set_word_pos(&mut self, word_index: u64) -> Result<(), Infallible> {
self.word_index = word_index.min(usize::MAX as u64) as usize;
Ok(())
}
}
impl<W: Word, B: AsRef<[W]>> WordSeek for MemWordReader<W, B, false> {
type Error = WordError;
#[inline(always)]
fn word_pos(&mut self) -> Result<u64, WordError> {
Ok(self.word_index as u64)
}
#[inline(always)]
fn set_word_pos(&mut self, word_index: u64) -> Result<(), WordError> {
if word_index > self.data.as_ref().len() as u64 {
Err(WordError::UnexpectedEof {
word_pos: self.word_index,
})
} else {
self.word_index = word_index as usize;
Ok(())
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::codes::{DeltaWrite, delta::DeltaReadParam};
#[test]
fn test_eof_table_read() {
let mut words: [u64; 1] = [0];
let mut writer = crate::prelude::BufBitWriter::<crate::prelude::LE, _>::new(
MemWordWriterSlice::new(&mut words),
);
for _ in 0..16 {
writer.write_delta(1).unwrap();
}
writer.flush().unwrap();
drop(writer);
let mut reader = crate::prelude::BufBitReader::<crate::prelude::LE, _>::new(
MemWordReader::new_inf(&words),
);
for _ in 0..16 {
assert_eq!(reader.read_delta_param::<true, true>().unwrap(), 1);
}
}
}