Geant4  10.03
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, 2013 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  gz_statep state;
164  z_streamp strm;
165 
166  /* get internal structure */
167  if (file == NULL)
168  return 0;
169  state = (gz_statep)file;
170  strm = &(state->strm);
171 
172  /* check that we're writing and that there's no error */
173  if (state->mode != GZ_WRITE || state->err != Z_OK)
174  return 0;
175 
176  /* since an int is returned, make sure len fits in one, otherwise return
177  with an error (this avoids the flaw in the interface) */
178  if ((int)len < 0) {
179  gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
180  return 0;
181  }
182 
183  /* if len is zero, avoid unnecessary operations */
184  if (len == 0)
185  return 0;
186 
187  /* allocate memory if this is the first time through */
188  if (state->size == 0 && gz_init(state) == -1)
189  return 0;
190 
191  /* check for seek request */
192  if (state->seek) {
193  state->seek = 0;
194  if (gz_zero(state, state->skip) == -1)
195  return 0;
196  }
197 
198  /* for small len, copy to input buffer, otherwise compress directly */
199  if (len < state->size) {
200  /* copy to input buffer, compress when full */
201  do {
202  unsigned have, copy;
203 
204  if (strm->avail_in == 0)
205  strm->next_in = state->in;
206  have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
207  copy = state->size - have;
208  if (copy > len)
209  copy = len;
210  memcpy(state->in + have, buf, copy);
211  strm->avail_in += copy;
212  state->x.pos += copy;
213  buf = (const char *)buf + copy;
214  len -= copy;
215  if (len && gz_comp(state, Z_NO_FLUSH) == -1)
216  return 0;
217  } while (len);
218  }
219  else {
220  /* consume whatever's left in the input buffer */
221  if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
222  return 0;
223 
224  /* directly compress user buffer to file */
225  strm->avail_in = len;
226  strm->next_in = (z_const Bytef *)buf;
227  state->x.pos += len;
228  if (gz_comp(state, Z_NO_FLUSH) == -1)
229  return 0;
230  }
231 
232  /* input was all buffered or compressed (put will fit in int) */
233  return (int)put;
234 }
235 
236 /* -- see zlib.h -- */
237 int ZEXPORT gzputc(gzFile file, int c)
238 {
239  unsigned have;
240  unsigned char buf[1];
241  gz_statep state;
242  z_streamp strm;
243 
244  /* get internal structure */
245  if (file == NULL)
246  return -1;
247  state = (gz_statep)file;
248  strm = &(state->strm);
249 
250  /* check that we're writing and that there's no error */
251  if (state->mode != GZ_WRITE || state->err != Z_OK)
252  return -1;
253 
254  /* check for seek request */
255  if (state->seek) {
256  state->seek = 0;
257  if (gz_zero(state, state->skip) == -1)
258  return -1;
259  }
260 
261  /* try writing to input buffer for speed (state->size == 0 if buffer not
262  initialized) */
263  if (state->size) {
264  if (strm->avail_in == 0)
265  strm->next_in = state->in;
266  have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
267  if (have < state->size) {
268  state->in[have] = c;
269  strm->avail_in++;
270  state->x.pos++;
271  return c & 0xff;
272  }
273  }
274 
275  /* no room in buffer or not initialized, use gz_write() */
276  buf[0] = c;
277  if (gzwrite(file, buf, 1) != 1)
278  return -1;
279  return c & 0xff;
280 }
281 
282 /* -- see zlib.h -- */
283 int ZEXPORT gzputs(gzFile file, const char *str)
284 {
285  int ret;
286  unsigned len;
287 
288  /* write string */
289  len = (unsigned)strlen(str);
290  ret = gzwrite(file, str, len);
291  return ret == 0 && len != 0 ? -1 : ret;
292 }
293 
294 #if defined(STDC) || defined(Z_HAVE_STDARG_H)
295 #include <stdarg.h>
296 
297 /* -- see zlib.h -- */
298 int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
299 {
300  int size, len;
301  gz_statep state;
302  z_streamp strm;
303 
304  /* get internal structure */
305  if (file == NULL)
306  return -1;
307  state = (gz_statep)file;
308  strm = &(state->strm);
309 
310  /* check that we're writing and that there's no error */
311  if (state->mode != GZ_WRITE || state->err != Z_OK)
312  return 0;
313 
314  /* make sure we have some buffer space */
315  if (state->size == 0 && gz_init(state) == -1)
316  return 0;
317 
318  /* check for seek request */
319  if (state->seek) {
320  state->seek = 0;
321  if (gz_zero(state, state->skip) == -1)
322  return 0;
323  }
324 
325  /* consume whatever's left in the input buffer */
326  if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
327  return 0;
328 
329  /* do the printf() into the input buffer, put length in len */
330  size = (int)(state->size);
331  state->in[size - 1] = 0;
332 #ifdef NO_vsnprintf
333 # ifdef HAS_vsprintf_void
334  (void)vsprintf((char *)(state->in), format, va);
335 
336  for (len = 0; len < size; len++)
337  if (state->in[len] == 0) break;
338 # else
339  len = vsprintf((char *)(state->in), format, va);
340 
341 # endif
342 #else
343 # ifdef HAS_vsnprintf_void
344  (void)vsnprintf((char *)(state->in), size, format, va);
345 
346  len = strlen((char *)(state->in));
347 # else
348  len = vsnprintf((char *)(state->in), size, format, va);
349 
350 # endif
351 #endif
352 
353  /* check that printf() results fit in buffer */
354  if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
355  return 0;
356 
357  /* update buffer and position, defer compression until needed */
358  strm->avail_in = (unsigned)len;
359  strm->next_in = state->in;
360  state->x.pos += len;
361  return len;
362 }
363 
364 int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
365 {
366  va_list va;
367  int ret;
368 
369  va_start(va, format);
370  ret = gzvprintf(file, format, va);
371  va_end(va);
372  return ret;
373 }
374 
375 #else /* !STDC && !Z_HAVE_STDARG_H */
376 
377 /* -- see zlib.h -- */
378 int ZEXPORTVA gzprintf (gzFile file, const char *format,
379  int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10,
380  int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20)
381 {
382  int size, len;
383  gz_statep state;
384  z_streamp strm;
385 
386  /* get internal structure */
387  if (file == NULL)
388  return -1;
389  state = (gz_statep)file;
390  strm = &(state->strm);
391 
392  /* check that can really pass pointer in ints */
393  if (sizeof(int) != sizeof(void *))
394  return 0;
395 
396  /* check that we're writing and that there's no error */
397  if (state->mode != GZ_WRITE || state->err != Z_OK)
398  return 0;
399 
400  /* make sure we have some buffer space */
401  if (state->size == 0 && gz_init(state) == -1)
402  return 0;
403 
404  /* check for seek request */
405  if (state->seek) {
406  state->seek = 0;
407  if (gz_zero(state, state->skip) == -1)
408  return 0;
409  }
410 
411  /* consume whatever's left in the input buffer */
412  if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
413  return 0;
414 
415  /* do the printf() into the input buffer, put length in len */
416  size = (int)(state->size);
417  state->in[size - 1] = 0;
418 #ifdef NO_snprintf
419 # ifdef HAS_sprintf_void
420  sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
421  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
422  for (len = 0; len < size; len++)
423  if (state->in[len] == 0) break;
424 # else
425  len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
426  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
427 # endif
428 #else
429 # ifdef HAS_snprintf_void
430  snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
431  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
432  len = strlen((char *)(state->in));
433 # else
434  len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
435  a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
436  a19, a20);
437 # endif
438 #endif
439 
440  /* check that printf() results fit in buffer */
441  if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
442  return 0;
443 
444  /* update buffer and position, defer compression until needed */
445  strm->avail_in = (unsigned)len;
446  strm->next_in = state->in;
447  state->x.pos += len;
448  return len;
449 }
450 
451 #endif
452 
453 /* -- see zlib.h -- */
454 int ZEXPORT gzflush(gzFile file, int flush)
455 {
456  gz_statep state;
457 
458  /* get internal structure */
459  if (file == NULL)
460  return -1;
461  state = (gz_statep)file;
462 
463  /* check that we're writing and that there's no error */
464  if (state->mode != GZ_WRITE || state->err != Z_OK)
465  return Z_STREAM_ERROR;
466 
467  /* check flush parameter */
468  if (flush < 0 || flush > Z_FINISH)
469  return Z_STREAM_ERROR;
470 
471  /* check for seek request */
472  if (state->seek) {
473  state->seek = 0;
474  if (gz_zero(state, state->skip) == -1)
475  return -1;
476  }
477 
478  /* compress remaining data with requested flush */
479  gz_comp(state, flush);
480  return state->err;
481 }
482 
483 /* -- see zlib.h -- */
484 int ZEXPORT gzsetparams(gzFile file, int level, int strategy)
485 {
486  gz_statep state;
487  z_streamp strm;
488 
489  /* get internal structure */
490  if (file == NULL)
491  return Z_STREAM_ERROR;
492  state = (gz_statep)file;
493  strm = &(state->strm);
494 
495  /* check that we're writing and that there's no error */
496  if (state->mode != GZ_WRITE || state->err != Z_OK)
497  return Z_STREAM_ERROR;
498 
499  /* if no change is requested, then do nothing */
500  if (level == state->level && strategy == state->strategy)
501  return Z_OK;
502 
503  /* check for seek request */
504  if (state->seek) {
505  state->seek = 0;
506  if (gz_zero(state, state->skip) == -1)
507  return -1;
508  }
509 
510  /* change compression parameters for subsequent input */
511  if (state->size) {
512  /* flush previous input with previous parameters before changing */
513  if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
514  return state->err;
515  deflateParams(strm, level, strategy);
516  }
517  state->level = level;
518  state->strategy = strategy;
519  return Z_OK;
520 }
521 
522 /* -- see zlib.h -- */
523 int ZEXPORT gzclose_w(gzFile file)
524 {
525  int ret = Z_OK;
526  gz_statep state;
527 
528  /* get internal structure */
529  if (file == NULL)
530  return Z_STREAM_ERROR;
531  state = (gz_statep)file;
532 
533  /* check that we're writing */
534  if (state->mode != GZ_WRITE)
535  return Z_STREAM_ERROR;
536 
537  /* check for seek request */
538  if (state->seek) {
539  state->seek = 0;
540  if (gz_zero(state, state->skip) == -1)
541  ret = state->err;
542  }
543 
544  /* flush, free memory, and close file */
545  if (gz_comp(state, Z_FINISH) == -1)
546  ret = state->err;
547  if (state->size) {
548  if (!state->direct) {
549  (void)deflateEnd(&(state->strm));
550  free(state->out);
551  }
552  free(state->in);
553  }
554  gz_error(state, Z_OK, NULL);
555  free(state->path);
556  if (close(state->fd) == -1)
557  ret = Z_ERRNO;
558  free(state);
559  return ret;
560 }
int ZEXPORT deflateEnd(z_streamp strm)
Definition: deflate.cc:939
void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg)
Definition: gzlib.cc:545
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:378
int ZEXPORT gzsetparams(gzFile file, int level, int strategy)
Definition: gzwrite.cc:484
#define local
Definition: adler32.cc:10
int ZEXPORT gzputs(gzFile file, const char *str)
Definition: gzwrite.cc:283
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
int ZEXPORT gzputc(gzFile file, int c)
Definition: gzwrite.cc:237
int ZEXPORT gzclose_w(gzFile file)
Definition: gzwrite.cc:523
int ZEXPORT deflate(z_streamp strm, int flush)
Definition: deflate.cc:627
int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len)
Definition: gzwrite.cc:160
local int gz_init(gz_statep state)
Definition: gzwrite.cc:15
int ZEXPORT deflateReset(z_streamp strm)
Definition: deflate.cc:411
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:454