Geant4  10.01.p02
gzwrite.cc
Go to the documentation of this file.
1 /* gzwrite.c -- zlib functions for writing gzip files
2  * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler
3  * For conditions of distribution and use, see copyright notice in zlib.h
4  */
5 
6 #include "gzguts.h"
7 
8 /* Local functions */
9 local int gz_init OF((gz_statep));
10 local int gz_comp OF((gz_statep, int));
11 local int gz_zero OF((gz_statep, z_off64_t));
12 
13 /* Initialize state for writing a gzip file. Mark initialization by setting
14  state->size to non-zero. Return -1 on failure or 0 on success. */
15 local int gz_init(gz_statep state)
16 {
17  int ret;
18  z_streamp strm = &(state->strm);
19 
20  /* allocate input buffer */
21  state->in = (unsigned char *)malloc(state->want);
22  if (state->in == NULL) {
23  gz_error(state, Z_MEM_ERROR, "out of memory");
24  return -1;
25  }
26 
27  /* only need output buffer and deflate state if compressing */
28  if (!state->direct) {
29  /* allocate output buffer */
30  state->out = (unsigned char *)malloc(state->want);
31  if (state->out == NULL) {
32  free(state->in);
33  gz_error(state, Z_MEM_ERROR, "out of memory");
34  return -1;
35  }
36 
37  /* allocate deflate memory, set up for gzip compression */
38  strm->zalloc = Z_NULL;
39  strm->zfree = Z_NULL;
40  strm->opaque = Z_NULL;
41  ret = deflateInit2(strm, state->level, Z_DEFLATED,
42  MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
43  if (ret != Z_OK) {
44  free(state->out);
45  free(state->in);
46  gz_error(state, Z_MEM_ERROR, "out of memory");
47  return -1;
48  }
49  }
50 
51  /* mark state as initialized */
52  state->size = state->want;
53 
54  /* initialize write buffer if compressing */
55  if (!state->direct) {
56  strm->avail_out = state->size;
57  strm->next_out = state->out;
58  state->x.next = strm->next_out;
59  }
60  return 0;
61 }
62 
63 /* Compress whatever is at avail_in and next_in and write to the output file.
64  Return -1 if there is an error writing to the output file, otherwise 0.
65  flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
66  then the deflate() state is reset to start a new gzip stream. If gz->direct
67  is true, then simply write to the output file without compressing, and
68  ignore flush. */
69 local int gz_comp(gz_statep state, int flush)
70 {
71  int ret, got;
72  unsigned have;
73  z_streamp strm = &(state->strm);
74 
75  /* allocate memory if this is the first time through */
76  if (state->size == 0 && gz_init(state) == -1)
77  return -1;
78 
79  /* write directly if requested */
80  if (state->direct) {
81  got = write(state->fd, strm->next_in, strm->avail_in);
82  if (got < 0 || (unsigned)got != strm->avail_in) {
83  gz_error(state, Z_ERRNO, zstrerror());
84  return -1;
85  }
86  strm->avail_in = 0;
87  return 0;
88  }
89 
90  /* run deflate() on provided input until it produces no more output */
91  ret = Z_OK;
92  do {
93  /* write out current buffer contents if full, or if flushing, but if
94  doing Z_FINISH then don't write until we get to Z_STREAM_END */
95  if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
96  (flush != Z_FINISH || ret == Z_STREAM_END))) {
97  have = (unsigned)(strm->next_out - state->x.next);
98  if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
99  (unsigned)got != have)) {
100  gz_error(state, Z_ERRNO, zstrerror());
101  return -1;
102  }
103  if (strm->avail_out == 0) {
104  strm->avail_out = state->size;
105  strm->next_out = state->out;
106  }
107  state->x.next = strm->next_out;
108  }
109 
110  /* compress */
111  have = strm->avail_out;
112  ret = deflate(strm, flush);
113  if (ret == Z_STREAM_ERROR) {
114  gz_error(state, Z_STREAM_ERROR,
115  "internal error: deflate stream corrupt");
116  return -1;
117  }
118  have -= strm->avail_out;
119  } while (have);
120 
121  /* if that completed a deflate stream, allow another to start */
122  if (flush == Z_FINISH)
123  deflateReset(strm);
124 
125  /* all done, no errors */
126  return 0;
127 }
128 
129 /* Compress len zeros to output. Return -1 on error, 0 on success. */
130 local int gz_zero(gz_statep state, z_off64_t len)
131 {
132  int first;
133  unsigned n;
134  z_streamp strm = &(state->strm);
135 
136  /* consume whatever's left in the input buffer */
137  if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
138  return -1;
139 
140  /* compress len zeros (len guaranteed > 0) */
141  first = 1;
142  while (len) {
143  n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
144  (unsigned)len : state->size;
145  if (first) {
146  memset(state->in, 0, n);
147  first = 0;
148  }
149  strm->avail_in = n;
150  strm->next_in = state->in;
151  state->x.pos += n;
152  if (gz_comp(state, Z_NO_FLUSH) == -1)
153  return -1;
154  len -= n;
155  }
156  return 0;
157 }
158 
159 /* -- see zlib.h -- */
160 int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len)
161 {
162  unsigned put = len;
163  unsigned n;
164  gz_statep state;
165  z_streamp strm;
166 
167  /* get internal structure */
168  if (file == NULL)
169  return 0;
170  state = (gz_statep)file;
171  strm = &(state->strm);
172 
173  /* check that we're writing and that there's no error */
174  if (state->mode != GZ_WRITE || state->err != Z_OK)
175  return 0;
176 
177  /* since an int is returned, make sure len fits in one, otherwise return
178  with an error (this avoids the flaw in the interface) */
179  if ((int)len < 0) {
180  gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
181  return 0;
182  }
183 
184  /* if len is zero, avoid unnecessary operations */
185  if (len == 0)
186  return 0;
187 
188  /* allocate memory if this is the first time through */
189  if (state->size == 0 && gz_init(state) == -1)
190  return 0;
191 
192  /* check for seek request */
193  if (state->seek) {
194  state->seek = 0;
195  if (gz_zero(state, state->skip) == -1)
196  return 0;
197  }
198 
199  /* for small len, copy to input buffer, otherwise compress directly */
200  if (len < state->size) {
201  /* copy to input buffer, compress when full */
202  do {
203  if (strm->avail_in == 0)
204  strm->next_in = state->in;
205  n = state->size - strm->avail_in;
206  if (n > len)
207  n = len;
208  memcpy(strm->next_in + strm->avail_in, buf, n);
209  strm->avail_in += n;
210  state->x.pos += n;
211  buf = (char *)buf + n;
212  len -= n;
213  if (len && gz_comp(state, Z_NO_FLUSH) == -1)
214  return 0;
215  } while (len);
216  }
217  else {
218  /* consume whatever's left in the input buffer */
219  if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
220  return 0;
221 
222  /* directly compress user buffer to file */
223  strm->avail_in = len;
224  strm->next_in = (z_const Bytef *)buf;
225  state->x.pos += len;
226  if (gz_comp(state, Z_NO_FLUSH) == -1)
227  return 0;
228  }
229 
230  /* input was all buffered or compressed (put will fit in int) */
231  return (int)put;
232 }
233 
234 /* -- see zlib.h -- */
235 int ZEXPORT gzputc(gzFile file, int c)
236 {
237  unsigned char buf[1];
238  gz_statep state;
239  z_streamp strm;
240 
241  /* get internal structure */
242  if (file == NULL)
243  return -1;
244  state = (gz_statep)file;
245  strm = &(state->strm);
246 
247  /* check that we're writing and that there's no error */
248  if (state->mode != GZ_WRITE || state->err != Z_OK)
249  return -1;
250 
251  /* check for seek request */
252  if (state->seek) {
253  state->seek = 0;
254  if (gz_zero(state, state->skip) == -1)
255  return -1;
256  }
257 
258  /* try writing to input buffer for speed (state->size == 0 if buffer not
259  initialized) */
260  if (strm->avail_in < state->size) {
261  if (strm->avail_in == 0)
262  strm->next_in = state->in;
263  strm->next_in[strm->avail_in++] = c;
264  state->x.pos++;
265  return c & 0xff;
266  }
267 
268  /* no room in buffer or not initialized, use gz_write() */
269  buf[0] = c;
270  if (gzwrite(file, buf, 1) != 1)
271  return -1;
272  return c & 0xff;
273 }
274 
275 /* -- see zlib.h -- */
276 int ZEXPORT gzputs(gzFile file, const char *str)
277 {
278  int ret;
279  unsigned len;
280 
281  /* write string */
282  len = (unsigned)strlen(str);
283  ret = gzwrite(file, str, len);
284  return ret == 0 && len != 0 ? -1 : ret;
285 }
286 
287 #if defined(STDC) || defined(Z_HAVE_STDARG_H)
288 #include <stdarg.h>
289 
290 /* -- see zlib.h -- */
291 int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
292 {
293  int size, len;
294  gz_statep state;
295  z_streamp strm;
296  va_list va;
297 
298  /* get internal structure */
299  if (file == NULL)
300  return -1;
301  state = (gz_statep)file;
302  strm = &(state->strm);
303 
304  /* check that we're writing and that there's no error */
305  if (state->mode != GZ_WRITE || state->err != Z_OK)
306  return 0;
307 
308  /* make sure we have some buffer space */
309  if (state->size == 0 && gz_init(state) == -1)
310  return 0;
311 
312  /* check for seek request */
313  if (state->seek) {
314  state->seek = 0;
315  if (gz_zero(state, state->skip) == -1)
316  return 0;
317  }
318 
319  /* consume whatever's left in the input buffer */
320  if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
321  return 0;
322 
323  /* do the printf() into the input buffer, put length in len */
324  size = (int)(state->size);
325  state->in[size - 1] = 0;
326  va_start(va, format);
327 #ifdef NO_vsnprintf
328 # ifdef HAS_vsprintf_void
329  (void)vsprintf((char *)(state->in), format, va);
330  va_end(va);
331  for (len = 0; len < size; len++)
332  if (state->in[len] == 0) break;
333 # else
334  len = vsprintf((char *)(state->in), format, va);
335  va_end(va);
336 # endif
337 #else
338 # ifdef HAS_vsnprintf_void
339  (void)vsnprintf((char *)(state->in), size, format, va);
340  va_end(va);
341  len = strlen((char *)(state->in));
342 # else
343  len = vsnprintf((char *)(state->in), size, format, va);
344  va_end(va);
345 # endif
346 #endif
347 
348  /* check that printf() results fit in buffer */
349  if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
350  return 0;
351 
352  /* update buffer and position, defer compression until needed */
353  strm->avail_in = (unsigned)len;
354  strm->next_in = state->in;
355  state->x.pos += len;
356  return len;
357 }
358 
359 #else /* !STDC && !Z_HAVE_STDARG_H */
360 
361 /* -- see zlib.h -- */
362 int ZEXPORTVA gzprintf (gzFile file, const char *format,
363  int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10,
364  int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20)
365 {
366  int size, len;
367  gz_statep state;
368  z_streamp strm;
369 
370  /* get internal structure */
371  if (file == NULL)
372  return -1;
373  state = (gz_statep)file;
374  strm = &(state->strm);
375 
376  /* check that can really pass pointer in ints */
377  if (sizeof(int) != sizeof(void *))
378  return 0;
379 
380  /* check that we're writing and that there's no error */
381  if (state->mode != GZ_WRITE || state->err != Z_OK)
382  return 0;
383 
384  /* make sure we have some buffer space */
385  if (state->size == 0 && gz_init(state) == -1)
386  return 0;
387 
388  /* check for seek request */
389  if (state->seek) {
390  state->seek = 0;
391  if (gz_zero(state, state->skip) == -1)
392  return 0;
393  }
394 
395  /* consume whatever's left in the input buffer */
396  if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
397  return 0;
398 
399  /* do the printf() into the input buffer, put length in len */
400  size = (int)(state->size);
401  state->in[size - 1] = 0;
402 #ifdef NO_snprintf
403 # ifdef HAS_sprintf_void
404  sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
405  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
406  for (len = 0; len < size; len++)
407  if (state->in[len] == 0) break;
408 # else
409  len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
410  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
411 # endif
412 #else
413 # ifdef HAS_snprintf_void
414  snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
415  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
416  len = strlen((char *)(state->in));
417 # else
418  len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
419  a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
420  a19, a20);
421 # endif
422 #endif
423 
424  /* check that printf() results fit in buffer */
425  if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
426  return 0;
427 
428  /* update buffer and position, defer compression until needed */
429  strm->avail_in = (unsigned)len;
430  strm->next_in = state->in;
431  state->x.pos += len;
432  return len;
433 }
434 
435 #endif
436 
437 /* -- see zlib.h -- */
438 int ZEXPORT gzflush(gzFile file, int flush)
439 {
440  gz_statep state;
441 
442  /* get internal structure */
443  if (file == NULL)
444  return -1;
445  state = (gz_statep)file;
446 
447  /* check that we're writing and that there's no error */
448  if (state->mode != GZ_WRITE || state->err != Z_OK)
449  return Z_STREAM_ERROR;
450 
451  /* check flush parameter */
452  if (flush < 0 || flush > Z_FINISH)
453  return Z_STREAM_ERROR;
454 
455  /* check for seek request */
456  if (state->seek) {
457  state->seek = 0;
458  if (gz_zero(state, state->skip) == -1)
459  return -1;
460  }
461 
462  /* compress remaining data with requested flush */
463  gz_comp(state, flush);
464  return state->err;
465 }
466 
467 /* -- see zlib.h -- */
468 int ZEXPORT gzsetparams(gzFile file, int level, int strategy)
469 {
470  gz_statep state;
471  z_streamp strm;
472 
473  /* get internal structure */
474  if (file == NULL)
475  return Z_STREAM_ERROR;
476  state = (gz_statep)file;
477  strm = &(state->strm);
478 
479  /* check that we're writing and that there's no error */
480  if (state->mode != GZ_WRITE || state->err != Z_OK)
481  return Z_STREAM_ERROR;
482 
483  /* if no change is requested, then do nothing */
484  if (level == state->level && strategy == state->strategy)
485  return Z_OK;
486 
487  /* check for seek request */
488  if (state->seek) {
489  state->seek = 0;
490  if (gz_zero(state, state->skip) == -1)
491  return -1;
492  }
493 
494  /* change compression parameters for subsequent input */
495  if (state->size) {
496  /* flush previous input with previous parameters before changing */
497  if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
498  return state->err;
499  deflateParams(strm, level, strategy);
500  }
501  state->level = level;
502  state->strategy = strategy;
503  return Z_OK;
504 }
505 
506 /* -- see zlib.h -- */
507 int ZEXPORT gzclose_w(gzFile file)
508 {
509  int ret = Z_OK;
510  gz_statep state;
511 
512  /* get internal structure */
513  if (file == NULL)
514  return Z_STREAM_ERROR;
515  state = (gz_statep)file;
516 
517  /* check that we're writing */
518  if (state->mode != GZ_WRITE)
519  return Z_STREAM_ERROR;
520 
521  /* check for seek request */
522  if (state->seek) {
523  state->seek = 0;
524  if (gz_zero(state, state->skip) == -1)
525  ret = state->err;
526  }
527 
528  /* flush, free memory, and close file */
529  if (state->size) {
530  if (gz_comp(state, Z_FINISH) == -1)
531  ret = state->err;
532  if (!state->direct) {
533  (void)deflateEnd(&(state->strm));
534  free(state->out);
535  }
536  free(state->in);
537  }
538  gz_error(state, Z_OK, NULL);
539  free(state->path);
540  if (close(state->fd) == -1)
541  ret = Z_ERRNO;
542  free(state);
543  return ret;
544 }
int ZEXPORT deflateEnd(z_streamp strm)
Definition: deflate.cc:937
void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg)
Definition: gzlib.cc:534
int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20)
Definition: gzwrite.cc:362
int ZEXPORT gzsetparams(gzFile file, int level, int strategy)
Definition: gzwrite.cc:468
static const G4double a1
static const G4double a4
#define local
Definition: adler32.cc:10
int ZEXPORT gzputs(gzFile file, const char *str)
Definition: gzwrite.cc:276
local int gz_init OF((gz_statep))
int ZEXPORT deflateParams(z_streamp strm, int level, int strategy)
Definition: deflate.cc:465
local int gz_comp(gz_statep state, int flush)
Definition: gzwrite.cc:69
const G4int n
static const G4double a3
int ZEXPORT gzputc(gzFile file, int c)
Definition: gzwrite.cc:235
int ZEXPORT gzclose_w(gzFile file)
Definition: gzwrite.cc:507
int ZEXPORT deflate(z_streamp strm, int flush)
Definition: deflate.cc:625
int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len)
Definition: gzwrite.cc:160
static const G4double a5
local int gz_init(gz_statep state)
Definition: gzwrite.cc:15
int ZEXPORT deflateReset(z_streamp strm)
Definition: deflate.cc:411
static const G4double a2
local int gz_zero(gz_statep state, z_off64_t len)
Definition: gzwrite.cc:130
int ZEXPORT gzflush(gzFile file, int flush)
Definition: gzwrite.cc:438