Last active
August 29, 2015 14:02
-
-
Save loggerhead/0735d9d8644b6ff8c15b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* zpipe.c: example of proper use of zlib's inflate() and deflate() | |
Not copyrighted -- provided to the public domain | |
Version 1.4 11 December 2005 Mark Adler */ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <assert.h> | |
#include "zlib.h" | |
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) | |
# include <fcntl.h> | |
# include <io.h> | |
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) | |
#else | |
# define SET_BINARY_MODE(file) | |
#endif | |
#define CHUNK 16384 | |
/* Decompress from file source to file dest until stream ends or EOF. | |
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be | |
allocated for processing, Z_DATA_ERROR if the deflate data is | |
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and | |
the version of the library linked do not match, or Z_ERRNO if there | |
is an error reading or writing the files. */ | |
int inf(FILE *source, FILE *dest) | |
{ | |
int ret; | |
unsigned have; | |
z_stream strm; | |
unsigned char in[CHUNK]; | |
unsigned char out[CHUNK]; | |
/* avoid end-of-line conversions */ | |
SET_BINARY_MODE(source); | |
SET_BINARY_MODE(dest); | |
/* allocate inflate state */ | |
strm.zalloc = Z_NULL; | |
strm.zfree = Z_NULL; | |
strm.opaque = Z_NULL; | |
strm.avail_in = 0; | |
strm.next_in = Z_NULL; | |
ret = inflateInit2(&strm, 15 + 32); | |
// ret = inflateInit(&strm); | |
if (ret != Z_OK) | |
return ret; | |
/* decompress until deflate stream ends or end of file */ | |
do { | |
strm.avail_in = fread(in, 1, CHUNK, source); | |
if (ferror(source)) { | |
(void)inflateEnd(&strm); | |
return Z_ERRNO; | |
} | |
if (strm.avail_in == 0) | |
break; | |
strm.next_in = in; | |
/* run inflate() on input until output buffer not full */ | |
do { | |
strm.avail_out = CHUNK; | |
strm.next_out = out; | |
ret = inflate(&strm, Z_NO_FLUSH); | |
assert(ret != Z_STREAM_ERROR); /* state not clobbered */ | |
switch (ret) { | |
case Z_NEED_DICT: | |
ret = Z_DATA_ERROR; /* and fall through */ | |
case Z_DATA_ERROR: | |
case Z_MEM_ERROR: | |
(void)inflateEnd(&strm); | |
return ret; | |
} | |
have = CHUNK - strm.avail_out; | |
if (fwrite(out, 1, have, dest) != have || ferror(dest)) { | |
(void)inflateEnd(&strm); | |
return Z_ERRNO; | |
} | |
} while (strm.avail_out == 0); | |
/* done when inflate() says it's done */ | |
} while (ret != Z_STREAM_END); | |
/* clean up and return */ | |
(void)inflateEnd(&strm); | |
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; | |
} | |
/* another way to decompress gzip file */ | |
int inf2(const char *srcname, FILE *dest) { | |
unsigned char buf[CHUNK]; | |
size_t len = CHUNK; | |
gzFile zfp = gzopen(srcname, "rb"); | |
while (len > 0) { | |
len = gzread(zfp, buf, CHUNK); | |
if (len > 0) | |
fwrite(buf, 1, len, dest); | |
} | |
return gzclose(zfp); | |
} | |
/* report a zlib or i/o error */ | |
void zerr(int ret) | |
{ | |
fputs("zpipe: ", stderr); | |
switch (ret) { | |
case Z_ERRNO: | |
if (ferror(stdin)) | |
fputs("error reading stdin\n", stderr); | |
if (ferror(stdout)) | |
fputs("error writing stdout\n", stderr); | |
break; | |
case Z_STREAM_ERROR: | |
fputs("invalid compression level\n", stderr); | |
break; | |
case Z_DATA_ERROR: | |
fputs("invalid or incomplete deflate data\n", stderr); | |
break; | |
case Z_MEM_ERROR: | |
fputs("out of memory\n", stderr); | |
break; | |
case Z_VERSION_ERROR: | |
fputs("zlib version mismatch!\n", stderr); | |
} | |
} | |
/* compress or decompress from stdin to stdout */ | |
int main(int argc, char **argv) | |
{ | |
const char *srcname = "in.html"; | |
int ret; | |
FILE *fp = fopen(srcname, "r"); | |
// ret = inf(fp, stdout); | |
ret = inf2(srcname, stdout); | |
if (ret != Z_OK) | |
zerr(ret); | |
fclose(fp); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment