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