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
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));
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(state)
19 z_streamp strm = &(state->strm);
21 /* allocate input buffer (double size for gzprintf) */
22 state->in = (unsigned char *)malloc(state->want << 1);
23 if (state->in == NULL) {
24 gz_error(state, Z_MEM_ERROR, "out of memory");
28 /* only need output buffer and deflate state if compressing */
30 /* allocate output buffer */
31 state->out = (unsigned char *)malloc(state->want);
32 if (state->out == NULL) {
34 gz_error(state, Z_MEM_ERROR, "out of memory");
38 /* allocate deflate memory, set up for gzip compression */
39 strm->zalloc = Z_NULL;
41 strm->opaque = Z_NULL;
42 ret = deflateInit2(strm, state->level, Z_DEFLATED,
43 MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
47 gz_error(state, Z_MEM_ERROR, "out of memory");
53 /* mark state as initialized */
54 state->size = state->want;
56 /* initialize write buffer if compressing */
58 strm->avail_out = state->size;
59 strm->next_out = state->out;
60 state->x.next = strm->next_out;
65 /* Compress whatever is at avail_in and next_in and write to the output file.
66 Return -1 if there is an error writing to the output file, otherwise 0.
67 flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
68 then the deflate() state is reset to start a new gzip stream. If gz->direct
69 is true, then simply write to the output file without compressing, and
71 local int gz_comp(state, flush)
77 z_streamp strm = &(state->strm);
79 /* allocate memory if this is the first time through */
80 if (state->size == 0 && gz_init(state) == -1)
83 /* write directly if requested */
85 got = write(state->fd, strm->next_in, strm->avail_in);
86 if (got < 0 || (unsigned)got != strm->avail_in) {
87 gz_error(state, Z_ERRNO, zstrerror());
94 /* run deflate() on provided input until it produces no more output */
97 /* write out current buffer contents if full, or if flushing, but if
98 doing Z_FINISH then don't write until we get to Z_STREAM_END */
99 if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
100 (flush != Z_FINISH || ret == Z_STREAM_END))) {
101 have = (unsigned)(strm->next_out - state->x.next);
102 if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
103 (unsigned)got != have)) {
104 gz_error(state, Z_ERRNO, zstrerror());
107 if (strm->avail_out == 0) {
108 strm->avail_out = state->size;
109 strm->next_out = state->out;
111 state->x.next = strm->next_out;
115 have = strm->avail_out;
116 ret = deflate(strm, flush);
117 if (ret == Z_STREAM_ERROR) {
118 gz_error(state, Z_STREAM_ERROR,
119 "internal error: deflate stream corrupt");
122 have -= strm->avail_out;
125 /* if that completed a deflate stream, allow another to start */
126 if (flush == Z_FINISH)
129 /* all done, no errors */
133 /* Compress len zeros to output. Return -1 on error, 0 on success. */
134 local int gz_zero(state, len)
140 z_streamp strm = &(state->strm);
142 /* consume whatever's left in the input buffer */
143 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
146 /* compress len zeros (len guaranteed > 0) */
149 n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
150 (unsigned)len : state->size;
152 memset(state->in, 0, n);
156 strm->next_in = state->in;
158 if (gz_comp(state, Z_NO_FLUSH) == -1)
165 /* -- see zlib.h -- */
166 int ZEXPORT gzwrite(file, buf, len)
175 /* get internal structure */
178 state = (gz_statep)file;
179 strm = &(state->strm);
181 /* check that we're writing and that there's no error */
182 if (state->mode != GZ_WRITE || state->err != Z_OK)
185 /* since an int is returned, make sure len fits in one, otherwise return
186 with an error (this avoids the flaw in the interface) */
188 gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
192 /* if len is zero, avoid unnecessary operations */
196 /* allocate memory if this is the first time through */
197 if (state->size == 0 && gz_init(state) == -1)
200 /* check for seek request */
203 if (gz_zero(state, state->skip) == -1)
207 /* for small len, copy to input buffer, otherwise compress directly */
208 if (len < state->size) {
209 /* copy to input buffer, compress when full */
213 if (strm->avail_in == 0)
214 strm->next_in = state->in;
215 have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
216 copy = state->size - have;
219 memcpy(state->in + have, buf, copy);
220 strm->avail_in += copy;
221 state->x.pos += copy;
222 buf = (const char *)buf + copy;
224 if (len && gz_comp(state, Z_NO_FLUSH) == -1)
229 /* consume whatever's left in the input buffer */
230 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
233 /* directly compress user buffer to file */
234 strm->avail_in = len;
235 strm->next_in = (z_const Bytef *)buf;
237 if (gz_comp(state, Z_NO_FLUSH) == -1)
241 /* input was all buffered or compressed (put will fit in int) */
245 /* -- see zlib.h -- */
246 int ZEXPORT gzputc(file, c)
251 unsigned char buf[1];
255 /* get internal structure */
258 state = (gz_statep)file;
259 strm = &(state->strm);
261 /* check that we're writing and that there's no error */
262 if (state->mode != GZ_WRITE || state->err != Z_OK)
265 /* check for seek request */
268 if (gz_zero(state, state->skip) == -1)
272 /* try writing to input buffer for speed (state->size == 0 if buffer not
275 if (strm->avail_in == 0)
276 strm->next_in = state->in;
277 have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
278 if (have < state->size) {
286 /* no room in buffer or not initialized, use gz_write() */
288 if (gzwrite(file, buf, 1) != 1)
293 /* -- see zlib.h -- */
294 int ZEXPORT gzputs(file, str)
302 len = (unsigned)strlen(str);
303 ret = gzwrite(file, str, len);
304 return ret == 0 && len != 0 ? -1 : ret;
307 #if defined(STDC) || defined(Z_HAVE_STDARG_H)
310 /* -- see zlib.h -- */
311 int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
318 /* get internal structure */
321 state = (gz_statep)file;
322 strm = &(state->strm);
324 /* check that we're writing and that there's no error */
325 if (state->mode != GZ_WRITE || state->err != Z_OK)
328 /* make sure we have some buffer space */
329 if (state->size == 0 && gz_init(state) == -1)
332 /* check for seek request */
335 if (gz_zero(state, state->skip) == -1)
339 /* do the printf() into the input buffer, put length in len -- the input
340 buffer is double-sized just for this function, so there is guaranteed to
341 be state->size bytes available after the current contents */
342 if (strm->avail_in == 0)
343 strm->next_in = state->in;
344 next = (char *)(strm->next_in + strm->avail_in);
345 next[state->size - 1] = 0;
347 # ifdef HAS_vsprintf_void
348 (void)vsprintf(next, format, va);
349 for (len = 0; len < state->size; len++)
350 if (next[len] == 0) break;
352 len = vsprintf(next, format, va);
355 # ifdef HAS_vsnprintf_void
356 (void)vsnprintf(next, state->size, format, va);
359 len = vsnprintf(next, state->size, format, va);
363 /* check that printf() results fit in buffer */
364 if (len == 0 || len >= state->size || next[state->size - 1] != 0)
367 /* update buffer and position, compress first half if past that */
368 strm->avail_in += len;
370 if (strm->avail_in >= state->size) {
371 left = strm->avail_in - state->size;
372 strm->avail_in = state->size;
373 if (gz_comp(state, Z_NO_FLUSH) == -1)
375 memcpy(state->in, state->in + state->size, left);
376 strm->next_in = state->in;
377 strm->avail_in = left;
382 int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
387 va_start(va, format);
388 ret = gzvprintf(file, format, va);
393 #else /* !STDC && !Z_HAVE_STDARG_H */
395 /* -- see zlib.h -- */
396 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
397 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
400 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
401 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
408 /* get internal structure */
411 state = (gz_statep)file;
412 strm = &(state->strm);
414 /* check that can really pass pointer in ints */
415 if (sizeof(int) != sizeof(void *))
418 /* check that we're writing and that there's no error */
419 if (state->mode != GZ_WRITE || state->err != Z_OK)
422 /* make sure we have some buffer space */
423 if (state->size == 0 && gz_init(state) == -1)
426 /* check for seek request */
429 if (gz_zero(state, state->skip) == -1)
433 /* do the printf() into the input buffer, put length in len -- the input
434 buffer is double-sized just for this function, so there is guaranteed to
435 be state->size bytes available after the current contents */
436 if (strm->avail_in == 0)
437 strm->next_in = state->in;
438 next = (char *)(strm->next_in + strm->avail_in);
439 next[state->size - 1] = 0;
441 # ifdef HAS_sprintf_void
442 sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
443 a13, a14, a15, a16, a17, a18, a19, a20);
444 for (len = 0; len < size; len++)
448 len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
449 a12, a13, a14, a15, a16, a17, a18, a19, a20);
452 # ifdef HAS_snprintf_void
453 snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
454 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
457 len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
458 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
462 /* check that printf() results fit in buffer */
463 if (len == 0 || len >= state->size || next[state->size - 1] != 0)
466 /* update buffer and position, compress first half if past that */
467 strm->avail_in += len;
469 if (strm->avail_in >= state->size) {
470 left = strm->avail_in - state->size;
471 strm->avail_in = state->size;
472 if (gz_comp(state, Z_NO_FLUSH) == -1)
474 memcpy(state->in, state->in + state->size, left);
475 strm->next_in = state->in;
476 strm->avail_in = left;
483 /* -- see zlib.h -- */
484 int ZEXPORT gzflush(file, flush)
490 /* get internal structure */
493 state = (gz_statep)file;
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;
499 /* check flush parameter */
500 if (flush < 0 || flush > Z_FINISH)
501 return Z_STREAM_ERROR;
503 /* check for seek request */
506 if (gz_zero(state, state->skip) == -1)
510 /* compress remaining data with requested flush */
511 gz_comp(state, flush);
515 /* -- see zlib.h -- */
516 int ZEXPORT gzsetparams(file, level, strategy)
524 /* get internal structure */
526 return Z_STREAM_ERROR;
527 state = (gz_statep)file;
528 strm = &(state->strm);
530 /* check that we're writing and that there's no error */
531 if (state->mode != GZ_WRITE || state->err != Z_OK)
532 return Z_STREAM_ERROR;
534 /* if no change is requested, then do nothing */
535 if (level == state->level && strategy == state->strategy)
538 /* check for seek request */
541 if (gz_zero(state, state->skip) == -1)
545 /* change compression parameters for subsequent input */
547 /* flush previous input with previous parameters before changing */
548 if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
550 deflateParams(strm, level, strategy);
552 state->level = level;
553 state->strategy = strategy;
557 /* -- see zlib.h -- */
558 int ZEXPORT gzclose_w(file)
564 /* get internal structure */
566 return Z_STREAM_ERROR;
567 state = (gz_statep)file;
569 /* check that we're writing */
570 if (state->mode != GZ_WRITE)
571 return Z_STREAM_ERROR;
573 /* check for seek request */
576 if (gz_zero(state, state->skip) == -1)
580 /* flush, free memory, and close file */
581 if (gz_comp(state, Z_FINISH) == -1)
584 if (!state->direct) {
585 (void)deflateEnd(&(state->strm));
590 gz_error(state, Z_OK, NULL);
592 if (close(state->fd) == -1)