feat(compress): port the CCtx parameter object API to Rust
Move CCtx parameter reset/init, parameter set/get, and external sequence producer registration to Rust with a private C-layout mirror. Keep allocation, advanced initialization, bounds policy, and context-dependent APIs in C, and retain C layout assertions and helper bridges for the shared object. Test Plan: - rustfmt +nightly --check --edition 2021 rust/src/zstd_compress_params_api.rs rust/src/lib.rs - RUSTC_WRAPPER= CARGO_BUILD_RUSTC_WRAPPER= cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression zstd_compress_params_api - RUSTC_WRAPPER= CARGO_BUILD_RUSTC_WRAPPER= cargo clippy --manifest-path rust/Cargo.toml --all-targets --no-default-features --features compression -- -D warnings - make -B -C lib libzstd.a V=1 - git diff --cached --check
This commit is contained in:
+105
-424
@@ -65,6 +65,83 @@ size_t ZSTD_rust_params_maxNbSeq(size_t blockSize, U32 minMatch,
|
||||
int useSequenceProducer);
|
||||
size_t ZSTD_rust_params_resolveMaxBlockSize(size_t maxBlockSize);
|
||||
|
||||
/* CCtx parameter state is mirrored by rust/src/zstd_compress_params_api.rs.
|
||||
* Keep bounds and build-configuration policy in C, and expose only the
|
||||
* private helpers required by that Rust ABI implementation. */
|
||||
size_t ZSTD_rust_cctx_params_clamp_bounds(int param, int* value);
|
||||
int ZSTD_rust_cctx_params_within_bounds(int param, int value);
|
||||
int ZSTD_rust_cctx_params_is_multithreaded(void);
|
||||
int ZSTD_rust_cctx_params_job_size_min(void);
|
||||
|
||||
#define ZSTD_RUST_CCTX_PARAMS_ASSERT(name, condition) \
|
||||
typedef char name[(condition) ? 1 : -1]
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_ldm_size, sizeof(ldmParams_t) == 24);
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_custom_mem_size,
|
||||
sizeof(ZSTD_customMem) == (sizeof(void*) == 8 ? 24 : 12));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_size,
|
||||
sizeof(ZSTD_CCtx_params) == (sizeof(void*) == 8 ? 224 : 180));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_format_offset,
|
||||
offsetof(ZSTD_CCtx_params, format) == 0);
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_cparams_offset,
|
||||
offsetof(ZSTD_CCtx_params, cParams) == 4);
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_fparams_offset,
|
||||
offsetof(ZSTD_CCtx_params, fParams) == 32);
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_level_offset,
|
||||
offsetof(ZSTD_CCtx_params, compressionLevel) == 44);
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_force_window_offset,
|
||||
offsetof(ZSTD_CCtx_params, forceWindow) == 48);
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_target_block_offset,
|
||||
offsetof(ZSTD_CCtx_params, targetCBlockSize) == (sizeof(void*) == 8 ? 56 : 52));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_src_hint_offset,
|
||||
offsetof(ZSTD_CCtx_params, srcSizeHint) == (sizeof(void*) == 8 ? 64 : 56));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_attach_offset,
|
||||
offsetof(ZSTD_CCtx_params, attachDictPref) == (sizeof(void*) == 8 ? 68 : 60));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_literal_mode_offset,
|
||||
offsetof(ZSTD_CCtx_params, literalCompressionMode) == (sizeof(void*) == 8 ? 72 : 64));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_workers_offset,
|
||||
offsetof(ZSTD_CCtx_params, nbWorkers) == (sizeof(void*) == 8 ? 76 : 68));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_job_size_offset,
|
||||
offsetof(ZSTD_CCtx_params, jobSize) == (sizeof(void*) == 8 ? 80 : 72));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_overlap_offset,
|
||||
offsetof(ZSTD_CCtx_params, overlapLog) == (sizeof(void*) == 8 ? 88 : 76));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_rsyncable_offset,
|
||||
offsetof(ZSTD_CCtx_params, rsyncable) == (sizeof(void*) == 8 ? 92 : 80));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_ldm_offset,
|
||||
offsetof(ZSTD_CCtx_params, ldmParams) == (sizeof(void*) == 8 ? 96 : 84));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_dedicated_dict_offset,
|
||||
offsetof(ZSTD_CCtx_params, enableDedicatedDictSearch) == (sizeof(void*) == 8 ? 120 : 108));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_in_buffer_offset,
|
||||
offsetof(ZSTD_CCtx_params, inBufferMode) == (sizeof(void*) == 8 ? 124 : 112));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_out_buffer_offset,
|
||||
offsetof(ZSTD_CCtx_params, outBufferMode) == (sizeof(void*) == 8 ? 128 : 116));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_delimiters_offset,
|
||||
offsetof(ZSTD_CCtx_params, blockDelimiters) == (sizeof(void*) == 8 ? 132 : 120));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_validate_offset,
|
||||
offsetof(ZSTD_CCtx_params, validateSequences) == (sizeof(void*) == 8 ? 136 : 124));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_post_splitter_offset,
|
||||
offsetof(ZSTD_CCtx_params, postBlockSplitter) == (sizeof(void*) == 8 ? 140 : 128));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_pre_splitter_offset,
|
||||
offsetof(ZSTD_CCtx_params, preBlockSplitter_level) == (sizeof(void*) == 8 ? 144 : 132));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_max_block_offset,
|
||||
offsetof(ZSTD_CCtx_params, maxBlockSize) == (sizeof(void*) == 8 ? 152 : 136));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_row_matcher_offset,
|
||||
offsetof(ZSTD_CCtx_params, useRowMatchFinder) == (sizeof(void*) == 8 ? 160 : 140));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_deterministic_prefix_offset,
|
||||
offsetof(ZSTD_CCtx_params, deterministicRefPrefix) == (sizeof(void*) == 8 ? 164 : 144));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_custom_mem_offset,
|
||||
offsetof(ZSTD_CCtx_params, customMem) == (sizeof(void*) == 8 ? 168 : 148));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_prefetch_offset,
|
||||
offsetof(ZSTD_CCtx_params, prefetchCDictTables) == (sizeof(void*) == 8 ? 192 : 160));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_fallback_offset,
|
||||
offsetof(ZSTD_CCtx_params, enableMatchFinderFallback) == (sizeof(void*) == 8 ? 196 : 164));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_state_offset,
|
||||
offsetof(ZSTD_CCtx_params, extSeqProdState) == (sizeof(void*) == 8 ? 200 : 168));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_function_offset,
|
||||
offsetof(ZSTD_CCtx_params, extSeqProdFunc) == (sizeof(void*) == 8 ? 208 : 172));
|
||||
ZSTD_RUST_CCTX_PARAMS_ASSERT(ZSTD_rust_cctx_params_repcode_offset,
|
||||
offsetof(ZSTD_CCtx_params, searchForExternalRepcodes) == (sizeof(void*) == 8 ? 216 : 176));
|
||||
#undef ZSTD_RUST_CCTX_PARAMS_ASSERT
|
||||
|
||||
typedef struct {
|
||||
U32 hashLog3Max;
|
||||
size_t matchTSize;
|
||||
@@ -461,19 +538,6 @@ size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params)
|
||||
{
|
||||
return ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT);
|
||||
}
|
||||
|
||||
size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) {
|
||||
RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!");
|
||||
ZSTD_memset(cctxParams, 0, sizeof(*cctxParams));
|
||||
cctxParams->compressionLevel = compressionLevel;
|
||||
cctxParams->fParams.contentSizeFlag = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ZSTD_NO_CLEVEL 0
|
||||
|
||||
/**
|
||||
@@ -731,6 +795,34 @@ static size_t ZSTD_cParam_clampBounds(ZSTD_cParameter cParam, int* value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t ZSTD_rust_cctx_params_clamp_bounds(int param, int* value)
|
||||
{
|
||||
return ZSTD_cParam_clampBounds((ZSTD_cParameter)param, value);
|
||||
}
|
||||
|
||||
int ZSTD_rust_cctx_params_within_bounds(int param, int value)
|
||||
{
|
||||
return ZSTD_cParam_withinBounds((ZSTD_cParameter)param, value);
|
||||
}
|
||||
|
||||
int ZSTD_rust_cctx_params_is_multithreaded(void)
|
||||
{
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ZSTD_rust_cctx_params_job_size_min(void)
|
||||
{
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
return ZSTDMT_JOBSIZE_MIN;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define BOUNDCHECK(cParam, val) \
|
||||
do { \
|
||||
RETURN_ERROR_IF(!ZSTD_cParam_withinBounds(cParam,val), \
|
||||
@@ -850,407 +942,11 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
|
||||
return ZSTD_CCtxParams_setParameter(&cctx->requestedParams, param, value);
|
||||
}
|
||||
|
||||
size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
|
||||
ZSTD_cParameter param, int value)
|
||||
{
|
||||
DEBUGLOG(4, "ZSTD_CCtxParams_setParameter (%i, %i)", (int)param, value);
|
||||
switch(param)
|
||||
{
|
||||
case ZSTD_c_format :
|
||||
BOUNDCHECK(ZSTD_c_format, value);
|
||||
CCtxParams->format = (ZSTD_format_e)value;
|
||||
return (size_t)CCtxParams->format;
|
||||
|
||||
case ZSTD_c_compressionLevel : {
|
||||
FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
|
||||
if (value == 0)
|
||||
CCtxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default */
|
||||
else
|
||||
CCtxParams->compressionLevel = value;
|
||||
if (CCtxParams->compressionLevel >= 0) return (size_t)CCtxParams->compressionLevel;
|
||||
return 0; /* return type (size_t) cannot represent negative values */
|
||||
}
|
||||
|
||||
case ZSTD_c_windowLog :
|
||||
if (value!=0) /* 0 => use default */
|
||||
BOUNDCHECK(ZSTD_c_windowLog, value);
|
||||
CCtxParams->cParams.windowLog = (U32)value;
|
||||
return CCtxParams->cParams.windowLog;
|
||||
|
||||
case ZSTD_c_hashLog :
|
||||
if (value!=0) /* 0 => use default */
|
||||
BOUNDCHECK(ZSTD_c_hashLog, value);
|
||||
CCtxParams->cParams.hashLog = (U32)value;
|
||||
return CCtxParams->cParams.hashLog;
|
||||
|
||||
case ZSTD_c_chainLog :
|
||||
if (value!=0) /* 0 => use default */
|
||||
BOUNDCHECK(ZSTD_c_chainLog, value);
|
||||
CCtxParams->cParams.chainLog = (U32)value;
|
||||
return CCtxParams->cParams.chainLog;
|
||||
|
||||
case ZSTD_c_searchLog :
|
||||
if (value!=0) /* 0 => use default */
|
||||
BOUNDCHECK(ZSTD_c_searchLog, value);
|
||||
CCtxParams->cParams.searchLog = (U32)value;
|
||||
return (size_t)value;
|
||||
|
||||
case ZSTD_c_minMatch :
|
||||
if (value!=0) /* 0 => use default */
|
||||
BOUNDCHECK(ZSTD_c_minMatch, value);
|
||||
CCtxParams->cParams.minMatch = (U32)value;
|
||||
return CCtxParams->cParams.minMatch;
|
||||
|
||||
case ZSTD_c_targetLength :
|
||||
BOUNDCHECK(ZSTD_c_targetLength, value);
|
||||
CCtxParams->cParams.targetLength = (U32)value;
|
||||
return CCtxParams->cParams.targetLength;
|
||||
|
||||
case ZSTD_c_strategy :
|
||||
if (value!=0) /* 0 => use default */
|
||||
BOUNDCHECK(ZSTD_c_strategy, value);
|
||||
CCtxParams->cParams.strategy = (ZSTD_strategy)value;
|
||||
return (size_t)CCtxParams->cParams.strategy;
|
||||
|
||||
case ZSTD_c_contentSizeFlag :
|
||||
/* Content size written in frame header _when known_ (default:1) */
|
||||
DEBUGLOG(4, "set content size flag = %u", (value!=0));
|
||||
CCtxParams->fParams.contentSizeFlag = value != 0;
|
||||
return (size_t)CCtxParams->fParams.contentSizeFlag;
|
||||
|
||||
case ZSTD_c_checksumFlag :
|
||||
/* A 32-bits content checksum will be calculated and written at end of frame (default:0) */
|
||||
CCtxParams->fParams.checksumFlag = value != 0;
|
||||
return (size_t)CCtxParams->fParams.checksumFlag;
|
||||
|
||||
case ZSTD_c_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */
|
||||
DEBUGLOG(4, "set dictIDFlag = %u", (value!=0));
|
||||
CCtxParams->fParams.noDictIDFlag = !value;
|
||||
return !CCtxParams->fParams.noDictIDFlag;
|
||||
|
||||
case ZSTD_c_forceMaxWindow :
|
||||
CCtxParams->forceWindow = (value != 0);
|
||||
return (size_t)CCtxParams->forceWindow;
|
||||
|
||||
case ZSTD_c_forceAttachDict : {
|
||||
const ZSTD_dictAttachPref_e pref = (ZSTD_dictAttachPref_e)value;
|
||||
BOUNDCHECK(ZSTD_c_forceAttachDict, (int)pref);
|
||||
CCtxParams->attachDictPref = pref;
|
||||
return CCtxParams->attachDictPref;
|
||||
}
|
||||
|
||||
case ZSTD_c_literalCompressionMode : {
|
||||
const ZSTD_ParamSwitch_e lcm = (ZSTD_ParamSwitch_e)value;
|
||||
BOUNDCHECK(ZSTD_c_literalCompressionMode, (int)lcm);
|
||||
CCtxParams->literalCompressionMode = lcm;
|
||||
return CCtxParams->literalCompressionMode;
|
||||
}
|
||||
|
||||
case ZSTD_c_nbWorkers :
|
||||
#ifndef ZSTD_MULTITHREAD
|
||||
RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
|
||||
return 0;
|
||||
#else
|
||||
FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
|
||||
CCtxParams->nbWorkers = value;
|
||||
return (size_t)(CCtxParams->nbWorkers);
|
||||
#endif
|
||||
|
||||
case ZSTD_c_jobSize :
|
||||
#ifndef ZSTD_MULTITHREAD
|
||||
RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
|
||||
return 0;
|
||||
#else
|
||||
/* Adjust to the minimum non-default value. */
|
||||
if (value != 0 && value < ZSTDMT_JOBSIZE_MIN)
|
||||
value = ZSTDMT_JOBSIZE_MIN;
|
||||
FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
|
||||
assert(value >= 0);
|
||||
CCtxParams->jobSize = (size_t)value;
|
||||
return CCtxParams->jobSize;
|
||||
#endif
|
||||
|
||||
case ZSTD_c_overlapLog :
|
||||
#ifndef ZSTD_MULTITHREAD
|
||||
RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
|
||||
return 0;
|
||||
#else
|
||||
FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), "");
|
||||
CCtxParams->overlapLog = value;
|
||||
return (size_t)CCtxParams->overlapLog;
|
||||
#endif
|
||||
|
||||
case ZSTD_c_rsyncable :
|
||||
#ifndef ZSTD_MULTITHREAD
|
||||
RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
|
||||
return 0;
|
||||
#else
|
||||
FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), "");
|
||||
CCtxParams->rsyncable = value;
|
||||
return (size_t)CCtxParams->rsyncable;
|
||||
#endif
|
||||
|
||||
case ZSTD_c_enableDedicatedDictSearch :
|
||||
CCtxParams->enableDedicatedDictSearch = (value!=0);
|
||||
return (size_t)CCtxParams->enableDedicatedDictSearch;
|
||||
|
||||
case ZSTD_c_enableLongDistanceMatching :
|
||||
BOUNDCHECK(ZSTD_c_enableLongDistanceMatching, value);
|
||||
CCtxParams->ldmParams.enableLdm = (ZSTD_ParamSwitch_e)value;
|
||||
return CCtxParams->ldmParams.enableLdm;
|
||||
|
||||
case ZSTD_c_ldmHashLog :
|
||||
if (value!=0) /* 0 ==> auto */
|
||||
BOUNDCHECK(ZSTD_c_ldmHashLog, value);
|
||||
CCtxParams->ldmParams.hashLog = (U32)value;
|
||||
return CCtxParams->ldmParams.hashLog;
|
||||
|
||||
case ZSTD_c_ldmMinMatch :
|
||||
if (value!=0) /* 0 ==> default */
|
||||
BOUNDCHECK(ZSTD_c_ldmMinMatch, value);
|
||||
CCtxParams->ldmParams.minMatchLength = (U32)value;
|
||||
return CCtxParams->ldmParams.minMatchLength;
|
||||
|
||||
case ZSTD_c_ldmBucketSizeLog :
|
||||
if (value!=0) /* 0 ==> default */
|
||||
BOUNDCHECK(ZSTD_c_ldmBucketSizeLog, value);
|
||||
CCtxParams->ldmParams.bucketSizeLog = (U32)value;
|
||||
return CCtxParams->ldmParams.bucketSizeLog;
|
||||
|
||||
case ZSTD_c_ldmHashRateLog :
|
||||
if (value!=0) /* 0 ==> default */
|
||||
BOUNDCHECK(ZSTD_c_ldmHashRateLog, value);
|
||||
CCtxParams->ldmParams.hashRateLog = (U32)value;
|
||||
return CCtxParams->ldmParams.hashRateLog;
|
||||
|
||||
case ZSTD_c_targetCBlockSize :
|
||||
if (value!=0) { /* 0 ==> default */
|
||||
value = MAX(value, ZSTD_TARGETCBLOCKSIZE_MIN);
|
||||
BOUNDCHECK(ZSTD_c_targetCBlockSize, value);
|
||||
}
|
||||
CCtxParams->targetCBlockSize = (U32)value;
|
||||
return CCtxParams->targetCBlockSize;
|
||||
|
||||
case ZSTD_c_srcSizeHint :
|
||||
if (value!=0) /* 0 ==> default */
|
||||
BOUNDCHECK(ZSTD_c_srcSizeHint, value);
|
||||
CCtxParams->srcSizeHint = value;
|
||||
return (size_t)CCtxParams->srcSizeHint;
|
||||
|
||||
case ZSTD_c_stableInBuffer:
|
||||
BOUNDCHECK(ZSTD_c_stableInBuffer, value);
|
||||
CCtxParams->inBufferMode = (ZSTD_bufferMode_e)value;
|
||||
return CCtxParams->inBufferMode;
|
||||
|
||||
case ZSTD_c_stableOutBuffer:
|
||||
BOUNDCHECK(ZSTD_c_stableOutBuffer, value);
|
||||
CCtxParams->outBufferMode = (ZSTD_bufferMode_e)value;
|
||||
return CCtxParams->outBufferMode;
|
||||
|
||||
case ZSTD_c_blockDelimiters:
|
||||
BOUNDCHECK(ZSTD_c_blockDelimiters, value);
|
||||
CCtxParams->blockDelimiters = (ZSTD_SequenceFormat_e)value;
|
||||
return CCtxParams->blockDelimiters;
|
||||
|
||||
case ZSTD_c_validateSequences:
|
||||
BOUNDCHECK(ZSTD_c_validateSequences, value);
|
||||
CCtxParams->validateSequences = value;
|
||||
return (size_t)CCtxParams->validateSequences;
|
||||
|
||||
case ZSTD_c_splitAfterSequences:
|
||||
BOUNDCHECK(ZSTD_c_splitAfterSequences, value);
|
||||
CCtxParams->postBlockSplitter = (ZSTD_ParamSwitch_e)value;
|
||||
return CCtxParams->postBlockSplitter;
|
||||
|
||||
case ZSTD_c_blockSplitterLevel:
|
||||
BOUNDCHECK(ZSTD_c_blockSplitterLevel, value);
|
||||
CCtxParams->preBlockSplitter_level = value;
|
||||
return (size_t)CCtxParams->preBlockSplitter_level;
|
||||
|
||||
case ZSTD_c_useRowMatchFinder:
|
||||
BOUNDCHECK(ZSTD_c_useRowMatchFinder, value);
|
||||
CCtxParams->useRowMatchFinder = (ZSTD_ParamSwitch_e)value;
|
||||
return CCtxParams->useRowMatchFinder;
|
||||
|
||||
case ZSTD_c_deterministicRefPrefix:
|
||||
BOUNDCHECK(ZSTD_c_deterministicRefPrefix, value);
|
||||
CCtxParams->deterministicRefPrefix = !!value;
|
||||
return (size_t)CCtxParams->deterministicRefPrefix;
|
||||
|
||||
case ZSTD_c_prefetchCDictTables:
|
||||
BOUNDCHECK(ZSTD_c_prefetchCDictTables, value);
|
||||
CCtxParams->prefetchCDictTables = (ZSTD_ParamSwitch_e)value;
|
||||
return CCtxParams->prefetchCDictTables;
|
||||
|
||||
case ZSTD_c_enableSeqProducerFallback:
|
||||
BOUNDCHECK(ZSTD_c_enableSeqProducerFallback, value);
|
||||
CCtxParams->enableMatchFinderFallback = value;
|
||||
return (size_t)CCtxParams->enableMatchFinderFallback;
|
||||
|
||||
case ZSTD_c_maxBlockSize:
|
||||
if (value!=0) /* 0 ==> default */
|
||||
BOUNDCHECK(ZSTD_c_maxBlockSize, value);
|
||||
assert(value>=0);
|
||||
CCtxParams->maxBlockSize = (size_t)value;
|
||||
return CCtxParams->maxBlockSize;
|
||||
|
||||
case ZSTD_c_repcodeResolution:
|
||||
BOUNDCHECK(ZSTD_c_repcodeResolution, value);
|
||||
CCtxParams->searchForExternalRepcodes = (ZSTD_ParamSwitch_e)value;
|
||||
return CCtxParams->searchForExternalRepcodes;
|
||||
|
||||
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
|
||||
}
|
||||
}
|
||||
|
||||
size_t ZSTD_CCtx_getParameter(ZSTD_CCtx const* cctx, ZSTD_cParameter param, int* value)
|
||||
{
|
||||
return ZSTD_CCtxParams_getParameter(&cctx->requestedParams, param, value);
|
||||
}
|
||||
|
||||
size_t ZSTD_CCtxParams_getParameter(
|
||||
ZSTD_CCtx_params const* CCtxParams, ZSTD_cParameter param, int* value)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case ZSTD_c_format :
|
||||
*value = (int)CCtxParams->format;
|
||||
break;
|
||||
case ZSTD_c_compressionLevel :
|
||||
*value = CCtxParams->compressionLevel;
|
||||
break;
|
||||
case ZSTD_c_windowLog :
|
||||
*value = (int)CCtxParams->cParams.windowLog;
|
||||
break;
|
||||
case ZSTD_c_hashLog :
|
||||
*value = (int)CCtxParams->cParams.hashLog;
|
||||
break;
|
||||
case ZSTD_c_chainLog :
|
||||
*value = (int)CCtxParams->cParams.chainLog;
|
||||
break;
|
||||
case ZSTD_c_searchLog :
|
||||
*value = (int)CCtxParams->cParams.searchLog;
|
||||
break;
|
||||
case ZSTD_c_minMatch :
|
||||
*value = (int)CCtxParams->cParams.minMatch;
|
||||
break;
|
||||
case ZSTD_c_targetLength :
|
||||
*value = (int)CCtxParams->cParams.targetLength;
|
||||
break;
|
||||
case ZSTD_c_strategy :
|
||||
*value = (int)CCtxParams->cParams.strategy;
|
||||
break;
|
||||
case ZSTD_c_contentSizeFlag :
|
||||
*value = CCtxParams->fParams.contentSizeFlag;
|
||||
break;
|
||||
case ZSTD_c_checksumFlag :
|
||||
*value = CCtxParams->fParams.checksumFlag;
|
||||
break;
|
||||
case ZSTD_c_dictIDFlag :
|
||||
*value = !CCtxParams->fParams.noDictIDFlag;
|
||||
break;
|
||||
case ZSTD_c_forceMaxWindow :
|
||||
*value = CCtxParams->forceWindow;
|
||||
break;
|
||||
case ZSTD_c_forceAttachDict :
|
||||
*value = (int)CCtxParams->attachDictPref;
|
||||
break;
|
||||
case ZSTD_c_literalCompressionMode :
|
||||
*value = (int)CCtxParams->literalCompressionMode;
|
||||
break;
|
||||
case ZSTD_c_nbWorkers :
|
||||
#ifndef ZSTD_MULTITHREAD
|
||||
assert(CCtxParams->nbWorkers == 0);
|
||||
#endif
|
||||
*value = CCtxParams->nbWorkers;
|
||||
break;
|
||||
case ZSTD_c_jobSize :
|
||||
#ifndef ZSTD_MULTITHREAD
|
||||
RETURN_ERROR(parameter_unsupported, "not compiled with multithreading");
|
||||
#else
|
||||
assert(CCtxParams->jobSize <= INT_MAX);
|
||||
*value = (int)CCtxParams->jobSize;
|
||||
break;
|
||||
#endif
|
||||
case ZSTD_c_overlapLog :
|
||||
#ifndef ZSTD_MULTITHREAD
|
||||
RETURN_ERROR(parameter_unsupported, "not compiled with multithreading");
|
||||
#else
|
||||
*value = CCtxParams->overlapLog;
|
||||
break;
|
||||
#endif
|
||||
case ZSTD_c_rsyncable :
|
||||
#ifndef ZSTD_MULTITHREAD
|
||||
RETURN_ERROR(parameter_unsupported, "not compiled with multithreading");
|
||||
#else
|
||||
*value = CCtxParams->rsyncable;
|
||||
break;
|
||||
#endif
|
||||
case ZSTD_c_enableDedicatedDictSearch :
|
||||
*value = CCtxParams->enableDedicatedDictSearch;
|
||||
break;
|
||||
case ZSTD_c_enableLongDistanceMatching :
|
||||
*value = (int)CCtxParams->ldmParams.enableLdm;
|
||||
break;
|
||||
case ZSTD_c_ldmHashLog :
|
||||
*value = (int)CCtxParams->ldmParams.hashLog;
|
||||
break;
|
||||
case ZSTD_c_ldmMinMatch :
|
||||
*value = (int)CCtxParams->ldmParams.minMatchLength;
|
||||
break;
|
||||
case ZSTD_c_ldmBucketSizeLog :
|
||||
*value = (int)CCtxParams->ldmParams.bucketSizeLog;
|
||||
break;
|
||||
case ZSTD_c_ldmHashRateLog :
|
||||
*value = (int)CCtxParams->ldmParams.hashRateLog;
|
||||
break;
|
||||
case ZSTD_c_targetCBlockSize :
|
||||
*value = (int)CCtxParams->targetCBlockSize;
|
||||
break;
|
||||
case ZSTD_c_srcSizeHint :
|
||||
*value = (int)CCtxParams->srcSizeHint;
|
||||
break;
|
||||
case ZSTD_c_stableInBuffer :
|
||||
*value = (int)CCtxParams->inBufferMode;
|
||||
break;
|
||||
case ZSTD_c_stableOutBuffer :
|
||||
*value = (int)CCtxParams->outBufferMode;
|
||||
break;
|
||||
case ZSTD_c_blockDelimiters :
|
||||
*value = (int)CCtxParams->blockDelimiters;
|
||||
break;
|
||||
case ZSTD_c_validateSequences :
|
||||
*value = (int)CCtxParams->validateSequences;
|
||||
break;
|
||||
case ZSTD_c_splitAfterSequences :
|
||||
*value = (int)CCtxParams->postBlockSplitter;
|
||||
break;
|
||||
case ZSTD_c_blockSplitterLevel :
|
||||
*value = CCtxParams->preBlockSplitter_level;
|
||||
break;
|
||||
case ZSTD_c_useRowMatchFinder :
|
||||
*value = (int)CCtxParams->useRowMatchFinder;
|
||||
break;
|
||||
case ZSTD_c_deterministicRefPrefix:
|
||||
*value = (int)CCtxParams->deterministicRefPrefix;
|
||||
break;
|
||||
case ZSTD_c_prefetchCDictTables:
|
||||
*value = (int)CCtxParams->prefetchCDictTables;
|
||||
break;
|
||||
case ZSTD_c_enableSeqProducerFallback:
|
||||
*value = CCtxParams->enableMatchFinderFallback;
|
||||
break;
|
||||
case ZSTD_c_maxBlockSize:
|
||||
*value = (int)CCtxParams->maxBlockSize;
|
||||
break;
|
||||
case ZSTD_c_repcodeResolution:
|
||||
*value = (int)CCtxParams->searchForExternalRepcodes;
|
||||
break;
|
||||
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** ZSTD_CCtx_setParametersUsingCCtxParams() :
|
||||
* just applies `params` into `cctx`
|
||||
* no action is performed, parameters are merely stored.
|
||||
@@ -7053,18 +6749,3 @@ void ZSTD_registerSequenceProducer(
|
||||
&zc->requestedParams, extSeqProdState, extSeqProdFunc
|
||||
);
|
||||
}
|
||||
|
||||
void ZSTD_CCtxParams_registerSequenceProducer(
|
||||
ZSTD_CCtx_params* params,
|
||||
void* extSeqProdState,
|
||||
ZSTD_sequenceProducer_F extSeqProdFunc)
|
||||
{
|
||||
assert(params != NULL);
|
||||
if (extSeqProdFunc != NULL) {
|
||||
params->extSeqProdFunc = extSeqProdFunc;
|
||||
params->extSeqProdState = extSeqProdState;
|
||||
} else {
|
||||
params->extSeqProdFunc = NULL;
|
||||
params->extSeqProdState = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ pub mod zstd_compress_literals;
|
||||
#[cfg(feature = "compression")]
|
||||
pub mod zstd_compress_params;
|
||||
#[cfg(feature = "compression")]
|
||||
pub mod zstd_compress_params_api;
|
||||
#[cfg(feature = "compression")]
|
||||
pub mod zstd_compress_sequences;
|
||||
#[cfg(feature = "compression")]
|
||||
pub mod zstd_compress_stats;
|
||||
|
||||
@@ -0,0 +1,1000 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
|
||||
//! Rust implementation of the narrow `ZSTD_CCtx_params` object API.
|
||||
//!
|
||||
//! Allocation, advanced initialization, bounds calculation, and context
|
||||
//! policy remain in `zstd_compress.c`. This module owns only the object
|
||||
//! reset/initialization, parameter set/get, and sequence-producer registration
|
||||
//! entry points.
|
||||
|
||||
use crate::errors::{ZstdErrorCode, ERROR};
|
||||
#[cfg(test)]
|
||||
use crate::zstd_compress_params::ZSTD_bounds;
|
||||
use crate::zstd_compress_params::{ZSTD_compressionParameters, ZSTD_frameParameters};
|
||||
use std::mem::size_of;
|
||||
use std::os::raw::{c_int, c_void};
|
||||
use std::ptr;
|
||||
|
||||
type ZstdAllocFunction = unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void;
|
||||
type ZstdFreeFunction = unsafe extern "C" fn(*mut c_void, *mut c_void);
|
||||
|
||||
/// ABI-compatible representation of `ZSTD_customMem`.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct ZSTD_customMem {
|
||||
customAlloc: Option<ZstdAllocFunction>,
|
||||
customFree: Option<ZstdFreeFunction>,
|
||||
opaque: *mut c_void,
|
||||
}
|
||||
|
||||
/// ABI-compatible private LDM parameter object.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
struct ldmParams_t {
|
||||
enableLdm: c_int,
|
||||
hashLog: u32,
|
||||
bucketSizeLog: u32,
|
||||
minMatchLength: u32,
|
||||
hashRateLog: u32,
|
||||
windowLog: u32,
|
||||
}
|
||||
|
||||
/// ABI-compatible callback parameter type from `zstd.h`.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct ZSTD_Sequence {
|
||||
offset: u32,
|
||||
litLength: u32,
|
||||
matchLength: u32,
|
||||
rep: u32,
|
||||
}
|
||||
|
||||
pub type ZSTD_sequenceProducer_F = unsafe extern "C" fn(
|
||||
sequenceProducerState: *mut c_void,
|
||||
outSeqs: *mut ZSTD_Sequence,
|
||||
outSeqsCapacity: usize,
|
||||
src: *const c_void,
|
||||
srcSize: usize,
|
||||
dict: *const c_void,
|
||||
dictSize: usize,
|
||||
compressionLevel: c_int,
|
||||
windowSize: usize,
|
||||
) -> usize;
|
||||
|
||||
/// Layout mirror for `struct ZSTD_CCtx_params_s`.
|
||||
///
|
||||
/// The type is public only because exported Rust ABI functions cannot expose
|
||||
/// a private type. Its fields and all helper types remain private to this
|
||||
/// module; C remains the owner of the actual parameter object contract.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ZSTD_CCtx_params {
|
||||
format: c_int,
|
||||
cParams: ZSTD_compressionParameters,
|
||||
fParams: ZSTD_frameParameters,
|
||||
|
||||
compressionLevel: c_int,
|
||||
forceWindow: c_int,
|
||||
targetCBlockSize: usize,
|
||||
srcSizeHint: c_int,
|
||||
|
||||
attachDictPref: c_int,
|
||||
literalCompressionMode: c_int,
|
||||
|
||||
nbWorkers: c_int,
|
||||
jobSize: usize,
|
||||
overlapLog: c_int,
|
||||
rsyncable: c_int,
|
||||
|
||||
ldmParams: ldmParams_t,
|
||||
|
||||
enableDedicatedDictSearch: c_int,
|
||||
|
||||
inBufferMode: c_int,
|
||||
outBufferMode: c_int,
|
||||
|
||||
blockDelimiters: c_int,
|
||||
validateSequences: c_int,
|
||||
|
||||
postBlockSplitter: c_int,
|
||||
preBlockSplitter_level: c_int,
|
||||
|
||||
maxBlockSize: usize,
|
||||
|
||||
useRowMatchFinder: c_int,
|
||||
deterministicRefPrefix: c_int,
|
||||
|
||||
customMem: ZSTD_customMem,
|
||||
|
||||
prefetchCDictTables: c_int,
|
||||
enableMatchFinderFallback: c_int,
|
||||
|
||||
extSeqProdState: *mut c_void,
|
||||
extSeqProdFunc: Option<ZSTD_sequenceProducer_F>,
|
||||
|
||||
searchForExternalRepcodes: c_int,
|
||||
}
|
||||
|
||||
const DEFAULT_CLEVEL: c_int = 3;
|
||||
#[cfg(test)]
|
||||
const PS_AUTO: c_int = 0;
|
||||
#[cfg(test)]
|
||||
const PS_DISABLE: c_int = 2;
|
||||
|
||||
#[cfg(test)]
|
||||
const BLOCKSIZE_MAX: usize = 1 << 17;
|
||||
#[cfg(test)]
|
||||
const BLOCKSIZE_MAX_MIN: c_int = 1 << 10;
|
||||
const TARGET_C_BLOCK_SIZE_MIN: c_int = 1340;
|
||||
|
||||
const C_COMPRESSION_LEVEL: c_int = 100;
|
||||
const C_WINDOW_LOG: c_int = 101;
|
||||
const C_HASH_LOG: c_int = 102;
|
||||
const C_CHAIN_LOG: c_int = 103;
|
||||
const C_SEARCH_LOG: c_int = 104;
|
||||
const C_MIN_MATCH: c_int = 105;
|
||||
const C_TARGET_LENGTH: c_int = 106;
|
||||
const C_STRATEGY: c_int = 107;
|
||||
const C_TARGET_C_BLOCK_SIZE: c_int = 130;
|
||||
const C_ENABLE_LDM: c_int = 160;
|
||||
const C_LDM_HASH_LOG: c_int = 161;
|
||||
const C_LDM_MIN_MATCH: c_int = 162;
|
||||
const C_LDM_BUCKET_SIZE_LOG: c_int = 163;
|
||||
const C_LDM_HASH_RATE_LOG: c_int = 164;
|
||||
const C_CONTENT_SIZE_FLAG: c_int = 200;
|
||||
const C_CHECKSUM_FLAG: c_int = 201;
|
||||
const C_DICT_ID_FLAG: c_int = 202;
|
||||
const C_NB_WORKERS: c_int = 400;
|
||||
const C_JOB_SIZE: c_int = 401;
|
||||
const C_OVERLAP_LOG: c_int = 402;
|
||||
|
||||
const C_RSYNCABLE: c_int = 500;
|
||||
const C_FORMAT: c_int = 10;
|
||||
const C_FORCE_MAX_WINDOW: c_int = 1000;
|
||||
const C_FORCE_ATTACH_DICT: c_int = 1001;
|
||||
const C_LITERAL_COMPRESSION_MODE: c_int = 1002;
|
||||
const C_SRC_SIZE_HINT: c_int = 1004;
|
||||
const C_ENABLE_DEDICATED_DICT_SEARCH: c_int = 1005;
|
||||
const C_STABLE_IN_BUFFER: c_int = 1006;
|
||||
const C_STABLE_OUT_BUFFER: c_int = 1007;
|
||||
const C_BLOCK_DELIMITERS: c_int = 1008;
|
||||
const C_VALIDATE_SEQUENCES: c_int = 1009;
|
||||
const C_SPLIT_AFTER_SEQUENCES: c_int = 1010;
|
||||
const C_USE_ROW_MATCH_FINDER: c_int = 1011;
|
||||
const C_DETERMINISTIC_REF_PREFIX: c_int = 1012;
|
||||
const C_PREFETCH_CDICT_TABLES: c_int = 1013;
|
||||
const C_ENABLE_SEQ_PRODUCER_FALLBACK: c_int = 1014;
|
||||
const C_MAX_BLOCK_SIZE: c_int = 1015;
|
||||
const C_REPCODE_RESOLUTION: c_int = 1016;
|
||||
const C_BLOCK_SPLITTER_LEVEL: c_int = 1017;
|
||||
|
||||
#[cfg(not(test))]
|
||||
unsafe extern "C" {
|
||||
fn ZSTD_rust_cctx_params_clamp_bounds(param: c_int, value: *mut c_int) -> usize;
|
||||
fn ZSTD_rust_cctx_params_within_bounds(param: c_int, value: c_int) -> c_int;
|
||||
fn ZSTD_rust_cctx_params_is_multithreaded() -> c_int;
|
||||
fn ZSTD_rust_cctx_params_job_size_min() -> c_int;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn fallback_bounds(param: c_int) -> ZSTD_bounds {
|
||||
let (lower, upper) = match param {
|
||||
C_COMPRESSION_LEVEL | C_WINDOW_LOG | C_HASH_LOG | C_CHAIN_LOG | C_SEARCH_LOG
|
||||
| C_MIN_MATCH | C_TARGET_LENGTH | C_STRATEGY => {
|
||||
return crate::zstd_compress_params::ZSTD_rust_params_getBounds(param)
|
||||
}
|
||||
C_FORMAT => (0, 1),
|
||||
C_FORCE_ATTACH_DICT => (0, 3),
|
||||
C_LITERAL_COMPRESSION_MODE => (0, 2),
|
||||
C_CONTENT_SIZE_FLAG | C_CHECKSUM_FLAG | C_DICT_ID_FLAG => (0, 1),
|
||||
C_NB_WORKERS | C_JOB_SIZE | C_OVERLAP_LOG => (0, 0),
|
||||
C_ENABLE_DEDICATED_DICT_SEARCH => (0, 1),
|
||||
C_ENABLE_LDM
|
||||
| C_SPLIT_AFTER_SEQUENCES
|
||||
| C_USE_ROW_MATCH_FINDER
|
||||
| C_PREFETCH_CDICT_TABLES
|
||||
| C_REPCODE_RESOLUTION => (PS_AUTO, PS_DISABLE),
|
||||
C_LDM_HASH_LOG => (6, 30),
|
||||
C_LDM_MIN_MATCH => (4, 4096),
|
||||
C_LDM_BUCKET_SIZE_LOG => (1, 8),
|
||||
C_LDM_HASH_RATE_LOG => (0, if size_of::<usize>() == 4 { 24 } else { 25 }),
|
||||
C_RSYNCABLE
|
||||
| C_FORCE_MAX_WINDOW
|
||||
| C_VALIDATE_SEQUENCES
|
||||
| C_DETERMINISTIC_REF_PREFIX
|
||||
| C_ENABLE_SEQ_PRODUCER_FALLBACK => (0, 1),
|
||||
C_TARGET_C_BLOCK_SIZE => (TARGET_C_BLOCK_SIZE_MIN, BLOCKSIZE_MAX as c_int),
|
||||
C_SRC_SIZE_HINT => (0, c_int::MAX),
|
||||
C_STABLE_IN_BUFFER | C_STABLE_OUT_BUFFER | C_BLOCK_DELIMITERS => (0, 1),
|
||||
C_BLOCK_SPLITTER_LEVEL => (0, 6),
|
||||
C_MAX_BLOCK_SIZE => (BLOCKSIZE_MAX_MIN, BLOCKSIZE_MAX as c_int),
|
||||
_ => {
|
||||
return ZSTD_bounds {
|
||||
error: ERROR(ZstdErrorCode::ParameterUnsupported),
|
||||
lowerBound: 0,
|
||||
upperBound: 0,
|
||||
};
|
||||
}
|
||||
};
|
||||
ZSTD_bounds {
|
||||
error: 0,
|
||||
lowerBound: lower,
|
||||
upperBound: upper,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn within_bounds(param: c_int, value: c_int) -> bool {
|
||||
#[cfg(not(test))]
|
||||
{
|
||||
unsafe { ZSTD_rust_cctx_params_within_bounds(param, value) != 0 }
|
||||
}
|
||||
#[cfg(test)]
|
||||
{
|
||||
let bounds = fallback_bounds(param);
|
||||
bounds.error == 0 && value >= bounds.lowerBound && value <= bounds.upperBound
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn clamp_bounds(param: c_int, value: &mut c_int) -> usize {
|
||||
#[cfg(not(test))]
|
||||
{
|
||||
unsafe { ZSTD_rust_cctx_params_clamp_bounds(param, value) }
|
||||
}
|
||||
#[cfg(test)]
|
||||
{
|
||||
let bounds = fallback_bounds(param);
|
||||
if bounds.error != 0 {
|
||||
return bounds.error;
|
||||
}
|
||||
*value = (*value).clamp(bounds.lowerBound, bounds.upperBound);
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn multithreading_enabled() -> bool {
|
||||
#[cfg(not(test))]
|
||||
{
|
||||
unsafe { ZSTD_rust_cctx_params_is_multithreaded() != 0 }
|
||||
}
|
||||
#[cfg(test)]
|
||||
{
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn job_size_min() -> c_int {
|
||||
#[cfg(not(test))]
|
||||
{
|
||||
unsafe { ZSTD_rust_cctx_params_job_size_min() }
|
||||
}
|
||||
#[cfg(test)]
|
||||
{
|
||||
512 << 10
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn require_bounds(param: c_int, value: c_int) -> Result<(), usize> {
|
||||
if unsafe { within_bounds(param, value) } {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ERROR(ZstdErrorCode::ParameterOutOfBound))
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn init_impl(params: *mut ZSTD_CCtx_params, compression_level: c_int) -> usize {
|
||||
if params.is_null() {
|
||||
return ERROR(ZstdErrorCode::Generic);
|
||||
}
|
||||
unsafe {
|
||||
ptr::write_bytes(params.cast::<u8>(), 0, size_of::<ZSTD_CCtx_params>());
|
||||
(*params).compressionLevel = compression_level;
|
||||
(*params).fParams.contentSizeFlag = 1;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ZSTD_CCtxParams_reset(params: *mut ZSTD_CCtx_params) -> usize {
|
||||
unsafe { init_impl(params, DEFAULT_CLEVEL) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ZSTD_CCtxParams_init(
|
||||
params: *mut ZSTD_CCtx_params,
|
||||
compression_level: c_int,
|
||||
) -> usize {
|
||||
unsafe { init_impl(params, compression_level) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_parameter(params: *mut ZSTD_CCtx_params, param: c_int, mut value: c_int) -> usize {
|
||||
let params = unsafe { &mut *params };
|
||||
match param {
|
||||
C_FORMAT => {
|
||||
if let Err(error) = unsafe { require_bounds(C_FORMAT, value) } {
|
||||
return error;
|
||||
}
|
||||
params.format = value;
|
||||
value as usize
|
||||
}
|
||||
C_COMPRESSION_LEVEL => {
|
||||
let error = unsafe { clamp_bounds(C_COMPRESSION_LEVEL, &mut value) };
|
||||
if error != 0 {
|
||||
return error;
|
||||
}
|
||||
params.compressionLevel = if value == 0 { DEFAULT_CLEVEL } else { value };
|
||||
if params.compressionLevel >= 0 {
|
||||
params.compressionLevel as usize
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
C_WINDOW_LOG => {
|
||||
if value != 0 {
|
||||
if let Err(error) = unsafe { require_bounds(C_WINDOW_LOG, value) } {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
params.cParams.windowLog = value as u32;
|
||||
params.cParams.windowLog as usize
|
||||
}
|
||||
C_HASH_LOG => {
|
||||
if value != 0 {
|
||||
if let Err(error) = unsafe { require_bounds(C_HASH_LOG, value) } {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
params.cParams.hashLog = value as u32;
|
||||
params.cParams.hashLog as usize
|
||||
}
|
||||
C_CHAIN_LOG => {
|
||||
if value != 0 {
|
||||
if let Err(error) = unsafe { require_bounds(C_CHAIN_LOG, value) } {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
params.cParams.chainLog = value as u32;
|
||||
params.cParams.chainLog as usize
|
||||
}
|
||||
C_SEARCH_LOG => {
|
||||
if value != 0 {
|
||||
if let Err(error) = unsafe { require_bounds(C_SEARCH_LOG, value) } {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
params.cParams.searchLog = value as u32;
|
||||
value as usize
|
||||
}
|
||||
C_MIN_MATCH => {
|
||||
if value != 0 {
|
||||
if let Err(error) = unsafe { require_bounds(C_MIN_MATCH, value) } {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
params.cParams.minMatch = value as u32;
|
||||
params.cParams.minMatch as usize
|
||||
}
|
||||
C_TARGET_LENGTH => {
|
||||
if let Err(error) = unsafe { require_bounds(C_TARGET_LENGTH, value) } {
|
||||
return error;
|
||||
}
|
||||
params.cParams.targetLength = value as u32;
|
||||
params.cParams.targetLength as usize
|
||||
}
|
||||
C_STRATEGY => {
|
||||
if value != 0 {
|
||||
if let Err(error) = unsafe { require_bounds(C_STRATEGY, value) } {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
params.cParams.strategy = value;
|
||||
value as usize
|
||||
}
|
||||
C_CONTENT_SIZE_FLAG => {
|
||||
params.fParams.contentSizeFlag = (value != 0) as c_int;
|
||||
params.fParams.contentSizeFlag as usize
|
||||
}
|
||||
C_CHECKSUM_FLAG => {
|
||||
params.fParams.checksumFlag = (value != 0) as c_int;
|
||||
params.fParams.checksumFlag as usize
|
||||
}
|
||||
C_DICT_ID_FLAG => {
|
||||
params.fParams.noDictIDFlag = (value == 0) as c_int;
|
||||
(params.fParams.noDictIDFlag == 0) as usize
|
||||
}
|
||||
C_FORCE_MAX_WINDOW => {
|
||||
params.forceWindow = (value != 0) as c_int;
|
||||
params.forceWindow as usize
|
||||
}
|
||||
C_FORCE_ATTACH_DICT => {
|
||||
if let Err(error) = unsafe { require_bounds(C_FORCE_ATTACH_DICT, value) } {
|
||||
return error;
|
||||
}
|
||||
params.attachDictPref = value;
|
||||
value as usize
|
||||
}
|
||||
C_LITERAL_COMPRESSION_MODE => {
|
||||
if let Err(error) = unsafe { require_bounds(C_LITERAL_COMPRESSION_MODE, value) } {
|
||||
return error;
|
||||
}
|
||||
params.literalCompressionMode = value;
|
||||
value as usize
|
||||
}
|
||||
C_NB_WORKERS => {
|
||||
if !unsafe { multithreading_enabled() } {
|
||||
if value != 0 {
|
||||
return ERROR(ZstdErrorCode::ParameterUnsupported);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
let error = unsafe { clamp_bounds(C_NB_WORKERS, &mut value) };
|
||||
if error != 0 {
|
||||
return error;
|
||||
}
|
||||
params.nbWorkers = value;
|
||||
params.nbWorkers as usize
|
||||
}
|
||||
C_JOB_SIZE => {
|
||||
if !unsafe { multithreading_enabled() } {
|
||||
if value != 0 {
|
||||
return ERROR(ZstdErrorCode::ParameterUnsupported);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
let minimum = unsafe { job_size_min() };
|
||||
if value != 0 && value < minimum {
|
||||
value = minimum;
|
||||
}
|
||||
let error = unsafe { clamp_bounds(C_JOB_SIZE, &mut value) };
|
||||
if error != 0 {
|
||||
return error;
|
||||
}
|
||||
params.jobSize = value as usize;
|
||||
params.jobSize
|
||||
}
|
||||
C_OVERLAP_LOG => {
|
||||
if !unsafe { multithreading_enabled() } {
|
||||
if value != 0 {
|
||||
return ERROR(ZstdErrorCode::ParameterUnsupported);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
let error = unsafe { clamp_bounds(C_OVERLAP_LOG, &mut value) };
|
||||
if error != 0 {
|
||||
return error;
|
||||
}
|
||||
params.overlapLog = value;
|
||||
params.overlapLog as usize
|
||||
}
|
||||
C_RSYNCABLE => {
|
||||
if !unsafe { multithreading_enabled() } {
|
||||
if value != 0 {
|
||||
return ERROR(ZstdErrorCode::ParameterUnsupported);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* The C implementation intentionally clamps this with overlapLog. */
|
||||
let error = unsafe { clamp_bounds(C_OVERLAP_LOG, &mut value) };
|
||||
if error != 0 {
|
||||
return error;
|
||||
}
|
||||
params.rsyncable = value;
|
||||
params.rsyncable as usize
|
||||
}
|
||||
C_ENABLE_DEDICATED_DICT_SEARCH => {
|
||||
params.enableDedicatedDictSearch = (value != 0) as c_int;
|
||||
params.enableDedicatedDictSearch as usize
|
||||
}
|
||||
C_ENABLE_LDM => {
|
||||
if let Err(error) = unsafe { require_bounds(C_ENABLE_LDM, value) } {
|
||||
return error;
|
||||
}
|
||||
params.ldmParams.enableLdm = value;
|
||||
value as usize
|
||||
}
|
||||
C_LDM_HASH_LOG => {
|
||||
if value != 0 {
|
||||
if let Err(error) = unsafe { require_bounds(C_LDM_HASH_LOG, value) } {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
params.ldmParams.hashLog = value as u32;
|
||||
params.ldmParams.hashLog as usize
|
||||
}
|
||||
C_LDM_MIN_MATCH => {
|
||||
if value != 0 {
|
||||
if let Err(error) = unsafe { require_bounds(C_LDM_MIN_MATCH, value) } {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
params.ldmParams.minMatchLength = value as u32;
|
||||
params.ldmParams.minMatchLength as usize
|
||||
}
|
||||
C_LDM_BUCKET_SIZE_LOG => {
|
||||
if value != 0 {
|
||||
if let Err(error) = unsafe { require_bounds(C_LDM_BUCKET_SIZE_LOG, value) } {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
params.ldmParams.bucketSizeLog = value as u32;
|
||||
params.ldmParams.bucketSizeLog as usize
|
||||
}
|
||||
C_LDM_HASH_RATE_LOG => {
|
||||
if value != 0 {
|
||||
if let Err(error) = unsafe { require_bounds(C_LDM_HASH_RATE_LOG, value) } {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
params.ldmParams.hashRateLog = value as u32;
|
||||
params.ldmParams.hashRateLog as usize
|
||||
}
|
||||
C_TARGET_C_BLOCK_SIZE => {
|
||||
if value != 0 {
|
||||
value = value.max(TARGET_C_BLOCK_SIZE_MIN);
|
||||
if let Err(error) = unsafe { require_bounds(C_TARGET_C_BLOCK_SIZE, value) } {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
params.targetCBlockSize = value as u32 as usize;
|
||||
params.targetCBlockSize
|
||||
}
|
||||
C_SRC_SIZE_HINT => {
|
||||
if value != 0 {
|
||||
if let Err(error) = unsafe { require_bounds(C_SRC_SIZE_HINT, value) } {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
params.srcSizeHint = value;
|
||||
params.srcSizeHint as usize
|
||||
}
|
||||
C_STABLE_IN_BUFFER => {
|
||||
if let Err(error) = unsafe { require_bounds(C_STABLE_IN_BUFFER, value) } {
|
||||
return error;
|
||||
}
|
||||
params.inBufferMode = value;
|
||||
value as usize
|
||||
}
|
||||
C_STABLE_OUT_BUFFER => {
|
||||
if let Err(error) = unsafe { require_bounds(C_STABLE_OUT_BUFFER, value) } {
|
||||
return error;
|
||||
}
|
||||
params.outBufferMode = value;
|
||||
value as usize
|
||||
}
|
||||
C_BLOCK_DELIMITERS => {
|
||||
if let Err(error) = unsafe { require_bounds(C_BLOCK_DELIMITERS, value) } {
|
||||
return error;
|
||||
}
|
||||
params.blockDelimiters = value;
|
||||
value as usize
|
||||
}
|
||||
C_VALIDATE_SEQUENCES => {
|
||||
if let Err(error) = unsafe { require_bounds(C_VALIDATE_SEQUENCES, value) } {
|
||||
return error;
|
||||
}
|
||||
params.validateSequences = value;
|
||||
value as usize
|
||||
}
|
||||
C_SPLIT_AFTER_SEQUENCES => {
|
||||
if let Err(error) = unsafe { require_bounds(C_SPLIT_AFTER_SEQUENCES, value) } {
|
||||
return error;
|
||||
}
|
||||
params.postBlockSplitter = value;
|
||||
value as usize
|
||||
}
|
||||
C_BLOCK_SPLITTER_LEVEL => {
|
||||
if let Err(error) = unsafe { require_bounds(C_BLOCK_SPLITTER_LEVEL, value) } {
|
||||
return error;
|
||||
}
|
||||
params.preBlockSplitter_level = value;
|
||||
value as usize
|
||||
}
|
||||
C_USE_ROW_MATCH_FINDER => {
|
||||
if let Err(error) = unsafe { require_bounds(C_USE_ROW_MATCH_FINDER, value) } {
|
||||
return error;
|
||||
}
|
||||
params.useRowMatchFinder = value;
|
||||
value as usize
|
||||
}
|
||||
C_DETERMINISTIC_REF_PREFIX => {
|
||||
if let Err(error) = unsafe { require_bounds(C_DETERMINISTIC_REF_PREFIX, value) } {
|
||||
return error;
|
||||
}
|
||||
params.deterministicRefPrefix = (value != 0) as c_int;
|
||||
params.deterministicRefPrefix as usize
|
||||
}
|
||||
C_PREFETCH_CDICT_TABLES => {
|
||||
if let Err(error) = unsafe { require_bounds(C_PREFETCH_CDICT_TABLES, value) } {
|
||||
return error;
|
||||
}
|
||||
params.prefetchCDictTables = value;
|
||||
value as usize
|
||||
}
|
||||
C_ENABLE_SEQ_PRODUCER_FALLBACK => {
|
||||
if let Err(error) = unsafe { require_bounds(C_ENABLE_SEQ_PRODUCER_FALLBACK, value) } {
|
||||
return error;
|
||||
}
|
||||
params.enableMatchFinderFallback = value;
|
||||
value as usize
|
||||
}
|
||||
C_MAX_BLOCK_SIZE => {
|
||||
if value != 0 {
|
||||
if let Err(error) = unsafe { require_bounds(C_MAX_BLOCK_SIZE, value) } {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
params.maxBlockSize = value as usize;
|
||||
params.maxBlockSize
|
||||
}
|
||||
C_REPCODE_RESOLUTION => {
|
||||
if let Err(error) = unsafe { require_bounds(C_REPCODE_RESOLUTION, value) } {
|
||||
return error;
|
||||
}
|
||||
params.searchForExternalRepcodes = value;
|
||||
value as usize
|
||||
}
|
||||
_ => ERROR(ZstdErrorCode::ParameterUnsupported),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ZSTD_CCtxParams_setParameter(
|
||||
params: *mut ZSTD_CCtx_params,
|
||||
param: c_int,
|
||||
value: c_int,
|
||||
) -> usize {
|
||||
unsafe { set_parameter(params, param, value) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ZSTD_CCtxParams_getParameter(
|
||||
params: *const ZSTD_CCtx_params,
|
||||
param: c_int,
|
||||
value: *mut c_int,
|
||||
) -> usize {
|
||||
let params = unsafe { &*params };
|
||||
let result = match param {
|
||||
C_FORMAT => params.format,
|
||||
C_COMPRESSION_LEVEL => params.compressionLevel,
|
||||
C_WINDOW_LOG => params.cParams.windowLog as c_int,
|
||||
C_HASH_LOG => params.cParams.hashLog as c_int,
|
||||
C_CHAIN_LOG => params.cParams.chainLog as c_int,
|
||||
C_SEARCH_LOG => params.cParams.searchLog as c_int,
|
||||
C_MIN_MATCH => params.cParams.minMatch as c_int,
|
||||
C_TARGET_LENGTH => params.cParams.targetLength as c_int,
|
||||
C_STRATEGY => params.cParams.strategy,
|
||||
C_CONTENT_SIZE_FLAG => params.fParams.contentSizeFlag,
|
||||
C_CHECKSUM_FLAG => params.fParams.checksumFlag,
|
||||
C_DICT_ID_FLAG => (params.fParams.noDictIDFlag == 0) as c_int,
|
||||
C_FORCE_MAX_WINDOW => params.forceWindow,
|
||||
C_FORCE_ATTACH_DICT => params.attachDictPref,
|
||||
C_LITERAL_COMPRESSION_MODE => params.literalCompressionMode,
|
||||
C_NB_WORKERS => {
|
||||
if !unsafe { multithreading_enabled() } {
|
||||
debug_assert_eq!(params.nbWorkers, 0);
|
||||
}
|
||||
params.nbWorkers
|
||||
}
|
||||
C_JOB_SIZE => {
|
||||
if !unsafe { multithreading_enabled() } {
|
||||
return ERROR(ZstdErrorCode::ParameterUnsupported);
|
||||
}
|
||||
debug_assert!(params.jobSize <= c_int::MAX as usize);
|
||||
params.jobSize as c_int
|
||||
}
|
||||
C_OVERLAP_LOG => {
|
||||
if !unsafe { multithreading_enabled() } {
|
||||
return ERROR(ZstdErrorCode::ParameterUnsupported);
|
||||
}
|
||||
params.overlapLog
|
||||
}
|
||||
C_RSYNCABLE => {
|
||||
if !unsafe { multithreading_enabled() } {
|
||||
return ERROR(ZstdErrorCode::ParameterUnsupported);
|
||||
}
|
||||
params.rsyncable
|
||||
}
|
||||
C_ENABLE_DEDICATED_DICT_SEARCH => params.enableDedicatedDictSearch,
|
||||
C_ENABLE_LDM => params.ldmParams.enableLdm,
|
||||
C_LDM_HASH_LOG => params.ldmParams.hashLog as c_int,
|
||||
C_LDM_MIN_MATCH => params.ldmParams.minMatchLength as c_int,
|
||||
C_LDM_BUCKET_SIZE_LOG => params.ldmParams.bucketSizeLog as c_int,
|
||||
C_LDM_HASH_RATE_LOG => params.ldmParams.hashRateLog as c_int,
|
||||
C_TARGET_C_BLOCK_SIZE => params.targetCBlockSize as c_int,
|
||||
C_SRC_SIZE_HINT => params.srcSizeHint,
|
||||
C_STABLE_IN_BUFFER => params.inBufferMode,
|
||||
C_STABLE_OUT_BUFFER => params.outBufferMode,
|
||||
C_BLOCK_DELIMITERS => params.blockDelimiters,
|
||||
C_VALIDATE_SEQUENCES => params.validateSequences,
|
||||
C_SPLIT_AFTER_SEQUENCES => params.postBlockSplitter,
|
||||
C_BLOCK_SPLITTER_LEVEL => params.preBlockSplitter_level,
|
||||
C_USE_ROW_MATCH_FINDER => params.useRowMatchFinder,
|
||||
C_DETERMINISTIC_REF_PREFIX => params.deterministicRefPrefix,
|
||||
C_PREFETCH_CDICT_TABLES => params.prefetchCDictTables,
|
||||
C_ENABLE_SEQ_PRODUCER_FALLBACK => params.enableMatchFinderFallback,
|
||||
C_MAX_BLOCK_SIZE => params.maxBlockSize as c_int,
|
||||
C_REPCODE_RESOLUTION => params.searchForExternalRepcodes,
|
||||
_ => return ERROR(ZstdErrorCode::ParameterUnsupported),
|
||||
};
|
||||
unsafe { *value = result };
|
||||
0
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ZSTD_CCtxParams_registerSequenceProducer(
|
||||
params: *mut ZSTD_CCtx_params,
|
||||
ext_seq_prod_state: *mut c_void,
|
||||
ext_seq_prod_func: Option<ZSTD_sequenceProducer_F>,
|
||||
) {
|
||||
debug_assert!(!params.is_null());
|
||||
let params = unsafe { &mut *params };
|
||||
if ext_seq_prod_func.is_some() {
|
||||
params.extSeqProdFunc = ext_seq_prod_func;
|
||||
params.extSeqProdState = ext_seq_prod_state;
|
||||
} else {
|
||||
params.extSeqProdFunc = None;
|
||||
params.extSeqProdState = ptr::null_mut();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::errors::{ERR_getErrorCode, ERR_isError};
|
||||
use std::mem::{align_of, offset_of, size_of, MaybeUninit};
|
||||
|
||||
#[test]
|
||||
fn private_parameter_mirror_matches_the_c_layout() {
|
||||
let pointer_size = size_of::<usize>();
|
||||
assert_eq!(align_of::<ZSTD_CCtx_params>(), pointer_size);
|
||||
assert_eq!(size_of::<ZSTD_compressionParameters>(), 28);
|
||||
assert_eq!(size_of::<ZSTD_frameParameters>(), 12);
|
||||
assert_eq!(size_of::<ldmParams_t>(), 24);
|
||||
assert_eq!(
|
||||
size_of::<ZSTD_customMem>(),
|
||||
if pointer_size == 8 { 24 } else { 12 }
|
||||
);
|
||||
assert_eq!(offset_of!(ZSTD_CCtx_params, format), 0);
|
||||
assert_eq!(offset_of!(ZSTD_CCtx_params, cParams), 4);
|
||||
assert_eq!(offset_of!(ZSTD_CCtx_params, fParams), 32);
|
||||
assert_eq!(offset_of!(ZSTD_CCtx_params, compressionLevel), 44);
|
||||
assert_eq!(offset_of!(ZSTD_CCtx_params, forceWindow), 48);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, targetCBlockSize),
|
||||
if pointer_size == 8 { 56 } else { 52 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, srcSizeHint),
|
||||
if pointer_size == 8 { 64 } else { 56 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, attachDictPref),
|
||||
if pointer_size == 8 { 68 } else { 60 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, literalCompressionMode),
|
||||
if pointer_size == 8 { 72 } else { 64 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, nbWorkers),
|
||||
if pointer_size == 8 { 76 } else { 68 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, jobSize),
|
||||
if pointer_size == 8 { 80 } else { 72 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, overlapLog),
|
||||
if pointer_size == 8 { 88 } else { 76 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, rsyncable),
|
||||
if pointer_size == 8 { 92 } else { 80 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, ldmParams),
|
||||
if pointer_size == 8 { 96 } else { 84 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, enableDedicatedDictSearch),
|
||||
if pointer_size == 8 { 120 } else { 108 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, inBufferMode),
|
||||
if pointer_size == 8 { 124 } else { 112 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, outBufferMode),
|
||||
if pointer_size == 8 { 128 } else { 116 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, blockDelimiters),
|
||||
if pointer_size == 8 { 132 } else { 120 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, validateSequences),
|
||||
if pointer_size == 8 { 136 } else { 124 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, postBlockSplitter),
|
||||
if pointer_size == 8 { 140 } else { 128 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, preBlockSplitter_level),
|
||||
if pointer_size == 8 { 144 } else { 132 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, maxBlockSize),
|
||||
if pointer_size == 8 { 152 } else { 136 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, useRowMatchFinder),
|
||||
if pointer_size == 8 { 160 } else { 140 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, deterministicRefPrefix),
|
||||
if pointer_size == 8 { 164 } else { 144 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, customMem),
|
||||
if pointer_size == 8 { 168 } else { 148 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, prefetchCDictTables),
|
||||
if pointer_size == 8 { 192 } else { 160 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, enableMatchFinderFallback),
|
||||
if pointer_size == 8 { 196 } else { 164 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, extSeqProdState),
|
||||
if pointer_size == 8 { 200 } else { 168 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, extSeqProdFunc),
|
||||
if pointer_size == 8 { 208 } else { 172 }
|
||||
);
|
||||
assert_eq!(
|
||||
offset_of!(ZSTD_CCtx_params, searchForExternalRepcodes),
|
||||
if pointer_size == 8 { 216 } else { 176 }
|
||||
);
|
||||
assert_eq!(
|
||||
size_of::<ZSTD_CCtx_params>(),
|
||||
if pointer_size == 8 { 224 } else { 180 }
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_reset_and_set_get_preserve_public_semantics() {
|
||||
let mut storage = MaybeUninit::<ZSTD_CCtx_params>::uninit();
|
||||
let params = storage.as_mut_ptr();
|
||||
unsafe {
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_init(ptr::null_mut(), DEFAULT_CLEVEL),
|
||||
ERROR(ZstdErrorCode::Generic)
|
||||
);
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_reset(ptr::null_mut()),
|
||||
ERROR(ZstdErrorCode::Generic)
|
||||
);
|
||||
assert_eq!(ZSTD_CCtxParams_init(params, -7), 0);
|
||||
assert_eq!(ZSTD_CCtxParams_setParameter(params, C_FORMAT, 1), 1);
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_setParameter(params, C_COMPRESSION_LEVEL, 0),
|
||||
3
|
||||
);
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_setParameter(params, C_COMPRESSION_LEVEL, -7),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_setParameter(params, C_TARGET_C_BLOCK_SIZE, 1),
|
||||
1340
|
||||
);
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_setParameter(params, C_CONTENT_SIZE_FLAG, -1),
|
||||
1
|
||||
);
|
||||
assert_eq!(ZSTD_CCtxParams_setParameter(params, C_DICT_ID_FLAG, 0), 0);
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_setParameter(params, C_WINDOW_LOG, 9),
|
||||
ERROR(ZstdErrorCode::ParameterOutOfBound)
|
||||
);
|
||||
|
||||
let mut value = -1;
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_getParameter(params, C_COMPRESSION_LEVEL, &mut value),
|
||||
0
|
||||
);
|
||||
assert_eq!(value, -7);
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_getParameter(params, C_FORMAT, &mut value),
|
||||
0
|
||||
);
|
||||
assert_eq!(value, 1);
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_getParameter(params, C_DICT_ID_FLAG, &mut value),
|
||||
0
|
||||
);
|
||||
assert_eq!(value, 0);
|
||||
|
||||
assert_eq!(ZSTD_CCtxParams_reset(params), 0);
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_getParameter(params, C_COMPRESSION_LEVEL, &mut value),
|
||||
0
|
||||
);
|
||||
assert_eq!(value, DEFAULT_CLEVEL);
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_getParameter(params, C_CHECKSUM_FLAG, &mut value),
|
||||
0
|
||||
);
|
||||
assert_eq!(value, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsupported_and_non_multithreaded_parameters_keep_error_codes() {
|
||||
let mut storage = MaybeUninit::<ZSTD_CCtx_params>::uninit();
|
||||
let params = storage.as_mut_ptr();
|
||||
unsafe {
|
||||
assert_eq!(ZSTD_CCtxParams_init(params, DEFAULT_CLEVEL), 0);
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_setParameter(params, C_NB_WORKERS, 1),
|
||||
ERROR(ZstdErrorCode::ParameterUnsupported)
|
||||
);
|
||||
let mut value = -1;
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_getParameter(params, C_JOB_SIZE, &mut value),
|
||||
ERROR(ZstdErrorCode::ParameterUnsupported)
|
||||
);
|
||||
assert_eq!(
|
||||
ZSTD_CCtxParams_setParameter(params, 12345, 0),
|
||||
ERROR(ZstdErrorCode::ParameterUnsupported)
|
||||
);
|
||||
assert!(ERR_isError(ERROR(ZstdErrorCode::ParameterUnsupported)));
|
||||
assert_eq!(
|
||||
ERR_getErrorCode(ERROR(ZstdErrorCode::ParameterUnsupported)),
|
||||
ZstdErrorCode::ParameterUnsupported as i32
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sequence_producer_registration_sets_and_clears_both_fields() {
|
||||
unsafe extern "C" fn producer(
|
||||
_state: *mut c_void,
|
||||
_out: *mut ZSTD_Sequence,
|
||||
_capacity: usize,
|
||||
_src: *const c_void,
|
||||
_src_size: usize,
|
||||
_dict: *const c_void,
|
||||
_dict_size: usize,
|
||||
_level: c_int,
|
||||
_window: usize,
|
||||
) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
let mut storage = MaybeUninit::<ZSTD_CCtx_params>::uninit();
|
||||
let params = storage.as_mut_ptr();
|
||||
let state = std::ptr::dangling_mut::<c_void>();
|
||||
unsafe {
|
||||
assert_eq!(ZSTD_CCtxParams_init(params, DEFAULT_CLEVEL), 0);
|
||||
ZSTD_CCtxParams_registerSequenceProducer(params, state, Some(producer));
|
||||
assert_eq!((*params).extSeqProdState, state);
|
||||
assert!((*params).extSeqProdFunc.is_some());
|
||||
ZSTD_CCtxParams_registerSequenceProducer(params, state, None);
|
||||
assert!((*params).extSeqProdState.is_null());
|
||||
assert!((*params).extSeqProdFunc.is_none());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user