use crate::{
bitstream::BitRead,
error::LhaError,
stub_io::Read,
};
mod pm1;
mod pm2;
mod history_list;
#[cfg_attr(docsrs, doc(cfg(feature = "pm")))]
pub use pm1::*;
#[cfg_attr(docsrs, doc(cfg(feature = "pm")))]
pub use pm2::*;
use history_list::*;
use super::unsafe_assert;
#[derive(Debug, Clone, Copy)]
struct VarLenEntry {
offs: u16,
bits: u16,
}
#[derive(Debug)]
#[repr(transparent)]
struct NoEofReader<R>(R);
impl VarLenEntry {
const fn new(offs: u16, bits: u16) -> Self {
VarLenEntry { offs, bits }
}
#[inline]
fn decode_variable_length<R: BitRead>(&self, br: &mut R) -> Result<u16, LhaError<R::Error>> {
let value: u16 = br.read_bits(self.bits.into())?;
Ok(value + self.offs)
}
}
impl<R: Read> Read for NoEofReader<R> {
type Error = R::Error;
#[inline(always)]
fn unexpected_eof() -> Self::Error {
R::unexpected_eof()
}
fn read_all(&mut self, buf: &mut[u8]) -> Result<usize, Self::Error> {
let n = self.0.read_all(buf)?;
if n < buf.len() {
buf[n..].fill(0);
}
Ok(buf.len())
}
}
#[cfg(test)]
mod tests {
#[cfg(feature = "std")]
use std::io;
#[cfg(not(feature = "std"))]
use crate::UnexpectedEofError;
use super::*;
#[test]
fn pmarc_works() {
assert!(matches!(VarLenEntry::new(100, 3), VarLenEntry { offs: 100, bits: 3}));
#[cfg(feature = "std")]
assert_eq!(<NoEofReader::<&[u8]> as Read>::unexpected_eof().kind(), io::ErrorKind::UnexpectedEof);
#[cfg(not(feature = "std"))]
assert_eq!(<NoEofReader::<&[u8]> as Read>::unexpected_eof(), UnexpectedEofError);
}
}