feat(compress): move frame header projection into Rust
Remove the C frame-header callback from the Rust-owned compressContinue orchestration. Project the applied frame parameters and dictionary ID as scalars, so Rust can call the existing header serializer directly while preserving pledged-size subtraction, stage transitions, and output accounting. Route the sequence API's remaining header call directly to the same Rust leaf and delete the redundant C wrapper. Test Plan: - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --lib zstd_compress::tests::compress_continue -- --nocapture - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --all-targets -- -D warnings - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test - ulimit -v 41943040; make -j1 - ulimit -v 41943040; make -j1 -C tests test-zstream ZSTREAM_TESTTIME=-T2s - ulimit -v 41943040; make -j1 -C tests test-fuzzer FUZZERTEST=-T3s FUZZER_FLAGS=--no-big-tests
This commit is contained in:
@@ -878,11 +878,8 @@ typedef char ZSTD_rust_frame_chunk_state_layout[
|
||||
? 1 : -1];
|
||||
|
||||
/* The high-level continue/block entry points are Rust-owned. This projection
|
||||
* carries only mutable scalar state and C callbacks; the private CCtx and
|
||||
* match-state layout never crosses the ABI. */
|
||||
typedef size_t (*ZSTD_rust_compressContinueHeader_f)(void* context,
|
||||
void* dst,
|
||||
size_t dstCapacity);
|
||||
* carries frame-header scalars, mutable state, and C callbacks; the private
|
||||
* CCtx and match-state layout never crosses the ABI. */
|
||||
typedef void (*ZSTD_rust_compressContinueWindow_f)(void* context,
|
||||
const void* src,
|
||||
size_t srcSize);
|
||||
@@ -894,7 +891,6 @@ typedef size_t (*ZSTD_rust_compressContinueBlock_f)(void* context,
|
||||
U32 lastFrameChunk);
|
||||
typedef struct {
|
||||
void* callbackContext;
|
||||
ZSTD_rust_compressContinueHeader_f writeFrameHeader;
|
||||
ZSTD_rust_compressContinueWindow_f updateWindow;
|
||||
ZSTD_rust_compressContinueWindow_f correctOverflow;
|
||||
ZSTD_rust_compressContinueBlock_f compressFrameChunk;
|
||||
@@ -905,6 +901,12 @@ typedef struct {
|
||||
U64 pledgedSrcSizePlusOne;
|
||||
size_t blockSizeMax;
|
||||
int checkBlockSize;
|
||||
int noDictIDFlag;
|
||||
int checksumFlag;
|
||||
int contentSizeFlag;
|
||||
int format;
|
||||
U32 windowLog;
|
||||
U32 dictID;
|
||||
} ZSTD_rust_compressContinueState;
|
||||
size_t ZSTD_rust_compressContinue(
|
||||
const ZSTD_rust_compressContinueState* state,
|
||||
@@ -913,21 +915,32 @@ size_t ZSTD_rust_compressContinue(
|
||||
U32 frame, U32 lastFrameChunk);
|
||||
typedef char ZSTD_rust_compress_continue_state_layout[
|
||||
(offsetof(ZSTD_rust_compressContinueState, callbackContext) == 0
|
||||
&& offsetof(ZSTD_rust_compressContinueState, writeFrameHeader) == sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, updateWindow) == 2 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, correctOverflow) == 3 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, compressFrameChunk) == 4 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, compressBlock) == 5 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, stage) == 6 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, consumedSrcSize) == 7 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, producedCSize) == 8 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, pledgedSrcSizePlusOne) == 9 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, updateWindow) == sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, correctOverflow) == 2 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, compressFrameChunk) == 3 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, compressBlock) == 4 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, stage) == 5 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, consumedSrcSize) == 6 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, producedCSize) == 7 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, pledgedSrcSizePlusOne) == 8 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, blockSizeMax)
|
||||
== 9 * sizeof(void*) + sizeof(U64)
|
||||
== 8 * sizeof(void*) + sizeof(U64)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, checkBlockSize)
|
||||
== 9 * sizeof(void*) + sizeof(U64) + sizeof(size_t)
|
||||
== 8 * sizeof(void*) + sizeof(U64) + sizeof(size_t)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, noDictIDFlag)
|
||||
== 8 * sizeof(void*) + sizeof(U64) + sizeof(size_t) + sizeof(int)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, checksumFlag)
|
||||
== 8 * sizeof(void*) + sizeof(U64) + sizeof(size_t) + 2 * sizeof(int)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, contentSizeFlag)
|
||||
== 8 * sizeof(void*) + sizeof(U64) + sizeof(size_t) + 3 * sizeof(int)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, format)
|
||||
== 8 * sizeof(void*) + sizeof(U64) + sizeof(size_t) + 4 * sizeof(int)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, windowLog)
|
||||
== 8 * sizeof(void*) + sizeof(U64) + sizeof(size_t) + 5 * sizeof(int)
|
||||
&& offsetof(ZSTD_rust_compressContinueState, dictID)
|
||||
== 8 * sizeof(void*) + sizeof(U64) + sizeof(size_t) + 5 * sizeof(int) + sizeof(U32)
|
||||
&& sizeof(ZSTD_rust_compressContinueState)
|
||||
== (sizeof(void*) == 8 ? 96 : 52))
|
||||
== (sizeof(void*) == 8 ? 112 : 72))
|
||||
? 1 : -1];
|
||||
|
||||
/* Rust owns the end-of-frame orchestration. The callbacks retain the
|
||||
@@ -5600,28 +5613,6 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
|
||||
}
|
||||
|
||||
|
||||
static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
||||
const ZSTD_CCtx_params* params,
|
||||
U64 pledgedSrcSize, U32 dictID)
|
||||
{
|
||||
return ZSTD_rust_writeFrameHeader(dst, dstCapacity,
|
||||
params->fParams.noDictIDFlag,
|
||||
params->fParams.checksumFlag,
|
||||
params->fParams.contentSizeFlag,
|
||||
(int)params->format,
|
||||
params->cParams.windowLog,
|
||||
pledgedSrcSize, dictID);
|
||||
}
|
||||
|
||||
static size_t ZSTD_rust_compressContinue_writeFrameHeader(
|
||||
void* context, void* dst, size_t dstCapacity)
|
||||
{
|
||||
ZSTD_CCtx* const cctx = (ZSTD_CCtx*)context;
|
||||
return ZSTD_writeFrameHeader(
|
||||
dst, dstCapacity, &cctx->appliedParams,
|
||||
cctx->pledgedSrcSizePlusOne - 1, cctx->dictID);
|
||||
}
|
||||
|
||||
static void ZSTD_rust_compressContinue_updateWindow(
|
||||
void* context, const void* src, size_t srcSize)
|
||||
{
|
||||
@@ -5676,7 +5667,6 @@ static size_t ZSTD_compressContinue_dispatch(
|
||||
{
|
||||
ZSTD_rust_compressContinueState state;
|
||||
state.callbackContext = cctx;
|
||||
state.writeFrameHeader = ZSTD_rust_compressContinue_writeFrameHeader;
|
||||
state.updateWindow = ZSTD_rust_compressContinue_updateWindow;
|
||||
state.correctOverflow = ZSTD_rust_compressContinue_correctOverflow;
|
||||
state.compressFrameChunk = ZSTD_rust_compressContinue_frameChunk;
|
||||
@@ -5687,6 +5677,12 @@ static size_t ZSTD_compressContinue_dispatch(
|
||||
state.pledgedSrcSizePlusOne = cctx->pledgedSrcSizePlusOne;
|
||||
state.blockSizeMax = blockSizeMax;
|
||||
state.checkBlockSize = checkBlockSize;
|
||||
state.noDictIDFlag = cctx->appliedParams.fParams.noDictIDFlag;
|
||||
state.checksumFlag = cctx->appliedParams.fParams.checksumFlag;
|
||||
state.contentSizeFlag = cctx->appliedParams.fParams.contentSizeFlag;
|
||||
state.format = (int)cctx->appliedParams.format;
|
||||
state.windowLog = cctx->appliedParams.cParams.windowLog;
|
||||
state.dictID = cctx->dictID;
|
||||
return ZSTD_rust_compressContinue(
|
||||
&state, dst, dstCapacity, src, srcSize, frame, lastFrameChunk);
|
||||
}
|
||||
@@ -8030,8 +8026,15 @@ static size_t ZSTD_rust_sequenceApi_writeFrameHeader(
|
||||
void* context, void* dst, size_t dstCapacity, size_t pledgedSrcSize)
|
||||
{
|
||||
ZSTD_CCtx const* const cctx = (ZSTD_CCtx const*)context;
|
||||
return ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams,
|
||||
pledgedSrcSize, cctx->dictID);
|
||||
return ZSTD_rust_writeFrameHeader(
|
||||
dst, dstCapacity,
|
||||
cctx->appliedParams.fParams.noDictIDFlag,
|
||||
cctx->appliedParams.fParams.checksumFlag,
|
||||
cctx->appliedParams.fParams.contentSizeFlag,
|
||||
(int)cctx->appliedParams.format,
|
||||
cctx->appliedParams.cParams.windowLog,
|
||||
pledgedSrcSize,
|
||||
cctx->dictID);
|
||||
}
|
||||
|
||||
static void ZSTD_rust_sequenceApi_updateChecksum(
|
||||
|
||||
+73
-43
@@ -790,7 +790,6 @@ pub unsafe extern "C" fn ZSTD_rust_compressFrameChunk(
|
||||
}
|
||||
}
|
||||
|
||||
type CompressContinueHeaderFn = unsafe extern "C" fn(*mut c_void, *mut c_void, usize) -> usize;
|
||||
type CompressContinueWindowFn = unsafe extern "C" fn(*mut c_void, *const c_void, usize);
|
||||
type CompressContinueBlockFn =
|
||||
unsafe extern "C" fn(*mut c_void, *mut c_void, usize, *const c_void, usize, c_uint) -> usize;
|
||||
@@ -799,12 +798,12 @@ type CompressContinueBlockFn =
|
||||
///
|
||||
/// Rust owns stage transitions, frame-header sequencing, input progression,
|
||||
/// and dispatch between the already-migrated frame-chunk/block bodies. The
|
||||
/// opaque callback context remains in C, where callbacks update the private
|
||||
/// match-state windows and invoke the C-owned context-sensitive operations.
|
||||
/// frame-header parameters are projected as scalars, while the opaque callback
|
||||
/// context remains in C, where callbacks update the private match-state
|
||||
/// windows and invoke the C-owned context-sensitive operations.
|
||||
#[repr(C)]
|
||||
pub struct ZSTD_rust_compressContinueState {
|
||||
callback_context: *mut c_void,
|
||||
write_frame_header: CompressContinueHeaderFn,
|
||||
update_window: CompressContinueWindowFn,
|
||||
correct_overflow: CompressContinueWindowFn,
|
||||
compress_frame_chunk: CompressContinueBlockFn,
|
||||
@@ -815,42 +814,74 @@ pub struct ZSTD_rust_compressContinueState {
|
||||
pledged_src_size_plus_one: u64,
|
||||
block_size_max: usize,
|
||||
check_block_size: c_int,
|
||||
no_dict_id_flag: c_int,
|
||||
checksum_flag: c_int,
|
||||
content_size_flag: c_int,
|
||||
format: c_int,
|
||||
window_log: c_uint,
|
||||
dict_id: c_uint,
|
||||
}
|
||||
|
||||
const COMPRESS_CONTINUE_SCALARS_OFFSET: usize =
|
||||
size_of::<[usize; 8]>() + size_of::<u64>() + size_of::<usize>();
|
||||
|
||||
const _: () = {
|
||||
assert!(offset_of!(ZSTD_rust_compressContinueState, callback_context) == 0);
|
||||
assert!(offset_of!(ZSTD_rust_compressContinueState, write_frame_header) == size_of::<usize>());
|
||||
assert!(offset_of!(ZSTD_rust_compressContinueState, update_window) == 2 * size_of::<usize>());
|
||||
assert!(offset_of!(ZSTD_rust_compressContinueState, update_window) == size_of::<usize>());
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_compressContinueState, correct_overflow) == 3 * size_of::<usize>()
|
||||
offset_of!(ZSTD_rust_compressContinueState, correct_overflow) == 2 * size_of::<usize>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_compressContinueState, compress_frame_chunk) == 4 * size_of::<usize>()
|
||||
offset_of!(ZSTD_rust_compressContinueState, compress_frame_chunk) == 3 * size_of::<usize>()
|
||||
);
|
||||
assert!(offset_of!(ZSTD_rust_compressContinueState, compress_block) == 5 * size_of::<usize>());
|
||||
assert!(offset_of!(ZSTD_rust_compressContinueState, stage) == 6 * size_of::<usize>());
|
||||
assert!(offset_of!(ZSTD_rust_compressContinueState, compress_block) == 4 * size_of::<usize>());
|
||||
assert!(offset_of!(ZSTD_rust_compressContinueState, stage) == 5 * size_of::<usize>());
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_compressContinueState, consumed_src_size) == 7 * size_of::<usize>()
|
||||
offset_of!(ZSTD_rust_compressContinueState, consumed_src_size) == 6 * size_of::<usize>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_compressContinueState, produced_c_size)
|
||||
== 8 * (usize::BITS as usize / 8)
|
||||
== 7 * (usize::BITS as usize / 8)
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_compressContinueState, pledged_src_size_plus_one)
|
||||
== 9 * size_of::<usize>()
|
||||
== size_of::<[usize; 8]>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_compressContinueState, block_size_max)
|
||||
== 9 * size_of::<usize>() + size_of::<u64>()
|
||||
== size_of::<[usize; 8]>() + size_of::<u64>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_compressContinueState, check_block_size)
|
||||
== 9 * size_of::<usize>() + size_of::<u64>() + size_of::<usize>()
|
||||
== COMPRESS_CONTINUE_SCALARS_OFFSET
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_compressContinueState, no_dict_id_flag)
|
||||
== COMPRESS_CONTINUE_SCALARS_OFFSET + size_of::<c_int>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_compressContinueState, checksum_flag)
|
||||
== COMPRESS_CONTINUE_SCALARS_OFFSET + size_of::<[c_int; 2]>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_compressContinueState, content_size_flag)
|
||||
== COMPRESS_CONTINUE_SCALARS_OFFSET + size_of::<[c_int; 3]>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_compressContinueState, format)
|
||||
== COMPRESS_CONTINUE_SCALARS_OFFSET + size_of::<[c_int; 4]>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_compressContinueState, window_log)
|
||||
== COMPRESS_CONTINUE_SCALARS_OFFSET + size_of::<[c_int; 5]>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_compressContinueState, dict_id)
|
||||
== COMPRESS_CONTINUE_SCALARS_OFFSET + size_of::<[c_int; 5]>() + size_of::<c_uint>()
|
||||
);
|
||||
assert!(
|
||||
size_of::<ZSTD_rust_compressContinueState>()
|
||||
== if size_of::<usize>() == 8 { 96 } else { 52 }
|
||||
== if size_of::<usize>() == 8 { 112 } else { 72 }
|
||||
);
|
||||
};
|
||||
|
||||
@@ -885,8 +916,19 @@ unsafe fn compress_continue_body_with(
|
||||
|
||||
let mut frame_header_size = 0usize;
|
||||
if frame != 0 && unsafe { *state.stage } == ZSTD_COMPRESSION_STAGE_INIT {
|
||||
frame_header_size =
|
||||
unsafe { (state.write_frame_header)(state.callback_context, dst, dst_capacity) };
|
||||
frame_header_size = unsafe {
|
||||
ZSTD_rust_writeFrameHeader(
|
||||
dst,
|
||||
dst_capacity,
|
||||
state.no_dict_id_flag,
|
||||
state.checksum_flag,
|
||||
state.content_size_flag,
|
||||
state.format,
|
||||
state.window_log,
|
||||
state.pledged_src_size_plus_one.wrapping_sub(1),
|
||||
state.dict_id,
|
||||
)
|
||||
};
|
||||
if ERR_isError(frame_header_size) {
|
||||
return frame_header_size;
|
||||
}
|
||||
@@ -10964,13 +11006,11 @@ mod tests {
|
||||
|
||||
#[derive(Default)]
|
||||
struct CompressContinueTestContext {
|
||||
header_calls: usize,
|
||||
update_window_calls: usize,
|
||||
overflow_calls: usize,
|
||||
frame_calls: usize,
|
||||
block_calls: usize,
|
||||
last_frame_chunk: c_uint,
|
||||
header_result: usize,
|
||||
frame_result: usize,
|
||||
block_result: usize,
|
||||
}
|
||||
@@ -10981,16 +11021,6 @@ mod tests {
|
||||
unsafe { &mut *context.cast::<CompressContinueTestContext>() }
|
||||
}
|
||||
|
||||
unsafe extern "C" fn compress_continue_test_header(
|
||||
context: *mut c_void,
|
||||
_dst: *mut c_void,
|
||||
_dst_capacity: usize,
|
||||
) -> usize {
|
||||
let context = unsafe { compress_continue_test_context(context) };
|
||||
context.header_calls += 1;
|
||||
context.header_result
|
||||
}
|
||||
|
||||
unsafe extern "C" fn compress_continue_test_window(
|
||||
context: *mut c_void,
|
||||
_src: *const c_void,
|
||||
@@ -11047,7 +11077,6 @@ mod tests {
|
||||
) -> ZSTD_rust_compressContinueState {
|
||||
ZSTD_rust_compressContinueState {
|
||||
callback_context: (context as *mut CompressContinueTestContext).cast(),
|
||||
write_frame_header: compress_continue_test_header,
|
||||
update_window: compress_continue_test_window,
|
||||
correct_overflow: compress_continue_test_overflow,
|
||||
compress_frame_chunk: compress_continue_test_frame,
|
||||
@@ -11058,13 +11087,18 @@ mod tests {
|
||||
pledged_src_size_plus_one,
|
||||
block_size_max,
|
||||
check_block_size,
|
||||
no_dict_id_flag: 0,
|
||||
checksum_flag: 0,
|
||||
content_size_flag: 0,
|
||||
format: 0,
|
||||
window_log: 10,
|
||||
dict_id: 0,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compress_continue_starts_frame_and_updates_progression() {
|
||||
let mut context = CompressContinueTestContext {
|
||||
header_result: 4,
|
||||
frame_result: 6,
|
||||
..CompressContinueTestContext::default()
|
||||
};
|
||||
@@ -11095,11 +11129,10 @@ mod tests {
|
||||
)
|
||||
};
|
||||
|
||||
assert_eq!(result, 10);
|
||||
assert_eq!(result, 12);
|
||||
assert_eq!(stage, ZSTD_COMPRESSION_STAGE_ONGOING);
|
||||
assert_eq!(consumed, 12);
|
||||
assert_eq!(produced, 21);
|
||||
assert_eq!(context.header_calls, 1);
|
||||
assert_eq!(produced, 23);
|
||||
assert_eq!(context.update_window_calls, 1);
|
||||
assert_eq!(context.overflow_calls, 0);
|
||||
assert_eq!(context.frame_calls, 1);
|
||||
@@ -11109,10 +11142,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn compress_continue_empty_frame_only_writes_header() {
|
||||
let mut context = CompressContinueTestContext {
|
||||
header_result: 3,
|
||||
..CompressContinueTestContext::default()
|
||||
};
|
||||
let mut context = CompressContinueTestContext::default();
|
||||
let mut stage = ZSTD_COMPRESSION_STAGE_INIT;
|
||||
let mut consumed = 7;
|
||||
let mut produced = 11;
|
||||
@@ -11125,7 +11155,7 @@ mod tests {
|
||||
16,
|
||||
0,
|
||||
);
|
||||
let mut output = [0xa5u8; 8];
|
||||
let mut output = [0xa5u8; 18];
|
||||
|
||||
let result = unsafe {
|
||||
ZSTD_rust_compressContinue(
|
||||
@@ -11139,13 +11169,13 @@ mod tests {
|
||||
)
|
||||
};
|
||||
|
||||
assert_eq!(result, 3);
|
||||
assert_eq!(result, 6);
|
||||
assert_eq!(stage, ZSTD_COMPRESSION_STAGE_ONGOING);
|
||||
assert_eq!((consumed, produced), (7, 11));
|
||||
assert_eq!(context.header_calls, 1);
|
||||
assert_eq!(context.update_window_calls, 0);
|
||||
assert_eq!(context.frame_calls, 0);
|
||||
assert_eq!(output, [0xa5; 8]);
|
||||
assert_eq!(&output[..6], &[0x28, 0xb5, 0x2f, 0xfd, 0x00, 0x00]);
|
||||
assert_eq!(&output[6..], &[0xa5; 12]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -112,9 +112,9 @@ pub unsafe extern "C" fn ZSTD_rust_writeBlockHeader(
|
||||
/// Rust implementation of the private `ZSTD_writeFrameHeader()` leaf.
|
||||
///
|
||||
/// `no_dict_id_flag`, `checksum_flag`, `content_size_flag`, `format`, and
|
||||
/// `window_log` are extracted by a C wrapper from `ZSTD_CCtx_params`. The
|
||||
/// wrapper preserves the existing static C function signature, avoiding any
|
||||
/// dependency on the full context-parameter layout here.
|
||||
/// `window_log` are extracted by C callers from `ZSTD_CCtx_params`. Keeping
|
||||
/// those projections scalar avoids any dependency on the full
|
||||
/// context-parameter layout here.
|
||||
///
|
||||
/// The caller must provide a writable buffer of at least
|
||||
/// `ZSTD_FRAMEHEADERSIZE_MAX` bytes, or this returns `dstSize_tooSmall`. As
|
||||
|
||||
Reference in New Issue
Block a user