Skip to content

Commit ee5e2fb

Browse files
committed
Merge branch 'add-state-flexibility'
2 parents 8031bc6 + 02febc8 commit ee5e2fb

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

libcrc_fast.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ extern "C" {
7777
*/
7878
struct CrcFastDigestHandle *crc_fast_digest_new(enum CrcFastAlgorithm algorithm);
7979

80+
/**
81+
* Creates a new Digest with a custom initial state
82+
*/
83+
struct CrcFastDigestHandle *crc_fast_digest_new_with_init_state(enum CrcFastAlgorithm algorithm,
84+
uint64_t init_state);
85+
8086
/**
8187
* Creates a new Digest to compute CRC checksums using custom parameters
8288
*/
@@ -118,6 +124,11 @@ void crc_fast_digest_combine(struct CrcFastDigestHandle *handle1,
118124
*/
119125
uint64_t crc_fast_digest_get_amount(struct CrcFastDigestHandle *handle);
120126

127+
/**
128+
* Gets the current state of the Digest
129+
*/
130+
uint64_t crc_fast_digest_get_state(struct CrcFastDigestHandle *handle);
131+
121132
/**
122133
* Helper method to calculate a CRC checksum directly for a string using algorithm
123134
*/

src/ffi.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,17 @@ pub extern "C" fn crc_fast_digest_new(algorithm: CrcFastAlgorithm) -> *mut CrcFa
219219
Box::into_raw(handle)
220220
}
221221

222+
/// Creates a new Digest with a custom initial state
223+
#[no_mangle]
224+
pub extern "C" fn crc_fast_digest_new_with_init_state(
225+
algorithm: CrcFastAlgorithm,
226+
init_state: u64,
227+
) -> *mut CrcFastDigestHandle {
228+
let digest = Box::new(Digest::new_with_init_state(algorithm.into(), init_state));
229+
let handle = Box::new(CrcFastDigestHandle(Box::into_raw(digest)));
230+
Box::into_raw(handle)
231+
}
232+
222233
/// Creates a new Digest to compute CRC checksums using custom parameters
223234
#[no_mangle]
224235
pub extern "C" fn crc_fast_digest_new_with_params(
@@ -333,6 +344,18 @@ pub extern "C" fn crc_fast_digest_get_amount(handle: *mut CrcFastDigestHandle) -
333344
}
334345
}
335346

347+
/// Gets the current state of the Digest
348+
#[no_mangle]
349+
pub extern "C" fn crc_fast_digest_get_state(handle: *mut CrcFastDigestHandle) -> u64 {
350+
if handle.is_null() {
351+
return 0;
352+
}
353+
unsafe {
354+
let digest = &*(*handle).0;
355+
digest.get_state()
356+
}
357+
}
358+
336359
/// Helper method to calculate a CRC checksum directly for a string using algorithm
337360
#[no_mangle]
338361
pub extern "C" fn crc_fast_checksum(

src/lib.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,18 @@ impl DynDigest for Digest {
376376

377377
impl Digest {
378378
/// Creates a new `Digest` instance for the specified CRC algorithm.
379+
///
380+
/// # Examples
381+
///
382+
/// ```rust
383+
/// use crc_fast::{Digest, CrcAlgorithm::Crc32IsoHdlc};
384+
///
385+
/// let mut digest = Digest::new(Crc32IsoHdlc);
386+
/// digest.update(b"123456789");
387+
/// let checksum = digest.finalize();
388+
///
389+
/// assert_eq!(checksum, 0xcbf43926);
390+
/// ```
379391
#[inline(always)]
380392
pub fn new(algorithm: CrcAlgorithm) -> Self {
381393
let (calculator, params) = get_calculator_params(algorithm);
@@ -388,6 +400,41 @@ impl Digest {
388400
}
389401
}
390402

403+
/// Creates a new `Digest` instance for the specified CRC algorithm with a custom initial state.
404+
///
405+
/// # Examples
406+
///
407+
/// ```rust
408+
/// use crc_fast::{Digest, CrcAlgorithm::Crc32IsoHdlc};
409+
///
410+
/// // CRC-32/ISO-HDLC with initial state of 0x00000000, instead of the default initial state
411+
/// // of 0xffffffff,
412+
/// let mut digest = Digest::new_with_init_state(Crc32IsoHdlc, 0x00000000);
413+
/// digest.update(b"123456789");
414+
/// let checksum = digest.finalize();
415+
///
416+
/// // different initial state, so checksum will be different
417+
/// assert_eq!(checksum, 0xd202d277);
418+
///
419+
/// let mut digest = Digest::new_with_init_state(Crc32IsoHdlc, 0xffffffff);
420+
/// digest.update(b"123456789");
421+
/// let checksum = digest.finalize();
422+
///
423+
/// // same initial state as the default, so checksum will be the same
424+
/// assert_eq!(checksum, 0xcbf43926);
425+
/// ```
426+
#[inline(always)]
427+
pub fn new_with_init_state(algorithm: CrcAlgorithm, init_state: u64) -> Self {
428+
let (calculator, params) = get_calculator_params(algorithm);
429+
430+
Self {
431+
state: init_state,
432+
amount: 0,
433+
params,
434+
calculator,
435+
}
436+
}
437+
391438
/// Creates a new `Digest` instance with custom CRC parameters.
392439
///
393440
/// # Examples
@@ -474,6 +521,27 @@ impl Digest {
474521
pub fn get_amount(&self) -> u64 {
475522
self.amount
476523
}
524+
525+
/// Gets the current CRC state.
526+
///
527+
/// # Examples
528+
/// ```rust
529+
/// use crc_fast::{Digest, CrcAlgorithm::Crc32IsoHdlc};
530+
///
531+
/// let mut digest = Digest::new(Crc32IsoHdlc);
532+
/// digest.update(b"123456789");
533+
/// let state = digest.get_state();
534+
///
535+
/// // non-finalized state, so it won't match the final checksum
536+
/// assert_eq!(state, 0x340bc6d9);
537+
///
538+
/// // finalized state will match the checksum
539+
/// assert_eq!(digest.finalize(), 0xcbf43926);
540+
/// ```
541+
#[inline(always)]
542+
pub fn get_state(&self) -> u64 {
543+
self.state
544+
}
477545
}
478546

479547
impl Write for Digest {

0 commit comments

Comments
 (0)