annotate src/zlib-1.2.8/examples/zpipe.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 5ea0608b923f
children
rev   line source
Chris@43 1 /* zpipe.c: example of proper use of zlib's inflate() and deflate()
Chris@43 2 Not copyrighted -- provided to the public domain
Chris@43 3 Version 1.4 11 December 2005 Mark Adler */
Chris@43 4
Chris@43 5 /* Version history:
Chris@43 6 1.0 30 Oct 2004 First version
Chris@43 7 1.1 8 Nov 2004 Add void casting for unused return values
Chris@43 8 Use switch statement for inflate() return values
Chris@43 9 1.2 9 Nov 2004 Add assertions to document zlib guarantees
Chris@43 10 1.3 6 Apr 2005 Remove incorrect assertion in inf()
Chris@43 11 1.4 11 Dec 2005 Add hack to avoid MSDOS end-of-line conversions
Chris@43 12 Avoid some compiler warnings for input and output buffers
Chris@43 13 */
Chris@43 14
Chris@43 15 #include <stdio.h>
Chris@43 16 #include <string.h>
Chris@43 17 #include <assert.h>
Chris@43 18 #include "zlib.h"
Chris@43 19
Chris@43 20 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
Chris@43 21 # include <fcntl.h>
Chris@43 22 # include <io.h>
Chris@43 23 # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
Chris@43 24 #else
Chris@43 25 # define SET_BINARY_MODE(file)
Chris@43 26 #endif
Chris@43 27
Chris@43 28 #define CHUNK 16384
Chris@43 29
Chris@43 30 /* Compress from file source to file dest until EOF on source.
Chris@43 31 def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
Chris@43 32 allocated for processing, Z_STREAM_ERROR if an invalid compression
Chris@43 33 level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
Chris@43 34 version of the library linked do not match, or Z_ERRNO if there is
Chris@43 35 an error reading or writing the files. */
Chris@43 36 int def(FILE *source, FILE *dest, int level)
Chris@43 37 {
Chris@43 38 int ret, flush;
Chris@43 39 unsigned have;
Chris@43 40 z_stream strm;
Chris@43 41 unsigned char in[CHUNK];
Chris@43 42 unsigned char out[CHUNK];
Chris@43 43
Chris@43 44 /* allocate deflate state */
Chris@43 45 strm.zalloc = Z_NULL;
Chris@43 46 strm.zfree = Z_NULL;
Chris@43 47 strm.opaque = Z_NULL;
Chris@43 48 ret = deflateInit(&strm, level);
Chris@43 49 if (ret != Z_OK)
Chris@43 50 return ret;
Chris@43 51
Chris@43 52 /* compress until end of file */
Chris@43 53 do {
Chris@43 54 strm.avail_in = fread(in, 1, CHUNK, source);
Chris@43 55 if (ferror(source)) {
Chris@43 56 (void)deflateEnd(&strm);
Chris@43 57 return Z_ERRNO;
Chris@43 58 }
Chris@43 59 flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
Chris@43 60 strm.next_in = in;
Chris@43 61
Chris@43 62 /* run deflate() on input until output buffer not full, finish
Chris@43 63 compression if all of source has been read in */
Chris@43 64 do {
Chris@43 65 strm.avail_out = CHUNK;
Chris@43 66 strm.next_out = out;
Chris@43 67 ret = deflate(&strm, flush); /* no bad return value */
Chris@43 68 assert(ret != Z_STREAM_ERROR); /* state not clobbered */
Chris@43 69 have = CHUNK - strm.avail_out;
Chris@43 70 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
Chris@43 71 (void)deflateEnd(&strm);
Chris@43 72 return Z_ERRNO;
Chris@43 73 }
Chris@43 74 } while (strm.avail_out == 0);
Chris@43 75 assert(strm.avail_in == 0); /* all input will be used */
Chris@43 76
Chris@43 77 /* done when last data in file processed */
Chris@43 78 } while (flush != Z_FINISH);
Chris@43 79 assert(ret == Z_STREAM_END); /* stream will be complete */
Chris@43 80
Chris@43 81 /* clean up and return */
Chris@43 82 (void)deflateEnd(&strm);
Chris@43 83 return Z_OK;
Chris@43 84 }
Chris@43 85
Chris@43 86 /* Decompress from file source to file dest until stream ends or EOF.
Chris@43 87 inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
Chris@43 88 allocated for processing, Z_DATA_ERROR if the deflate data is
Chris@43 89 invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
Chris@43 90 the version of the library linked do not match, or Z_ERRNO if there
Chris@43 91 is an error reading or writing the files. */
Chris@43 92 int inf(FILE *source, FILE *dest)
Chris@43 93 {
Chris@43 94 int ret;
Chris@43 95 unsigned have;
Chris@43 96 z_stream strm;
Chris@43 97 unsigned char in[CHUNK];
Chris@43 98 unsigned char out[CHUNK];
Chris@43 99
Chris@43 100 /* allocate inflate state */
Chris@43 101 strm.zalloc = Z_NULL;
Chris@43 102 strm.zfree = Z_NULL;
Chris@43 103 strm.opaque = Z_NULL;
Chris@43 104 strm.avail_in = 0;
Chris@43 105 strm.next_in = Z_NULL;
Chris@43 106 ret = inflateInit(&strm);
Chris@43 107 if (ret != Z_OK)
Chris@43 108 return ret;
Chris@43 109
Chris@43 110 /* decompress until deflate stream ends or end of file */
Chris@43 111 do {
Chris@43 112 strm.avail_in = fread(in, 1, CHUNK, source);
Chris@43 113 if (ferror(source)) {
Chris@43 114 (void)inflateEnd(&strm);
Chris@43 115 return Z_ERRNO;
Chris@43 116 }
Chris@43 117 if (strm.avail_in == 0)
Chris@43 118 break;
Chris@43 119 strm.next_in = in;
Chris@43 120
Chris@43 121 /* run inflate() on input until output buffer not full */
Chris@43 122 do {
Chris@43 123 strm.avail_out = CHUNK;
Chris@43 124 strm.next_out = out;
Chris@43 125 ret = inflate(&strm, Z_NO_FLUSH);
Chris@43 126 assert(ret != Z_STREAM_ERROR); /* state not clobbered */
Chris@43 127 switch (ret) {
Chris@43 128 case Z_NEED_DICT:
Chris@43 129 ret = Z_DATA_ERROR; /* and fall through */
Chris@43 130 case Z_DATA_ERROR:
Chris@43 131 case Z_MEM_ERROR:
Chris@43 132 (void)inflateEnd(&strm);
Chris@43 133 return ret;
Chris@43 134 }
Chris@43 135 have = CHUNK - strm.avail_out;
Chris@43 136 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
Chris@43 137 (void)inflateEnd(&strm);
Chris@43 138 return Z_ERRNO;
Chris@43 139 }
Chris@43 140 } while (strm.avail_out == 0);
Chris@43 141
Chris@43 142 /* done when inflate() says it's done */
Chris@43 143 } while (ret != Z_STREAM_END);
Chris@43 144
Chris@43 145 /* clean up and return */
Chris@43 146 (void)inflateEnd(&strm);
Chris@43 147 return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
Chris@43 148 }
Chris@43 149
Chris@43 150 /* report a zlib or i/o error */
Chris@43 151 void zerr(int ret)
Chris@43 152 {
Chris@43 153 fputs("zpipe: ", stderr);
Chris@43 154 switch (ret) {
Chris@43 155 case Z_ERRNO:
Chris@43 156 if (ferror(stdin))
Chris@43 157 fputs("error reading stdin\n", stderr);
Chris@43 158 if (ferror(stdout))
Chris@43 159 fputs("error writing stdout\n", stderr);
Chris@43 160 break;
Chris@43 161 case Z_STREAM_ERROR:
Chris@43 162 fputs("invalid compression level\n", stderr);
Chris@43 163 break;
Chris@43 164 case Z_DATA_ERROR:
Chris@43 165 fputs("invalid or incomplete deflate data\n", stderr);
Chris@43 166 break;
Chris@43 167 case Z_MEM_ERROR:
Chris@43 168 fputs("out of memory\n", stderr);
Chris@43 169 break;
Chris@43 170 case Z_VERSION_ERROR:
Chris@43 171 fputs("zlib version mismatch!\n", stderr);
Chris@43 172 }
Chris@43 173 }
Chris@43 174
Chris@43 175 /* compress or decompress from stdin to stdout */
Chris@43 176 int main(int argc, char **argv)
Chris@43 177 {
Chris@43 178 int ret;
Chris@43 179
Chris@43 180 /* avoid end-of-line conversions */
Chris@43 181 SET_BINARY_MODE(stdin);
Chris@43 182 SET_BINARY_MODE(stdout);
Chris@43 183
Chris@43 184 /* do compression if no arguments */
Chris@43 185 if (argc == 1) {
Chris@43 186 ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
Chris@43 187 if (ret != Z_OK)
Chris@43 188 zerr(ret);
Chris@43 189 return ret;
Chris@43 190 }
Chris@43 191
Chris@43 192 /* do decompression if -d specified */
Chris@43 193 else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
Chris@43 194 ret = inf(stdin, stdout);
Chris@43 195 if (ret != Z_OK)
Chris@43 196 zerr(ret);
Chris@43 197 return ret;
Chris@43 198 }
Chris@43 199
Chris@43 200 /* otherwise, report usage */
Chris@43 201 else {
Chris@43 202 fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
Chris@43 203 return 1;
Chris@43 204 }
Chris@43 205 }