Skip to content

Commit fd368a3

Browse files
authored
Merge pull request #5 from SpringMT/update-zstd-for-v1.1.4
Update zstd version to v1.1.4
2 parents 5d0c9ad + 01467c8 commit fd368a3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1336
-346
lines changed

ext/zstdruby/libzstd/Makefile

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,22 @@ CPPFLAGS+= -I. -I./common -DXXH_NAMESPACE=ZSTD_
2424
CFLAGS ?= -O3
2525
DEBUGFLAGS = -g -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
2626
-Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
27-
-Wstrict-prototypes -Wundef -Wpointer-arith
27+
-Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security
2828
CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS)
2929
FLAGS = $(CPPFLAGS) $(CFLAGS)
3030

3131

3232
ZSTD_FILES := $(wildcard common/*.c compress/*.c decompress/*.c dictBuilder/*.c deprecated/*.c)
3333

34-
ifeq ($(ZSTD_LEGACY_SUPPORT), 0)
35-
CPPFLAGS += -DZSTD_LEGACY_SUPPORT=0
36-
else
37-
CPPFLAGS += -I./legacy -DZSTD_LEGACY_SUPPORT=1
38-
ZSTD_FILES+= $(wildcard legacy/*.c)
34+
ZSTD_LEGACY_SUPPORT ?= 4
35+
36+
ifneq ($(ZSTD_LEGACY_SUPPORT), 0)
37+
ifeq ($(shell test $(ZSTD_LEGACY_SUPPORT) -lt 8; echo $$?), 0)
38+
ZSTD_FILES += $(shell ls legacy/*.c | grep 'v0[$(ZSTD_LEGACY_SUPPORT)-7]')
39+
endif
40+
CPPFLAGS += -I./legacy
3941
endif
42+
CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT)
4043

4144
ZSTD_OBJ := $(patsubst %.c,%.o,$(ZSTD_FILES))
4245

ext/zstdruby/libzstd/common/bitstream.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ extern "C" {
6060
# include <immintrin.h> /* support for bextr (experimental) */
6161
#endif
6262

63+
#define STREAM_ACCUMULATOR_MIN_32 25
64+
#define STREAM_ACCUMULATOR_MIN_64 57
65+
#define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64))
6366

6467
/*-******************************************
6568
* bitStream encoding API (write forward)

ext/zstdruby/libzstd/common/entropy_common.c

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,27 +43,21 @@
4343
#include "huf.h"
4444

4545

46-
/*-****************************************
47-
* FSE Error Management
48-
******************************************/
49-
unsigned FSE_isError(size_t code) { return ERR_isError(code); }
46+
/*=== Version ===*/
47+
unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; }
5048

51-
const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); }
5249

50+
/*=== Error Management ===*/
51+
unsigned FSE_isError(size_t code) { return ERR_isError(code); }
52+
const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); }
5353

54-
/* **************************************************************
55-
* HUF Error Management
56-
****************************************************************/
5754
unsigned HUF_isError(size_t code) { return ERR_isError(code); }
58-
5955
const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); }
6056

6157

6258
/*-**************************************************************
6359
* FSE NCount encoding-decoding
6460
****************************************************************/
65-
static short FSE_abs(short a) { return (short)(a<0 ? -a : a); }
66-
6761
size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
6862
const void* headerBuffer, size_t hbSize)
6963
{
@@ -117,21 +111,21 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
117111
} else {
118112
bitStream >>= 2;
119113
} }
120-
{ short const max = (short)((2*threshold-1)-remaining);
121-
short count;
114+
{ int const max = (2*threshold-1) - remaining;
115+
int count;
122116

123117
if ((bitStream & (threshold-1)) < (U32)max) {
124-
count = (short)(bitStream & (threshold-1));
125-
bitCount += nbBits-1;
118+
count = bitStream & (threshold-1);
119+
bitCount += nbBits-1;
126120
} else {
127-
count = (short)(bitStream & (2*threshold-1));
121+
count = bitStream & (2*threshold-1);
128122
if (count >= threshold) count -= max;
129-
bitCount += nbBits;
123+
bitCount += nbBits;
130124
}
131125

132126
count--; /* extra accuracy */
133-
remaining -= FSE_abs(count);
134-
normalizedCounter[charnum++] = count;
127+
remaining -= count < 0 ? -count : count; /* -1 means +1 */
128+
normalizedCounter[charnum++] = (short)count;
135129
previous0 = !count;
136130
while (remaining < threshold) {
137131
nbBits--;

ext/zstdruby/libzstd/common/fse.h

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,32 @@ extern "C" {
4545
#include <stddef.h> /* size_t, ptrdiff_t */
4646

4747

48+
/*-*****************************************
49+
* FSE_PUBLIC_API : control library symbols visibility
50+
******************************************/
51+
#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4)
52+
# define FSE_PUBLIC_API __attribute__ ((visibility ("default")))
53+
#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */
54+
# define FSE_PUBLIC_API __declspec(dllexport)
55+
#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1)
56+
# define FSE_PUBLIC_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
57+
#else
58+
# define FSE_PUBLIC_API
59+
#endif
60+
61+
/*------ Version ------*/
62+
#define FSE_VERSION_MAJOR 0
63+
#define FSE_VERSION_MINOR 9
64+
#define FSE_VERSION_RELEASE 0
65+
66+
#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE
67+
#define FSE_QUOTE(str) #str
68+
#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str)
69+
#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION)
70+
71+
#define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE)
72+
FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number; to be used when checking dll version */
73+
4874
/*-****************************************
4975
* FSE simple functions
5076
******************************************/
@@ -56,8 +82,8 @@ extern "C" {
5682
if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression instead.
5783
if FSE_isError(return), compression failed (more details using FSE_getErrorName())
5884
*/
59-
size_t FSE_compress(void* dst, size_t dstCapacity,
60-
const void* src, size_t srcSize);
85+
FSE_PUBLIC_API size_t FSE_compress(void* dst, size_t dstCapacity,
86+
const void* src, size_t srcSize);
6187

6288
/*! FSE_decompress():
6389
Decompress FSE data from buffer 'cSrc', of size 'cSrcSize',
@@ -69,18 +95,18 @@ size_t FSE_compress(void* dst, size_t dstCapacity,
6995
Why ? : making this distinction requires a header.
7096
Header management is intentionally delegated to the user layer, which can better manage special cases.
7197
*/
72-
size_t FSE_decompress(void* dst, size_t dstCapacity,
73-
const void* cSrc, size_t cSrcSize);
98+
FSE_PUBLIC_API size_t FSE_decompress(void* dst, size_t dstCapacity,
99+
const void* cSrc, size_t cSrcSize);
74100

75101

76102
/*-*****************************************
77103
* Tool functions
78104
******************************************/
79-
size_t FSE_compressBound(size_t size); /* maximum compressed size */
105+
FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */
80106

81107
/* Error Management */
82-
unsigned FSE_isError(size_t code); /* tells if a return value is an error code */
83-
const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */
108+
FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */
109+
FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */
84110

85111

86112
/*-*****************************************
@@ -94,7 +120,7 @@ const char* FSE_getErrorName(size_t code); /* provides error code string (usef
94120
if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression.
95121
if FSE_isError(return), it's an error code.
96122
*/
97-
size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
123+
FSE_PUBLIC_API size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
98124

99125

100126
/*-*****************************************
@@ -127,50 +153,50 @@ or to save and provide normalized distribution using external method.
127153
@return : the count of the most frequent symbol (which is not identified).
128154
if return == srcSize, there is only one symbol.
129155
Can also return an error code, which can be tested with FSE_isError(). */
130-
size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
156+
FSE_PUBLIC_API size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
131157

132158
/*! FSE_optimalTableLog():
133159
dynamically downsize 'tableLog' when conditions are met.
134160
It saves CPU time, by using smaller tables, while preserving or even improving compression ratio.
135161
@return : recommended tableLog (necessarily <= 'maxTableLog') */
136-
unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
162+
FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
137163

138164
/*! FSE_normalizeCount():
139165
normalize counts so that sum(count[]) == Power_of_2 (2^tableLog)
140166
'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1).
141167
@return : tableLog,
142168
or an errorCode, which can be tested using FSE_isError() */
143-
size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, const unsigned* count, size_t srcSize, unsigned maxSymbolValue);
169+
FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, const unsigned* count, size_t srcSize, unsigned maxSymbolValue);
144170

145171
/*! FSE_NCountWriteBound():
146172
Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'.
147173
Typically useful for allocation purpose. */
148-
size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog);
174+
FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog);
149175

150176
/*! FSE_writeNCount():
151177
Compactly save 'normalizedCounter' into 'buffer'.
152178
@return : size of the compressed table,
153179
or an errorCode, which can be tested using FSE_isError(). */
154-
size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
180+
FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
155181

156182

157183
/*! Constructor and Destructor of FSE_CTable.
158184
Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */
159185
typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */
160-
FSE_CTable* FSE_createCTable (unsigned tableLog, unsigned maxSymbolValue);
161-
void FSE_freeCTable (FSE_CTable* ct);
186+
FSE_PUBLIC_API FSE_CTable* FSE_createCTable (unsigned tableLog, unsigned maxSymbolValue);
187+
FSE_PUBLIC_API void FSE_freeCTable (FSE_CTable* ct);
162188

163189
/*! FSE_buildCTable():
164190
Builds `ct`, which must be already allocated, using FSE_createCTable().
165191
@return : 0, or an errorCode, which can be tested using FSE_isError() */
166-
size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
192+
FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
167193

168194
/*! FSE_compress_usingCTable():
169195
Compress `src` using `ct` into `dst` which must be already allocated.
170196
@return : size of compressed data (<= `dstCapacity`),
171197
or 0 if compressed data could not fit into `dst`,
172198
or an errorCode, which can be tested using FSE_isError() */
173-
size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct);
199+
FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct);
174200

175201
/*!
176202
Tutorial :
@@ -223,25 +249,25 @@ If there is an error, the function will return an ErrorCode (which can be tested
223249
@return : size read from 'rBuffer',
224250
or an errorCode, which can be tested using FSE_isError().
225251
maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */
226-
size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize);
252+
FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize);
227253

228254
/*! Constructor and Destructor of FSE_DTable.
229255
Note that its size depends on 'tableLog' */
230256
typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */
231-
FSE_DTable* FSE_createDTable(unsigned tableLog);
232-
void FSE_freeDTable(FSE_DTable* dt);
257+
FSE_PUBLIC_API FSE_DTable* FSE_createDTable(unsigned tableLog);
258+
FSE_PUBLIC_API void FSE_freeDTable(FSE_DTable* dt);
233259

234260
/*! FSE_buildDTable():
235261
Builds 'dt', which must be already allocated, using FSE_createDTable().
236262
return : 0, or an errorCode, which can be tested using FSE_isError() */
237-
size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
263+
FSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
238264

239265
/*! FSE_decompress_usingDTable():
240266
Decompress compressed source `cSrc` of size `cSrcSize` using `dt`
241267
into `dst` which must be already allocated.
242268
@return : size of regenerated data (necessarily <= `dstCapacity`),
243269
or an errorCode, which can be tested using FSE_isError() */
244-
size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt);
270+
FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt);
245271

246272
/*!
247273
Tutorial :

ext/zstdruby/libzstd/common/fse_decompress.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
****************************************************************/
6060
#include <stdlib.h> /* malloc, free, qsort */
6161
#include <string.h> /* memcpy, memset */
62-
#include <stdio.h> /* printf (debug) */
6362
#include "bitstream.h"
6463
#define FSE_STATIC_LINKING_ONLY
6564
#include "fse.h"

ext/zstdruby/libzstd/common/huf.h

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize
9191

9292
/** HUF_compress4X_wksp() :
9393
* Same as HUF_compress2(), but uses externally allocated `workSpace`, which must be a table of >= 1024 unsigned */
94-
size_t HUF_compress4X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least 1024 unsigned */
94+
size_t HUF_compress4X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
9595

9696

9797

@@ -102,10 +102,11 @@ size_t HUF_compress4X_wksp (void* dst, size_t dstSize, const void* src, size_t s
102102

103103

104104
/* *** Constants *** */
105-
#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
106-
#define HUF_TABLELOG_MAX 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
105+
#define HUF_TABLELOG_MAX 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
107106
#define HUF_TABLELOG_DEFAULT 11 /* tableLog by default, when not specified */
108-
#define HUF_SYMBOLVALUE_MAX 255
107+
#define HUF_SYMBOLVALUE_MAX 255
108+
109+
#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
109110
#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX)
110111
# error "HUF_TABLELOG_MAX is too large !"
111112
#endif
@@ -133,6 +134,10 @@ typedef U32 HUF_DTable;
133134
#define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \
134135
HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) }
135136

137+
/* The workspace must have alignment at least 4 and be at least this large */
138+
#define HUF_WORKSPACE_SIZE (6 << 10)
139+
#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32))
140+
136141

137142
/* ****************************************
138143
* Advanced decompression functions
@@ -168,6 +173,17 @@ size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSym
168173
size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);
169174
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
170175

176+
typedef enum {
177+
HUF_repeat_none, /**< Cannot use the previous table */
178+
HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */
179+
HUF_repeat_valid /**< Can use the previous table and it is asumed to be valid */
180+
} HUF_repeat;
181+
/** HUF_compress4X_repeat() :
182+
* Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
183+
* If it uses hufTable it does not modify hufTable or repeat.
184+
* If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
185+
* If preferRepeat then the old table will always be used if valid. */
186+
size_t HUF_compress4X_repeat(void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize, HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
171187

172188
/** HUF_buildCTable_wksp() :
173189
* Same as HUF_buildCTable(), but using externally allocated scratch buffer.
@@ -214,8 +230,14 @@ size_t HUF_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* c
214230
/* single stream variants */
215231

216232
size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
217-
size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least 1024 unsigned */
233+
size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
218234
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
235+
/** HUF_compress1X_repeat() :
236+
* Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
237+
* If it uses hufTable it does not modify hufTable or repeat.
238+
* If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
239+
* If preferRepeat then the old table will always be used if valid. */
240+
size_t HUF_compress1X_repeat(void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize, HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
219241

220242
size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
221243
size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */

0 commit comments

Comments
 (0)