pub trait Encoder {
fn encode(&mut self, x: usize);
}
pub struct PQEncoderGeneric<'a> {
code: &'a mut [u8],
position: usize,
offset: u8,
nbits: usize,
reg: u64,
}
impl<'a> PQEncoderGeneric<'a> {
pub fn new(code: &'a mut [u8], nbits: usize) -> Self {
assert!(nbits <= 64);
Self {
code,
position: 0,
offset: 0,
nbits,
reg: 0,
}
}
#[inline]
fn encode_64(&mut self, x: u64) {
self.reg |= x << self.offset;
let mut x = x >> (8 - self.offset);
if self.offset + self.nbits as u8 >= 8 {
if self.position < self.code.len() {
self.code[self.position] = self.reg as u8;
self.position += 1;
}
for _ in 0..(self.nbits - (8 - self.offset as usize)) / 8 {
if self.position < self.code.len() {
self.code[self.position] = x as u8;
self.position += 1;
}
x >>= 8;
}
self.offset = ((self.offset as usize + self.nbits) % 8) as u8;
self.reg = x;
} else {
self.offset += self.nbits as u8;
}
}
}
impl<'a> Encoder for PQEncoderGeneric<'a> {
fn encode(&mut self, x: usize) {
self.encode_64(x as u64);
}
}
pub struct PQEncoder8<'a> {
code: &'a mut [u8],
position: usize,
}
impl<'a> PQEncoder8<'a> {
pub fn new(code: &'a mut [u8]) -> Self {
PQEncoder8 { code, position: 0 }
}
#[inline]
fn encode_8(&mut self, x: u8) {
self.code[self.position] = x;
self.position += 1;
}
}
impl<'a> Encoder for PQEncoder8<'a> {
fn encode(&mut self, x: usize) {
self.encode_8(x as u8);
}
}
pub struct PQEncoder16<'a> {
code: &'a mut [u16],
position: usize,
}
impl<'a> PQEncoder16<'a> {
pub fn new(code: &'a mut [u8]) -> Self {
let code_16 = unsafe { &mut *(code as *mut [u8] as *mut [u16]) };
PQEncoder16 {
code: code_16,
position: 0,
}
}
#[inline]
fn encode_16(&mut self, x: u16) {
self.code[self.position] = x;
self.position += 1;
}
}
impl<'a> Encoder for PQEncoder16<'a> {
fn encode(&mut self, x: usize) {
self.encode_16(x as u16);
}
}
impl<'a, T> Encoder for &'a mut T
where
T: Encoder + ?Sized,
{
fn encode(&mut self, x: usize) {
(**self).encode(x);
}
}
impl<T> Encoder for Box<T>
where
T: Encoder + ?Sized,
{
fn encode(&mut self, x: usize) {
(**self).encode(x);
}
}