use core::ffi::c_void; use crate::{crc::Crc, ffi::ref_to_voidptr}; pub type ChecksumCrc32 = u32; // uint32_t in C unsafe extern "C" { fn crc32_new() -> Crc32; fn crc32_process(data: *const u8, len: u32, crc32: *mut Crc32); fn crc32_checksum(data: *const u8, len: u32) -> ChecksumCrc32; } #[repr(C)] pub struct Crc32 { buf: ChecksumCrc32, } impl Crc for Crc32 { type Input = [u8]; type Checksum = ChecksumCrc32; #[inline] fn new() -> Self { unsafe { crc32_new() } } #[inline] fn process(&mut self, data: &Self::Input) { unsafe { crc32_process(data, data.len() as u32, self as *mut Self) } } #[inline] fn shift_reg(&mut self) -> &mut Self::Checksum { &mut self.buf } #[inline] fn checksum(data: &Self::Input) -> Self::Checksum { unsafe { crc32_checksum(data, data.len() as u32) } } } #[cfg(test)] mod tests { use crate::crc::CHECK_DATA; use super::*; #[test] fn test_check() { // see https://reveng.sourceforge.io/crc-catalogue/17plus.htm#crc.cat-bits.32 for the check // value assert_eq!(Crc32::checksum(&CHECK_DATA), 0xCBF43926); } }