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