return 0;
}
- while (entry = readdir(dir)) {
+ while ((entry = readdir(dir)) != NULL) {
if (strcmp (entry->d_name, "..") == 0 ||
strcmp (entry->d_name, ".") == 0) continue;
pathLength = snprintf(path, PATH_MAX, "%s/%s", dirName, entry->d_name);
--- /dev/null
+# Object files
+*.o
+*.ko
+
+# Libraries
+*.lib
+*.a
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+
+# Default result files
+_*
+
+# Misc files
+*.bat
+*.zip
+examples/example2.c
--- /dev/null
+# Makefile for example of using zstd wrapper for zlib
+#
+# make - compiles statically and dynamically linked examples/example.c
+# make test testdll - compiles and runs statically and dynamically linked examples/example.c
+# make LOC=-DZWRAP_USE_ZSTD=1 - compiles statically and dynamically linked examples/example.c with zstd compression turned on
+
+
+# Paths to static and dynamic zlib and zstd libraries
+ifneq (,$(filter Windows%,$(OS)))
+STATICLIB = ../../zlib/libz.a ../lib/libzstd.a
+IMPLIB = ../../zlib/libz.dll.a ../lib/libzstd.a
+else
+STATICLIB = -static -lz ../lib/libzstd.a
+IMPLIB = -lz ../lib/libzstd.a
+endif
+
+ZLIBWRAPPER_PATH = .
+EXAMPLE_PATH = examples/
+CC = gcc
+CFLAGS = $(LOC) -I../lib/common -I$(ZLIBWRAPPER_PATH) -O3 -Wall -std=gnu89
+LDFLAGS = $(LOC)
+RM = rm -f
+
+
+all: example example_d
+
+test: example
+ ./example
+
+testdll: example_d
+ ./example_d
+
+.c.o:
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o
+ $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(STATICLIB)
+
+example_d: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o
+ $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(IMPLIB)
+
+$(EXAMPLE_PATH)/example.o: $(EXAMPLE_PATH)/example.c
+ $(CC) $(CFLAGS) -I. -c -o $@ $(EXAMPLE_PATH)/example.c
+
+$(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h
+ $(CC) $(CFLAGS) -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c
+
+clean:
+ -$(RM) $(ZLIBWRAPPER_PATH)/*.o
+ -$(RM) $(EXAMPLE_PATH)/*.o
+ -$(RM) *.o
+ -$(RM) *.exe
+ -$(RM) foo.gz
+
--- /dev/null
+zstd wrapper for zlib
+================================
+
+The main objective of creating a zstd wrapper for zlib is to allow a quick and smooth transition to zstd for projects already using zlib.
+
+#### Required files
+
+To build the zstd wrapper for zlib the following files are required:
+- zlib.h
+- a static or dynamic zlib library
+- zlibWrapper/zstd_zlibwrapper.h
+- zlibWrapper/zstd_zlibwrapper.c
+- a static or dynamic zstd library
+
+The first two files are required by all projects using zlib and they are not included with the zstd distribution.
+The further files are supplied with the zstd distribution.
+
+
+#### Embedding the zstd wrapper within your project
+
+Let's assume that your project that uses zlib is compiled with:
+```gcc project.o -lz```
+
+To compile the zstd wrapper with your project you have to do the following:
+- change all references with ```#include "zlib.h"``` to ```#include "zstd_zlibwrapper.h"```
+- compile your project with zlib_wrapper.c and a static or dynamic zstd library
+
+The linking should be changed to:
+```gcc project.o zlib_wrapper.o -lz -lzstd```
+
+
+#### Using the zstd wrapper with your project
+
+After embedding the zstd wrapper within your project the zstd library is turned off by default.
+Your project should work as before with zlib. There are two options to enable zstd compression:
+- compilation with ```-DZWRAP_USE_ZSTD=1``` (or using ```#define ZWRAP_USE_ZSTD 1``` before ```#include "zstd_zlibwrapper.h"```)
+- using the ```void useZSTD(int turn_on)``` function (declared in ```#include "zstd_zlibwrapper.h"```)
+There is no switch for zstd decompression because zlib and zstd streams are automatically detected and decompressed using a proper library.
+
+
+#### Example
+We have take the file ```test\example.c``` from the zlib library distribution and copied it to ```zlibWrapper\examples\example.c```.
+After compilation and execution it shows the following results:
+```
+zlib version 1.2.8 = 0x1280, compile flags = 0x65
+uncompress(): hello, hello!
+gzread(): hello, hello!
+gzgets() after gzseek: hello!
+inflate(): hello, hello!
+large_inflate(): OK
+after inflateSync(): hello, hello!
+inflate with dictionary: hello, hello!
+```
+Then we have compiled the example.c file with ```-DZWRAP_USE_ZSTD=1``` and linked with ```zlib_wrapper.o -lzstd```.
+We have also turned of the following functions: test_gzio, test_flush, test_sync which use currently unsupported features.
+It shows the following results:
+```
+zlib version 1.2.8 = 0x1280, compile flags = 0x65
+uncompress(): hello, hello!
+inflate(): hello, hello!
+large_inflate(): OK
+inflate with dictionary: hello, hello!
+```
+The script used for compilation can be found at [zlibWrapper\Makefile](.\Makefile).
+
+
+#### Compatibility issues
+After enabling zstd compression not all functions are supported. Unsupported methods when called print error message and return an error value.
+
+Supported methods:
+- deflateInit
+- deflate (with exception of Z_FULL_FLUSH)
+- deflateSetDictionary
+- deflateEnd
+- deflateBound
+- inflateInit
+- inflate
+- inflateSetDictionary
+- compress
+- compress2
+- compressBound
+- uncompress
+
+Ignored methods (they do nothing):
+- deflateParams
+
+Unsupported methods:
+- gzip file access functions
+- deflateCopy
+- deflateReset
+- deflateTune
+- deflatePending
+- deflatePrime
+- deflateSetHeader
+- inflateGetDictionary
+- inflateCopy
+- inflateReset
+- inflateReset2
+- inflatePrime
+- inflateMark
+- inflateGetHeader
+- inflateBackInit
+- inflateBack
+- inflateBackEnd
--- /dev/null
+/* the file contains minimal changes required to be compiled with zstd wrapper for zlib */
+
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2006, 2011 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zstd_zlibwrapper.h"
+#include <stdio.h>
+
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+#endif
+
+#if defined(VMS) || defined(RISCOS)
+# define TESTFILE "foo-gz"
+#else
+# define TESTFILE "foo.gz"
+#endif
+
+#define CHECK_ERR(err, msg) { \
+ if (err != Z_OK) { \
+ fprintf(stderr, "%s error: %d\n", msg, err); \
+ exit(1); \
+ } \
+}
+
+z_const char hello[] = "hello, hello!";
+/* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ */
+
+const char dictionary[] = "hello";
+uLong dictId; /* Adler32 value of the dictionary */
+
+void test_deflate OF((Byte *compr, uLong comprLen));
+void test_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_flush OF((Byte *compr, uLong *comprLen));
+void test_sync OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate OF((Byte *compr, uLong comprLen));
+void test_dict_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+int main OF((int argc, char *argv[]));
+
+
+#ifdef Z_SOLO
+
+void *myalloc OF((void *, unsigned, unsigned));
+void myfree OF((void *, void *));
+
+void *myalloc(q, n, m)
+ void *q;
+ unsigned n, m;
+{
+ q = Z_NULL;
+ return calloc(n, m);
+}
+
+void myfree(void *q, void *p)
+{
+ q = Z_NULL;
+ free(p);
+}
+
+static alloc_func zalloc = myalloc;
+static free_func zfree = myfree;
+
+#else /* !Z_SOLO */
+
+static alloc_func zalloc = (alloc_func)0;
+static free_func zfree = (free_func)0;
+
+void test_compress OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_gzio OF((const char *fname,
+ Byte *uncompr, uLong uncomprLen));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ uLong len = (uLong)strlen(hello)+1;
+
+ err = compress(compr, &comprLen, (const Bytef*)hello, len);
+ CHECK_ERR(err, "compress");
+
+ strcpy((char*)uncompr, "garbage");
+
+ err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+ CHECK_ERR(err, "uncompress");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad uncompress\n");
+ exit(1);
+ } else {
+ printf("uncompress(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(fname, uncompr, uncomprLen)
+ const char *fname; /* compressed file name */
+ Byte *uncompr;
+ uLong uncomprLen;
+{
+#ifdef NO_GZCOMPRESS
+ fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
+#else
+ int err;
+ int len = (int)strlen(hello)+1;
+ gzFile file;
+ z_off_t pos;
+
+ file = gzopen(fname, "wb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ exit(1);
+ }
+ gzputc(file, 'h');
+ if (gzputs(file, "ello") != 4) {
+ fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (gzprintf(file, ", %s!", "hello") != 8) {
+ fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
+ gzclose(file);
+
+ file = gzopen(fname, "rb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ exit(1);
+ }
+ strcpy((char*)uncompr, "garbage");
+
+ if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
+ fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
+ exit(1);
+ } else {
+ printf("gzread(): %s\n", (char*)uncompr);
+ }
+
+ pos = gzseek(file, -8L, SEEK_CUR);
+ if (pos != 6 || gztell(file) != pos) {
+ fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
+ (long)pos, (long)gztell(file));
+ exit(1);
+ }
+
+ if (gzgetc(file) != ' ') {
+ fprintf(stderr, "gzgetc error\n");
+ exit(1);
+ }
+
+ if (gzungetc(' ', file) != ' ') {
+ fprintf(stderr, "gzungetc error\n");
+ exit(1);
+ }
+
+ gzgets(file, (char*)uncompr, (int)uncomprLen);
+ if (strlen((char*)uncompr) != 7) { /* " hello!" */
+ fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello + 6)) {
+ fprintf(stderr, "bad gzgets after gzseek\n");
+ exit(1);
+ } else {
+ printf("gzgets() after gzseek: %s\n", (char*)uncompr);
+ }
+
+ gzclose(file);
+#endif
+}
+
+#endif /* Z_SOLO */
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ uLong len = (uLong)strlen(hello)+1;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.next_out = compr;
+
+ while (c_stream.total_in != len && c_stream.total_out < comprLen) {
+ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ }
+ /* Finish the stream, still forcing small buffers: */
+ for (;;) {
+ c_stream.avail_out = 1;
+ err = deflate(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "deflate");
+ }
+
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 0;
+ d_stream.next_out = uncompr;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+ d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate\n");
+ exit(1);
+ } else {
+ printf("inflate(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with large buffers and dynamic change of compression level
+ */
+void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_SPEED);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ /* At this point, uncompr is still mostly zeroes, so it should compress
+ * very well:
+ */
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ if (c_stream.avail_in != 0) {
+ fprintf(stderr, "deflate not greedy\n");
+ exit(1);
+ }
+
+ /* Feed in already compressed data and switch to no compression: */
+ deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+ c_stream.next_in = compr;
+ c_stream.avail_in = (uInt)comprLen/2;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ /* Switch back to compressing mode: */
+ deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with large buffers
+ */
+void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ for (;;) {
+ d_stream.next_out = uncompr; /* discard the output */
+ d_stream.avail_out = (uInt)uncomprLen;
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "large inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
+ fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
+ exit(1);
+ } else {
+ printf("large_inflate(): OK\n");
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr, comprLen)
+ Byte *compr;
+ uLong *comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ uInt len = (uInt)strlen(hello)+1;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.next_out = compr;
+ c_stream.avail_in = 3;
+ c_stream.avail_out = (uInt)*comprLen;
+ err = deflate(&c_stream, Z_FULL_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ compr[3]++; /* force an error in first compressed block */
+ c_stream.avail_in = len - 3;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ CHECK_ERR(err, "deflate");
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+
+ *comprLen = c_stream.total_out;
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 2; /* just read the zlib header */
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ inflate(&d_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "inflate");
+
+ d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
+ err = inflateSync(&d_stream); /* but skip the damaged part */
+ CHECK_ERR(err, "inflateSync");
+
+ err = inflate(&d_stream, Z_FINISH);
+ if (err != Z_DATA_ERROR) {
+ fprintf(stderr, "inflate should report DATA_ERROR\n");
+ /* Because of incorrect adler32 */
+ exit(1);
+ }
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ printf("after inflateSync(): hel%s\n", (char *)uncompr);
+}
+
+/* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ err = deflateSetDictionary(&c_stream,
+ (const Bytef*)dictionary, (int)sizeof(dictionary));
+ CHECK_ERR(err, "deflateSetDictionary");
+
+ dictId = c_stream.adler;
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.avail_in = (uInt)strlen(hello)+1;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ for (;;) {
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ if (err == Z_NEED_DICT) {
+ if (d_stream.adler != dictId) {
+ fprintf(stderr, "unexpected dictionary");
+ exit(1);
+ }
+ err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+ (int)sizeof(dictionary));
+ }
+ CHECK_ERR(err, "inflate with dict");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate with dict\n");
+ exit(1);
+ } else {
+ printf("inflate with dictionary: %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Usage: example [output.gz [input.gz]]
+ */
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ Byte *compr, *uncompr;
+ uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
+ uLong uncomprLen = comprLen;
+ static const char* myVersion = ZLIB_VERSION;
+
+ if (zlibVersion()[0] != myVersion[0]) {
+ fprintf(stderr, "incompatible zlib version\n");
+ exit(1);
+
+ } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
+ fprintf(stderr, "warning: different zlib version\n");
+ }
+
+ printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
+ ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
+ if (isUsingZSTD()) printf("zstd version %s\n", zstdVersion());
+
+ compr = (Byte*)calloc((uInt)comprLen, 1);
+ uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
+ /* compr and uncompr are cleared to avoid reading uninitialized
+ * data and to ensure that uncompr compresses well.
+ */
+ if (compr == Z_NULL || uncompr == Z_NULL) {
+ printf("out of memory\n");
+ exit(1);
+ }
+
+#ifdef Z_SOLO
+ argc = strlen(argv[0]);
+#else
+ test_compress(compr, comprLen, uncompr, uncomprLen);
+
+ if (!isUsingZSTD())
+ test_gzio((argc > 1 ? argv[1] : TESTFILE),
+ uncompr, uncomprLen);
+#endif
+
+ test_deflate(compr, comprLen);
+ test_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+ test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ if (!isUsingZSTD()) {
+ test_flush(compr, &comprLen);
+ test_sync(compr, comprLen, uncompr, uncomprLen);
+ }
+ comprLen = uncomprLen;
+
+ test_dict_deflate(compr, comprLen);
+ test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ free(compr);
+ free(uncompr);
+
+ return 0;
+}
--- /dev/null
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2006, 2011 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+#include <stdio.h>
+
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+#endif
+
+#if defined(VMS) || defined(RISCOS)
+# define TESTFILE "foo-gz"
+#else
+# define TESTFILE "foo.gz"
+#endif
+
+#define CHECK_ERR(err, msg) { \
+ if (err != Z_OK) { \
+ fprintf(stderr, "%s error: %d\n", msg, err); \
+ exit(1); \
+ } \
+}
+
+z_const char hello[] = "hello, hello!";
+/* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ */
+
+const char dictionary[] = "hello";
+uLong dictId; /* Adler32 value of the dictionary */
+
+void test_deflate OF((Byte *compr, uLong comprLen));
+void test_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_flush OF((Byte *compr, uLong *comprLen));
+void test_sync OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate OF((Byte *compr, uLong comprLen));
+void test_dict_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+int main OF((int argc, char *argv[]));
+
+
+#ifdef Z_SOLO
+
+void *myalloc OF((void *, unsigned, unsigned));
+void myfree OF((void *, void *));
+
+void *myalloc(q, n, m)
+ void *q;
+ unsigned n, m;
+{
+ q = Z_NULL;
+ return calloc(n, m);
+}
+
+void myfree(void *q, void *p)
+{
+ q = Z_NULL;
+ free(p);
+}
+
+static alloc_func zalloc = myalloc;
+static free_func zfree = myfree;
+
+#else /* !Z_SOLO */
+
+static alloc_func zalloc = (alloc_func)0;
+static free_func zfree = (free_func)0;
+
+void test_compress OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_gzio OF((const char *fname,
+ Byte *uncompr, uLong uncomprLen));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ uLong len = (uLong)strlen(hello)+1;
+
+ err = compress(compr, &comprLen, (const Bytef*)hello, len);
+ CHECK_ERR(err, "compress");
+
+ strcpy((char*)uncompr, "garbage");
+
+ err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+ CHECK_ERR(err, "uncompress");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad uncompress\n");
+ exit(1);
+ } else {
+ printf("uncompress(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(fname, uncompr, uncomprLen)
+ const char *fname; /* compressed file name */
+ Byte *uncompr;
+ uLong uncomprLen;
+{
+#ifdef NO_GZCOMPRESS
+ fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
+#else
+ int err;
+ int len = (int)strlen(hello)+1;
+ gzFile file;
+ z_off_t pos;
+
+ file = gzopen(fname, "wb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ exit(1);
+ }
+ gzputc(file, 'h');
+ if (gzputs(file, "ello") != 4) {
+ fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (gzprintf(file, ", %s!", "hello") != 8) {
+ fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
+ gzclose(file);
+
+ file = gzopen(fname, "rb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ exit(1);
+ }
+ strcpy((char*)uncompr, "garbage");
+
+ if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
+ fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
+ exit(1);
+ } else {
+ printf("gzread(): %s\n", (char*)uncompr);
+ }
+
+ pos = gzseek(file, -8L, SEEK_CUR);
+ if (pos != 6 || gztell(file) != pos) {
+ fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
+ (long)pos, (long)gztell(file));
+ exit(1);
+ }
+
+ if (gzgetc(file) != ' ') {
+ fprintf(stderr, "gzgetc error\n");
+ exit(1);
+ }
+
+ if (gzungetc(' ', file) != ' ') {
+ fprintf(stderr, "gzungetc error\n");
+ exit(1);
+ }
+
+ gzgets(file, (char*)uncompr, (int)uncomprLen);
+ if (strlen((char*)uncompr) != 7) { /* " hello!" */
+ fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello + 6)) {
+ fprintf(stderr, "bad gzgets after gzseek\n");
+ exit(1);
+ } else {
+ printf("gzgets() after gzseek: %s\n", (char*)uncompr);
+ }
+
+ gzclose(file);
+#endif
+}
+
+#endif /* Z_SOLO */
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ uLong len = (uLong)strlen(hello)+1;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.next_out = compr;
+
+ while (c_stream.total_in != len && c_stream.total_out < comprLen) {
+ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ }
+ /* Finish the stream, still forcing small buffers: */
+ for (;;) {
+ c_stream.avail_out = 1;
+ err = deflate(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "deflate");
+ }
+
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 0;
+ d_stream.next_out = uncompr;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+ d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate\n");
+ exit(1);
+ } else {
+ printf("inflate(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with large buffers and dynamic change of compression level
+ */
+void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_SPEED);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ /* At this point, uncompr is still mostly zeroes, so it should compress
+ * very well:
+ */
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ if (c_stream.avail_in != 0) {
+ fprintf(stderr, "deflate not greedy\n");
+ exit(1);
+ }
+
+ /* Feed in already compressed data and switch to no compression: */
+ deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+ c_stream.next_in = compr;
+ c_stream.avail_in = (uInt)comprLen/2;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ /* Switch back to compressing mode: */
+ deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with large buffers
+ */
+void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ for (;;) {
+ d_stream.next_out = uncompr; /* discard the output */
+ d_stream.avail_out = (uInt)uncomprLen;
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "large inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
+ fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
+ exit(1);
+ } else {
+ printf("large_inflate(): OK\n");
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr, comprLen)
+ Byte *compr;
+ uLong *comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ uInt len = (uInt)strlen(hello)+1;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.next_out = compr;
+ c_stream.avail_in = 3;
+ c_stream.avail_out = (uInt)*comprLen;
+ err = deflate(&c_stream, Z_FULL_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ compr[3]++; /* force an error in first compressed block */
+ c_stream.avail_in = len - 3;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ CHECK_ERR(err, "deflate");
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+
+ *comprLen = c_stream.total_out;
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 2; /* just read the zlib header */
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ inflate(&d_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "inflate");
+
+ d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
+ err = inflateSync(&d_stream); /* but skip the damaged part */
+ CHECK_ERR(err, "inflateSync");
+
+ err = inflate(&d_stream, Z_FINISH);
+ if (err != Z_DATA_ERROR) {
+ fprintf(stderr, "inflate should report DATA_ERROR\n");
+ /* Because of incorrect adler32 */
+ exit(1);
+ }
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ printf("after inflateSync(): hel%s\n", (char *)uncompr);
+}
+
+/* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ err = deflateSetDictionary(&c_stream,
+ (const Bytef*)dictionary, (int)sizeof(dictionary));
+ CHECK_ERR(err, "deflateSetDictionary");
+
+ dictId = c_stream.adler;
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.avail_in = (uInt)strlen(hello)+1;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ for (;;) {
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ if (err == Z_NEED_DICT) {
+ if (d_stream.adler != dictId) {
+ fprintf(stderr, "unexpected dictionary");
+ exit(1);
+ }
+ err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+ (int)sizeof(dictionary));
+ }
+ CHECK_ERR(err, "inflate with dict");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate with dict\n");
+ exit(1);
+ } else {
+ printf("inflate with dictionary: %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Usage: example [output.gz [input.gz]]
+ */
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ Byte *compr, *uncompr;
+ uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
+ uLong uncomprLen = comprLen;
+ static const char* myVersion = ZLIB_VERSION;
+
+ if (zlibVersion()[0] != myVersion[0]) {
+ fprintf(stderr, "incompatible zlib version\n");
+ exit(1);
+
+ } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
+ fprintf(stderr, "warning: different zlib version\n");
+ }
+
+ printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
+ ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
+
+ compr = (Byte*)calloc((uInt)comprLen, 1);
+ uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
+ /* compr and uncompr are cleared to avoid reading uninitialized
+ * data and to ensure that uncompr compresses well.
+ */
+ if (compr == Z_NULL || uncompr == Z_NULL) {
+ printf("out of memory\n");
+ exit(1);
+ }
+
+#ifdef Z_SOLO
+ argc = strlen(argv[0]);
+#else
+ test_compress(compr, comprLen, uncompr, uncomprLen);
+
+ test_gzio((argc > 1 ? argv[1] : TESTFILE),
+ uncompr, uncomprLen);
+#endif
+
+ test_deflate(compr, comprLen);
+ test_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+ test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ test_flush(compr, &comprLen);
+ test_sync(compr, comprLen, uncompr, uncomprLen);
+ comprLen = uncomprLen;
+
+ test_dict_deflate(compr, comprLen);
+ test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ free(compr);
+ free(uncompr);
+
+ return 0;
+}
--- /dev/null
+/*
+ zstd_zlibwrapper.c - zstd wrapper for zlib
+ Copyright (C) 2016, Przemyslaw Skibinski.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - zstd source repository : https://github.com/Cyan4973/zstd
+*/
+
+#include <stdio.h> /* fprintf */
+#include <stdlib.h> /* malloc */
+#include <zlib.h>
+#include "zstd_zlibwrapper.h"
+#include "zstd.h"
+#include "zstd_static.h" /* ZSTD_MAGICNUMBER */
+#include "zstd_internal.h" /* MIN */
+#include "zbuff.h"
+
+
+#define Z_INFLATE_SYNC 8
+#define ZWRAP_HEADERSIZE 4
+#define ZSTD_FRAMEHEADERSIZE_MIN 5
+
+#define LOG_WRAPPER(...) // printf(__VA_ARGS__)
+
+
+#define FINISH_WITH_ERR(msg) { \
+ fprintf(stderr, "ERROR: %s\n", msg); \
+ return Z_MEM_ERROR; \
+}
+
+#define FINISH_WITH_NULL_ERR(msg) { \
+ fprintf(stderr, "ERROR: %s\n", msg); \
+ return NULL; \
+}
+
+#ifndef ZWRAP_USE_ZSTD
+ #define ZWRAP_USE_ZSTD 0
+#endif
+
+static int g_useZSTD = ZWRAP_USE_ZSTD; /* 0 = don't use ZSTD */
+
+
+
+void useZSTD(int turn_on) { g_useZSTD = turn_on; }
+
+int isUsingZSTD() { return g_useZSTD; }
+
+const char * zstdVersion() { return ZSTD_VERSION_STRING; }
+
+ZEXTERN const char * ZEXPORT z_zlibVersion OF((void)) { return zlibVersion(); }
+
+
+
+/* *** Compression *** */
+
+typedef struct {
+ ZBUFF_CCtx* zbc;
+ size_t bytesLeft;
+ int compressionLevel;
+} ZWRAP_CCtx;
+
+
+ZWRAP_CCtx* ZWRAP_createCCtx()
+{
+ ZWRAP_CCtx* zwc = (ZWRAP_CCtx*)malloc(sizeof(ZWRAP_CCtx));
+ if (zwc==NULL) return NULL;
+ memset(zwc, 0, sizeof(*zwc));
+ zwc->zbc = ZBUFF_createCCtx();
+ return zwc;
+}
+
+
+size_t ZWRAP_freeCCtx(ZWRAP_CCtx* zwc)
+{
+ if (zwc==NULL) return 0; /* support free on NULL */
+ ZBUFF_freeCCtx(zwc->zbc);
+ free(zwc);
+ return 0;
+}
+
+
+ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size))
+{
+ ZWRAP_CCtx* zwc;
+
+ if (!g_useZSTD) {
+ LOG_WRAPPER("- deflateInit level=%d\n", level);
+ return deflateInit_((strm), (level), version, stream_size);
+ }
+
+ LOG_WRAPPER("- deflateInit level=%d\n", level);
+ zwc = ZWRAP_createCCtx();
+ if (zwc == NULL) return Z_MEM_ERROR;
+
+ { size_t const errorCode = ZBUFF_compressInit(zwc->zbc, level);
+ if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; }
+
+ zwc->compressionLevel = level;
+ strm->opaque = (voidpf) zwc;
+ strm->total_in = 0;
+ strm->total_out = 0;
+ return Z_OK;
+}
+
+
+ZEXTERN int ZEXPORT z_deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size))
+{
+ if (!g_useZSTD)
+ return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, version, stream_size);
+
+ return z_deflateInit_ (strm, level, version, stream_size);
+}
+
+
+ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength))
+{
+ if (!g_useZSTD)
+ return deflateSetDictionary(strm, dictionary, dictLength);
+
+ { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->opaque;
+ LOG_WRAPPER("- deflateSetDictionary level=%d\n", (int)strm->data_type);
+ { size_t const errorCode = ZBUFF_compressInitDictionary(zwc->zbc, dictionary, dictLength, zwc->compressionLevel);
+ if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; }
+ }
+
+ return Z_OK;
+}
+
+
+ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush))
+{
+ ZWRAP_CCtx* zwc;
+
+ if (!g_useZSTD) {
+ int res = deflate(strm, flush);
+ LOG_WRAPPER("- avail_in=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->total_in, (int)strm->total_out);
+ return res;
+ }
+
+ zwc = (ZWRAP_CCtx*) strm->opaque;
+
+ LOG_WRAPPER("deflate 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);
+ if (strm->avail_in > 0) {
+ size_t dstCapacity = strm->avail_out;
+ size_t srcSize = strm->avail_in;
+ size_t const errorCode = ZBUFF_compressContinue(zwc->zbc, strm->next_out, &dstCapacity, strm->next_in, &srcSize);
+ LOG_WRAPPER("ZBUFF_compressContinue srcSize=%d dstCapacity=%d\n", (int)srcSize, (int)dstCapacity);
+ if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
+ strm->next_out += dstCapacity;
+ strm->total_out += dstCapacity;
+ strm->avail_out -= dstCapacity;
+ strm->total_in += srcSize;
+ strm->next_in += srcSize;
+ strm->avail_in -= srcSize;
+ }
+
+ if (flush == Z_FULL_FLUSH) FINISH_WITH_ERR("Z_FULL_FLUSH is not supported!");
+
+ if (flush == Z_FINISH || flush == Z_FULL_FLUSH) {
+ size_t bytesLeft;
+ size_t dstCapacity = strm->avail_out;
+ if (zwc->bytesLeft) {
+ bytesLeft = ZBUFF_compressFlush(zwc->zbc, strm->next_out, &dstCapacity);
+ LOG_WRAPPER("ZBUFF_compressFlush avail_out=%d dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)dstCapacity, (int)bytesLeft);
+ } else {
+ bytesLeft = ZBUFF_compressEnd(zwc->zbc, strm->next_out, &dstCapacity);
+ LOG_WRAPPER("ZBUFF_compressEnd dstCapacity=%d bytesLeft=%d\n", (int)dstCapacity, (int)bytesLeft);
+ // { size_t const errorCode = ZBUFF_compressInit(zwc->zbc, 1);
+ // if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; }
+ }
+ if (ZSTD_isError(bytesLeft)) return Z_MEM_ERROR;
+ strm->next_out += dstCapacity;
+ strm->total_out += dstCapacity;
+ strm->avail_out -= dstCapacity;
+ if (flush == Z_FINISH && bytesLeft == 0) return Z_STREAM_END;
+ zwc->bytesLeft = bytesLeft;
+ }
+ return Z_OK;
+}
+
+
+ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm))
+{
+ if (!g_useZSTD) {
+ LOG_WRAPPER("- deflateEnd\n");
+ return deflateEnd(strm);
+ }
+ LOG_WRAPPER("- deflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out));
+ { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->opaque;
+ size_t const errorCode = ZWRAP_freeCCtx(zwc);
+ if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
+ }
+ return Z_OK;
+}
+
+
+ZEXTERN uLong ZEXPORT z_deflateBound OF((z_streamp strm,
+ uLong sourceLen))
+{
+ if (!g_useZSTD)
+ return deflateBound(strm, sourceLen);
+
+ return ZSTD_compressBound(sourceLen);
+}
+
+
+ZEXTERN int ZEXPORT z_deflateParams OF((z_streamp strm,
+ int level,
+ int strategy))
+{
+ if (!g_useZSTD) {
+ LOG_WRAPPER("- deflateParams level=%d strategy=%d\n", level, strategy);
+ return deflateParams(strm, level, strategy);
+ }
+
+ return Z_OK;
+}
+
+
+
+
+
+/* *** Decompression *** */
+
+typedef struct {
+ ZBUFF_DCtx* zbd;
+ char headerBuf[ZSTD_FRAMEHEADERSIZE_MIN];
+ int errorCount;
+ int requiredHeaderSize;
+
+ /* zlib params */
+ int stream_size;
+ char *version;
+ int windowBits;
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+} ZWRAP_DCtx;
+
+
+ZWRAP_DCtx* ZWRAP_createDCtx(void)
+{
+ ZWRAP_DCtx* zwd = (ZWRAP_DCtx*)malloc(sizeof(ZWRAP_DCtx));
+ if (zwd==NULL) return NULL;
+ memset(zwd, 0, sizeof(*zwd));
+ return zwd;
+}
+
+
+size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd)
+{
+ if (zwd==NULL) return 0; /* support free on null */
+ if (zwd->version) free(zwd->version);
+ if (zwd->zbd) ZBUFF_freeDCtx(zwd->zbd);
+ free(zwd);
+ return 0;
+}
+
+
+ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size))
+{
+ ZWRAP_DCtx* zwd = ZWRAP_createDCtx();
+ LOG_WRAPPER("- inflateInit\n");
+ if (zwd == NULL) return Z_MEM_ERROR;
+
+ zwd->stream_size = stream_size;
+ zwd->version = strdup(version);
+ zwd->zalloc = strm->zalloc;
+ zwd->zfree = strm->zfree;
+ zwd->opaque = strm->opaque;
+ zwd->requiredHeaderSize = ZWRAP_HEADERSIZE;
+
+ strm->state = (struct internal_state*) zwd;
+ strm->total_in = 0;
+ strm->total_out = 0;
+ strm->reserved = 1; /* mark as unknown steam */
+
+ return Z_OK;
+}
+
+
+ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size))
+{
+ int ret = z_inflateInit_ (strm, version, stream_size);
+ if (ret == Z_OK) {
+ ZWRAP_DCtx* zwd = (ZWRAP_DCtx*)strm->state;
+ zwd->windowBits = windowBits;
+ }
+ return ret;
+}
+
+
+
+
+ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength))
+{
+ if (!strm->reserved)
+ return inflateSetDictionary(strm, dictionary, dictLength);
+
+ LOG_WRAPPER("- inflateSetDictionary\n");
+ { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
+ size_t errorCode = ZBUFF_decompressInitDictionary(zwd->zbd, dictionary, dictLength);
+ if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
+
+ if (strm->total_in == ZSTD_frameHeaderSize_min) {
+ size_t dstCapacity = 0;
+ size_t srcSize = strm->total_in;
+ errorCode = ZBUFF_decompressContinue(zwd->zbd, strm->next_out, &dstCapacity, zwd->headerBuf, &srcSize);
+ LOG_WRAPPER("ZBUFF_decompressContinue3 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)srcSize, (int)dstCapacity);
+ if (dstCapacity > 0 || ZSTD_isError(errorCode)) {
+ LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode));
+ return Z_MEM_ERROR;
+ }
+ }
+ }
+
+ return Z_OK;
+}
+
+
+ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush))
+{
+ if (!strm->reserved)
+ return inflate(strm, flush);
+
+ if (strm->avail_in > 0) {
+ size_t errorCode, dstCapacity, srcSize;
+ ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
+ LOG_WRAPPER("inflate avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
+ while (strm->total_in < ZSTD_FRAMEHEADERSIZE_MIN)
+ {
+ srcSize = MIN(strm->avail_in, zwd->requiredHeaderSize - strm->total_in);
+ memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize);
+ strm->total_in += srcSize;
+ strm->next_in += srcSize;
+ strm->avail_in -= srcSize;
+ if (strm->total_in < zwd->requiredHeaderSize) return Z_OK;
+
+ if (MEM_readLE32(zwd->headerBuf) != ZSTD_MAGICNUMBER) {
+ z_stream strm2;
+ strm2.next_in = strm->next_in;
+ strm2.avail_in = strm->avail_in;
+ strm2.next_out = strm->next_out;
+ strm2.avail_out = strm->avail_out;
+
+ if (zwd->windowBits)
+ errorCode = inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size);
+ else
+ errorCode = inflateInit_(strm, zwd->version, zwd->stream_size);
+ LOG_WRAPPER("ZLIB inflateInit errorCode=%d\n", (int)errorCode);
+ if (errorCode != Z_OK) return errorCode;
+
+ /* inflate header */
+ strm->next_in = (unsigned char*)zwd->headerBuf;
+ strm->avail_in = ZWRAP_HEADERSIZE;
+ strm->avail_out = 0;
+ errorCode = inflate(strm, Z_NO_FLUSH);
+ LOG_WRAPPER("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in);
+ if (errorCode != Z_OK) return errorCode;
+ if (strm->avail_in > 0) return Z_MEM_ERROR;
+
+ strm->next_in = strm2.next_in;
+ strm->avail_in = strm2.avail_in;
+ strm->next_out = strm2.next_out;
+ strm->avail_out = strm2.avail_out;
+ strm->reserved = 0; /* mark as zlib stream */
+ if (flush == Z_INFLATE_SYNC) return inflateSync(strm);
+ return inflate(strm, flush);
+ }
+
+ if (zwd->requiredHeaderSize < ZSTD_FRAMEHEADERSIZE_MIN) {
+ zwd->requiredHeaderSize = ZSTD_FRAMEHEADERSIZE_MIN;
+ continue;
+ }
+
+ zwd->zbd = ZBUFF_createDCtx();
+ { size_t const errorCode = ZBUFF_decompressInit(zwd->zbd);
+ if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; }
+
+ srcSize = ZSTD_FRAMEHEADERSIZE_MIN;
+ dstCapacity = 0;
+ errorCode = ZBUFF_decompressContinue(zwd->zbd, strm->next_out, &dstCapacity, zwd->headerBuf, &srcSize);
+ LOG_WRAPPER("ZBUFF_decompressContinue1 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)srcSize, (int)dstCapacity);
+ if (ZSTD_isError(errorCode)) {
+ LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode));
+ return Z_MEM_ERROR;
+ }
+ if (strm->avail_in == 0) return Z_OK;
+ break;
+ }
+
+ srcSize = strm->avail_in;
+ dstCapacity = strm->avail_out;
+ errorCode = ZBUFF_decompressContinue(zwd->zbd, strm->next_out, &dstCapacity, strm->next_in, &srcSize);
+ LOG_WRAPPER("ZBUFF_decompressContinue2 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)srcSize, (int)dstCapacity);
+ if (ZSTD_isError(errorCode)) {
+ LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode));
+ zwd->errorCount++;
+ return (zwd->errorCount<=1) ? Z_NEED_DICT : Z_MEM_ERROR;
+ }
+ strm->next_out += dstCapacity;
+ strm->total_out += dstCapacity;
+ strm->avail_out -= dstCapacity;
+ strm->total_in += srcSize;
+ strm->next_in += srcSize;
+ strm->avail_in -= srcSize;
+ if (errorCode == 0) return Z_STREAM_END;
+ }
+ return Z_OK;
+}
+
+
+ZEXTERN int ZEXPORT z_inflateEnd OF((z_streamp strm))
+{
+ int ret = Z_OK;
+ if (!strm->reserved)
+ ret = inflateEnd(strm);
+
+ LOG_WRAPPER("- inflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out));
+ { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
+ size_t const errorCode = ZWRAP_freeDCtx(zwd);
+ if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
+ }
+ return ret;
+}
+
+
+ZEXTERN int ZEXPORT z_inflateSync OF((z_streamp strm))
+{
+ return z_inflate(strm, Z_INFLATE_SYNC);
+}
+
+
+
+
+/* Advanced compression functions */
+ZEXTERN int ZEXPORT z_deflateCopy OF((z_streamp dest,
+ z_streamp source))
+{
+ if (!g_useZSTD)
+ return deflateCopy(dest, source);
+ FINISH_WITH_ERR("deflateCopy is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm))
+{
+ if (!g_useZSTD)
+ return deflateReset(strm);
+ FINISH_WITH_ERR("deflateReset is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain))
+{
+ if (!g_useZSTD)
+ return deflateTune(strm, good_length, max_lazy, nice_length, max_chain);
+ FINISH_WITH_ERR("deflateTune is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_deflatePending OF((z_streamp strm,
+ unsigned *pending,
+ int *bits))
+{
+ if (!g_useZSTD)
+ return deflatePending(strm, pending, bits);
+ FINISH_WITH_ERR("deflatePending is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_deflatePrime OF((z_streamp strm,
+ int bits,
+ int value))
+{
+ if (!g_useZSTD)
+ return deflatePrime(strm, bits, value);
+ FINISH_WITH_ERR("deflatePrime is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_deflateSetHeader OF((z_streamp strm,
+ gz_headerp head))
+{
+ if (!g_useZSTD)
+ return deflateSetHeader(strm, head);
+ FINISH_WITH_ERR("deflateSetHeader is not supported!");
+}
+
+
+
+
+/* Advanced compression functions */
+ZEXTERN int ZEXPORT z_inflateGetDictionary OF((z_streamp strm,
+ Bytef *dictionary,
+ uInt *dictLength))
+{
+ if (!strm->reserved)
+ return inflateGetDictionary(strm, dictionary, dictLength);
+ FINISH_WITH_ERR("inflateGetDictionary is not supported!");
+}
+
+
+
+ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest,
+ z_streamp source))
+{
+ if (!g_useZSTD)
+ return inflateCopy(dest, source);
+ FINISH_WITH_ERR("inflateCopy is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm))
+{
+ if (!strm->reserved)
+ return inflateReset(strm);
+ FINISH_WITH_ERR("inflateReset is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_inflateReset2 OF((z_streamp strm,
+ int windowBits))
+{
+ if (!strm->reserved)
+ return inflateReset2(strm, windowBits);
+ FINISH_WITH_ERR("inflateReset2 is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_inflatePrime OF((z_streamp strm,
+ int bits,
+ int value))
+{
+ if (!strm->reserved)
+ return inflatePrime(strm, bits, value);
+ FINISH_WITH_ERR("inflatePrime is not supported!");
+}
+
+
+ZEXTERN long ZEXPORT z_inflateMark OF((z_streamp strm))
+{
+ if (!strm->reserved)
+ return inflateMark(strm);
+ FINISH_WITH_ERR("inflateMark is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_inflateGetHeader OF((z_streamp strm,
+ gz_headerp head))
+{
+ if (!strm->reserved)
+ return inflateGetHeader(strm, head);
+ FINISH_WITH_ERR("inflateGetHeader is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_inflateBackInit_ OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size))
+{
+ if (!strm->reserved)
+ return inflateBackInit_(strm, windowBits, window, version, stream_size);
+ FINISH_WITH_ERR("inflateBackInit is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_inflateBack OF((z_streamp strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc))
+{
+ if (!strm->reserved)
+ return inflateBack(strm, in, in_desc, out, out_desc);
+ FINISH_WITH_ERR("inflateBack is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_inflateBackEnd OF((z_streamp strm))
+{
+ if (!strm->reserved)
+ return inflateBackEnd(strm);
+ FINISH_WITH_ERR("inflateBackEnd is not supported!");
+}
+
+
+ZEXTERN uLong ZEXPORT z_zlibCompileFlags OF((void)) { return zlibCompileFlags(); };
+
+
+
+ /* utility functions */
+#ifndef Z_SOLO
+
+ZEXTERN int ZEXPORT z_compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen))
+{
+ if (!g_useZSTD)
+ return compress(dest, destLen, source, sourceLen);
+
+ size_t dstCapacity = *destLen;
+ LOG_WRAPPER("z_compress sourceLen=%d dstCapacity=%d\n", (int)sourceLen, (int)dstCapacity);
+ { size_t const errorCode = ZSTD_compress(dest, dstCapacity, source, sourceLen, -1);
+ if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
+ *destLen = errorCode;
+ }
+ return Z_OK;
+}
+
+
+ZEXTERN int ZEXPORT z_compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level))
+{
+ if (!g_useZSTD)
+ return compress2(dest, destLen, source, sourceLen, level);
+
+ size_t dstCapacity = *destLen;
+ { size_t const errorCode = ZSTD_compress(dest, dstCapacity, source, sourceLen, level);
+ if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
+ *destLen = errorCode;
+ }
+ return Z_OK;
+}
+
+
+ZEXTERN uLong ZEXPORT z_compressBound OF((uLong sourceLen))
+{
+ if (!g_useZSTD)
+ return compressBound(sourceLen);
+
+ return ZSTD_compressBound(sourceLen);
+}
+
+
+ZEXTERN int ZEXPORT z_uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen))
+{
+ if (sourceLen < 4 || MEM_readLE32(source) != ZSTD_MAGICNUMBER)
+// if (!g_useZSTD)
+ return uncompress(dest, destLen, source, sourceLen);
+
+ size_t dstCapacity = *destLen;
+ { size_t const errorCode = ZSTD_decompress(dest, dstCapacity, source, sourceLen);
+ if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
+ *destLen = errorCode;
+ }
+ return Z_OK;
+}
+
+
+
+ /* gzip file access functions */
+ZEXTERN gzFile ZEXPORT z_gzopen OF((const char *path, const char *mode))
+{
+ if (!g_useZSTD)
+ return gzopen(path, mode);
+ FINISH_WITH_NULL_ERR("gzopen is not supported!");
+}
+
+
+ZEXTERN gzFile ZEXPORT z_gzdopen OF((int fd, const char *mode))
+{
+ if (!g_useZSTD)
+ return gzdopen(fd, mode);
+ FINISH_WITH_NULL_ERR("gzdopen is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzbuffer OF((gzFile file, unsigned size))
+{
+ if (!g_useZSTD)
+ return gzbuffer(file, size);
+ FINISH_WITH_ERR("gzbuffer is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzsetparams OF((gzFile file, int level, int strategy))
+{
+ if (!g_useZSTD)
+ return gzsetparams(file, level, strategy);
+ FINISH_WITH_ERR("gzsetparams is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzread OF((gzFile file, voidp buf, unsigned len))
+{
+ if (!g_useZSTD)
+ return gzread(file, buf, len);
+ FINISH_WITH_ERR("gzread is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzwrite OF((gzFile file,
+ voidpc buf, unsigned len))
+{
+ if (!g_useZSTD)
+ return gzwrite(file, buf, len);
+ FINISH_WITH_ERR("gzwrite is not supported!");
+}
+
+
+ZEXTERN int ZEXPORTVA z_gzprintf Z_ARG((gzFile file, const char *format, ...))
+{
+ if (!g_useZSTD) {
+ int ret;
+ char buf[1024];
+ va_list args;
+ va_start (args, format);
+ ret = vsprintf (buf, format, args);
+ va_end (args);
+
+ ret = gzprintf(file, buf);
+ // printf("gzprintf ret=%d\n", ret);
+ return ret;
+ }
+ FINISH_WITH_ERR("gzprintf is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzputs OF((gzFile file, const char *s))
+{
+ if (!g_useZSTD)
+ return gzputs(file, s);
+ FINISH_WITH_ERR("gzputs is not supported!");
+}
+
+
+ZEXTERN char * ZEXPORT z_gzgets OF((gzFile file, char *buf, int len))
+{
+ if (!g_useZSTD)
+ return gzgets(file, buf, len);
+ FINISH_WITH_NULL_ERR("gzgets is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzputc OF((gzFile file, int c))
+{
+ if (!g_useZSTD)
+ return gzputc(file, c);
+ FINISH_WITH_ERR("gzputc is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzgetc OF((gzFile file))
+{
+ if (!g_useZSTD)
+ return gzgetc(file);
+ FINISH_WITH_ERR("gzgetc is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzungetc OF((int c, gzFile file))
+{
+ if (!g_useZSTD)
+ return gzungetc(c, file);
+ FINISH_WITH_ERR("gzungetc is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzflush OF((gzFile file, int flush))
+{
+ if (!g_useZSTD)
+ return gzflush(file, flush);
+ FINISH_WITH_ERR("gzflush is not supported!");
+}
+
+
+ZEXTERN z_off_t ZEXPORT z_gzseek OF((gzFile file, z_off_t offset, int whence))
+{
+ if (!g_useZSTD)
+ return gzseek(file, offset, whence);
+ FINISH_WITH_ERR("gzseek is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzrewind OF((gzFile file))
+{
+ if (!g_useZSTD)
+ return gzrewind(file);
+ FINISH_WITH_ERR("gzrewind is not supported!");
+}
+
+
+ZEXTERN z_off_t ZEXPORT z_gztell OF((gzFile file))
+{
+ if (!g_useZSTD)
+ return gztell(file);
+ FINISH_WITH_ERR("gztell is not supported!");
+}
+
+
+ZEXTERN z_off_t ZEXPORT z_gzoffset OF((gzFile file))
+{
+ if (!g_useZSTD)
+ return gzoffset(file);
+ FINISH_WITH_ERR("gzoffset is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzeof OF((gzFile file))
+{
+ if (!g_useZSTD)
+ return gzeof(file);
+ FINISH_WITH_ERR("gzeof is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzdirect OF((gzFile file))
+{
+ if (!g_useZSTD)
+ return gzdirect(file);
+ FINISH_WITH_ERR("gzdirect is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzclose OF((gzFile file))
+{
+ if (!g_useZSTD)
+ return gzclose(file);
+ FINISH_WITH_ERR("gzclose is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzclose_r OF((gzFile file))
+{
+ if (!g_useZSTD)
+ return gzclose_r(file);
+ FINISH_WITH_ERR("gzclose_r is not supported!");
+}
+
+
+ZEXTERN int ZEXPORT z_gzclose_w OF((gzFile file))
+{
+ if (!g_useZSTD)
+ return gzclose_w(file);
+ FINISH_WITH_ERR("gzclose_w is not supported!");
+}
+
+
+ZEXTERN const char * ZEXPORT z_gzerror OF((gzFile file, int *errnum))
+{
+ if (!g_useZSTD)
+ return gzerror(file, errnum);
+ FINISH_WITH_NULL_ERR("gzerror is not supported!");
+}
+
+
+ZEXTERN void ZEXPORT z_gzclearerr OF((gzFile file))
+{
+ if (!g_useZSTD)
+ gzclearerr(file);
+}
+
+
+#endif /* !Z_SOLO */
+
+
+ /* checksum functions */
+
+ZEXTERN uLong ZEXPORT z_adler32 OF((uLong adler, const Bytef *buf, uInt len))
+{
+ return adler32(adler, buf, len);
+}
+
+ZEXTERN uLong ZEXPORT z_crc32 OF((uLong crc, const Bytef *buf, uInt len))
+{
+ return crc32(crc, buf, len);
+}
--- /dev/null
+/*
+ zstd_zlibwrapper.h - zstd wrapper for zlib
+ Copyright (C) 2016, Przemyslaw Skibinski.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - zstd source repository : https://github.com/Cyan4973/zstd
+*/
+
+#ifndef ZSTD_ZLIBWRAPPER_H
+#define ZSTD_ZLIBWRAPPER_H
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+#define Z_PREFIX
+#include <zlib.h>
+
+
+void useZSTD(int turn_on);
+int isUsingZSTD();
+const char * zstdVersion();
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* ZSTD_ZLIBWRAPPER_H */