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