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