Compress-Zstd
view release on metacpan or search on metacpan
ext/zstd/contrib/linux-kernel/lib/zstd/decompress.c view on Meta::CPAN
zds->ddict = ddict;
}
return zds;
}
size_t ZSTD_freeDStream(ZSTD_DStream *zds)
{
if (zds == NULL)
return 0; /* support free on null */
{
ZSTD_customMem const cMem = zds->customMem;
ZSTD_freeDCtx(zds->dctx);
zds->dctx = NULL;
ZSTD_freeDDict(zds->ddictLocal);
zds->ddictLocal = NULL;
ZSTD_free(zds->inBuff, cMem);
zds->inBuff = NULL;
ZSTD_free(zds->outBuff, cMem);
zds->outBuff = NULL;
ZSTD_free(zds, cMem);
return 0;
}
}
/* *** Initialization *** */
size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX + ZSTD_blockHeaderSize; }
size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
size_t ZSTD_resetDStream(ZSTD_DStream *zds)
{
zds->stage = zdss_loadHeader;
zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
zds->legacyVersion = 0;
zds->hostageByte = 0;
return ZSTD_frameHeaderSize_prefix;
}
/* ***** Decompression ***** */
ZSTD_STATIC size_t ZSTD_limitCopy(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
{
size_t const length = MIN(dstCapacity, srcSize);
memcpy(dst, src, length);
return length;
}
size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inBuffer *input)
{
const char *const istart = (const char *)(input->src) + input->pos;
const char *const iend = (const char *)(input->src) + input->size;
const char *ip = istart;
char *const ostart = (char *)(output->dst) + output->pos;
char *const oend = (char *)(output->dst) + output->size;
char *op = ostart;
U32 someMoreWork = 1;
while (someMoreWork) {
switch (zds->stage) {
case zdss_init:
ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */
/* fall-through */
case zdss_loadHeader: {
size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
if (ZSTD_isError(hSize))
return hSize;
if (hSize != 0) { /* need more input */
size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */
if (toLoad > (size_t)(iend - ip)) { /* not enough input to load full header */
memcpy(zds->headerBuffer + zds->lhSize, ip, iend - ip);
zds->lhSize += iend - ip;
input->pos = input->size;
return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) +
ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
}
memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad);
zds->lhSize = hSize;
ip += toLoad;
break;
}
/* check for single-pass mode opportunity */
if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */
&& (U64)(size_t)(oend - op) >= zds->fParams.frameContentSize) {
size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend - istart);
if (cSize <= (size_t)(iend - istart)) {
size_t const decompressedSize = ZSTD_decompress_usingDDict(zds->dctx, op, oend - op, istart, cSize, zds->ddict);
if (ZSTD_isError(decompressedSize))
return decompressedSize;
ip = istart + cSize;
op += decompressedSize;
zds->dctx->expected = 0;
zds->stage = zdss_init;
someMoreWork = 0;
break;
}
}
/* Consume header */
ZSTD_refDDict(zds->dctx, zds->ddict);
{
size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx); /* == ZSTD_frameHeaderSize_prefix */
CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
{
size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer + h1Size, h2Size));
}
}
zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
if (zds->fParams.windowSize > zds->maxWindowSize)
return ERROR(frameParameter_windowTooLarge);
/* Buffers are preallocated, but double check */
{
size_t const blockSize = MIN(zds->maxWindowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
size_t const neededOutSize = zds->maxWindowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
if (zds->inBuffSize < blockSize) {
return ERROR(GENERIC);
}
( run in 1.317 second using v1.01-cache-2.11-cpan-39bf76dae61 )