use crc32tables::CRC_TABLE;
mod crc32tables;
pub fn crc32(start_crc :u32, buf :&[u8]) -> u32
{
let len = buf.len();
let mut crc = start_crc;
let mut bufpos :uint = 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 uint];
crc = t ^ (crc >> 8);
bufpos += 1;
remaining_bytes -= 1;
}
crc ^ 0xffffffff
}
mod byfour
{
use crc32tables::CRC_TABLE;
fn dolit4(c: &mut u32, buf4: &[u32], buf4pos: &mut uint)
{
let c1 = *c ^ buf4[*buf4pos];
*buf4pos += 1;
*c = CRC_TABLE[3][(c1 & 0xff) as uint]
^ CRC_TABLE[2][((c1 >> 8) & 0xff) as uint]
^ CRC_TABLE[1][((c1 >> 16) & 0xff) as uint]
^ CRC_TABLE[0][(c1 >> 24) as uint];
}
fn dolit32(c: &mut u32, buf4: &[u32], buf4pos: &mut uint)
{
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]
{
unsafe {
let ptr: *const u32 = s8.as_ptr() as *const u32;
::std::mem::transmute(::std::raw::Slice { data: ptr, len: s8.len() / 4 })
}
}
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 uint) & 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 uint] ^ (c >> 8);
buf_align_bits += 1;
bufpos += 1;
len -= 1;
}
let buf4 = slice_u8_as_u32(buf.slice(bufpos, len - bufpos));
let mut buf4pos: uint = 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 uint] ^ (c >> 8);
bufpos += 1;
len -= 1;
if len == 0 {
break;
}
}
}
c = !c;
return c;
}
}