use crate::util::{self, U64Le};
pub struct CrcTable([[u32; 256]; 8]);
impl CrcTable {
#[inline]
pub fn at(&self, i: u8, j: u8) -> u64 {
let i = i as usize;
let j = j as usize;
u64::from(self.0[i][j])
}
}
const CRC_TABLE: CrcTable = CrcTable(include!(concat!(env!("OUT_DIR"), "/", "sw.table")));
pub fn crc32c(crci: u32, buffer: &[u8]) -> u32 {
let mut crc = u64::from(!crci);
let (start, mid, end) = util::split(buffer);
crc = crc_u8(crc, start);
crc = crc_u64(crc, mid);
crc = crc_u8(crc, end);
!(crc as u32)
}
#[inline]
fn crc_u8(crc: u64, buffer: &[u8]) -> u64 {
buffer.iter().fold(crc, |crc, &next| {
let index = (crc ^ u64::from(next)) as u8;
CRC_TABLE.at(0, index) ^ (crc >> 8)
})
}
#[inline]
fn crc_u64(crci: u64, buffer: &[U64Le]) -> u64 {
buffer.iter().fold(crci, |crc, &next| {
let crc = crc ^ next.get();
CRC_TABLE.at(7, crc as u8)
^ CRC_TABLE.at(6, (crc >> 8) as u8)
^ CRC_TABLE.at(5, (crc >> 16) as u8)
^ CRC_TABLE.at(4, (crc >> 24) as u8)
^ CRC_TABLE.at(3, (crc >> 32) as u8)
^ CRC_TABLE.at(2, (crc >> 40) as u8)
^ CRC_TABLE.at(1, (crc >> 48) as u8)
^ CRC_TABLE.at(0, (crc >> 56) as u8)
})
}