Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions libcrc_fast.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ extern "C" {
*/
struct CrcFastDigestHandle *crc_fast_digest_new(enum CrcFastAlgorithm algorithm);

/**
* Creates a new Digest with a custom initial state
*/
struct CrcFastDigestHandle *crc_fast_digest_new_with_init_state(enum CrcFastAlgorithm algorithm,
uint64_t init_state);

/**
* Creates a new Digest to compute CRC checksums using custom parameters
*/
Expand Down Expand Up @@ -118,6 +124,11 @@ void crc_fast_digest_combine(struct CrcFastDigestHandle *handle1,
*/
uint64_t crc_fast_digest_get_amount(struct CrcFastDigestHandle *handle);

/**
* Gets the current state of the Digest
*/
uint64_t crc_fast_digest_get_state(struct CrcFastDigestHandle *handle);

/**
* Helper method to calculate a CRC checksum directly for a string using algorithm
*/
Expand Down
23 changes: 23 additions & 0 deletions src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,17 @@ pub extern "C" fn crc_fast_digest_new(algorithm: CrcFastAlgorithm) -> *mut CrcFa
Box::into_raw(handle)
}

/// Creates a new Digest with a custom initial state
#[no_mangle]
pub extern "C" fn crc_fast_digest_new_with_init_state(
algorithm: CrcFastAlgorithm,
init_state: u64,
) -> *mut CrcFastDigestHandle {
let digest = Box::new(Digest::new_with_init_state(algorithm.into(), init_state));
let handle = Box::new(CrcFastDigestHandle(Box::into_raw(digest)));
Box::into_raw(handle)
}

/// Creates a new Digest to compute CRC checksums using custom parameters
#[no_mangle]
pub extern "C" fn crc_fast_digest_new_with_params(
Expand Down Expand Up @@ -333,6 +344,18 @@ pub extern "C" fn crc_fast_digest_get_amount(handle: *mut CrcFastDigestHandle) -
}
}

/// Gets the current state of the Digest
#[no_mangle]
pub extern "C" fn crc_fast_digest_get_state(handle: *mut CrcFastDigestHandle) -> u64 {
if handle.is_null() {
return 0;
}
unsafe {
let digest = &*(*handle).0;
digest.get_state()
}
}

/// Helper method to calculate a CRC checksum directly for a string using algorithm
#[no_mangle]
pub extern "C" fn crc_fast_checksum(
Expand Down
68 changes: 68 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,18 @@ impl DynDigest for Digest {

impl Digest {
/// Creates a new `Digest` instance for the specified CRC algorithm.
///
/// # Examples
///
/// ```rust
/// use crc_fast::{Digest, CrcAlgorithm::Crc32IsoHdlc};
///
/// let mut digest = Digest::new(Crc32IsoHdlc);
/// digest.update(b"123456789");
/// let checksum = digest.finalize();
///
/// assert_eq!(checksum, 0xcbf43926);
/// ```
#[inline(always)]
pub fn new(algorithm: CrcAlgorithm) -> Self {
let (calculator, params) = get_calculator_params(algorithm);
Expand All @@ -388,6 +400,41 @@ impl Digest {
}
}

/// Creates a new `Digest` instance for the specified CRC algorithm with a custom initial state.
///
/// # Examples
///
/// ```rust
/// use crc_fast::{Digest, CrcAlgorithm::Crc32IsoHdlc};
///
/// // CRC-32/ISO-HDLC with initial state of 0x00000000, instead of the default initial state
/// // of 0xffffffff,
/// let mut digest = Digest::new_with_init_state(Crc32IsoHdlc, 0x00000000);
/// digest.update(b"123456789");
/// let checksum = digest.finalize();
///
/// // different initial state, so checksum will be different
/// assert_eq!(checksum, 0xd202d277);
///
/// let mut digest = Digest::new_with_init_state(Crc32IsoHdlc, 0xffffffff);
/// digest.update(b"123456789");
/// let checksum = digest.finalize();
///
/// // same initial state as the default, so checksum will be the same
/// assert_eq!(checksum, 0xcbf43926);
/// ```
#[inline(always)]
pub fn new_with_init_state(algorithm: CrcAlgorithm, init_state: u64) -> Self {
let (calculator, params) = get_calculator_params(algorithm);

Self {
state: init_state,
amount: 0,
params,
calculator,
}
}

/// Creates a new `Digest` instance with custom CRC parameters.
///
/// # Examples
Expand Down Expand Up @@ -474,6 +521,27 @@ impl Digest {
pub fn get_amount(&self) -> u64 {
self.amount
}

/// Gets the current CRC state.
///
/// # Examples
/// ```rust
/// use crc_fast::{Digest, CrcAlgorithm::Crc32IsoHdlc};
///
/// let mut digest = Digest::new(Crc32IsoHdlc);
/// digest.update(b"123456789");
/// let state = digest.get_state();
///
/// // non-finalized state, so it won't match the final checksum
/// assert_eq!(state, 0x340bc6d9);
///
/// // finalized state will match the checksum
/// assert_eq!(digest.finalize(), 0xcbf43926);
/// ```
#[inline(always)]
pub fn get_state(&self) -> u64 {
self.state
}
}

impl Write for Digest {
Expand Down
Loading