zstd_zlibwrapper.c 41 KB

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