use core::error::Error;
use core::fmt::{Display, Formatter};
use crate::traits::*;
use num_primitive::PrimitiveUnsigned;
#[derive(Debug, Clone)]
pub enum CopyError<RE: Error + Send + Sync + 'static, WE: Error + Send + Sync + 'static> {
ReadError(RE),
WriteError(WE),
}
impl<RE: Error + Send + Sync + 'static, WE: Error + Send + Sync + 'static> Display
for CopyError<RE, WE>
{
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self {
CopyError::ReadError(e) => write!(f, "read error while copying: {}", e),
CopyError::WriteError(e) => write!(f, "write error while copying: {}", e),
}
}
}
impl<RE: Error + Send + Sync + 'static, WE: Error + Send + Sync + 'static> Error
for CopyError<RE, WE>
{
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
CopyError::ReadError(e) => Some(e),
CopyError::WriteError(e) => Some(e),
}
}
}
pub trait BitRead<E: Endianness> {
type Error: Error + Send + Sync + 'static;
type PeekWord: PrimitiveUnsigned;
const PEEK_BITS: usize;
fn read_bits(&mut self, num_bits: usize) -> Result<u64, Self::Error>;
fn peek_bits(&mut self, n: usize) -> Result<Self::PeekWord, Self::Error>;
fn skip_bits(&mut self, n: usize) -> Result<(), Self::Error>;
#[doc(hidden)]
fn skip_bits_after_peek(&mut self, n: usize);
fn read_unary(&mut self) -> Result<u64, Self::Error>;
fn copy_to<F: Endianness, W: BitWrite<F>>(
&mut self,
bit_write: &mut W,
mut n: u64,
) -> Result<(), CopyError<Self::Error, W::Error>> {
while n > 0 {
let to_read = core::cmp::min(n, 64) as usize;
let read = self.read_bits(to_read).map_err(CopyError::ReadError)?;
bit_write
.write_bits(read, to_read)
.map_err(CopyError::WriteError)?;
n -= to_read as u64;
}
Ok(())
}
}
pub trait BitWrite<E: Endianness> {
type Error: Error + Send + Sync + 'static;
fn write_bits(&mut self, value: u64, num_bits: usize) -> Result<usize, Self::Error>;
fn write_unary(&mut self, n: u64) -> Result<usize, Self::Error>;
fn flush(&mut self) -> Result<usize, Self::Error>;
fn copy_from<F: Endianness, R: BitRead<F>>(
&mut self,
bit_read: &mut R,
mut n: u64,
) -> Result<(), CopyError<R::Error, Self::Error>> {
while n > 0 {
let to_read = core::cmp::min(n, 64) as usize;
let read = bit_read.read_bits(to_read).map_err(CopyError::ReadError)?;
self.write_bits(read, to_read)
.map_err(CopyError::WriteError)?;
n -= to_read as u64;
}
Ok(())
}
}
pub trait BitSeek {
type Error: Error + Send + Sync + 'static;
fn bit_pos(&mut self) -> Result<u64, Self::Error>;
fn set_bit_pos(&mut self, bit_pos: u64) -> Result<(), Self::Error>;
}