1 /* gzwrite.c -- zlib functions for writing gzip files
2 * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
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 local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
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
17 local int gz_init(state)
21 z_streamp strm = &(state->strm);
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");
30 /* only need output buffer and deflate state if compressing */
32 /* allocate output buffer */
33 state->out = (unsigned char *)malloc(state->want);
34 if (state->out == NULL) {
36 gz_error(state, Z_MEM_ERROR, "out of memory");
40 /* allocate deflate memory, set up for gzip compression */
41 strm->zalloc = Z_NULL;
43 strm->opaque = Z_NULL;
44 ret = deflateInit2(strm, state->level, Z_DEFLATED,
45 MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
49 gz_error(state, Z_MEM_ERROR, "out of memory");
55 /* mark state as initialized */
56 state->size = state->want;
58 /* initialize write buffer if compressing */
60 strm->avail_out = state->size;
61 strm->next_out = state->out;
62 state->x.next = strm->next_out;
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. */
73 local int gz_comp(state, flush)
78 unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
79 z_streamp strm = &(state->strm);
81 /* allocate memory if this is the first time through */
82 if (state->size == 0 && gz_init(state) == -1)
85 /* write directly if requested */
87 while (strm->avail_in) {
88 put = strm->avail_in > max ? max : strm->avail_in;
89 writ = write(state->fd, strm->next_in, put);
91 gz_error(state, Z_ERRNO, zstrerror());
94 strm->avail_in -= (unsigned)writ;
95 strm->next_in += writ;
100 /* run deflate() on provided input until it produces no more output */
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);
112 gz_error(state, Z_ERRNO, zstrerror());
115 state->x.next += writ;
117 if (strm->avail_out == 0) {
118 strm->avail_out = state->size;
119 strm->next_out = state->out;
120 state->x.next = state->out;
125 have = strm->avail_out;
126 ret = deflate(strm, flush);
127 if (ret == Z_STREAM_ERROR) {
128 gz_error(state, Z_STREAM_ERROR,
129 "internal error: deflate stream corrupt");
132 have -= strm->avail_out;
135 /* if that completed a deflate stream, allow another to start */
136 if (flush == Z_FINISH)
139 /* all done, no errors */
143 /* Compress len zeros to output. Return -1 on a write error or memory
144 allocation failure by gz_comp(), or 0 on success. */
145 local int gz_zero(state, len)
151 z_streamp strm = &(state->strm);
153 /* consume whatever's left in the input buffer */
154 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
157 /* compress len zeros (len guaranteed > 0) */
160 n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
161 (unsigned)len : state->size;
163 memset(state->in, 0, n);
167 strm->next_in = state->in;
169 if (gz_comp(state, Z_NO_FLUSH) == -1)
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. */
178 local z_size_t gz_write(state, buf, len)
185 /* if len is zero, avoid unnecessary operations */
189 /* allocate memory if this is the first time through */
190 if (state->size == 0 && gz_init(state) == -1)
193 /* check for seek request */
196 if (gz_zero(state, state->skip) == -1)
200 /* for small len, copy to input buffer, otherwise compress directly */
201 if (len < state->size) {
202 /* copy to input buffer, compress when full */
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) -
210 copy = state->size - have;
213 memcpy(state->in + have, buf, copy);
214 state->strm.avail_in += copy;
215 state->x.pos += copy;
216 buf = (const char *)buf + copy;
218 if (len && gz_comp(state, Z_NO_FLUSH) == -1)
223 /* consume whatever's left in the input buffer */
224 if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
227 /* directly compress user buffer to file */
228 state->strm.next_in = (z_const Bytef *)buf;
230 unsigned n = (unsigned)-1;
233 state->strm.avail_in = n;
235 if (gz_comp(state, Z_NO_FLUSH) == -1)
241 /* input was all buffered or compressed */
245 /* -- see zlib.h -- */
246 int ZEXPORT gzwrite(file, buf, len)
253 /* get internal structure */
256 state = (gz_statep)file;
258 /* check that we're writing and that there's no error */
259 if (state->mode != GZ_WRITE || state->err != Z_OK)
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) */
265 gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
269 /* write len bytes from buf (the return value will fit in an int) */
270 return (int)gz_write(state, buf, len);
273 /* -- see zlib.h -- */
274 z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
283 /* get internal structure */
286 state = (gz_statep)file;
288 /* check that we're writing and that there's no error */
289 if (state->mode != GZ_WRITE || state->err != Z_OK)
292 /* compute bytes to read -- error on overflow */
294 if (size && len / size != nitems) {
295 gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
299 /* write len bytes to buf, return the number of full items written */
300 return len ? gz_write(state, buf, len) / size : 0;
303 /* -- see zlib.h -- */
304 int ZEXPORT gzputc(file, c)
309 unsigned char buf[1];
313 /* get internal structure */
316 state = (gz_statep)file;
317 strm = &(state->strm);
319 /* check that we're writing and that there's no error */
320 if (state->mode != GZ_WRITE || state->err != Z_OK)
323 /* check for seek request */
326 if (gz_zero(state, state->skip) == -1)
330 /* try writing to input buffer for speed (state->size == 0 if buffer not
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;
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)
351 /* -- see zlib.h -- */
352 int ZEXPORT gzputs(file, str)
360 /* get internal structure */
363 state = (gz_statep)file;
365 /* check that we're writing and that there's no error */
366 if (state->mode != GZ_WRITE || state->err != Z_OK)
371 ret = gz_write(state, str, len);
372 return ret == 0 && len != 0 ? -1 : ret;
375 #if defined(STDC) || defined(Z_HAVE_STDARG_H)
378 /* -- see zlib.h -- */
379 int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
387 /* get internal structure */
389 return Z_STREAM_ERROR;
390 state = (gz_statep)file;
391 strm = &(state->strm);
393 /* check that we're writing and that there's no error */
394 if (state->mode != GZ_WRITE || state->err != Z_OK)
395 return Z_STREAM_ERROR;
397 /* make sure we have some buffer space */
398 if (state->size == 0 && gz_init(state) == -1)
401 /* check for seek request */
404 if (gz_zero(state, state->skip) == -1)
408 /* do the printf() into the input buffer, put length in len -- the input
409 buffer is double-sized just for this function, so there is guaranteed to
410 be state->size bytes available after the current contents */
411 if (strm->avail_in == 0)
412 strm->next_in = state->in;
413 next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
414 next[state->size - 1] = 0;
416 # ifdef HAS_vsprintf_void
417 (void)vsprintf(next, format, va);
418 for (len = 0; len < state->size; len++)
419 if (next[len] == 0) break;
421 len = vsprintf(next, format, va);
424 # ifdef HAS_vsnprintf_void
425 (void)vsnprintf(next, state->size, format, va);
428 len = vsnprintf(next, state->size, format, va);
432 /* check that printf() results fit in buffer */
433 if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
436 /* update buffer and position, compress first half if past that */
437 strm->avail_in += (unsigned)len;
439 if (strm->avail_in >= state->size) {
440 left = strm->avail_in - state->size;
441 strm->avail_in = state->size;
442 if (gz_comp(state, Z_NO_FLUSH) == -1)
444 memcpy(state->in, state->in + state->size, left);
445 strm->next_in = state->in;
446 strm->avail_in = left;
451 int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
456 va_start(va, format);
457 ret = gzvprintf(file, format, va);
462 #else /* !STDC && !Z_HAVE_STDARG_H */
464 /* -- see zlib.h -- */
465 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
466 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
469 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
470 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
477 /* get internal structure */
479 return Z_STREAM_ERROR;
480 state = (gz_statep)file;
481 strm = &(state->strm);
483 /* check that can really pass pointer in ints */
484 if (sizeof(int) != sizeof(void *))
485 return Z_STREAM_ERROR;
487 /* check that we're writing and that there's no error */
488 if (state->mode != GZ_WRITE || state->err != Z_OK)
489 return Z_STREAM_ERROR;
491 /* make sure we have some buffer space */
492 if (state->size == 0 && gz_init(state) == -1)
495 /* check for seek request */
498 if (gz_zero(state, state->skip) == -1)
502 /* do the printf() into the input buffer, put length in len -- the input
503 buffer is double-sized just for this function, so there is guaranteed to
504 be state->size bytes available after the current contents */
505 if (strm->avail_in == 0)
506 strm->next_in = state->in;
507 next = (char *)(strm->next_in + strm->avail_in);
508 next[state->size - 1] = 0;
510 # ifdef HAS_sprintf_void
511 sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
512 a13, a14, a15, a16, a17, a18, a19, a20);
513 for (len = 0; len < size; len++)
517 len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
518 a12, a13, a14, a15, a16, a17, a18, a19, a20);
521 # ifdef HAS_snprintf_void
522 snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
523 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
526 len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
527 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
531 /* check that printf() results fit in buffer */
532 if (len == 0 || len >= state->size || next[state->size - 1] != 0)
535 /* update buffer and position, compress first half if past that */
536 strm->avail_in += len;
538 if (strm->avail_in >= state->size) {
539 left = strm->avail_in - state->size;
540 strm->avail_in = state->size;
541 if (gz_comp(state, Z_NO_FLUSH) == -1)
543 memcpy(state->in, state->in + state->size, left);
544 strm->next_in = state->in;
545 strm->avail_in = left;
552 /* -- see zlib.h -- */
553 int ZEXPORT gzflush(file, flush)
559 /* get internal structure */
561 return Z_STREAM_ERROR;
562 state = (gz_statep)file;
564 /* check that we're writing and that there's no error */
565 if (state->mode != GZ_WRITE || state->err != Z_OK)
566 return Z_STREAM_ERROR;
568 /* check flush parameter */
569 if (flush < 0 || flush > Z_FINISH)
570 return Z_STREAM_ERROR;
572 /* check for seek request */
575 if (gz_zero(state, state->skip) == -1)
579 /* compress remaining data with requested flush */
580 (void)gz_comp(state, flush);
584 /* -- see zlib.h -- */
585 int ZEXPORT gzsetparams(file, level, strategy)
593 /* get internal structure */
595 return Z_STREAM_ERROR;
596 state = (gz_statep)file;
597 strm = &(state->strm);
599 /* check that we're writing and that there's no error */
600 if (state->mode != GZ_WRITE || state->err != Z_OK)
601 return Z_STREAM_ERROR;
603 /* if no change is requested, then do nothing */
604 if (level == state->level && strategy == state->strategy)
607 /* check for seek request */
610 if (gz_zero(state, state->skip) == -1)
614 /* change compression parameters for subsequent input */
616 /* flush previous input with previous parameters before changing */
617 if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
619 deflateParams(strm, level, strategy);
621 state->level = level;
622 state->strategy = strategy;
626 /* -- see zlib.h -- */
627 int ZEXPORT gzclose_w(file)
633 /* get internal structure */
635 return Z_STREAM_ERROR;
636 state = (gz_statep)file;
638 /* check that we're writing */
639 if (state->mode != GZ_WRITE)
640 return Z_STREAM_ERROR;
642 /* check for seek request */
645 if (gz_zero(state, state->skip) == -1)
649 /* flush, free memory, and close file */
650 if (gz_comp(state, Z_FINISH) == -1)
653 if (!state->direct) {
654 (void)deflateEnd(&(state->strm));
659 gz_error(state, Z_OK, NULL);
661 if (close(state->fd) == -1)