Skip to content

Commit 99985e5

Browse files
committed
Add shared library support for custom CRC params
1 parent cdee06e commit 99985e5

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

libcrc_fast.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ typedef struct CrcFastDigestHandle {
5050
struct CrcFastDigest *_0;
5151
} CrcFastDigestHandle;
5252

53+
/**
54+
* Custom CRC parameters
55+
*/
56+
typedef struct CrcFastParams {
57+
enum CrcFastAlgorithm algorithm;
58+
uint8_t width;
59+
uint64_t poly;
60+
uint64_t init;
61+
bool refin;
62+
bool refout;
63+
uint64_t xorout;
64+
uint64_t check;
65+
uint64_t keys[23];
66+
} CrcFastParams;
67+
5368
#ifdef __cplusplus
5469
extern "C" {
5570
#endif // __cplusplus
@@ -59,6 +74,11 @@ extern "C" {
5974
*/
6075
struct CrcFastDigestHandle *crc_fast_digest_new(enum CrcFastAlgorithm algorithm);
6176

77+
/**
78+
* Creates a new Digest to compute CRC checksums using custom parameters
79+
*/
80+
struct CrcFastDigestHandle *crc_fast_digest_new_with_params(struct CrcFastParams params);
81+
6282
/**
6383
* Updates the Digest with data
6484
*/
@@ -100,13 +120,27 @@ uint64_t crc_fast_digest_get_amount(struct CrcFastDigestHandle *handle);
100120
*/
101121
uint64_t crc_fast_checksum(enum CrcFastAlgorithm algorithm, const char *data, uintptr_t len);
102122

123+
/**
124+
* Helper method to calculate a CRC checksum directly for data using custom parameters
125+
*/
126+
uint64_t crc_fast_checksum_with_params(struct CrcFastParams params,
127+
const char *data,
128+
uintptr_t len);
129+
103130
/**
104131
* Helper method to just calculate a CRC checksum directly for a file using algorithm
105132
*/
106133
uint64_t crc_fast_checksum_file(enum CrcFastAlgorithm algorithm,
107134
const uint8_t *path_ptr,
108135
uintptr_t path_len);
109136

137+
/**
138+
* Helper method to calculate a CRC checksum directly for a file using custom parameters
139+
*/
140+
uint64_t crc_fast_checksum_file_with_params(struct CrcFastParams params,
141+
const uint8_t *path_ptr,
142+
uintptr_t path_len);
143+
110144
/**
111145
* Combine two CRC checksums using algorithm
112146
*/

src/ffi.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::{get_calculator_target, Digest};
1212
use std::ffi::CStr;
1313
use std::os::raw::c_char;
1414
use std::slice;
15+
use crate::structs::CrcParams;
1516

1617
/// A handle to the Digest object
1718
#[repr(C)]
@@ -68,6 +69,38 @@ impl From<CrcFastAlgorithm> for CrcAlgorithm {
6869
}
6970
}
7071

72+
/// Custom CRC parameters
73+
#[repr(C)]
74+
pub struct CrcFastParams {
75+
pub algorithm: CrcFastAlgorithm,
76+
pub width: u8,
77+
pub poly: u64,
78+
pub init: u64,
79+
pub refin: bool,
80+
pub refout: bool,
81+
pub xorout: u64,
82+
pub check: u64,
83+
pub keys: [u64; 23],
84+
}
85+
86+
// Convert from FFI struct to internal struct
87+
impl From<CrcFastParams> for CrcParams {
88+
fn from(value: CrcFastParams) -> Self {
89+
CrcParams {
90+
algorithm: value.algorithm.into(),
91+
name: "custom", // C interface doesn't need the name field
92+
width: value.width,
93+
poly: value.poly,
94+
init: value.init,
95+
refin: value.refin,
96+
refout: value.refout,
97+
xorout: value.xorout,
98+
check: value.check,
99+
keys: value.keys,
100+
}
101+
}
102+
}
103+
71104
/// Creates a new Digest to compute CRC checksums using algorithm
72105
#[no_mangle]
73106
pub extern "C" fn crc_fast_digest_new(algorithm: CrcFastAlgorithm) -> *mut CrcFastDigestHandle {
@@ -76,6 +109,14 @@ pub extern "C" fn crc_fast_digest_new(algorithm: CrcFastAlgorithm) -> *mut CrcFa
76109
Box::into_raw(handle)
77110
}
78111

112+
/// Creates a new Digest to compute CRC checksums using custom parameters
113+
#[no_mangle]
114+
pub extern "C" fn crc_fast_digest_new_with_params(params: CrcFastParams) -> *mut CrcFastDigestHandle {
115+
let digest = Box::new(Digest::new_with_params(params.into()));
116+
let handle = Box::new(CrcFastDigestHandle(Box::into_raw(digest)));
117+
Box::into_raw(handle)
118+
}
119+
79120
/// Updates the Digest with data
80121
#[no_mangle]
81122
pub extern "C" fn crc_fast_digest_update(
@@ -197,6 +238,23 @@ pub extern "C" fn crc_fast_checksum(
197238
}
198239
}
199240

241+
/// Helper method to calculate a CRC checksum directly for data using custom parameters
242+
#[no_mangle]
243+
pub extern "C" fn crc_fast_checksum_with_params(
244+
params: CrcFastParams,
245+
data: *const c_char,
246+
len: usize,
247+
) -> u64 {
248+
if data.is_null() {
249+
return 0;
250+
}
251+
unsafe {
252+
#[allow(clippy::unnecessary_cast)]
253+
let bytes = slice::from_raw_parts(data as *const u8, len);
254+
crate::checksum_with_params(params.into(), bytes)
255+
}
256+
}
257+
200258
/// Helper method to just calculate a CRC checksum directly for a file using algorithm
201259
#[no_mangle]
202260
pub extern "C" fn crc_fast_checksum_file(
@@ -218,6 +276,27 @@ pub extern "C" fn crc_fast_checksum_file(
218276
}
219277
}
220278

279+
/// Helper method to calculate a CRC checksum directly for a file using custom parameters
280+
#[no_mangle]
281+
pub extern "C" fn crc_fast_checksum_file_with_params(
282+
params: CrcFastParams,
283+
path_ptr: *const u8,
284+
path_len: usize,
285+
) -> u64 {
286+
if path_ptr.is_null() {
287+
return 0;
288+
}
289+
290+
unsafe {
291+
crate::checksum_file_with_params(
292+
params.into(),
293+
&convert_to_string(path_ptr, path_len),
294+
None,
295+
)
296+
.unwrap_or(0) // Return 0 on error instead of panicking
297+
}
298+
}
299+
221300
/// Combine two CRC checksums using algorithm
222301
#[no_mangle]
223302
pub extern "C" fn crc_fast_checksum_combine(

0 commit comments

Comments
 (0)