diff options
Diffstat (limited to 'rust/vendor/crc/src/crc32.rs')
-rw-r--r-- | rust/vendor/crc/src/crc32.rs | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/rust/vendor/crc/src/crc32.rs b/rust/vendor/crc/src/crc32.rs new file mode 100644 index 0000000..6093d3b --- /dev/null +++ b/rust/vendor/crc/src/crc32.rs @@ -0,0 +1,81 @@ +#[cfg(feature = "std")] +use std::hash::Hasher; +#[cfg(not(feature = "std"))] +use core::hash::Hasher; + +pub use util::make_table_crc32 as make_table; + +include!(concat!(env!("OUT_DIR"), "/crc32_constants.rs")); + +pub struct Digest { + table: [u32; 256], + initial: u32, + value: u32 +} + +pub trait Hasher32 { + fn reset(&mut self); + fn write(&mut self, bytes: &[u8]); + fn sum32(&self) -> u32; +} + +pub fn update(mut value: u32, table: &[u32; 256], bytes: &[u8]) -> u32 { + value = !value; + for &i in bytes.iter() { + value = table[((value as u8) ^ i) as usize] ^ (value >> 8) + } + !value +} + +pub fn checksum_ieee(bytes: &[u8]) -> u32 { + return update(0, &IEEE_TABLE, bytes); +} + +pub fn checksum_castagnoli(bytes: &[u8]) -> u32 { + return update(0, &CASTAGNOLI_TABLE, bytes); +} + +pub fn checksum_koopman(bytes: &[u8]) -> u32 { + return update(0, &KOOPMAN_TABLE, bytes); +} + +impl Digest { + pub fn new(poly: u32) -> Digest { + Digest { + table: make_table(poly), + initial: 0, + value: 0 + } + } + + pub fn new_with_initial(poly: u32, initial: u32) -> Digest { + Digest { + table: make_table(poly), + initial: initial, + value: initial + } + } +} + +impl Hasher32 for Digest { + fn reset(&mut self) { + self.value = self.initial; + } + fn write(&mut self, bytes: &[u8]) { + self.value = update(self.value, &self.table, bytes); + } + fn sum32(&self) -> u32 { + self.value + } +} + +/// Implementation of std::hash::Hasher so that types which #[derive(Hash)] can hash with Digest. +impl Hasher for Digest { + fn write(&mut self, bytes: &[u8]) { + Hasher32::write(self, bytes); + } + + fn finish(&self) -> u64 { + self.sum32() as u64 + } +} |