diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index feba89aed..198078c00 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -137,6 +137,8 @@ ZSTD_CCtx_params* ZSTD_rust_createCCtxParams(ZSTD_customMem customMem); size_t ZSTD_rust_freeCCtxParams(ZSTD_CCtx_params* params); size_t ZSTD_rust_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params); +void ZSTD_rust_CCtxParams_setZstdParams(ZSTD_CCtx_params* cctxParams, + const ZSTD_parameters* params); int ZSTD_rust_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams); int ZSTD_rust_blockSplitterEnabled(ZSTD_CCtx_params* cctxParams); @@ -711,12 +713,7 @@ static void ZSTD_CCtxParams_setZstdParams( ZSTD_CCtx_params* cctxParams, const ZSTD_parameters* params) { assert(!ZSTD_checkCParams(params->cParams)); - cctxParams->cParams = params->cParams; - cctxParams->fParams = params->fParams; - /* Should not matter, as all cParams are presumed properly defined. - * But, set it for tracing anyway. - */ - cctxParams->compressionLevel = ZSTD_NO_CLEVEL; + ZSTD_rust_CCtxParams_setZstdParams(cctxParams, params); } ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) diff --git a/rust/src/zstd_compress_params_api.rs b/rust/src/zstd_compress_params_api.rs index be28b091e..68754c6d2 100644 --- a/rust/src/zstd_compress_params_api.rs +++ b/rust/src/zstd_compress_params_api.rs @@ -488,6 +488,26 @@ pub unsafe extern "C" fn ZSTD_rust_CCtxParams_init_advanced( unsafe { init_advanced_impl(params, zstd_params) } } +#[inline] +unsafe fn set_zstd_params_impl( + cctx_params: *mut ZSTD_CCtx_params, + zstd_params: *const ZSTD_parameters, +) { + unsafe { + (*cctx_params).cParams = (*zstd_params).cParams; + (*cctx_params).fParams = (*zstd_params).fParams; + (*cctx_params).compressionLevel = NO_CLEVEL; + } +} + +#[no_mangle] +pub unsafe extern "C" fn ZSTD_rust_CCtxParams_setZstdParams( + cctx_params: *mut ZSTD_CCtx_params, + zstd_params: *const ZSTD_parameters, +) { + unsafe { set_zstd_params_impl(cctx_params, zstd_params) } +} + unsafe fn custom_calloc(size: usize, custom_mem: ZSTD_customMem) -> *mut c_void { if let Some(custom_alloc) = custom_mem.customAlloc { let allocation = unsafe { custom_alloc(custom_mem.opaque, size) }; @@ -1343,6 +1363,56 @@ mod tests { assert_eq!(value, -1); } + #[test] + fn set_zstd_params_updates_only_zstd_parameter_fields() { + let zstd_params = ZSTD_parameters { + cParams: ZSTD_compressionParameters { + windowLog: 20, + chainLog: 19, + hashLog: 18, + searchLog: 5, + minMatch: 4, + targetLength: 32, + strategy: STRATEGY_GREEDY, + }, + fParams: ZSTD_frameParameters { + contentSizeFlag: 1, + checksumFlag: 1, + noDictIDFlag: 1, + }, + }; + let mut storage = MaybeUninit::::zeroed(); + let params = storage.as_mut_ptr(); + + unsafe { + (*params).format = 1; + (*params).compressionLevel = 99; + (*params).forceWindow = 1; + (*params).targetCBlockSize = 4096; + (*params).ldmParams.enableLdm = 1; + (*params).customMem.opaque = ptr::dangling_mut::(); + (*params).extSeqProdState = ptr::dangling_mut::(); + (*params).searchForExternalRepcodes = 1; + let before = *params; + + ZSTD_rust_CCtxParams_setZstdParams(params, &zstd_params); + + assert_eq!((*params).cParams, zstd_params.cParams); + assert_eq!((*params).fParams, zstd_params.fParams); + assert_eq!((*params).compressionLevel, NO_CLEVEL); + assert_eq!((*params).format, before.format); + assert_eq!((*params).forceWindow, before.forceWindow); + assert_eq!((*params).targetCBlockSize, before.targetCBlockSize); + assert_eq!((*params).ldmParams.enableLdm, before.ldmParams.enableLdm); + assert_eq!((*params).customMem.opaque, before.customMem.opaque); + assert_eq!((*params).extSeqProdState, before.extSeqProdState); + assert_eq!( + (*params).searchForExternalRepcodes, + before.searchForExternalRepcodes + ); + } + } + #[test] fn advanced_init_resolves_policy_and_resets_internal_fields() { let cases = [