#![allow(dead_code)]
use crate::traits::{CrcCalculator, CrcWidth};
use crate::{arch, cache, CrcAlgorithm, CrcParams};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Algorithm<W> {
pub width: u8,
pub poly: W,
pub init: W,
pub refin: bool,
pub refout: bool,
pub xorout: W,
pub check: W,
pub residue: W,
}
#[derive(Clone, Copy)]
pub struct Width16;
impl CrcWidth for Width16 {
const WIDTH: u32 = 16;
type Value = u16;
}
#[derive(Clone, Copy)]
pub struct Width32;
impl CrcWidth for Width32 {
const WIDTH: u32 = 32;
type Value = u32;
}
#[derive(Clone, Copy)]
pub struct Width64;
impl CrcWidth for Width64 {
const WIDTH: u32 = 64;
type Value = u64;
}
#[derive(Debug, Clone, Copy)]
pub struct CrcState<T> {
pub value: T,
pub reflected: bool,
}
pub(crate) struct Calculator {}
impl CrcCalculator for Calculator {
#[inline(always)]
fn calculate(state: u64, data: &[u8], params: &CrcParams) -> u64 {
unsafe { arch::update(state, data, params) }
}
}
impl CrcParams {
pub fn new(
name: &'static str,
width: u8,
poly: u64,
init: u64,
reflected: bool,
xorout: u64,
check: u64,
) -> Self {
let keys_array = cache::get_or_generate_keys(width, poly, reflected);
let keys = crate::CrcKeysStorage::from_keys_fold_256(keys_array);
if width != 16 && width != 32 && width != 64 {
panic!("Unsupported width: {width}");
}
let init_algorithm = if width == 16 && reflected {
(init as u16).reverse_bits() as u64
} else {
init
};
Self {
algorithm: CrcAlgorithm::CrcCustom,
name,
width,
poly,
init,
init_algorithm,
refin: reflected,
refout: reflected,
xorout,
check,
keys,
}
}
#[inline(always)]
pub fn get_key(&self, index: usize) -> u64 {
self.keys.get_key(index)
}
#[inline(always)]
pub fn get_key_checked(&self, index: usize) -> Option<u64> {
if index < self.keys.key_count() {
Some(self.keys.get_key(index))
} else {
None
}
}
#[inline(always)]
pub fn key_count(&self) -> usize {
self.keys.key_count()
}
}