feat(compress): move frame epilogue serialization to Rust
Port the scalar frame-finalization policy and byte serialization into the Rust compression leaf while keeping checksum finalization, tracing, and the compression context in C. Preserve the init-to-ongoing transition on partial failure and reset the stage only after a successful epilogue. Test Plan: - cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression - cargo clippy --manifest-path rust/Cargo.toml - cargo clippy --manifest-path rust/Cargo.toml --benches - cargo clippy --manifest-path rust/Cargo.toml --tests - make -B -C lib -j2 lib - make -B -C tests -j2 test-zstream (84 deterministic, 6737 and 9012 fuzzer cases)
This commit is contained in:
@@ -37,6 +37,10 @@ size_t ZSTD_rust_writeFrameHeader(void* dst, size_t dstCapacity,
|
||||
int contentSizeFlag, int format,
|
||||
U32 windowLog, U64 pledgedSrcSize,
|
||||
U32 dictID);
|
||||
size_t ZSTD_rust_writeEpilogue(void* dst, size_t dstCapacity, int* stage,
|
||||
int noDictIDFlag, int checksumFlag,
|
||||
int contentSizeFlag, int format, U32 windowLog,
|
||||
U32 checksum);
|
||||
size_t ZSTD_rust_resetCCtxForSimpleCompression(void* cctx);
|
||||
size_t ZSTD_rust_prepareCCtxForSimpleCompression(void* cctx,
|
||||
size_t srcSize,
|
||||
@@ -3938,41 +3942,20 @@ size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)
|
||||
* @return : nb of bytes written into dst (or an error code) */
|
||||
static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
|
||||
{
|
||||
BYTE* const ostart = (BYTE*)dst;
|
||||
BYTE* op = ostart;
|
||||
|
||||
U32 const checksum = cctx->appliedParams.fParams.checksumFlag
|
||||
? (U32)XXH64_digest(&cctx->xxhState)
|
||||
: 0;
|
||||
DEBUGLOG(4, "ZSTD_writeEpilogue");
|
||||
RETURN_ERROR_IF(cctx->stage == ZSTDcs_created, stage_wrong, "init missing");
|
||||
|
||||
/* special case : empty frame */
|
||||
if (cctx->stage == ZSTDcs_init) {
|
||||
size_t fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, 0, 0);
|
||||
FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed");
|
||||
dstCapacity -= fhSize;
|
||||
op += fhSize;
|
||||
cctx->stage = ZSTDcs_ongoing;
|
||||
}
|
||||
|
||||
if (cctx->stage != ZSTDcs_ending) {
|
||||
/* write one last empty block, make it the "last" block */
|
||||
U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0;
|
||||
ZSTD_STATIC_ASSERT(ZSTD_BLOCKHEADERSIZE == 3);
|
||||
RETURN_ERROR_IF(dstCapacity<3, dstSize_tooSmall, "no room for epilogue");
|
||||
MEM_writeLE24(op, cBlockHeader24);
|
||||
op += ZSTD_blockHeaderSize;
|
||||
dstCapacity -= ZSTD_blockHeaderSize;
|
||||
}
|
||||
|
||||
if (cctx->appliedParams.fParams.checksumFlag) {
|
||||
U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
|
||||
RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum");
|
||||
if (cctx->appliedParams.fParams.checksumFlag)
|
||||
DEBUGLOG(4, "ZSTD_writeEpilogue: write checksum : %08X", (unsigned)checksum);
|
||||
MEM_writeLE32(op, checksum);
|
||||
op += 4;
|
||||
}
|
||||
|
||||
cctx->stage = ZSTDcs_created; /* return to "created but no init" status */
|
||||
return (size_t)(op-ostart);
|
||||
return ZSTD_rust_writeEpilogue(
|
||||
dst, dstCapacity, (int*)&cctx->stage,
|
||||
cctx->appliedParams.fParams.noDictIDFlag,
|
||||
cctx->appliedParams.fParams.checksumFlag,
|
||||
cctx->appliedParams.fParams.contentSizeFlag,
|
||||
(int)cctx->appliedParams.format,
|
||||
cctx->appliedParams.cParams.windowLog,
|
||||
checksum);
|
||||
}
|
||||
|
||||
void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize)
|
||||
|
||||
Reference in New Issue
Block a user