Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
A ZSTD_DCtx object can be re-used multiple times.
- First optional operation is to retrieve frame parameters, using ZSTD_getFrameParams().
+ First optional operation is to retrieve frame parameters, using ZSTD_getFrameParams(), which doesn't consume the input.
It can provide the minimum size of rolling buffer required to properly decompress data,
and optionally the final size of uncompressed content.
(Note : content size is an optional info that may not be present. 0 means : content size unknown)
{ ZSTD_CCtx* ctxOrig = ZSTD_createCCtx();
ZSTD_CCtx* ctxDuplicated = ZSTD_createCCtx();
ZSTD_DCtx* dctx = ZSTD_createDCtx();
- const size_t dictSize = 500;
+ size_t const dictSize = 500;
size_t cSizeOrig;
DISPLAYLEVEL(4, "test%3i : copy context too soon : ", testNb++);
CNBuffer, dictSize);
if (ZSTD_isError(result)) goto _output_error;
if (result != COMPRESSIBLE_NOISE_LENGTH - dictSize) goto _output_error;
- ZSTD_freeCCtx(ctxOrig); /* if ctxOrig is read, will produce segfault */
DISPLAYLEVEL(4, "OK \n");
DISPLAYLEVEL(4, "test%3i : compress with duplicated context : ", testNb++);
if (ZSTD_isError(result)) goto _output_error;
cSize += result;
if (cSize != cSizeOrig) goto _output_error; /* should be identical == have same size */
- ZSTD_freeCCtx(ctxDuplicated);
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);
DISPLAYLEVEL(4, "test%3i : frame built with duplicated context should be decompressible : ", testNb++);
CNBuffer, dictSize);
if (ZSTD_isError(result)) goto _output_error;
if (result != COMPRESSIBLE_NOISE_LENGTH - dictSize) goto _output_error;
- ZSTD_freeDCtx(dctx);
DISPLAYLEVEL(4, "OK \n");
+
+ DISPLAYLEVEL(4, "test%3i : check content size on duplicated context : ", testNb++);
+ { size_t const testSize = COMPRESSIBLE_NOISE_LENGTH / 3;
+ { ZSTD_parameters p;
+ p.cParams = ZSTD_getCParams(2, testSize, dictSize);
+ p.fParams.contentSizeFlag = 1;
+ { size_t const initResult = ZSTD_compressBegin_advanced(ctxOrig, CNBuffer, dictSize, p, testSize-1);
+ if (ZSTD_isError(initResult)) goto _output_error;
+ } }
+ { size_t const copyResult = ZSTD_copyCCtx(ctxDuplicated, ctxOrig);
+ if (ZSTD_isError(copyResult)) goto _output_error; }
+ cSize = ZSTD_compressContinue(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize), (const char*)CNBuffer + dictSize, COMPRESSIBLE_NOISE_LENGTH - dictSize);
+ if (ZSTD_isError(cSize)) goto _output_error;
+ { ZSTD_frameParams fp;
+ size_t const gfpResult = ZSTD_getFrameParams(&fp, compressedBuffer, cSize);
+ if (gfpResult!=0) goto _output_error;
+ if ((fp.frameContentSize != testSize) && (fp.frameContentSize != 0)) goto _output_error;
+ } }
+ DISPLAYLEVEL(4, "OK \n");
+
+ ZSTD_freeCCtx(ctxOrig);
+ ZSTD_freeCCtx(ctxDuplicated);
+ ZSTD_freeDCtx(dctx);
}
/* Decompression defense tests */