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
12 local int gz_init OF((gz_statep));
13 local int gz_comp OF((gz_statep, int));
14 local int gz_zero OF((gz_statep, z_off64_t));
16 /* Initialize state for writing a gzip file. Mark initialization by setting
17 state->size to non-zero. Return -1 on failure or 0 on success. */
18 local int gz_init(state)
22 z_streamp strm = &(state->strm);
24 /* allocate input buffer */
25 state->in = (unsigned char *)malloc(state->want);
26 if (state->in == NULL) {
27 gz_error(state, Z_MEM_ERROR, "out of memory");
31 /* only need output buffer and deflate state if compressing */
33 /* allocate output buffer */
34 state->out = (unsigned char *)malloc(state->want);
35 if (state->out == NULL) {
37 gz_error(state, Z_MEM_ERROR, "out of memory");
41 /* allocate deflate memory, set up for gzip compression */
42 strm->zalloc = Z_NULL;
44 strm->opaque = Z_NULL;
45 ret = deflateInit2(strm, state->level, Z_DEFLATED,
46 MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
50 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, otherwise 0.
69 flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
70 then the deflate() state is reset to start a new gzip stream. If gz->direct
71 is true, then simply write to the output file without compressing, and
73 local int gz_comp(state, flush)
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 got = write(state->fd, strm->next_in, strm->avail_in);
88 if (got < 0 || (unsigned)got != strm->avail_in) {
89 gz_error(state, Z_ERRNO, zstrerror());
96 /* run deflate() on provided input until it produces no more output */
99 /* write out current buffer contents if full, or if flushing, but if
100 doing Z_FINISH then don't write until we get to Z_STREAM_END */
101 if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
102 (flush != Z_FINISH || ret == Z_STREAM_END))) {
103 have = (unsigned)(strm->next_out - state->x.next);
104 if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
105 (unsigned)got != have)) {
106 gz_error(state, Z_ERRNO, zstrerror());
109 if (strm->avail_out == 0) {
110 strm->avail_out = state->size;
111 strm->next_out = state->out;
113 state->x.next = strm->next_out;
117 have = strm->avail_out;
118 ret = deflate(strm, flush);
119 if (ret == Z_STREAM_ERROR) {
120 gz_error(state, Z_STREAM_ERROR,
121 "internal error: deflate stream corrupt");
124 have -= strm->avail_out;
127 /* if that completed a deflate stream, allow another to start */
128 if (flush == Z_FINISH)
131 /* all done, no errors */
135 /* Compress len zeros to output. Return -1 on error, 0 on success. */
136 local int gz_zero(state, len)
142 z_streamp strm = &(state->strm);
144 /* consume whatever's left in the input buffer */
145 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
148 /* compress len zeros (len guaranteed > 0) */
151 n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
152 (unsigned)len : state->size;
154 memset(state->in, 0, n);
158 strm->next_in = state->in;
160 if (gz_comp(state, Z_NO_FLUSH) == -1)
167 /* -- see zlib.h -- */
168 int ZEXPORT gzwrite(file, buf, len)
177 /* get internal structure */
180 state = (gz_statep)file;
181 strm = &(state->strm);
183 /* check that we're writing and that there's no error */
184 if (state->mode != GZ_WRITE || state->err != Z_OK)
187 /* since an int is returned, make sure len fits in one, otherwise return
188 with an error (this avoids the flaw in the interface) */
190 gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
194 /* if len is zero, avoid unnecessary operations */
198 /* allocate memory if this is the first time through */
199 if (state->size == 0 && gz_init(state) == -1)
202 /* check for seek request */
205 if (gz_zero(state, state->skip) == -1)
209 /* for small len, copy to input buffer, otherwise compress directly */
210 if (len < state->size) {
211 /* copy to input buffer, compress when full */
215 if (strm->avail_in == 0)
216 strm->next_in = state->in;
217 have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
218 copy = state->size - have;
221 memcpy(state->in + have, buf, copy);
222 strm->avail_in += copy;
223 state->x.pos += copy;
224 buf = (const char *)buf + copy;
226 if (len && gz_comp(state, Z_NO_FLUSH) == -1)
231 /* consume whatever's left in the input buffer */
232 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
235 /* directly compress user buffer to file */
236 strm->avail_in = len;
237 strm->next_in = (z_const Bytef *)buf;
239 if (gz_comp(state, Z_NO_FLUSH) == -1)
243 /* input was all buffered or compressed (put will fit in int) */
247 /* -- see zlib.h -- */
248 int ZEXPORT gzputc(file, c)
253 unsigned char buf[1];
257 /* get internal structure */
260 state = (gz_statep)file;
261 strm = &(state->strm);
263 /* check that we're writing and that there's no error */
264 if (state->mode != GZ_WRITE || state->err != Z_OK)
267 /* check for seek request */
270 if (gz_zero(state, state->skip) == -1)
274 /* try writing to input buffer for speed (state->size == 0 if buffer not
277 if (strm->avail_in == 0)
278 strm->next_in = state->in;
279 have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
280 if (have < state->size) {
288 /* no room in buffer or not initialized, use gz_write() */
290 if (gzwrite(file, buf, 1) != 1)
295 /* -- see zlib.h -- */
296 int ZEXPORT gzputs(file, str)
304 len = (unsigned)strlen(str);
305 ret = gzwrite(file, str, len);
306 return ret == 0 && len != 0 ? -1 : ret;
309 #if defined(STDC) || defined(Z_HAVE_STDARG_H)
312 /* -- see zlib.h -- */
313 int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
319 /* get internal structure */
322 state = (gz_statep)file;
323 strm = &(state->strm);
325 /* check that we're writing and that there's no error */
326 if (state->mode != GZ_WRITE || state->err != Z_OK)
329 /* make sure we have some buffer space */
330 if (state->size == 0 && gz_init(state) == -1)
333 /* check for seek request */
336 if (gz_zero(state, state->skip) == -1)
340 /* consume whatever's left in the input buffer */
341 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
344 /* do the printf() into the input buffer, put length in len */
345 size = (int)(state->size);
346 state->in[size - 1] = 0;
348 # ifdef HAS_vsprintf_void
349 (void)vsprintf((char *)(state->in), format, va);
350 for (len = 0; len < size; len++)
351 if (state->in[len] == 0) break;
353 len = vsprintf((char *)(state->in), format, va);
356 # ifdef HAS_vsnprintf_void
357 (void)vsnprintf((char *)(state->in), size, format, va);
358 len = strlen((char *)(state->in));
360 len = vsnprintf((char *)(state->in), size, format, va);
364 /* check that printf() results fit in buffer */
365 if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
368 /* update buffer and position, defer compression until needed */
369 strm->avail_in = (unsigned)len;
370 strm->next_in = state->in;
375 int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
380 va_start(va, format);
381 ret = gzvprintf(file, format, va);
386 #else /* !STDC && !Z_HAVE_STDARG_H */
388 /* -- see zlib.h -- */
389 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
390 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
393 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
394 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
400 /* get internal structure */
403 state = (gz_statep)file;
404 strm = &(state->strm);
406 /* check that can really pass pointer in ints */
407 if (sizeof(int) != sizeof(void *))
410 /* check that we're writing and that there's no error */
411 if (state->mode != GZ_WRITE || state->err != Z_OK)
414 /* make sure we have some buffer space */
415 if (state->size == 0 && gz_init(state) == -1)
418 /* check for seek request */
421 if (gz_zero(state, state->skip) == -1)
425 /* consume whatever's left in the input buffer */
426 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
429 /* do the printf() into the input buffer, put length in len */
430 size = (int)(state->size);
431 state->in[size - 1] = 0;
433 # ifdef HAS_sprintf_void
434 sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
435 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
436 for (len = 0; len < size; len++)
437 if (state->in[len] == 0) break;
439 len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
440 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
443 # ifdef HAS_snprintf_void
444 snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
445 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
446 len = strlen((char *)(state->in));
448 len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
449 a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
454 /* check that printf() results fit in buffer */
455 if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
458 /* update buffer and position, defer compression until needed */
459 strm->avail_in = (unsigned)len;
460 strm->next_in = state->in;
467 /* -- see zlib.h -- */
468 int ZEXPORT gzflush(file, flush)
474 /* get internal structure */
477 state = (gz_statep)file;
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;
483 /* check flush parameter */
484 if (flush < 0 || flush > Z_FINISH)
485 return Z_STREAM_ERROR;
487 /* check for seek request */
490 if (gz_zero(state, state->skip) == -1)
494 /* compress remaining data with requested flush */
495 gz_comp(state, flush);
499 /* -- see zlib.h -- */
500 int ZEXPORT gzsetparams(file, level, strategy)
508 /* get internal structure */
510 return Z_STREAM_ERROR;
511 state = (gz_statep)file;
512 strm = &(state->strm);
514 /* check that we're writing and that there's no error */
515 if (state->mode != GZ_WRITE || state->err != Z_OK)
516 return Z_STREAM_ERROR;
518 /* if no change is requested, then do nothing */
519 if (level == state->level && strategy == state->strategy)
522 /* check for seek request */
525 if (gz_zero(state, state->skip) == -1)
529 /* change compression parameters for subsequent input */
531 /* flush previous input with previous parameters before changing */
532 if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
534 deflateParams(strm, level, strategy);
536 state->level = level;
537 state->strategy = strategy;
541 /* -- see zlib.h -- */
542 int ZEXPORT gzclose_w(file)
548 /* get internal structure */
550 return Z_STREAM_ERROR;
551 state = (gz_statep)file;
553 /* check that we're writing */
554 if (state->mode != GZ_WRITE)
555 return Z_STREAM_ERROR;
557 /* check for seek request */
560 if (gz_zero(state, state->skip) == -1)
564 /* flush, free memory, and close file */
565 if (gz_comp(state, Z_FINISH) == -1)
568 if (!state->direct) {
569 (void)deflateEnd(&(state->strm));
574 gz_error(state, Z_OK, NULL);
576 if (close(state->fd) == -1)