mod crc32tables;
use crate::crc32tables::CRC_TABLE;
pub fn crc32(start_crc: u32, buf: &[u8]) -> u32 {
let len = buf.len();
let mut crc = start_crc;
let mut bufpos: usize = 0; let mut remaining_bytes = len;
crc = crc ^ 0xffffffff;
let t0 = &CRC_TABLE[0];
while remaining_bytes > 0 {
let b = buf[bufpos];
let b32 = b as u32;
let b_index = (crc ^ b32) & 0xff;
let t = t0[b_index as usize];
crc = t ^ (crc >> 8);
bufpos += 1;
remaining_bytes -= 1;
}
crc ^ 0xffffffff
}
mod byfour {
use crate::crc32tables::CRC_TABLE;
fn dolit4(c: &mut u32, buf4: &[u32], buf4pos: &mut usize) {
let c1 = *c ^ buf4[*buf4pos];
*buf4pos += 1;
*c = CRC_TABLE[3][(c1 & 0xff) as usize]
^ CRC_TABLE[2][((c1 >> 8) & 0xff) as usize]
^ CRC_TABLE[1][((c1 >> 16) & 0xff) as usize]
^ CRC_TABLE[0][(c1 >> 24) as usize];
}
fn dolit32(c: &mut u32, buf4: &[u32], buf4pos: &mut usize) {
dolit4(c, buf4, buf4pos);
dolit4(c, buf4, buf4pos);
dolit4(c, buf4, buf4pos);
dolit4(c, buf4, buf4pos);
dolit4(c, buf4, buf4pos);
dolit4(c, buf4, buf4pos);
dolit4(c, buf4, buf4pos);
dolit4(c, buf4, buf4pos);
}
fn slice_u8_as_u32(s8: &[u8]) -> &[u32] {
assert!(s8.len() % 4 == 0, "Input slice length must be a multiple of 4");
let len_u32 = s8.len() / 4;
let ptr: *const u32 = s8.as_ptr() as *const u32;
unsafe {
std::slice::from_raw_parts(ptr, len_u32)
}
}
fn crc32_little(crc: u32, buf: &[u8]) -> u32 {
let mut len = buf.len();
let mut bufpos = 0;
let mut c: u32 = crc;
c = !c;
let mut buf_align_bits = (buf.as_ptr() as usize) & 3;
while len != 0 && (buf_align_bits & 3) != 0 {
let b = buf[bufpos];
let bi = (c & 0xff) as u8 ^ b;
c = CRC_TABLE[0][bi as usize] ^ (c >> 8);
buf_align_bits += 1;
bufpos += 1;
len -= 1;
}
let buf4 = slice_u8_as_u32(&buf[bufpos..(len - bufpos)]);
let mut buf4pos: usize = 0;
while len >= 32 {
dolit32(&mut c, buf4, &mut buf4pos);
len -= 32;
}
while len >= 4 {
dolit4(&mut c, buf4, &mut buf4pos);
len -= 4;
}
bufpos += buf4pos * 4;
if len != 0 {
loop {
let b = buf[bufpos];
let bi = (c & 0xff) as u8 ^ b;
c = CRC_TABLE[0][bi as usize] ^ (c >> 8);
bufpos += 1;
len -= 1;
if len == 0 {
break;
}
}
}
c = !c;
return c;
}
}