1 /*
2  * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under both the BSD-style license (found in the
6  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7  * in the COPYING file in the root directory of this source tree).
8  * You may select, at your option, one of the above-listed licenses.
9  */
10 
11 
12 /* ===   Tuning parameters   === */
13 #ifndef ZWRAP_USE_ZSTD
14     #define ZWRAP_USE_ZSTD 0
15 #endif
16 
17 
18 /* ===   Dependencies   === */
19 #include <stdlib.h>
20 #include <stdio.h>                 /* vsprintf */
21 #include <stdarg.h>                /* va_list, for z_gzprintf */
22 #define NO_DUMMY_DECL
23 #define ZLIB_CONST
24 #include <zlib.h>                  /* without #define Z_PREFIX */
25 #include "zstd_zlibwrapper.h"
26 #define ZSTD_STATIC_LINKING_ONLY   /* ZSTD_isFrame, ZSTD_MAGICNUMBER */
27 #include "zstd.h"
28 #include "zstd_internal.h"         /* ZSTD_malloc, ZSTD_free */
29 
30 
31 /* ===   Constants   === */
32 #define Z_INFLATE_SYNC              8
33 #define ZLIB_HEADERSIZE             4
34 #define ZSTD_HEADERSIZE             ZSTD_FRAMEHEADERSIZE_MIN
35 #define ZWRAP_DEFAULT_CLEVEL        3   /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */
36 
37 
38 /* ===   Debug   === */
39 #define LOG_WRAPPERC(...)  /* fprintf(stderr, __VA_ARGS__) */
40 #define LOG_WRAPPERD(...)  /* fprintf(stderr, __VA_ARGS__) */
41 
42 #define FINISH_WITH_GZ_ERR(msg) { (void)msg; return Z_STREAM_ERROR; }
43 #define FINISH_WITH_NULL_ERR(msg) { (void)msg; return NULL; }
44 
45 
46 /* ===   Wrapper   === */
47 static int g_ZWRAP_useZSTDcompression = ZWRAP_USE_ZSTD; /* 0 = don't use ZSTD */
48 
49 void ZWRAP_useZSTDcompression(int turn_on) { g_ZWRAP_useZSTDcompression = turn_on; }
50 
51 int ZWRAP_isUsingZSTDcompression(void) { return g_ZWRAP_useZSTDcompression; }
52 
53 
54 
55 static ZWRAP_decompress_type g_ZWRAPdecompressionType = ZWRAP_AUTO;
56 
57 void ZWRAP_setDecompressionType(ZWRAP_decompress_type type) { g_ZWRAPdecompressionType = type; };
58 
59 ZWRAP_decompress_type ZWRAP_getDecompressionType(void) { return g_ZWRAPdecompressionType; }
60 
61 
62 
63 const char * zstdVersion(void) { return ZSTD_VERSION_STRING; }
64 
65 ZEXTERN const char * ZEXPORT z_zlibVersion OF((void)) { return zlibVersion();  }
66 
67 
68 
69 static void* ZWRAP_allocFunction(void* opaque, size_t size)
70 {
71     z_streamp strm = (z_streamp) opaque;
72     void* address = strm->zalloc(strm->opaque, 1, (uInt)size);
73     /* LOG_WRAPPERC("ZWRAP alloc %p, %d \n", address, (int)size); */
74     return address;
75 }
76 
77 static void ZWRAP_freeFunction(void* opaque, void* address)
78 {
79     z_streamp strm = (z_streamp) opaque;
80     strm->zfree(strm->opaque, address);
81    /* if (address) LOG_WRAPPERC("ZWRAP free %p \n", address); */
82 }
83 
84 
85 
86 /* ===   Compression   === */
87 typedef enum { ZWRAP_useInit, ZWRAP_useReset, ZWRAP_streamEnd } ZWRAP_state_t;
88 
89 typedef struct {
90     ZSTD_CStream* zbc;
91     int compressionLevel;
92     int streamEnd; /* a flag to signal the end of a stream */
93     unsigned long long totalInBytes; /* we need it as strm->total_in can be reset by user */
94     ZSTD_customMem customMem;
95     z_stream allocFunc; /* copy of zalloc, zfree, opaque */
96     ZSTD_inBuffer inBuffer;
97     ZSTD_outBuffer outBuffer;
98     ZWRAP_state_t comprState;
99     unsigned long long pledgedSrcSize;
100 } ZWRAP_CCtx;
101 
102 typedef ZWRAP_CCtx internal_state;
103 
104 
105 
106 static size_t ZWRAP_freeCCtx(ZWRAP_CCtx* zwc)
107 {
108     if (zwc==NULL) return 0;   /* support free on NULL */
109     ZSTD_freeCStream(zwc->zbc);
110     ZSTD_free(zwc, zwc->customMem);
111     return 0;
112 }
113 
114 
115 static ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm)
116 {
117     ZWRAP_CCtx* zwc;
118 
119     if (strm->zalloc && strm->zfree) {
120         zwc = (ZWRAP_CCtx*)strm->zalloc(strm->opaque, 1, sizeof(ZWRAP_CCtx));
121         if (zwc==NULL) return NULL;
122         memset(zwc, 0, sizeof(ZWRAP_CCtx));
123         memcpy(&zwc->allocFunc, strm, sizeof(z_stream));
124         { ZSTD_customMem const ZWRAP_customMem = { ZWRAP_allocFunction, ZWRAP_freeFunction, &zwc->allocFunc };
125           zwc->customMem = ZWRAP_customMem; }
126     } else {
127         zwc = (ZWRAP_CCtx*)calloc(1, sizeof(*zwc));
128         if (zwc==NULL) return NULL;
129     }
130 
131     return zwc;
132 }
133 
134 
135 static int ZWRAP_initializeCStream(ZWRAP_CCtx* zwc, const void* dict, size_t dictSize, unsigned long long pledgedSrcSize)
136 {
137     LOG_WRAPPERC("- ZWRAP_initializeCStream=%p\n", zwc);
138     if (zwc == NULL || zwc->zbc == NULL) return Z_STREAM_ERROR;
139 
140     if (!pledgedSrcSize) pledgedSrcSize = zwc->pledgedSrcSize;
141     {   ZSTD_parameters const params = ZSTD_getParams(zwc->compressionLevel, pledgedSrcSize, dictSize);
142         size_t initErr;
143         LOG_WRAPPERC("pledgedSrcSize=%d windowLog=%d chainLog=%d hashLog=%d searchLog=%d minMatch=%d strategy=%d\n",
144                     (int)pledgedSrcSize, params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.minMatch, params.cParams.strategy);
145         initErr = ZSTD_initCStream_advanced(zwc->zbc, dict, dictSize, params, pledgedSrcSize);
146         if (ZSTD_isError(initErr)) return Z_STREAM_ERROR;
147     }
148 
149     return Z_OK;
150 }
151 
152 
153 static int ZWRAPC_finishWithError(ZWRAP_CCtx* zwc, z_streamp strm, int error)
154 {
155     LOG_WRAPPERC("- ZWRAPC_finishWithError=%d\n", error);
156     if (zwc) ZWRAP_freeCCtx(zwc);
157     if (strm) strm->state = NULL;
158     return (error) ? error : Z_STREAM_ERROR;
159 }
160 
161 
162 static int ZWRAPC_finishWithErrorMsg(z_streamp strm, char* message)
163 {
164     ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
165     strm->msg = message;
166     if (zwc == NULL) return Z_STREAM_ERROR;
167 
168     return ZWRAPC_finishWithError(zwc, strm, 0);
169 }
170 
171 
172 int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize)
173 {
174     ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
175     if (zwc == NULL) return Z_STREAM_ERROR;
176 
177     zwc->pledgedSrcSize = pledgedSrcSize;
178     zwc->comprState = ZWRAP_useInit;
179     return Z_OK;
180 }
181 
182 
183 ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level,
184                                      const char *version, int stream_size))
185 {
186     ZWRAP_CCtx* zwc;
187 
188     LOG_WRAPPERC("- deflateInit level=%d\n", level);
189     if (!g_ZWRAP_useZSTDcompression) {
190         return deflateInit_((strm), (level), version, stream_size);
191     }
192 
193     zwc = ZWRAP_createCCtx(strm);
194     if (zwc == NULL) return Z_MEM_ERROR;
195 
196     if (level == Z_DEFAULT_COMPRESSION)
197         level = ZWRAP_DEFAULT_CLEVEL;
198 
199     zwc->streamEnd = 0;
200     zwc->totalInBytes = 0;
201     zwc->compressionLevel = level;
202     strm->state = (struct internal_state*) zwc; /* use state which in not used by user */
203     strm->total_in = 0;
204     strm->total_out = 0;
205     strm->adler = 0;
206     return Z_OK;
207 }
208 
209 
210 ZEXTERN int ZEXPORT z_deflateInit2_ OF((z_streamp strm, int level, int method,
211                                       int windowBits, int memLevel,
212                                       int strategy, const char *version,
213                                       int stream_size))
214 {
215     if (!g_ZWRAP_useZSTDcompression)
216         return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, version, stream_size);
217 
218     return z_deflateInit_ (strm, level, version, stream_size);
219 }
220 
221 
222 int ZWRAP_deflateReset_keepDict(z_streamp strm)
223 {
224     LOG_WRAPPERC("- ZWRAP_deflateReset_keepDict\n");
225     if (!g_ZWRAP_useZSTDcompression)
226         return deflateReset(strm);
227 
228     { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
229       if (zwc) {
230           zwc->streamEnd = 0;
231           zwc->totalInBytes = 0;
232       }
233     }
234 
235     strm->total_in = 0;
236     strm->total_out = 0;
237     strm->adler = 0;
238     return Z_OK;
239 }
240 
241 
242 ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm))
243 {
244     LOG_WRAPPERC("- deflateReset\n");
245     if (!g_ZWRAP_useZSTDcompression)
246         return deflateReset(strm);
247 
248     ZWRAP_deflateReset_keepDict(strm);
249 
250     { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
251       if (zwc) zwc->comprState = ZWRAP_useInit;
252     }
253     return Z_OK;
254 }
255 
256 
257 ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm,
258                                              const Bytef *dictionary,
259                                              uInt  dictLength))
260 {
261     if (!g_ZWRAP_useZSTDcompression) {
262         LOG_WRAPPERC("- deflateSetDictionary\n");
263         return deflateSetDictionary(strm, dictionary, dictLength);
264     }
265 
266     {   ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
267         LOG_WRAPPERC("- deflateSetDictionary level=%d\n", (int)zwc->compressionLevel);
268         if (!zwc) return Z_STREAM_ERROR;
269         if (zwc->zbc == NULL) {
270             zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem);
271             if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, 0);
272         }
273         { int res = ZWRAP_initializeCStream(zwc, dictionary, dictLength, ZSTD_CONTENTSIZE_UNKNOWN);
274           if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); }
275         zwc->comprState = ZWRAP_useReset;
276     }
277 
278     return Z_OK;
279 }
280 
281 
282 ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush))
283 {
284     ZWRAP_CCtx* zwc;
285 
286     if (!g_ZWRAP_useZSTDcompression) {
287         LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n",
288                     (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
289         return deflate(strm, flush);
290     }
291 
292     zwc = (ZWRAP_CCtx*) strm->state;
293     if (zwc == NULL) { LOG_WRAPPERC("zwc == NULL\n"); return Z_STREAM_ERROR; }
294 
295     if (zwc->zbc == NULL) {
296         zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem);
297         if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, 0);
298         { int const initErr = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : ZSTD_CONTENTSIZE_UNKNOWN);
299           if (initErr != Z_OK) return ZWRAPC_finishWithError(zwc, strm, initErr); }
300         if (flush != Z_FINISH) zwc->comprState = ZWRAP_useReset;
301     } else {
302         if (zwc->totalInBytes == 0) {
303             if (zwc->comprState == ZWRAP_useReset) {
304                 size_t const resetErr = ZSTD_resetCStream(zwc->zbc, (flush == Z_FINISH) ? strm->avail_in : zwc->pledgedSrcSize);
305                 if (ZSTD_isError(resetErr)) {
306                     LOG_WRAPPERC("ERROR: ZSTD_resetCStream errorCode=%s\n",
307                                 ZSTD_getErrorName(resetErr));
308                     return ZWRAPC_finishWithError(zwc, strm, 0);
309                 }
310             } else {
311                 int const res = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : ZSTD_CONTENTSIZE_UNKNOWN);
312                 if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res);
313                 if (flush != Z_FINISH) zwc->comprState = ZWRAP_useReset;
314             }
315         }  /* (zwc->totalInBytes == 0) */
316     }  /* ! (zwc->zbc == NULL) */
317 
318     LOG_WRAPPERC("- deflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
319     if (strm->avail_in > 0) {
320         zwc->inBuffer.src = strm->next_in;
321         zwc->inBuffer.size = strm->avail_in;
322         zwc->inBuffer.pos = 0;
323         zwc->outBuffer.dst = strm->next_out;
324         zwc->outBuffer.size = strm->avail_out;
325         zwc->outBuffer.pos = 0;
326         { size_t const cErr = ZSTD_compressStream(zwc->zbc, &zwc->outBuffer, &zwc->inBuffer);
327           LOG_WRAPPERC("deflate ZSTD_compressStream srcSize=%d dstCapacity=%d\n", (int)zwc->inBuffer.size, (int)zwc->outBuffer.size);
328           if (ZSTD_isError(cErr)) return ZWRAPC_finishWithError(zwc, strm, 0);
329         }
330         strm->next_out += zwc->outBuffer.pos;
331         strm->total_out += zwc->outBuffer.pos;
332         strm->avail_out -= zwc->outBuffer.pos;
333         strm->total_in += zwc->inBuffer.pos;
334         zwc->totalInBytes += zwc->inBuffer.pos;
335         strm->next_in += zwc->inBuffer.pos;
336         strm->avail_in -= zwc->inBuffer.pos;
337     }
338 
339     if (flush == Z_FULL_FLUSH
340 #if ZLIB_VERNUM >= 0x1240
341         || flush == Z_TREES
342 #endif
343         || flush == Z_BLOCK)
344         return ZWRAPC_finishWithErrorMsg(strm, "Z_FULL_FLUSH, Z_BLOCK and Z_TREES are not supported!");
345 
346     if (flush == Z_FINISH) {
347         size_t bytesLeft;
348         if (zwc->streamEnd) return Z_STREAM_END;
349         zwc->outBuffer.dst = strm->next_out;
350         zwc->outBuffer.size = strm->avail_out;
351         zwc->outBuffer.pos = 0;
352         bytesLeft = ZSTD_endStream(zwc->zbc, &zwc->outBuffer);
353         LOG_WRAPPERC("deflate ZSTD_endStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft);
354         if (ZSTD_isError(bytesLeft)) return ZWRAPC_finishWithError(zwc, strm, 0);
355         strm->next_out += zwc->outBuffer.pos;
356         strm->total_out += zwc->outBuffer.pos;
357         strm->avail_out -= zwc->outBuffer.pos;
358         if (bytesLeft == 0) {
359             zwc->streamEnd = 1;
360             LOG_WRAPPERC("Z_STREAM_END2 strm->total_in=%d strm->avail_out=%d strm->total_out=%d\n",
361                         (int)strm->total_in, (int)strm->avail_out, (int)strm->total_out);
362             return Z_STREAM_END;
363     }   }
364     else
365     if (flush == Z_SYNC_FLUSH || flush == Z_PARTIAL_FLUSH) {
366         size_t bytesLeft;
367         zwc->outBuffer.dst = strm->next_out;
368         zwc->outBuffer.size = strm->avail_out;
369         zwc->outBuffer.pos = 0;
370         bytesLeft = ZSTD_flushStream(zwc->zbc, &zwc->outBuffer);
371         LOG_WRAPPERC("deflate ZSTD_flushStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft);
372         if (ZSTD_isError(bytesLeft)) return ZWRAPC_finishWithError(zwc, strm, 0);
373         strm->next_out += zwc->outBuffer.pos;
374         strm->total_out += zwc->outBuffer.pos;
375         strm->avail_out -= zwc->outBuffer.pos;
376     }
377     LOG_WRAPPERC("- deflate3 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
378     return Z_OK;
379 }
380 
381 
382 ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm))
383 {
384     if (!g_ZWRAP_useZSTDcompression) {
385         LOG_WRAPPERC("- deflateEnd\n");
386         return deflateEnd(strm);
387     }
388     LOG_WRAPPERC("- deflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out));
389     {   size_t errorCode;
390         ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
391         if (zwc == NULL) return Z_OK;  /* structures are already freed */
392         strm->state = NULL;
393         errorCode = ZWRAP_freeCCtx(zwc);
394         if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR;
395     }
396     return Z_OK;
397 }
398 
399 
400 ZEXTERN uLong ZEXPORT z_deflateBound OF((z_streamp strm,
401                                        uLong sourceLen))
402 {
403     if (!g_ZWRAP_useZSTDcompression)
404         return deflateBound(strm, sourceLen);
405 
406     return ZSTD_compressBound(sourceLen);
407 }
408 
409 
410 ZEXTERN int ZEXPORT z_deflateParams OF((z_streamp strm,
411                                       int level,
412                                       int strategy))
413 {
414     if (!g_ZWRAP_useZSTDcompression) {
415         LOG_WRAPPERC("- deflateParams level=%d strategy=%d\n", level, strategy);
416         return deflateParams(strm, level, strategy);
417     }
418 
419     return Z_OK;
420 }
421 
422 
423 
424 
425 
426 /* ===   Decompression   === */
427 
428 typedef enum { ZWRAP_ZLIB_STREAM, ZWRAP_ZSTD_STREAM, ZWRAP_UNKNOWN_STREAM } ZWRAP_stream_type;
429 
430 typedef struct {
431     ZSTD_DStream* zbd;
432     char headerBuf[16];   /* must be >= ZSTD_frameHeaderSize_min */
433     int errorCount;
434     unsigned long long totalInBytes; /* we need it as strm->total_in can be reset by user */
435     ZWRAP_state_t decompState;
436     ZSTD_inBuffer inBuffer;
437     ZSTD_outBuffer outBuffer;
438 
439     /* zlib params */
440     int stream_size;
441     char *version;
442     int windowBits;
443     ZSTD_customMem customMem;
444     z_stream allocFunc; /* just to copy zalloc, zfree, opaque */
445 } ZWRAP_DCtx;
446 
447 
448 static void ZWRAP_initDCtx(ZWRAP_DCtx* zwd)
449 {
450     zwd->errorCount = 0;
451     zwd->outBuffer.pos = 0;
452     zwd->outBuffer.size = 0;
453 }
454 
455 static ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm)
456 {
457     ZWRAP_DCtx* zwd;
458     MEM_STATIC_ASSERT(sizeof(zwd->headerBuf) >= ZSTD_FRAMEHEADERSIZE_MIN);   /* check static buffer size condition */
459 
460     if (strm->zalloc && strm->zfree) {
461         zwd = (ZWRAP_DCtx*)strm->zalloc(strm->opaque, 1, sizeof(ZWRAP_DCtx));
462         if (zwd==NULL) return NULL;
463         memset(zwd, 0, sizeof(ZWRAP_DCtx));
464         zwd->allocFunc = *strm;  /* just to copy zalloc, zfree & opaque */
465         { ZSTD_customMem const ZWRAP_customMem = { ZWRAP_allocFunction, ZWRAP_freeFunction, &zwd->allocFunc };
466           zwd->customMem = ZWRAP_customMem; }
467     } else {
468         zwd = (ZWRAP_DCtx*)calloc(1, sizeof(*zwd));
469         if (zwd==NULL) return NULL;
470     }
471 
472     ZWRAP_initDCtx(zwd);
473     return zwd;
474 }
475 
476 static size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd)
477 {
478     if (zwd==NULL) return 0;   /* support free on null */
479     ZSTD_freeDStream(zwd->zbd);
480     ZSTD_free(zwd->version, zwd->customMem);
481     ZSTD_free(zwd, zwd->customMem);
482     return 0;
483 }
484 
485 
486 int ZWRAP_isUsingZSTDdecompression(z_streamp strm)
487 {
488     if (strm == NULL) return 0;
489     return (strm->reserved == ZWRAP_ZSTD_STREAM);
490 }
491 
492 
493 static int ZWRAPD_finishWithError(ZWRAP_DCtx* zwd, z_streamp strm, int error)
494 {
495     LOG_WRAPPERD("- ZWRAPD_finishWithError=%d\n", error);
496     ZWRAP_freeDCtx(zwd);
497     strm->state = NULL;
498     return (error) ? error : Z_STREAM_ERROR;
499 }
500 
501 static int ZWRAPD_finishWithErrorMsg(z_streamp strm, char* message)
502 {
503     ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state;
504     strm->msg = message;
505     if (zwd == NULL) return Z_STREAM_ERROR;
506 
507     return ZWRAPD_finishWithError(zwd, strm, 0);
508 }
509 
510 
511 ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm,
512                                      const char *version, int stream_size))
513 {
514     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB) {
515         strm->reserved = ZWRAP_ZLIB_STREAM;
516         return inflateInit(strm);
517     }
518 
519     {   ZWRAP_DCtx* const zwd = ZWRAP_createDCtx(strm);
520         LOG_WRAPPERD("- inflateInit\n");
521         if (zwd == NULL) return ZWRAPD_finishWithError(zwd, strm, 0);
522 
523         zwd->version = ZSTD_malloc(strlen(version)+1, zwd->customMem);
524         if (zwd->version == NULL) return ZWRAPD_finishWithError(zwd, strm, 0);
525         strcpy(zwd->version, version);
526 
527         zwd->stream_size = stream_size;
528         zwd->totalInBytes = 0;
529         strm->state = (struct internal_state*) zwd;
530         strm->total_in = 0;
531         strm->total_out = 0;
532         strm->reserved = ZWRAP_UNKNOWN_STREAM;
533         strm->adler = 0;
534     }
535 
536     return Z_OK;
537 }
538 
539 
540 ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int  windowBits,
541                                       const char *version, int stream_size))
542 {
543     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB) {
544         return inflateInit2_(strm, windowBits, version, stream_size);
545     }
546 
547     {   int const ret = z_inflateInit_ (strm, version, stream_size);
548         LOG_WRAPPERD("- inflateInit2 windowBits=%d\n", windowBits);
549         if (ret == Z_OK) {
550             ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*)strm->state;
551             if (zwd == NULL) return Z_STREAM_ERROR;
552             zwd->windowBits = windowBits;
553         }
554         return ret;
555     }
556 }
557 
558 int ZWRAP_inflateReset_keepDict(z_streamp strm)
559 {
560     LOG_WRAPPERD("- ZWRAP_inflateReset_keepDict\n");
561     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
562         return inflateReset(strm);
563 
564     {   ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state;
565         if (zwd == NULL) return Z_STREAM_ERROR;
566         ZWRAP_initDCtx(zwd);
567         zwd->decompState = ZWRAP_useReset;
568         zwd->totalInBytes = 0;
569     }
570 
571     strm->total_in = 0;
572     strm->total_out = 0;
573     return Z_OK;
574 }
575 
576 
577 ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm))
578 {
579     LOG_WRAPPERD("- inflateReset\n");
580     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
581         return inflateReset(strm);
582 
583     { int const ret = ZWRAP_inflateReset_keepDict(strm);
584       if (ret != Z_OK) return ret; }
585 
586     { ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state;
587       if (zwd == NULL) return Z_STREAM_ERROR;
588       zwd->decompState = ZWRAP_useInit; }
589 
590     return Z_OK;
591 }
592 
593 
594 #if ZLIB_VERNUM >= 0x1240
595 ZEXTERN int ZEXPORT z_inflateReset2 OF((z_streamp strm,
596                                       int windowBits))
597 {
598     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
599         return inflateReset2(strm, windowBits);
600 
601     {   int const ret = z_inflateReset (strm);
602         if (ret == Z_OK) {
603             ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*)strm->state;
604             if (zwd == NULL) return Z_STREAM_ERROR;
605             zwd->windowBits = windowBits;
606         }
607         return ret;
608     }
609 }
610 #endif
611 
612 
613 ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm,
614                                              const Bytef *dictionary,
615                                              uInt  dictLength))
616 {
617     LOG_WRAPPERD("- inflateSetDictionary\n");
618     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
619         return inflateSetDictionary(strm, dictionary, dictLength);
620 
621     {   ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state;
622         if (zwd == NULL || zwd->zbd == NULL) return Z_STREAM_ERROR;
623         { size_t const initErr = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength);
624           if (ZSTD_isError(initErr)) return ZWRAPD_finishWithError(zwd, strm, 0); }
625         zwd->decompState = ZWRAP_useReset;
626 
627         if (zwd->totalInBytes == ZSTD_HEADERSIZE) {
628             zwd->inBuffer.src = zwd->headerBuf;
629             zwd->inBuffer.size = zwd->totalInBytes;
630             zwd->inBuffer.pos = 0;
631             zwd->outBuffer.dst = strm->next_out;
632             zwd->outBuffer.size = 0;
633             zwd->outBuffer.pos = 0;
634             {   size_t const errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer);
635                 LOG_WRAPPERD("inflateSetDictionary ZSTD_decompressStream errorCode=%d srcSize=%d dstCapacity=%d\n",
636                              (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size);
637                 if (zwd->inBuffer.pos < zwd->outBuffer.size || ZSTD_isError(errorCode)) {
638                     LOG_WRAPPERD("ERROR: ZSTD_decompressStream %s\n",
639                                  ZSTD_getErrorName(errorCode));
640                     return ZWRAPD_finishWithError(zwd, strm, 0);
641     }   }   }   }
642 
643     return Z_OK;
644 }
645 
646 
647 ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush))
648 {
649     ZWRAP_DCtx* zwd;
650 
651     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) {
652         int const result = inflate(strm, flush);
653         LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n",
654                      (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, result);
655         return result;
656     }
657 
658     if (strm->avail_in <= 0) return Z_OK;
659 
660     zwd = (ZWRAP_DCtx*) strm->state;
661     LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n",
662                  (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
663 
664     if (zwd == NULL) return Z_STREAM_ERROR;
665     if (zwd->decompState == ZWRAP_streamEnd) return Z_STREAM_END;
666 
667     if (zwd->totalInBytes < ZLIB_HEADERSIZE) {
668         if (zwd->totalInBytes == 0 && strm->avail_in >= ZLIB_HEADERSIZE) {
669             if (MEM_readLE32(strm->next_in) != ZSTD_MAGICNUMBER) {
670                 {   int const initErr = (zwd->windowBits) ?
671                                 inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size) :
672                                 inflateInit_(strm, zwd->version, zwd->stream_size);
673                     LOG_WRAPPERD("ZLIB inflateInit errorCode=%d\n", initErr);
674                     if (initErr != Z_OK) return ZWRAPD_finishWithError(zwd, strm, initErr);
675                 }
676 
677                 strm->reserved = ZWRAP_ZLIB_STREAM;
678                 { size_t const freeErr = ZWRAP_freeDCtx(zwd);
679                   if (ZSTD_isError(freeErr)) goto error; }
680 
681                 {   int const result = (flush == Z_INFLATE_SYNC) ?
682                                         inflateSync(strm) :
683                                         inflate(strm, flush);
684                     LOG_WRAPPERD("- inflate3 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n",
685                                  (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res);
686                     return result;
687             }   }
688         } else {  /* ! (zwd->totalInBytes == 0 && strm->avail_in >= ZLIB_HEADERSIZE) */
689             size_t const srcSize = MIN(strm->avail_in, ZLIB_HEADERSIZE - zwd->totalInBytes);
690             memcpy(zwd->headerBuf+zwd->totalInBytes, strm->next_in, srcSize);
691             strm->total_in += srcSize;
692             zwd->totalInBytes += srcSize;
693             strm->next_in += srcSize;
694             strm->avail_in -= srcSize;
695             if (zwd->totalInBytes < ZLIB_HEADERSIZE) return Z_OK;
696 
697             if (MEM_readLE32(zwd->headerBuf) != ZSTD_MAGICNUMBER) {
698                 z_stream strm2;
699                 strm2.next_in = strm->next_in;
700                 strm2.avail_in = strm->avail_in;
701                 strm2.next_out = strm->next_out;
702                 strm2.avail_out = strm->avail_out;
703 
704                 {   int const initErr = (zwd->windowBits) ?
705                                 inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size) :
706                                 inflateInit_(strm, zwd->version, zwd->stream_size);
707                     LOG_WRAPPERD("ZLIB inflateInit errorCode=%d\n", initErr);
708                     if (initErr != Z_OK) return ZWRAPD_finishWithError(zwd, strm, initErr);
709                 }
710 
711                 /* inflate header */
712                 strm->next_in = (unsigned char*)zwd->headerBuf;
713                 strm->avail_in = ZLIB_HEADERSIZE;
714                 strm->avail_out = 0;
715                 {   int const dErr = inflate(strm, Z_NO_FLUSH);
716                     LOG_WRAPPERD("ZLIB inflate errorCode=%d strm->avail_in=%d\n",
717                                   dErr, (int)strm->avail_in);
718                     if (dErr != Z_OK)
719                         return ZWRAPD_finishWithError(zwd, strm, dErr);
720                 }
721                 if (strm->avail_in > 0) goto error;
722 
723                 strm->next_in = strm2.next_in;
724                 strm->avail_in = strm2.avail_in;
725                 strm->next_out = strm2.next_out;
726                 strm->avail_out = strm2.avail_out;
727 
728                 strm->reserved = ZWRAP_ZLIB_STREAM; /* mark as zlib stream */
729                 { size_t const freeErr = ZWRAP_freeDCtx(zwd);
730                   if (ZSTD_isError(freeErr)) goto error; }
731 
732                 {   int const result = (flush == Z_INFLATE_SYNC) ?
733                                        inflateSync(strm) :
734                                        inflate(strm, flush);
735                     LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n",
736                                  (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res);
737                     return result;
738         }   }   }  /* if ! (zwd->totalInBytes == 0 && strm->avail_in >= ZLIB_HEADERSIZE) */
739     }  /* (zwd->totalInBytes < ZLIB_HEADERSIZE) */
740 
741     strm->reserved = ZWRAP_ZSTD_STREAM; /* mark as zstd steam */
742 
743     if (flush == Z_INFLATE_SYNC) { strm->msg = "inflateSync is not supported!"; goto error; }
744 
745     if (!zwd->zbd) {
746         zwd->zbd = ZSTD_createDStream_advanced(zwd->customMem);
747         if (zwd->zbd == NULL) { LOG_WRAPPERD("ERROR: ZSTD_createDStream_advanced\n"); goto error; }
748         zwd->decompState = ZWRAP_useInit;
749     }
750 
751     if (zwd->totalInBytes < ZSTD_HEADERSIZE) {
752         if (zwd->totalInBytes == 0 && strm->avail_in >= ZSTD_HEADERSIZE) {
753             if (zwd->decompState == ZWRAP_useInit) {
754                 size_t const initErr = ZSTD_initDStream(zwd->zbd);
755                 if (ZSTD_isError(initErr)) {
756                     LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n",
757                                  ZSTD_getErrorName(initErr));
758                     goto error;
759                 }
760             } else {
761                 size_t const resetErr = ZSTD_resetDStream(zwd->zbd);
762                 if (ZSTD_isError(resetErr)) goto error;
763             }
764         } else {
765             size_t const srcSize = MIN(strm->avail_in, ZSTD_HEADERSIZE - zwd->totalInBytes);
766             memcpy(zwd->headerBuf+zwd->totalInBytes, strm->next_in, srcSize);
767             strm->total_in += srcSize;
768             zwd->totalInBytes += srcSize;
769             strm->next_in += srcSize;
770             strm->avail_in -= srcSize;
771             if (zwd->totalInBytes < ZSTD_HEADERSIZE) return Z_OK;
772 
773             if (zwd->decompState == ZWRAP_useInit) {
774                 size_t const initErr = ZSTD_initDStream(zwd->zbd);
775                 if (ZSTD_isError(initErr)) {
776                     LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n",
777                                 ZSTD_getErrorName(initErr));
778                     goto error;
779                 }
780             } else {
781                 size_t const resetErr = ZSTD_resetDStream(zwd->zbd);
782                 if (ZSTD_isError(resetErr)) goto error;
783             }
784 
785             zwd->inBuffer.src = zwd->headerBuf;
786             zwd->inBuffer.size = ZSTD_HEADERSIZE;
787             zwd->inBuffer.pos = 0;
788             zwd->outBuffer.dst = strm->next_out;
789             zwd->outBuffer.size = 0;
790             zwd->outBuffer.pos = 0;
791             {   size_t const dErr = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer);
792                 LOG_WRAPPERD("inflate ZSTD_decompressStream1 errorCode=%d srcSize=%d dstCapacity=%d\n",
793                             (int)dErr, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size);
794                 if (ZSTD_isError(dErr)) {
795                     LOG_WRAPPERD("ERROR: ZSTD_decompressStream1 %s\n", ZSTD_getErrorName(dErr));
796                     goto error;
797             }   }
798             if (zwd->inBuffer.pos != zwd->inBuffer.size) goto error; /* not consumed */
799         }
800     }   /* (zwd->totalInBytes < ZSTD_HEADERSIZE) */
801 
802     zwd->inBuffer.src = strm->next_in;
803     zwd->inBuffer.size = strm->avail_in;
804     zwd->inBuffer.pos = 0;
805     zwd->outBuffer.dst = strm->next_out;
806     zwd->outBuffer.size = strm->avail_out;
807     zwd->outBuffer.pos = 0;
808     {   size_t const dErr = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer);
809         LOG_WRAPPERD("inflate ZSTD_decompressStream2 errorCode=%d srcSize=%d dstCapacity=%d\n",
810                     (int)dErr, (int)strm->avail_in, (int)strm->avail_out);
811         if (ZSTD_isError(dErr)) {
812             zwd->errorCount++;
813             LOG_WRAPPERD("ERROR: ZSTD_decompressStream2 %s zwd->errorCount=%d\n",
814                         ZSTD_getErrorName(dErr), zwd->errorCount);
815             if (zwd->errorCount<=1) return Z_NEED_DICT; else goto error;
816         }
817         LOG_WRAPPERD("inflate inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d outBuffer.size=%d o\n",
818                     (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos, (int)zwd->outBuffer.size);
819         strm->next_out += zwd->outBuffer.pos;
820         strm->total_out += zwd->outBuffer.pos;
821         strm->avail_out -= zwd->outBuffer.pos;
822         strm->total_in += zwd->inBuffer.pos;
823         zwd->totalInBytes += zwd->inBuffer.pos;
824         strm->next_in += zwd->inBuffer.pos;
825         strm->avail_in -= zwd->inBuffer.pos;
826         if (dErr == 0) {
827             LOG_WRAPPERD("inflate Z_STREAM_END1 avail_in=%d avail_out=%d total_in=%d total_out=%d\n",
828                         (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
829             zwd->decompState = ZWRAP_streamEnd;
830             return Z_STREAM_END;
831         }
832     }  /* dErr lifetime */
833 
834     LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n",
835                 (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, Z_OK);
836     return Z_OK;
837 
838 error:
839     return ZWRAPD_finishWithError(zwd, strm, 0);
840 }
841 
842 
843 ZEXTERN int ZEXPORT z_inflateEnd OF((z_streamp strm))
844 {
845     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
846         return inflateEnd(strm);
847 
848     LOG_WRAPPERD("- inflateEnd total_in=%d total_out=%d\n",
849                 (int)(strm->total_in), (int)(strm->total_out));
850     {   ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state;
851         if (zwd == NULL) return Z_OK;  /* structures are already freed */
852         { size_t const freeErr = ZWRAP_freeDCtx(zwd);
853           if (ZSTD_isError(freeErr)) return Z_STREAM_ERROR; }
854         strm->state = NULL;
855     }
856     return Z_OK;
857 }
858 
859 
860 ZEXTERN int ZEXPORT z_inflateSync OF((z_streamp strm))
861 {
862     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) {
863         return inflateSync(strm);
864     }
865 
866     return z_inflate(strm, Z_INFLATE_SYNC);
867 }
868 
869 
870 
871 /* Advanced compression functions */
872 ZEXTERN int ZEXPORT z_deflateCopy OF((z_streamp dest,
873                                     z_streamp source))
874 {
875     if (!g_ZWRAP_useZSTDcompression)
876         return deflateCopy(dest, source);
877     return ZWRAPC_finishWithErrorMsg(source, "deflateCopy is not supported!");
878 }
879 
880 
881 ZEXTERN int ZEXPORT z_deflateTune OF((z_streamp strm,
882                                     int good_length,
883                                     int max_lazy,
884                                     int nice_length,
885                                     int max_chain))
886 {
887     if (!g_ZWRAP_useZSTDcompression)
888         return deflateTune(strm, good_length, max_lazy, nice_length, max_chain);
889     return ZWRAPC_finishWithErrorMsg(strm, "deflateTune is not supported!");
890 }
891 
892 
893 #if ZLIB_VERNUM >= 0x1260
894 ZEXTERN int ZEXPORT z_deflatePending OF((z_streamp strm,
895                                        unsigned *pending,
896                                        int *bits))
897 {
898     if (!g_ZWRAP_useZSTDcompression)
899         return deflatePending(strm, pending, bits);
900     return ZWRAPC_finishWithErrorMsg(strm, "deflatePending is not supported!");
901 }
902 #endif
903 
904 
905 ZEXTERN int ZEXPORT z_deflatePrime OF((z_streamp strm,
906                                      int bits,
907                                      int value))
908 {
909     if (!g_ZWRAP_useZSTDcompression)
910         return deflatePrime(strm, bits, value);
911     return ZWRAPC_finishWithErrorMsg(strm, "deflatePrime is not supported!");
912 }
913 
914 
915 ZEXTERN int ZEXPORT z_deflateSetHeader OF((z_streamp strm,
916                                          gz_headerp head))
917 {
918     if (!g_ZWRAP_useZSTDcompression)
919         return deflateSetHeader(strm, head);
920     return ZWRAPC_finishWithErrorMsg(strm, "deflateSetHeader is not supported!");
921 }
922 
923 
924 
925 
926 /* Advanced decompression functions */
927 #if ZLIB_VERNUM >= 0x1280
928 ZEXTERN int ZEXPORT z_inflateGetDictionary OF((z_streamp strm,
929                                              Bytef *dictionary,
930                                              uInt  *dictLength))
931 {
932     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
933         return inflateGetDictionary(strm, dictionary, dictLength);
934     return ZWRAPD_finishWithErrorMsg(strm, "inflateGetDictionary is not supported!");
935 }
936 #endif
937 
938 
939 ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest,
940                                     z_streamp source))
941 {
942     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !source->reserved)
943         return inflateCopy(dest, source);
944     return ZWRAPD_finishWithErrorMsg(source, "inflateCopy is not supported!");
945 }
946 
947 
948 #if ZLIB_VERNUM >= 0x1240
949 ZEXTERN long ZEXPORT z_inflateMark OF((z_streamp strm))
950 {
951     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
952         return inflateMark(strm);
953     return ZWRAPD_finishWithErrorMsg(strm, "inflateMark is not supported!");
954 }
955 #endif
956 
957 
958 ZEXTERN int ZEXPORT z_inflatePrime OF((z_streamp strm,
959                                      int bits,
960                                      int value))
961 {
962     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
963         return inflatePrime(strm, bits, value);
964     return ZWRAPD_finishWithErrorMsg(strm, "inflatePrime is not supported!");
965 }
966 
967 
968 ZEXTERN int ZEXPORT z_inflateGetHeader OF((z_streamp strm,
969                                          gz_headerp head))
970 {
971     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
972         return inflateGetHeader(strm, head);
973     return ZWRAPD_finishWithErrorMsg(strm, "inflateGetHeader is not supported!");
974 }
975 
976 
977 ZEXTERN int ZEXPORT z_inflateBackInit_ OF((z_streamp strm, int windowBits,
978                                          unsigned char FAR *window,
979                                          const char *version,
980                                          int stream_size))
981 {
982     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
983         return inflateBackInit_(strm, windowBits, window, version, stream_size);
984     return ZWRAPD_finishWithErrorMsg(strm, "inflateBackInit is not supported!");
985 }
986 
987 
988 ZEXTERN int ZEXPORT z_inflateBack OF((z_streamp strm,
989                                     in_func in, void FAR *in_desc,
990                                     out_func out, void FAR *out_desc))
991 {
992     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
993         return inflateBack(strm, in, in_desc, out, out_desc);
994     return ZWRAPD_finishWithErrorMsg(strm, "inflateBack is not supported!");
995 }
996 
997 
998 ZEXTERN int ZEXPORT z_inflateBackEnd OF((z_streamp strm))
999 {
1000     if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
1001         return inflateBackEnd(strm);
1002     return ZWRAPD_finishWithErrorMsg(strm, "inflateBackEnd is not supported!");
1003 }
1004 
1005 
1006 ZEXTERN uLong ZEXPORT z_zlibCompileFlags OF((void)) { return zlibCompileFlags(); };
1007 
1008 
1009 
1010                     /* ===   utility functions  === */
1011 #ifndef Z_SOLO
1012 
1013 ZEXTERN int ZEXPORT z_compress OF((Bytef *dest,   uLongf *destLen,
1014                                  const Bytef *source, uLong sourceLen))
1015 {
1016     if (!g_ZWRAP_useZSTDcompression)
1017         return compress(dest, destLen, source, sourceLen);
1018 
1019     {   size_t dstCapacity = *destLen;
1020         size_t const cSize = ZSTD_compress(dest, dstCapacity,
1021                                            source, sourceLen,
1022                                            ZWRAP_DEFAULT_CLEVEL);
1023         LOG_WRAPPERD("z_compress sourceLen=%d dstCapacity=%d\n",
1024                     (int)sourceLen, (int)dstCapacity);
1025         if (ZSTD_isError(cSize)) return Z_STREAM_ERROR;
1026         *destLen = cSize;
1027     }
1028     return Z_OK;
1029 }
1030 
1031 
1032 ZEXTERN int ZEXPORT z_compress2 OF((Bytef *dest,   uLongf *destLen,
1033                                   const Bytef *source, uLong sourceLen,
1034                                   int level))
1035 {
1036     if (!g_ZWRAP_useZSTDcompression)
1037         return compress2(dest, destLen, source, sourceLen, level);
1038 
1039     { size_t dstCapacity = *destLen;
1040       size_t const cSize = ZSTD_compress(dest, dstCapacity, source, sourceLen, level);
1041       if (ZSTD_isError(cSize)) return Z_STREAM_ERROR;
1042       *destLen = cSize;
1043     }
1044     return Z_OK;
1045 }
1046 
1047 
1048 ZEXTERN uLong ZEXPORT z_compressBound OF((uLong sourceLen))
1049 {
1050     if (!g_ZWRAP_useZSTDcompression)
1051         return compressBound(sourceLen);
1052 
1053     return ZSTD_compressBound(sourceLen);
1054 }
1055 
1056 
1057 ZEXTERN int ZEXPORT z_uncompress OF((Bytef *dest,   uLongf *destLen,
1058                                    const Bytef *source, uLong sourceLen))
1059 {
1060     if (!ZSTD_isFrame(source, sourceLen))
1061         return uncompress(dest, destLen, source, sourceLen);
1062 
1063     { size_t dstCapacity = *destLen;
1064       size_t const dSize = ZSTD_decompress(dest, dstCapacity, source, sourceLen);
1065       if (ZSTD_isError(dSize)) return Z_STREAM_ERROR;
1066       *destLen = dSize;
1067      }
1068     return Z_OK;
1069 }
1070 
1071 #endif /* !Z_SOLO */
1072 
1073 
1074                         /* checksum functions */
1075 
1076 ZEXTERN uLong ZEXPORT z_adler32 OF((uLong adler, const Bytef *buf, uInt len))
1077 {
1078     return adler32(adler, buf, len);
1079 }
1080 
1081 ZEXTERN uLong ZEXPORT z_crc32   OF((uLong crc, const Bytef *buf, uInt len))
1082 {
1083     return crc32(crc, buf, len);
1084 }
1085 
1086 
1087 #if ZLIB_VERNUM >= 0x12B0
1088 ZEXTERN uLong ZEXPORT z_adler32_z OF((uLong adler, const Bytef *buf, z_size_t len))
1089 {
1090     return adler32_z(adler, buf, len);
1091 }
1092 
1093 ZEXTERN uLong ZEXPORT z_crc32_z OF((uLong crc, const Bytef *buf, z_size_t len))
1094 {
1095     return crc32_z(crc, buf, len);
1096 }
1097 #endif
1098 
1099 
1100 #if ZLIB_VERNUM >= 0x1270
1101 ZEXTERN const z_crc_t FAR * ZEXPORT z_get_crc_table    OF((void))
1102 {
1103     return get_crc_table();
1104 }
1105 #endif
1106