use std::io::{self, Read, Write};
use crate::DecodeError;
#[derive(Debug, Clone, Copy)]
pub(crate) struct Copier {
cnt: [u8; 16],
pos: usize,
write: bool,
}
impl Copier {
pub(crate) const fn write(&self) -> bool {
self.write
}
pub(crate) const fn is_empty(&self) -> bool {
!self.write && self.pos == 0
}
pub(crate) const fn new_decode() -> Self {
Self {
cnt: [0; 16],
pos: 0,
write: false,
}
}
pub(crate) const fn new_encode() -> Self {
Self {
cnt: [0; 16],
pos: 3,
write: false,
}
}
pub(crate) fn copy_encoded(
&mut self,
reader: &mut (impl Read + ?Sized),
nth_chunk: usize,
) -> io::Result<bool> {
let remainder = &mut self.cnt[self.pos..];
let n = reader.read(remainder)?;
if n == 0 {
if self.pos == 0 {
return Ok(true);
} else {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
DecodeError::UnpaddedTail {
index: self.pos + 16 * nth_chunk,
},
));
}
}
self.pos += n;
Ok(self.pos == 16)
}
pub(crate) fn copy_from(&mut self, reader: &mut (impl Read + ?Sized)) -> io::Result<bool> {
let remainder = &mut self.cnt[self.pos..];
let n = reader.read(remainder)?;
self.pos += n;
Ok(self.pos == 16)
}
pub(crate) fn copy_to(&mut self, writer: &mut (impl Write + ?Sized)) -> io::Result<bool> {
let remainder = &self.cnt[self.pos..];
let n = writer.write(remainder)?;
self.pos += n;
Ok(self.pos == 16)
}
pub(crate) fn decode(&mut self) -> Result<(), crate::DecodeError> {
self.write = true;
let mut buf = [0; 13];
let len = crate::decode_chunk(&self.cnt, &mut buf)?;
self.pos = 16 - len;
self.cnt[self.pos..].copy_from_slice(&buf[..len]);
Ok(())
}
pub(crate) fn encode(&mut self) {
self.write = true;
self.cnt = crate::encode_chunk(self.cnt.last_chunk().unwrap());
self.pos = 0;
}
pub(crate) fn encode_tail(&mut self) -> [u8; 16] {
let res = crate::encode_tail(&self.cnt[3..self.pos]);
*self = Self::new_encode();
res
}
}