1use crate::{
2 tables::{BYTE_TABLE, WORD_TABLE},
3 DEFAULT_CRC32,
4};
5
6#[derive(Clone, Copy, Debug, Eq, PartialEq)]
7pub struct State {
8 state: u32,
9}
10
11impl State {
12 pub fn new(state: u32) -> Self {
13 State { state }
14 }
15
16 pub fn update(&mut self, buf: &[u8]) {
17 self.state = slice_by_16(self.state, buf);
18 }
19
20 pub fn as_u32(self) -> u32 {
21 self.state
22 }
23
24 pub fn reset(&mut self) {
25 self.state = DEFAULT_CRC32;
26 }
27}
28
29#[inline(always)]
30pub(crate) fn slice_by_16(mut crc: u32, bytes: &[u8]) -> u32 {
31 crc = u32::swap_bytes(crc);
32 let chunks = bytes.chunks_exact(16);
33 let remainder = chunks.remainder();
34 crc = chunks.fold(crc, |mut crc, word| {
35 crc ^= u32::from_le_bytes(word[0..4].try_into().unwrap());
36 WORD_TABLE[15][(crc & 0xff) as usize]
37 ^ WORD_TABLE[14][((crc >> 8) & 0xff) as usize]
38 ^ WORD_TABLE[13][((crc >> 16) & 0xff) as usize]
39 ^ WORD_TABLE[12][(crc >> 24) as usize]
40 ^ WORD_TABLE[11][word[4] as usize]
41 ^ WORD_TABLE[10][word[5] as usize]
42 ^ WORD_TABLE[9][word[6] as usize]
43 ^ WORD_TABLE[8][word[7] as usize]
44 ^ WORD_TABLE[7][word[8] as usize]
45 ^ WORD_TABLE[6][word[9] as usize]
46 ^ WORD_TABLE[5][word[10] as usize]
47 ^ WORD_TABLE[4][word[11] as usize]
48 ^ WORD_TABLE[3][word[12] as usize]
49 ^ WORD_TABLE[2][word[13] as usize]
50 ^ WORD_TABLE[1][word[14] as usize]
51 ^ WORD_TABLE[0][word[15] as usize]
52 });
53 crc = u32::swap_bytes(crc);
54 slice_by_1(crc, remainder)
55}
56
57#[inline(always)]
58pub(crate) fn slice_by_1(crc: u32, bytes: &[u8]) -> u32 {
59 bytes.iter().fold(crc, |crc, &byte| {
60 (crc << 8) ^ BYTE_TABLE[(crc >> 24) as usize ^ byte as usize]
61 })
62}
63
64#[cfg(test)]
65mod tests {
66 use crate::golden;
67 use quickcheck_macros::quickcheck;
68
69 #[quickcheck]
70 fn slice_by_16_matches_golden(crc: u32, bytes: Vec<u8>) -> bool {
71 super::slice_by_16(crc, &bytes) == golden(crc, &bytes)
72 }
73
74 #[quickcheck]
75 fn slice_by_1_matches_golden(crc: u32, bytes: Vec<u8>) -> bool {
76 super::slice_by_1(crc, &bytes) == golden(crc, &bytes)
77 }
78}