From 3eabe9b4746e3ff6469a6dd1583814b6f49ef978 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 12 May 2016 17:15:41 +0200 Subject: [PATCH] added zlibWrapper - zstd wrapper for zlib --- programs/util.h | 2 +- zlibWrapper/.gitignore | 26 + zlibWrapper/Makefile | 54 ++ zlibWrapper/README.md | 104 +++ zlibWrapper/examples/example.c | 607 ++++++++++++++++ zlibWrapper/examples/example_original.c | 601 ++++++++++++++++ zlibWrapper/zstd_zlibwrapper.c | 905 ++++++++++++++++++++++++ zlibWrapper/zstd_zlibwrapper.h | 53 ++ 8 files changed, 2351 insertions(+), 1 deletion(-) create mode 100644 zlibWrapper/.gitignore create mode 100644 zlibWrapper/Makefile create mode 100644 zlibWrapper/README.md create mode 100644 zlibWrapper/examples/example.c create mode 100644 zlibWrapper/examples/example_original.c create mode 100644 zlibWrapper/zstd_zlibwrapper.c create mode 100644 zlibWrapper/zstd_zlibwrapper.h diff --git a/programs/util.h b/programs/util.h index 76273412b..d791a2c71 100644 --- a/programs/util.h +++ b/programs/util.h @@ -281,7 +281,7 @@ UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_ 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); diff --git a/zlibWrapper/.gitignore b/zlibWrapper/.gitignore new file mode 100644 index 000000000..56473513b --- /dev/null +++ b/zlibWrapper/.gitignore @@ -0,0 +1,26 @@ +# 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 diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile new file mode 100644 index 000000000..fd45ee6d3 --- /dev/null +++ b/zlibWrapper/Makefile @@ -0,0 +1,54 @@ +# 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 + diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md new file mode 100644 index 000000000..5572e3ec6 --- /dev/null +++ b/zlibWrapper/README.md @@ -0,0 +1,104 @@ +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 diff --git a/zlibWrapper/examples/example.c b/zlibWrapper/examples/example.c new file mode 100644 index 000000000..fe6c80ac1 --- /dev/null +++ b/zlibWrapper/examples/example.c @@ -0,0 +1,607 @@ +/* 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 + +#ifdef STDC +# include +# include +#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; +} diff --git a/zlibWrapper/examples/example_original.c b/zlibWrapper/examples/example_original.c new file mode 100644 index 000000000..138a699bd --- /dev/null +++ b/zlibWrapper/examples/example_original.c @@ -0,0 +1,601 @@ +/* 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 + +#ifdef STDC +# include +# include +#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; +} diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c new file mode 100644 index 000000000..5df1215e5 --- /dev/null +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -0,0 +1,905 @@ +/* + 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 /* fprintf */ +#include /* malloc */ +#include +#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); +} diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h new file mode 100644 index 000000000..c9039ddb5 --- /dev/null +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -0,0 +1,53 @@ +/* + 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 + + +void useZSTD(int turn_on); +int isUsingZSTD(); +const char * zstdVersion(); + + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_ZLIBWRAPPER_H */