1use crate::util::{self, U64Le};
4
5pub struct CrcTable([[u32; 256]; 8]);
7
8impl CrcTable {
9 #[inline]
11 pub fn at(&self, i: u8, j: u8) -> u64 {
12 let i = i as usize;
13 let j = j as usize;
14 u64::from(self.0[i][j])
15 }
16}
17
18const CRC_TABLE: CrcTable = CrcTable(include!(concat!(env!("OUT_DIR"), "/", "sw.table")));
19
20pub fn crc32c(crci: u32, buffer: &[u8]) -> u32 {
22 let mut crc = u64::from(!crci);
23
24 let (start, mid, end) = util::split(buffer);
25
26 crc = crc_u8(crc, start);
27
28 crc = crc_u64(crc, mid);
29
30 crc = crc_u8(crc, end);
31
32 !(crc as u32)
33}
34
35#[inline]
36fn crc_u8(crc: u64, buffer: &[u8]) -> u64 {
37 buffer.iter().fold(crc, |crc, &next| {
38 let index = (crc ^ u64::from(next)) as u8;
39 CRC_TABLE.at(0, index) ^ (crc >> 8)
40 })
41}
42
43#[inline]
44fn crc_u64(crci: u64, buffer: &[U64Le]) -> u64 {
45 buffer.iter().fold(crci, |crc, &next| {
46 let crc = crc ^ next.get();
47
48 CRC_TABLE.at(7, crc as u8)
51 ^ CRC_TABLE.at(6, (crc >> 8) as u8)
52 ^ CRC_TABLE.at(5, (crc >> 16) as u8)
53 ^ CRC_TABLE.at(4, (crc >> 24) as u8)
54 ^ CRC_TABLE.at(3, (crc >> 32) as u8)
55 ^ CRC_TABLE.at(2, (crc >> 40) as u8)
56 ^ CRC_TABLE.at(1, (crc >> 48) as u8)
57 ^ CRC_TABLE.at(0, (crc >> 56) as u8)
58 })
59}