#[cfg(feature = "deflate")]
use flate2::Crc;
#[cfg(feature = "deflate_zlib_ng")]
use libz_ng_sys::{adler32, adler32_combine, uInt, z_off_t};
#[cfg(all(feature = "any_zlib", not(feature = "deflate_zlib_ng")))]
use libz_sys::{adler32, adler32_combine, uInt, z_off_t};
pub trait Check {
fn sum(&self) -> u32;
fn amount(&self) -> u32;
fn new() -> Self
where
Self: Sized;
fn update(&mut self, bytes: &[u8]);
fn combine(&mut self, other: &Self)
where
Self: Sized;
}
#[cfg(feature = "libdeflate")]
pub struct LibDeflateCrc {
crc: libdeflater::Crc,
amount: u32,
}
#[cfg(feature = "libdeflate")]
impl Check for LibDeflateCrc {
#[inline]
fn sum(&self) -> u32 {
self.crc.sum()
}
#[inline]
fn amount(&self) -> u32 {
self.amount
}
#[inline]
fn new() -> Self
where
Self: Sized,
{
Self {
crc: libdeflater::Crc::new(),
amount: 0,
}
}
#[inline]
fn update(&mut self, bytes: &[u8]) {
self.amount += bytes.len() as u32;
self.crc.update(bytes);
}
fn combine(&mut self, _other: &Self)
where
Self: Sized,
{
unimplemented!()
}
}
#[cfg(feature = "any_zlib")]
pub struct Adler32 {
sum: u32,
amount: u32,
}
#[cfg(feature = "any_zlib")]
impl Check for Adler32 {
#[inline]
fn sum(&self) -> u32 {
self.sum
}
#[inline]
fn amount(&self) -> u32 {
self.amount
}
#[inline]
fn new() -> Self {
let start = unsafe { adler32(0, std::ptr::null_mut(), 0) } as u32;
Self {
sum: start,
amount: 0,
}
}
#[inline]
#[allow(clippy::useless_conversion)]
fn update(&mut self, bytes: &[u8]) {
self.amount += bytes.len() as u32;
self.sum = unsafe {
adler32(
self.sum.into(),
bytes.as_ptr() as *mut _,
bytes.len() as uInt,
)
} as u32;
}
#[inline]
#[allow(clippy::useless_conversion)]
fn combine(&mut self, other: &Self) {
self.sum =
unsafe { adler32_combine(self.sum.into(), other.sum.into(), other.amount as z_off_t) }
as u32;
self.amount += other.amount;
}
}
#[cfg(feature = "deflate")]
pub struct Crc32 {
crc: Crc,
}
#[cfg(feature = "deflate")]
impl Check for Crc32 {
#[inline]
fn sum(&self) -> u32 {
self.crc.sum()
}
#[inline]
fn amount(&self) -> u32 {
self.crc.amount()
}
#[inline]
fn new() -> Self {
let crc = flate2::Crc::new();
Self { crc }
}
#[inline]
fn update(&mut self, bytes: &[u8]) {
self.crc.update(bytes);
}
#[inline]
fn combine(&mut self, other: &Self) {
self.crc.combine(&other.crc);
}
}
pub struct PassThroughCheck {}
#[allow(unused)]
impl Check for PassThroughCheck {
#[inline]
fn sum(&self) -> u32 {
0
}
#[inline]
fn amount(&self) -> u32 {
0
}
#[inline]
fn new() -> Self
where
Self: Sized,
{
Self {}
}
#[inline]
fn update(&mut self, bytes: &[u8]) {}
#[inline]
fn combine(&mut self, other: &Self)
where
Self: Sized,
{
}
}