1
/* gzwrite.c -- zlib functions for writing gzip files
2
* Copyright (C) 2004, 2005, 2010, 2011, 2012 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 */
22
state->in = malloc(state->want);
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 = 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");
52
/* mark state as initialized */
53
state->size = state->want;
55
/* initialize write buffer if compressing */
57
strm->avail_out = state->size;
58
strm->next_out = state->out;
59
state->x.next = strm->next_out;
64
/* Compress whatever is at avail_in and next_in and write to the output file.
65
Return -1 if there is an error writing to the output file, otherwise 0.
66
flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
67
then the deflate() state is reset to start a new gzip stream. If gz->direct
68
is true, then simply write to the output file without compressing, and
70
local int gz_comp(state, flush)
76
z_streamp strm = &(state->strm);
78
/* allocate memory if this is the first time through */
79
if (state->size == 0 && gz_init(state) == -1)
82
/* write directly if requested */
84
got = write(state->fd, strm->next_in, strm->avail_in);
85
if (got < 0 || (unsigned)got != strm->avail_in) {
86
gz_error(state, Z_ERRNO, zstrerror());
93
/* run deflate() on provided input until it produces no more output */
96
/* write out current buffer contents if full, or if flushing, but if
97
doing Z_FINISH then don't write until we get to Z_STREAM_END */
98
if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
99
(flush != Z_FINISH || ret == Z_STREAM_END))) {
100
have = (unsigned)(strm->next_out - state->x.next);
101
if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
102
(unsigned)got != have)) {
103
gz_error(state, Z_ERRNO, zstrerror());
106
if (strm->avail_out == 0) {
107
strm->avail_out = state->size;
108
strm->next_out = state->out;
110
state->x.next = strm->next_out;
114
have = strm->avail_out;
115
ret = deflate(strm, flush);
116
if (ret == Z_STREAM_ERROR) {
117
gz_error(state, Z_STREAM_ERROR,
118
"internal error: deflate stream corrupt");
121
have -= strm->avail_out;
124
/* if that completed a deflate stream, allow another to start */
125
if (flush == Z_FINISH)
128
/* all done, no errors */
132
/* Compress len zeros to output. Return -1 on error, 0 on success. */
133
local int gz_zero(state, len)
139
z_streamp strm = &(state->strm);
141
/* consume whatever's left in the input buffer */
142
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
145
/* compress len zeros (len guaranteed > 0) */
148
n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
149
(unsigned)len : state->size;
151
memset(state->in, 0, n);
155
strm->next_in = state->in;
157
if (gz_comp(state, Z_NO_FLUSH) == -1)
164
/* -- see zlib.h -- */
165
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 */
211
if (strm->avail_in == 0)
212
strm->next_in = state->in;
213
n = state->size - strm->avail_in;
216
memcpy(strm->next_in + strm->avail_in, buf, n);
219
buf = (char *)buf + n;
221
if (len && gz_comp(state, Z_NO_FLUSH) == -1)
226
/* consume whatever's left in the input buffer */
227
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
230
/* directly compress user buffer to file */
231
strm->avail_in = len;
232
strm->next_in = (voidp)buf;
234
if (gz_comp(state, Z_NO_FLUSH) == -1)
238
/* input was all buffered or compressed (put will fit in int) */
242
/* -- see zlib.h -- */
243
int ZEXPORT gzputc(file, c)
247
unsigned char buf[1];
251
/* get internal structure */
254
state = (gz_statep)file;
255
strm = &(state->strm);
257
/* check that we're writing and that there's no error */
258
if (state->mode != GZ_WRITE || state->err != Z_OK)
261
/* check for seek request */
264
if (gz_zero(state, state->skip) == -1)
268
/* try writing to input buffer for speed (state->size == 0 if buffer not
270
if (strm->avail_in < state->size) {
271
if (strm->avail_in == 0)
272
strm->next_in = state->in;
273
strm->next_in[strm->avail_in++] = c;
278
/* no room in buffer or not initialized, use gz_write() */
280
if (gzwrite(file, buf, 1) != 1)
285
/* -- see zlib.h -- */
286
int ZEXPORT gzputs(file, str)
294
len = (unsigned)strlen(str);
295
ret = gzwrite(file, str, len);
296
return ret == 0 && len != 0 ? -1 : ret;
299
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
302
/* -- see zlib.h -- */
303
int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
310
/* get internal structure */
313
state = (gz_statep)file;
314
strm = &(state->strm);
316
/* check that we're writing and that there's no error */
317
if (state->mode != GZ_WRITE || state->err != Z_OK)
320
/* make sure we have some buffer space */
321
if (state->size == 0 && gz_init(state) == -1)
324
/* check for seek request */
327
if (gz_zero(state, state->skip) == -1)
331
/* consume whatever's left in the input buffer */
332
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
335
/* do the printf() into the input buffer, put length in len */
336
size = (int)(state->size);
337
state->in[size - 1] = 0;
338
va_start(va, format);
340
# ifdef HAS_vsprintf_void
341
(void)vsprintf(state->in, format, va);
343
for (len = 0; len < size; len++)
344
if (state->in[len] == 0) break;
346
len = vsprintf(state->in, format, va);
350
# ifdef HAS_vsnprintf_void
351
(void)vsnprintf(state->in, size, format, va);
353
len = strlen(state->in);
355
len = vsnprintf((char *)(state->in), size, format, va);
360
/* check that printf() results fit in buffer */
361
if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
364
/* update buffer and position, defer compression until needed */
365
strm->avail_in = (unsigned)len;
366
strm->next_in = state->in;
371
#else /* !STDC && !Z_HAVE_STDARG_H */
373
/* -- see zlib.h -- */
374
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
375
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
378
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
379
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
385
/* get internal structure */
388
state = (gz_statep)file;
389
strm = &(state->strm);
391
/* check that can really pass pointer in ints */
392
if (sizeof(int) != sizeof(void *))
395
/* check that we're writing and that there's no error */
396
if (state->mode != GZ_WRITE || state->err != Z_OK)
399
/* make sure we have some buffer space */
400
if (state->size == 0 && gz_init(state) == -1)
403
/* check for seek request */
406
if (gz_zero(state, state->skip) == -1)
410
/* consume whatever's left in the input buffer */
411
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
414
/* do the printf() into the input buffer, put length in len */
415
size = (int)(state->size);
416
state->in[size - 1] = 0;
418
# ifdef HAS_sprintf_void
419
sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
420
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
421
for (len = 0; len < size; len++)
422
if (state->in[len] == 0) break;
424
len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
425
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
428
# ifdef HAS_snprintf_void
429
snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
430
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
431
len = strlen(state->in);
433
len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
434
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
438
/* check that printf() results fit in buffer */
439
if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
442
/* update buffer and position, defer compression until needed */
443
strm->avail_in = (unsigned)len;
444
strm->next_in = state->in;
451
/* -- see zlib.h -- */
452
int ZEXPORT gzflush(file, flush)
458
/* get internal structure */
461
state = (gz_statep)file;
463
/* check that we're writing and that there's no error */
464
if (state->mode != GZ_WRITE || state->err != Z_OK)
465
return Z_STREAM_ERROR;
467
/* check flush parameter */
468
if (flush < 0 || flush > Z_FINISH)
469
return Z_STREAM_ERROR;
471
/* check for seek request */
474
if (gz_zero(state, state->skip) == -1)
478
/* compress remaining data with requested flush */
479
gz_comp(state, flush);
483
/* -- see zlib.h -- */
484
int ZEXPORT gzsetparams(file, level, strategy)
492
/* get internal structure */
494
return Z_STREAM_ERROR;
495
state = (gz_statep)file;
496
strm = &(state->strm);
498
/* check that we're writing and that there's no error */
499
if (state->mode != GZ_WRITE || state->err != Z_OK)
500
return Z_STREAM_ERROR;
502
/* if no change is requested, then do nothing */
503
if (level == state->level && strategy == state->strategy)
506
/* check for seek request */
509
if (gz_zero(state, state->skip) == -1)
513
/* change compression parameters for subsequent input */
515
/* flush previous input with previous parameters before changing */
516
if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
518
deflateParams(strm, level, strategy);
520
state->level = level;
521
state->strategy = strategy;
525
/* -- see zlib.h -- */
526
int ZEXPORT gzclose_w(file)
532
/* get internal structure */
534
return Z_STREAM_ERROR;
535
state = (gz_statep)file;
537
/* check that we're writing */
538
if (state->mode != GZ_WRITE)
539
return Z_STREAM_ERROR;
541
/* check for seek request */
544
if (gz_zero(state, state->skip) == -1)
548
/* flush, free memory, and close file */
549
if (gz_comp(state, Z_FINISH) == -1)
551
if (!state->direct) {
552
(void)deflateEnd(&(state->strm));
556
gz_error(state, Z_OK, NULL);
558
if (close(state->fd) == -1)
564
/* used by zlibVersion() to get the vsnprintf story from the horse's mouth */
565
unsigned long ZEXPORT gzflags()
567
unsigned long flags = 0;
568
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
571
# ifdef HAS_vsprintf_void
575
# ifdef HAS_vsnprintf_void
583
# ifdef HAS_sprintf_void
587
# ifdef HAS_snprintf_void