//! Cyclic redundancy check function.

fn crc_accum(a: u32, _: u32) -> u32
{
   if a & 1 == 1 {
      0xEDB8_8320 ^ a >> 1
   } else {
      a >> 1
   }
}

fn crc_init() -> [u32; 256]
{
   let mut t = [0; 256];
   for (n, v) in t.iter_mut().enumerate() {
      *v = (0..8).fold(n as u32, crc_accum);
   }
   t
}

/// Creates a CRC-32 of all bytes in `b` with the starting sum `s`. The
/// polynomial used is the one from ISO-3309.
///
/// # Examples
///
/// ```
/// use maraiah::durandal::crc::crc32;
///
/// assert_eq!(crc32(b"Lorem ipsum dolor sit amet", !0), 0x5F29_D461);
/// ```
pub fn crc32(b: &[u8], s: u32) -> u32
{
   let t = crc_init();
   !b.iter().fold(s, |a, &o| a >> 8 ^ t[usize::from(a as u8 ^ o)])
}

// EOF
