zstd-ruby 1.5.2.2 → 1.5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +15 -3
- data/ext/zstdruby/common.h +7 -0
- data/ext/zstdruby/libzstd/common/bits.h +175 -0
- data/ext/zstdruby/libzstd/common/bitstream.h +18 -59
- data/ext/zstdruby/libzstd/common/compiler.h +22 -3
- data/ext/zstdruby/libzstd/common/cpu.h +1 -1
- data/ext/zstdruby/libzstd/common/debug.c +1 -1
- data/ext/zstdruby/libzstd/common/debug.h +1 -1
- data/ext/zstdruby/libzstd/common/entropy_common.c +12 -40
- data/ext/zstdruby/libzstd/common/error_private.c +9 -2
- data/ext/zstdruby/libzstd/common/error_private.h +1 -1
- data/ext/zstdruby/libzstd/common/fse.h +5 -83
- data/ext/zstdruby/libzstd/common/fse_decompress.c +7 -99
- data/ext/zstdruby/libzstd/common/huf.h +65 -156
- data/ext/zstdruby/libzstd/common/mem.h +39 -46
- data/ext/zstdruby/libzstd/common/pool.c +26 -10
- data/ext/zstdruby/libzstd/common/pool.h +7 -1
- data/ext/zstdruby/libzstd/common/portability_macros.h +22 -3
- data/ext/zstdruby/libzstd/common/threading.c +68 -14
- data/ext/zstdruby/libzstd/common/threading.h +5 -10
- data/ext/zstdruby/libzstd/common/xxhash.c +2 -2
- data/ext/zstdruby/libzstd/common/xxhash.h +8 -8
- data/ext/zstdruby/libzstd/common/zstd_common.c +1 -1
- data/ext/zstdruby/libzstd/common/zstd_deps.h +1 -1
- data/ext/zstdruby/libzstd/common/zstd_internal.h +17 -113
- data/ext/zstdruby/libzstd/common/zstd_trace.h +3 -3
- data/ext/zstdruby/libzstd/compress/clevels.h +1 -1
- data/ext/zstdruby/libzstd/compress/fse_compress.c +7 -124
- data/ext/zstdruby/libzstd/compress/hist.c +1 -1
- data/ext/zstdruby/libzstd/compress/hist.h +1 -1
- data/ext/zstdruby/libzstd/compress/huf_compress.c +234 -169
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +1055 -455
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +165 -145
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +115 -39
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +16 -8
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +3 -3
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +25 -21
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +5 -3
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +95 -33
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +3 -2
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +433 -148
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +3 -2
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +306 -283
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +4 -2
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +5 -5
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +104 -80
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +12 -5
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +1 -1
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +434 -441
- data/ext/zstdruby/libzstd/decompress/huf_decompress_amd64.S +30 -39
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +3 -4
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +1 -1
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +164 -42
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +186 -65
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +1 -1
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +4 -2
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +19 -15
- data/ext/zstdruby/libzstd/dictBuilder/cover.h +1 -1
- data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +2 -2
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +9 -87
- data/ext/zstdruby/libzstd/zdict.h +53 -31
- data/ext/zstdruby/libzstd/zstd.h +489 -90
- data/ext/zstdruby/libzstd/zstd_errors.h +27 -8
- data/ext/zstdruby/main.c +4 -0
- data/ext/zstdruby/streaming_compress.c +1 -7
- data/ext/zstdruby/zstdruby.c +110 -26
- data/lib/zstd-ruby/version.rb +1 -1
- data/lib/zstd-ruby.rb +0 -1
- metadata +7 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
* TODO: Support Windows calling convention.
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
-
ZSTD_HIDE_ASM_FUNCTION(
|
|
34
|
-
ZSTD_HIDE_ASM_FUNCTION(
|
|
35
|
-
ZSTD_HIDE_ASM_FUNCTION(
|
|
36
|
-
ZSTD_HIDE_ASM_FUNCTION(
|
|
37
|
-
.global
|
|
38
|
-
.global
|
|
39
|
-
.global
|
|
40
|
-
.global
|
|
33
|
+
ZSTD_HIDE_ASM_FUNCTION(HUF_decompress4X1_usingDTable_internal_fast_asm_loop)
|
|
34
|
+
ZSTD_HIDE_ASM_FUNCTION(HUF_decompress4X2_usingDTable_internal_fast_asm_loop)
|
|
35
|
+
ZSTD_HIDE_ASM_FUNCTION(_HUF_decompress4X2_usingDTable_internal_fast_asm_loop)
|
|
36
|
+
ZSTD_HIDE_ASM_FUNCTION(_HUF_decompress4X1_usingDTable_internal_fast_asm_loop)
|
|
37
|
+
.global HUF_decompress4X1_usingDTable_internal_fast_asm_loop
|
|
38
|
+
.global HUF_decompress4X2_usingDTable_internal_fast_asm_loop
|
|
39
|
+
.global _HUF_decompress4X1_usingDTable_internal_fast_asm_loop
|
|
40
|
+
.global _HUF_decompress4X2_usingDTable_internal_fast_asm_loop
|
|
41
41
|
.text
|
|
42
42
|
|
|
43
43
|
/* Sets up register mappings for clarity.
|
|
@@ -95,8 +95,9 @@ ZSTD_HIDE_ASM_FUNCTION(_HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop)
|
|
|
95
95
|
/* Define both _HUF_* & HUF_* symbols because MacOS
|
|
96
96
|
* C symbols are prefixed with '_' & Linux symbols aren't.
|
|
97
97
|
*/
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
_HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
|
99
|
+
HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
|
100
|
+
ZSTD_CET_ENDBRANCH
|
|
100
101
|
/* Save all registers - even if they are callee saved for simplicity. */
|
|
101
102
|
push %rax
|
|
102
103
|
push %rbx
|
|
@@ -350,8 +351,9 @@ HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop:
|
|
|
350
351
|
pop %rax
|
|
351
352
|
ret
|
|
352
353
|
|
|
353
|
-
|
|
354
|
-
|
|
354
|
+
_HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
|
355
|
+
HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
|
356
|
+
ZSTD_CET_ENDBRANCH
|
|
355
357
|
/* Save all registers - even if they are callee saved for simplicity. */
|
|
356
358
|
push %rax
|
|
357
359
|
push %rbx
|
|
@@ -427,41 +429,30 @@ HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop:
|
|
|
427
429
|
/* r15 = (ip0 - ilimit) / 7 */
|
|
428
430
|
movq %rdx, %r15
|
|
429
431
|
|
|
430
|
-
|
|
431
|
-
movq 8(%rsp),
|
|
432
|
-
subq %op0,
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
/* r15 = min(%rdx, %r15) */
|
|
437
|
-
cmpq %rdx, %r15
|
|
438
|
-
cmova %rdx, %r15
|
|
432
|
+
/* r15 = min(r15, min(oend0 - op0, oend1 - op1, oend2 - op2, oend3 - op3) / 10) */
|
|
433
|
+
movq 8(%rsp), %rax /* rax = oend0 */
|
|
434
|
+
subq %op0, %rax /* rax = oend0 - op0 */
|
|
435
|
+
movq 16(%rsp), %rdx /* rdx = oend1 */
|
|
436
|
+
subq %op1, %rdx /* rdx = oend1 - op1 */
|
|
439
437
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
subq %op1, %rax /* rax = oend1 - op1 */
|
|
443
|
-
mulq %rdx
|
|
444
|
-
shrq $3, %rdx /* rdx = rax / 10 */
|
|
445
|
-
|
|
446
|
-
/* r15 = min(%rdx, %r15) */
|
|
447
|
-
cmpq %rdx, %r15
|
|
448
|
-
cmova %rdx, %r15
|
|
438
|
+
cmpq %rax, %rdx
|
|
439
|
+
cmova %rax, %rdx /* rdx = min(%rdx, %rax) */
|
|
449
440
|
|
|
450
|
-
movabsq $-3689348814741910323, %rdx
|
|
451
441
|
movq 24(%rsp), %rax /* rax = oend2 */
|
|
452
442
|
subq %op2, %rax /* rax = oend2 - op2 */
|
|
453
|
-
mulq %rdx
|
|
454
|
-
shrq $3, %rdx /* rdx = rax / 10 */
|
|
455
443
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
cmova %rdx, %r15
|
|
444
|
+
cmpq %rax, %rdx
|
|
445
|
+
cmova %rax, %rdx /* rdx = min(%rdx, %rax) */
|
|
459
446
|
|
|
460
|
-
movabsq $-3689348814741910323, %rdx
|
|
461
447
|
movq 32(%rsp), %rax /* rax = oend3 */
|
|
462
448
|
subq %op3, %rax /* rax = oend3 - op3 */
|
|
449
|
+
|
|
450
|
+
cmpq %rax, %rdx
|
|
451
|
+
cmova %rax, %rdx /* rdx = min(%rdx, %rax) */
|
|
452
|
+
|
|
453
|
+
movabsq $-3689348814741910323, %rax
|
|
463
454
|
mulq %rdx
|
|
464
|
-
shrq $3, %rdx /* rdx =
|
|
455
|
+
shrq $3, %rdx /* rdx = rdx / 10 */
|
|
465
456
|
|
|
466
457
|
/* r15 = min(%rdx, %r15) */
|
|
467
458
|
cmpq %rdx, %r15
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
#include "../common/mem.h" /* low level memory routines */
|
|
20
20
|
#define FSE_STATIC_LINKING_ONLY
|
|
21
21
|
#include "../common/fse.h"
|
|
22
|
-
#define HUF_STATIC_LINKING_ONLY
|
|
23
22
|
#include "../common/huf.h"
|
|
24
23
|
#include "zstd_decompress_internal.h"
|
|
25
24
|
#include "zstd_ddict.h"
|
|
@@ -134,7 +133,7 @@ static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict,
|
|
|
134
133
|
ZSTD_memcpy(internalBuffer, dict, dictSize);
|
|
135
134
|
}
|
|
136
135
|
ddict->dictSize = dictSize;
|
|
137
|
-
ddict->entropy.hufTable[0] = (HUF_DTable)((
|
|
136
|
+
ddict->entropy.hufTable[0] = (HUF_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001); /* cover both little and big endian */
|
|
138
137
|
|
|
139
138
|
/* parse dictionary content */
|
|
140
139
|
FORWARD_IF_ERROR( ZSTD_loadEntropy_intoDDict(ddict, dictContentType) , "");
|
|
@@ -240,5 +239,5 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)
|
|
|
240
239
|
unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
|
|
241
240
|
{
|
|
242
241
|
if (ddict==NULL) return 0;
|
|
243
|
-
return
|
|
242
|
+
return ddict->dictID;
|
|
244
243
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
|
@@ -59,13 +59,13 @@
|
|
|
59
59
|
#include "../common/mem.h" /* low level memory routines */
|
|
60
60
|
#define FSE_STATIC_LINKING_ONLY
|
|
61
61
|
#include "../common/fse.h"
|
|
62
|
-
#define HUF_STATIC_LINKING_ONLY
|
|
63
62
|
#include "../common/huf.h"
|
|
64
63
|
#include "../common/xxhash.h" /* XXH64_reset, XXH64_update, XXH64_digest, XXH64 */
|
|
65
64
|
#include "../common/zstd_internal.h" /* blockProperties_t */
|
|
66
65
|
#include "zstd_decompress_internal.h" /* ZSTD_DCtx */
|
|
67
66
|
#include "zstd_ddict.h" /* ZSTD_DDictDictContent */
|
|
68
67
|
#include "zstd_decompress_block.h" /* ZSTD_decompressBlock_internal */
|
|
68
|
+
#include "../common/bits.h" /* ZSTD_highbit32 */
|
|
69
69
|
|
|
70
70
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
|
|
71
71
|
# include "../legacy/zstd_legacy.h"
|
|
@@ -78,11 +78,11 @@
|
|
|
78
78
|
*************************************/
|
|
79
79
|
|
|
80
80
|
#define DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT 4
|
|
81
|
-
#define DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT 3
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
#define DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT 3 /* These two constants represent SIZE_MULT/COUNT_MULT load factor without using a float.
|
|
82
|
+
* Currently, that means a 0.75 load factor.
|
|
83
|
+
* So, if count * COUNT_MULT / size * SIZE_MULT != 0, then we've exceeded
|
|
84
|
+
* the load factor of the ddict hash set.
|
|
85
|
+
*/
|
|
86
86
|
|
|
87
87
|
#define DDICT_HASHSET_TABLE_BASE_SIZE 64
|
|
88
88
|
#define DDICT_HASHSET_RESIZE_FACTOR 2
|
|
@@ -243,6 +243,7 @@ static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx)
|
|
|
243
243
|
dctx->outBufferMode = ZSTD_bm_buffered;
|
|
244
244
|
dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum;
|
|
245
245
|
dctx->refMultipleDDicts = ZSTD_rmd_refSingleDDict;
|
|
246
|
+
dctx->disableHufAsm = 0;
|
|
246
247
|
}
|
|
247
248
|
|
|
248
249
|
static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
|
|
@@ -438,16 +439,40 @@ size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
|
|
|
438
439
|
* note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless
|
|
439
440
|
* @return : 0, `zfhPtr` is correctly filled,
|
|
440
441
|
* >0, `srcSize` is too small, value is wanted `srcSize` amount,
|
|
441
|
-
|
|
442
|
+
** or an error code, which can be tested using ZSTD_isError() */
|
|
442
443
|
size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)
|
|
443
444
|
{
|
|
444
445
|
const BYTE* ip = (const BYTE*)src;
|
|
445
446
|
size_t const minInputSize = ZSTD_startingInputLength(format);
|
|
446
447
|
|
|
447
|
-
|
|
448
|
-
if (srcSize < minInputSize) return minInputSize;
|
|
449
|
-
RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter");
|
|
448
|
+
DEBUGLOG(5, "ZSTD_getFrameHeader_advanced: minInputSize = %zu, srcSize = %zu", minInputSize, srcSize);
|
|
450
449
|
|
|
450
|
+
if (srcSize > 0) {
|
|
451
|
+
/* note : technically could be considered an assert(), since it's an invalid entry */
|
|
452
|
+
RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter : src==NULL, but srcSize>0");
|
|
453
|
+
}
|
|
454
|
+
if (srcSize < minInputSize) {
|
|
455
|
+
if (srcSize > 0 && format != ZSTD_f_zstd1_magicless) {
|
|
456
|
+
/* when receiving less than @minInputSize bytes,
|
|
457
|
+
* control these bytes at least correspond to a supported magic number
|
|
458
|
+
* in order to error out early if they don't.
|
|
459
|
+
**/
|
|
460
|
+
size_t const toCopy = MIN(4, srcSize);
|
|
461
|
+
unsigned char hbuf[4]; MEM_writeLE32(hbuf, ZSTD_MAGICNUMBER);
|
|
462
|
+
assert(src != NULL);
|
|
463
|
+
ZSTD_memcpy(hbuf, src, toCopy);
|
|
464
|
+
if ( MEM_readLE32(hbuf) != ZSTD_MAGICNUMBER ) {
|
|
465
|
+
/* not a zstd frame : let's check if it's a skippable frame */
|
|
466
|
+
MEM_writeLE32(hbuf, ZSTD_MAGIC_SKIPPABLE_START);
|
|
467
|
+
ZSTD_memcpy(hbuf, src, toCopy);
|
|
468
|
+
if ((MEM_readLE32(hbuf) & ZSTD_MAGIC_SKIPPABLE_MASK) != ZSTD_MAGIC_SKIPPABLE_START) {
|
|
469
|
+
RETURN_ERROR(prefix_unknown,
|
|
470
|
+
"first bytes don't correspond to any supported magic number");
|
|
471
|
+
} } }
|
|
472
|
+
return minInputSize;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzers may not understand that zfhPtr will be read only if return value is zero, since they are 2 different signals */
|
|
451
476
|
if ( (format != ZSTD_f_zstd1_magicless)
|
|
452
477
|
&& (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) {
|
|
453
478
|
if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
|
|
@@ -757,10 +782,11 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize
|
|
|
757
782
|
ip += 4;
|
|
758
783
|
}
|
|
759
784
|
|
|
785
|
+
frameSizeInfo.nbBlocks = nbBlocks;
|
|
760
786
|
frameSizeInfo.compressedSize = (size_t)(ip - ipstart);
|
|
761
787
|
frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN)
|
|
762
788
|
? zfh.frameContentSize
|
|
763
|
-
: nbBlocks * zfh.blockSizeMax;
|
|
789
|
+
: (unsigned long long)nbBlocks * zfh.blockSizeMax;
|
|
764
790
|
return frameSizeInfo;
|
|
765
791
|
}
|
|
766
792
|
}
|
|
@@ -800,6 +826,48 @@ unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
|
|
|
800
826
|
return bound;
|
|
801
827
|
}
|
|
802
828
|
|
|
829
|
+
size_t ZSTD_decompressionMargin(void const* src, size_t srcSize)
|
|
830
|
+
{
|
|
831
|
+
size_t margin = 0;
|
|
832
|
+
unsigned maxBlockSize = 0;
|
|
833
|
+
|
|
834
|
+
/* Iterate over each frame */
|
|
835
|
+
while (srcSize > 0) {
|
|
836
|
+
ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
|
|
837
|
+
size_t const compressedSize = frameSizeInfo.compressedSize;
|
|
838
|
+
unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
|
|
839
|
+
ZSTD_frameHeader zfh;
|
|
840
|
+
|
|
841
|
+
FORWARD_IF_ERROR(ZSTD_getFrameHeader(&zfh, src, srcSize), "");
|
|
842
|
+
if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)
|
|
843
|
+
return ERROR(corruption_detected);
|
|
844
|
+
|
|
845
|
+
if (zfh.frameType == ZSTD_frame) {
|
|
846
|
+
/* Add the frame header to our margin */
|
|
847
|
+
margin += zfh.headerSize;
|
|
848
|
+
/* Add the checksum to our margin */
|
|
849
|
+
margin += zfh.checksumFlag ? 4 : 0;
|
|
850
|
+
/* Add 3 bytes per block */
|
|
851
|
+
margin += 3 * frameSizeInfo.nbBlocks;
|
|
852
|
+
|
|
853
|
+
/* Compute the max block size */
|
|
854
|
+
maxBlockSize = MAX(maxBlockSize, zfh.blockSizeMax);
|
|
855
|
+
} else {
|
|
856
|
+
assert(zfh.frameType == ZSTD_skippableFrame);
|
|
857
|
+
/* Add the entire skippable frame size to our margin. */
|
|
858
|
+
margin += compressedSize;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
assert(srcSize >= compressedSize);
|
|
862
|
+
src = (const BYTE*)src + compressedSize;
|
|
863
|
+
srcSize -= compressedSize;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
/* Add the max block size back to the margin. */
|
|
867
|
+
margin += maxBlockSize;
|
|
868
|
+
|
|
869
|
+
return margin;
|
|
870
|
+
}
|
|
803
871
|
|
|
804
872
|
/*-*************************************************************
|
|
805
873
|
* Frame decoding
|
|
@@ -825,7 +893,7 @@ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
|
|
|
825
893
|
if (srcSize == 0) return 0;
|
|
826
894
|
RETURN_ERROR(dstBuffer_null, "");
|
|
827
895
|
}
|
|
828
|
-
|
|
896
|
+
ZSTD_memmove(dst, src, srcSize);
|
|
829
897
|
return srcSize;
|
|
830
898
|
}
|
|
831
899
|
|
|
@@ -903,6 +971,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|
|
903
971
|
|
|
904
972
|
/* Loop on each block */
|
|
905
973
|
while (1) {
|
|
974
|
+
BYTE* oBlockEnd = oend;
|
|
906
975
|
size_t decodedSize;
|
|
907
976
|
blockProperties_t blockProperties;
|
|
908
977
|
size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSrcSize, &blockProperties);
|
|
@@ -912,16 +981,34 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|
|
912
981
|
remainingSrcSize -= ZSTD_blockHeaderSize;
|
|
913
982
|
RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong, "");
|
|
914
983
|
|
|
984
|
+
if (ip >= op && ip < oBlockEnd) {
|
|
985
|
+
/* We are decompressing in-place. Limit the output pointer so that we
|
|
986
|
+
* don't overwrite the block that we are currently reading. This will
|
|
987
|
+
* fail decompression if the input & output pointers aren't spaced
|
|
988
|
+
* far enough apart.
|
|
989
|
+
*
|
|
990
|
+
* This is important to set, even when the pointers are far enough
|
|
991
|
+
* apart, because ZSTD_decompressBlock_internal() can decide to store
|
|
992
|
+
* literals in the output buffer, after the block it is decompressing.
|
|
993
|
+
* Since we don't want anything to overwrite our input, we have to tell
|
|
994
|
+
* ZSTD_decompressBlock_internal to never write past ip.
|
|
995
|
+
*
|
|
996
|
+
* See ZSTD_allocateLiteralsBuffer() for reference.
|
|
997
|
+
*/
|
|
998
|
+
oBlockEnd = op + (ip - op);
|
|
999
|
+
}
|
|
1000
|
+
|
|
915
1001
|
switch(blockProperties.blockType)
|
|
916
1002
|
{
|
|
917
1003
|
case bt_compressed:
|
|
918
|
-
decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(
|
|
1004
|
+
decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, /* frame */ 1, not_streaming);
|
|
919
1005
|
break;
|
|
920
1006
|
case bt_raw :
|
|
1007
|
+
/* Use oend instead of oBlockEnd because this function is safe to overlap. It uses memmove. */
|
|
921
1008
|
decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize);
|
|
922
1009
|
break;
|
|
923
1010
|
case bt_rle :
|
|
924
|
-
decodedSize = ZSTD_setRleBlock(op, (size_t)(
|
|
1011
|
+
decodedSize = ZSTD_setRleBlock(op, (size_t)(oBlockEnd-op), *ip, blockProperties.origSize);
|
|
925
1012
|
break;
|
|
926
1013
|
case bt_reserved :
|
|
927
1014
|
default:
|
|
@@ -956,6 +1043,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|
|
956
1043
|
}
|
|
957
1044
|
ZSTD_DCtx_trace_end(dctx, (U64)(op-ostart), (U64)(ip-istart), /* streaming */ 0);
|
|
958
1045
|
/* Allow caller to get size read */
|
|
1046
|
+
DEBUGLOG(4, "ZSTD_decompressFrame: decompressed frame of size %zi, consuming %zi bytes of input", op-ostart, ip - (const BYTE*)*srcPtr);
|
|
959
1047
|
*srcPtr = ip;
|
|
960
1048
|
*srcSizePtr = remainingSrcSize;
|
|
961
1049
|
return (size_t)(op-ostart);
|
|
@@ -1108,8 +1196,8 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
|
|
|
1108
1196
|
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
|
|
1109
1197
|
|
|
1110
1198
|
/**
|
|
1111
|
-
* Similar to ZSTD_nextSrcSizeToDecompress(), but when
|
|
1112
|
-
*
|
|
1199
|
+
* Similar to ZSTD_nextSrcSizeToDecompress(), but when a block input can be streamed, we
|
|
1200
|
+
* allow taking a partial block as the input. Currently only raw uncompressed blocks can
|
|
1113
1201
|
* be streamed.
|
|
1114
1202
|
*
|
|
1115
1203
|
* For blocks that can be streamed, this allows us to reduce the latency until we produce
|
|
@@ -1309,7 +1397,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
|
1309
1397
|
|
|
1310
1398
|
default:
|
|
1311
1399
|
assert(0); /* impossible */
|
|
1312
|
-
RETURN_ERROR(GENERIC, "impossible to reach"); /* some
|
|
1400
|
+
RETURN_ERROR(GENERIC, "impossible to reach"); /* some compilers require default to do something */
|
|
1313
1401
|
}
|
|
1314
1402
|
}
|
|
1315
1403
|
|
|
@@ -1350,11 +1438,11 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
|
|
|
1350
1438
|
/* in minimal huffman, we always use X1 variants */
|
|
1351
1439
|
size_t const hSize = HUF_readDTableX1_wksp(entropy->hufTable,
|
|
1352
1440
|
dictPtr, dictEnd - dictPtr,
|
|
1353
|
-
workspace, workspaceSize);
|
|
1441
|
+
workspace, workspaceSize, /* flags */ 0);
|
|
1354
1442
|
#else
|
|
1355
1443
|
size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable,
|
|
1356
1444
|
dictPtr, (size_t)(dictEnd - dictPtr),
|
|
1357
|
-
workspace, workspaceSize);
|
|
1445
|
+
workspace, workspaceSize, /* flags */ 0);
|
|
1358
1446
|
#endif
|
|
1359
1447
|
RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted, "");
|
|
1360
1448
|
dictPtr += hSize;
|
|
@@ -1453,7 +1541,7 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
|
|
|
1453
1541
|
dctx->prefixStart = NULL;
|
|
1454
1542
|
dctx->virtualStart = NULL;
|
|
1455
1543
|
dctx->dictEnd = NULL;
|
|
1456
|
-
dctx->entropy.hufTable[0] = (HUF_DTable)((
|
|
1544
|
+
dctx->entropy.hufTable[0] = (HUF_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001); /* cover both little and big endian */
|
|
1457
1545
|
dctx->litEntropy = dctx->fseEntropy = 0;
|
|
1458
1546
|
dctx->dictID = 0;
|
|
1459
1547
|
dctx->bType = bt_reserved;
|
|
@@ -1515,7 +1603,7 @@ unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
|
|
|
1515
1603
|
* This could for one of the following reasons :
|
|
1516
1604
|
* - The frame does not require a dictionary (most common case).
|
|
1517
1605
|
* - The frame was built with dictID intentionally removed.
|
|
1518
|
-
* Needed dictionary is a hidden information.
|
|
1606
|
+
* Needed dictionary is a hidden piece of information.
|
|
1519
1607
|
* Note : this use case also happens when using a non-conformant dictionary.
|
|
1520
1608
|
* - `srcSize` is too small, and as a result, frame header could not be decoded.
|
|
1521
1609
|
* Note : possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`.
|
|
@@ -1524,7 +1612,7 @@ unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
|
|
|
1524
1612
|
* ZSTD_getFrameHeader(), which will provide a more precise error code. */
|
|
1525
1613
|
unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
|
|
1526
1614
|
{
|
|
1527
|
-
ZSTD_frameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0 };
|
|
1615
|
+
ZSTD_frameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0, 0, 0 };
|
|
1528
1616
|
size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize);
|
|
1529
1617
|
if (ZSTD_isError(hError)) return 0;
|
|
1530
1618
|
return zfp.dictID;
|
|
@@ -1631,7 +1719,9 @@ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t di
|
|
|
1631
1719
|
size_t ZSTD_initDStream(ZSTD_DStream* zds)
|
|
1632
1720
|
{
|
|
1633
1721
|
DEBUGLOG(4, "ZSTD_initDStream");
|
|
1634
|
-
|
|
1722
|
+
FORWARD_IF_ERROR(ZSTD_DCtx_reset(zds, ZSTD_reset_session_only), "");
|
|
1723
|
+
FORWARD_IF_ERROR(ZSTD_DCtx_refDDict(zds, NULL), "");
|
|
1724
|
+
return ZSTD_startingInputLength(zds->format);
|
|
1635
1725
|
}
|
|
1636
1726
|
|
|
1637
1727
|
/* ZSTD_initDStream_usingDDict() :
|
|
@@ -1639,6 +1729,7 @@ size_t ZSTD_initDStream(ZSTD_DStream* zds)
|
|
|
1639
1729
|
* this function cannot fail */
|
|
1640
1730
|
size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
|
|
1641
1731
|
{
|
|
1732
|
+
DEBUGLOG(4, "ZSTD_initDStream_usingDDict");
|
|
1642
1733
|
FORWARD_IF_ERROR( ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only) , "");
|
|
1643
1734
|
FORWARD_IF_ERROR( ZSTD_DCtx_refDDict(dctx, ddict) , "");
|
|
1644
1735
|
return ZSTD_startingInputLength(dctx->format);
|
|
@@ -1649,6 +1740,7 @@ size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
|
|
|
1649
1740
|
* this function cannot fail */
|
|
1650
1741
|
size_t ZSTD_resetDStream(ZSTD_DStream* dctx)
|
|
1651
1742
|
{
|
|
1743
|
+
DEBUGLOG(4, "ZSTD_resetDStream");
|
|
1652
1744
|
FORWARD_IF_ERROR(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only), "");
|
|
1653
1745
|
return ZSTD_startingInputLength(dctx->format);
|
|
1654
1746
|
}
|
|
@@ -1720,6 +1812,11 @@ ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)
|
|
|
1720
1812
|
bounds.lowerBound = (int)ZSTD_rmd_refSingleDDict;
|
|
1721
1813
|
bounds.upperBound = (int)ZSTD_rmd_refMultipleDDicts;
|
|
1722
1814
|
return bounds;
|
|
1815
|
+
case ZSTD_d_disableHuffmanAssembly:
|
|
1816
|
+
bounds.lowerBound = 0;
|
|
1817
|
+
bounds.upperBound = 1;
|
|
1818
|
+
return bounds;
|
|
1819
|
+
|
|
1723
1820
|
default:;
|
|
1724
1821
|
}
|
|
1725
1822
|
bounds.error = ERROR(parameter_unsupported);
|
|
@@ -1760,6 +1857,9 @@ size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value
|
|
|
1760
1857
|
case ZSTD_d_refMultipleDDicts:
|
|
1761
1858
|
*value = (int)dctx->refMultipleDDicts;
|
|
1762
1859
|
return 0;
|
|
1860
|
+
case ZSTD_d_disableHuffmanAssembly:
|
|
1861
|
+
*value = (int)dctx->disableHufAsm;
|
|
1862
|
+
return 0;
|
|
1763
1863
|
default:;
|
|
1764
1864
|
}
|
|
1765
1865
|
RETURN_ERROR(parameter_unsupported, "");
|
|
@@ -1793,6 +1893,10 @@ size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value
|
|
|
1793
1893
|
}
|
|
1794
1894
|
dctx->refMultipleDDicts = (ZSTD_refMultipleDDicts_e)value;
|
|
1795
1895
|
return 0;
|
|
1896
|
+
case ZSTD_d_disableHuffmanAssembly:
|
|
1897
|
+
CHECK_DBOUNDS(ZSTD_d_disableHuffmanAssembly, value);
|
|
1898
|
+
dctx->disableHufAsm = value != 0;
|
|
1899
|
+
return 0;
|
|
1796
1900
|
default:;
|
|
1797
1901
|
}
|
|
1798
1902
|
RETURN_ERROR(parameter_unsupported, "");
|
|
@@ -1980,7 +2084,6 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
1980
2084
|
if (zds->refMultipleDDicts && zds->ddictSet) {
|
|
1981
2085
|
ZSTD_DCtx_selectFrameDDict(zds);
|
|
1982
2086
|
}
|
|
1983
|
-
DEBUGLOG(5, "header size : %u", (U32)hSize);
|
|
1984
2087
|
if (ZSTD_isError(hSize)) {
|
|
1985
2088
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
|
|
1986
2089
|
U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
|
|
@@ -2012,6 +2115,11 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2012
2115
|
zds->lhSize += remainingInput;
|
|
2013
2116
|
}
|
|
2014
2117
|
input->pos = input->size;
|
|
2118
|
+
/* check first few bytes */
|
|
2119
|
+
FORWARD_IF_ERROR(
|
|
2120
|
+
ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format),
|
|
2121
|
+
"First few bytes detected incorrect" );
|
|
2122
|
+
/* return hint input size */
|
|
2015
2123
|
return (MAX((size_t)ZSTD_FRAMEHEADERSIZE_MIN(zds->format), hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
|
|
2016
2124
|
}
|
|
2017
2125
|
assert(ip != NULL);
|
|
@@ -2029,8 +2137,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2029
2137
|
size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, (size_t)(oend-op), istart, cSize, ZSTD_getDDict(zds));
|
|
2030
2138
|
if (ZSTD_isError(decompressedSize)) return decompressedSize;
|
|
2031
2139
|
DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()")
|
|
2140
|
+
assert(istart != NULL);
|
|
2032
2141
|
ip = istart + cSize;
|
|
2033
|
-
op
|
|
2142
|
+
op = op ? op + decompressedSize : op; /* can occur if frameContentSize = 0 (empty frame) */
|
|
2034
2143
|
zds->expected = 0;
|
|
2035
2144
|
zds->streamStage = zdss_init;
|
|
2036
2145
|
someMoreWork = 0;
|
|
@@ -2114,6 +2223,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2114
2223
|
}
|
|
2115
2224
|
if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
|
|
2116
2225
|
FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, ip, neededInSize), "");
|
|
2226
|
+
assert(ip != NULL);
|
|
2117
2227
|
ip += neededInSize;
|
|
2118
2228
|
/* Function modifies the stage so we must break */
|
|
2119
2229
|
break;
|
|
@@ -2128,7 +2238,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2128
2238
|
int const isSkipFrame = ZSTD_isSkipFrame(zds);
|
|
2129
2239
|
size_t loadedSize;
|
|
2130
2240
|
/* At this point we shouldn't be decompressing a block that we can stream. */
|
|
2131
|
-
assert(neededInSize == ZSTD_nextSrcSizeToDecompressWithInputSize(zds, iend - ip));
|
|
2241
|
+
assert(neededInSize == ZSTD_nextSrcSizeToDecompressWithInputSize(zds, (size_t)(iend - ip)));
|
|
2132
2242
|
if (isSkipFrame) {
|
|
2133
2243
|
loadedSize = MIN(toLoad, (size_t)(iend-ip));
|
|
2134
2244
|
} else {
|
|
@@ -2137,8 +2247,11 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2137
2247
|
"should never happen");
|
|
2138
2248
|
loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, (size_t)(iend-ip));
|
|
2139
2249
|
}
|
|
2140
|
-
|
|
2141
|
-
|
|
2250
|
+
if (loadedSize != 0) {
|
|
2251
|
+
/* ip may be NULL */
|
|
2252
|
+
ip += loadedSize;
|
|
2253
|
+
zds->inPos += loadedSize;
|
|
2254
|
+
}
|
|
2142
2255
|
if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
|
|
2143
2256
|
|
|
2144
2257
|
/* decode loaded input */
|
|
@@ -2148,14 +2261,17 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2148
2261
|
break;
|
|
2149
2262
|
}
|
|
2150
2263
|
case zdss_flush:
|
|
2151
|
-
{
|
|
2264
|
+
{
|
|
2265
|
+
size_t const toFlushSize = zds->outEnd - zds->outStart;
|
|
2152
2266
|
size_t const flushedSize = ZSTD_limitCopy(op, (size_t)(oend-op), zds->outBuff + zds->outStart, toFlushSize);
|
|
2153
|
-
|
|
2267
|
+
|
|
2268
|
+
op = op ? op + flushedSize : op;
|
|
2269
|
+
|
|
2154
2270
|
zds->outStart += flushedSize;
|
|
2155
2271
|
if (flushedSize == toFlushSize) { /* flush completed */
|
|
2156
2272
|
zds->streamStage = zdss_read;
|
|
2157
2273
|
if ( (zds->outBuffSize < zds->fParams.frameContentSize)
|
|
2158
|
-
|
|
2274
|
+
&& (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) {
|
|
2159
2275
|
DEBUGLOG(5, "restart filling outBuff from beginning (left:%i, needed:%u)",
|
|
2160
2276
|
(int)(zds->outBuffSize - zds->outStart),
|
|
2161
2277
|
(U32)zds->fParams.blockSizeMax);
|
|
@@ -2169,7 +2285,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2169
2285
|
|
|
2170
2286
|
default:
|
|
2171
2287
|
assert(0); /* impossible */
|
|
2172
|
-
RETURN_ERROR(GENERIC, "impossible to reach"); /* some
|
|
2288
|
+
RETURN_ERROR(GENERIC, "impossible to reach"); /* some compilers require default to do something */
|
|
2173
2289
|
} }
|
|
2174
2290
|
|
|
2175
2291
|
/* result */
|
|
@@ -2182,8 +2298,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2182
2298
|
if ((ip==istart) && (op==ostart)) { /* no forward progress */
|
|
2183
2299
|
zds->noForwardProgress ++;
|
|
2184
2300
|
if (zds->noForwardProgress >= ZSTD_NO_FORWARD_PROGRESS_MAX) {
|
|
2185
|
-
RETURN_ERROR_IF(op==oend,
|
|
2186
|
-
RETURN_ERROR_IF(ip==iend,
|
|
2301
|
+
RETURN_ERROR_IF(op==oend, noForwardProgress_destFull, "");
|
|
2302
|
+
RETURN_ERROR_IF(ip==iend, noForwardProgress_inputEmpty, "");
|
|
2187
2303
|
assert(0);
|
|
2188
2304
|
}
|
|
2189
2305
|
} else {
|
|
@@ -2220,11 +2336,17 @@ size_t ZSTD_decompressStream_simpleArgs (
|
|
|
2220
2336
|
void* dst, size_t dstCapacity, size_t* dstPos,
|
|
2221
2337
|
const void* src, size_t srcSize, size_t* srcPos)
|
|
2222
2338
|
{
|
|
2223
|
-
ZSTD_outBuffer output
|
|
2224
|
-
ZSTD_inBuffer input
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2339
|
+
ZSTD_outBuffer output;
|
|
2340
|
+
ZSTD_inBuffer input;
|
|
2341
|
+
output.dst = dst;
|
|
2342
|
+
output.size = dstCapacity;
|
|
2343
|
+
output.pos = *dstPos;
|
|
2344
|
+
input.src = src;
|
|
2345
|
+
input.size = srcSize;
|
|
2346
|
+
input.pos = *srcPos;
|
|
2347
|
+
{ size_t const cErr = ZSTD_decompressStream(dctx, &output, &input);
|
|
2348
|
+
*dstPos = output.pos;
|
|
2349
|
+
*srcPos = input.pos;
|
|
2350
|
+
return cErr;
|
|
2351
|
+
}
|
|
2230
2352
|
}
|