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((char *)(state->in), format, va);
343
for (len = 0; len < size; len++)
344
if (state->in[len] == 0) break;
346
len = vsprintf((char *)(state->in), format, va);
350
# ifdef HAS_vsnprintf_void
351
(void)vsnprintf((char *)(state->in), size, format, va);
353
len = strlen((char *)(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((char *)(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((char *)(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((char *)(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((char *)(state->in));
433
len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
434
a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
439
/* check that printf() results fit in buffer */
440
if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
443
/* update buffer and position, defer compression until needed */
444
strm->avail_in = (unsigned)len;
445
strm->next_in = state->in;
452
/* -- see zlib.h -- */
453
int ZEXPORT gzflush(file, flush)
459
/* get internal structure */
462
state = (gz_statep)file;
464
/* check that we're writing and that there's no error */
465
if (state->mode != GZ_WRITE || state->err != Z_OK)
466
return Z_STREAM_ERROR;
468
/* check flush parameter */
469
if (flush < 0 || flush > Z_FINISH)
470
return Z_STREAM_ERROR;
472
/* check for seek request */
475
if (gz_zero(state, state->skip) == -1)
479
/* compress remaining data with requested flush */
480
gz_comp(state, flush);
484
/* -- see zlib.h -- */
485
int ZEXPORT gzsetparams(file, level, strategy)
493
/* get internal structure */
495
return Z_STREAM_ERROR;
496
state = (gz_statep)file;
497
strm = &(state->strm);
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;
503
/* if no change is requested, then do nothing */
504
if (level == state->level && strategy == state->strategy)
507
/* check for seek request */
510
if (gz_zero(state, state->skip) == -1)
514
/* change compression parameters for subsequent input */
516
/* flush previous input with previous parameters before changing */
517
if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
519
deflateParams(strm, level, strategy);
521
state->level = level;
522
state->strategy = strategy;
526
/* -- see zlib.h -- */
527
int ZEXPORT gzclose_w(file)
533
/* get internal structure */
535
return Z_STREAM_ERROR;
536
state = (gz_statep)file;
538
/* check that we're writing */
539
if (state->mode != GZ_WRITE)
540
return Z_STREAM_ERROR;
542
/* check for seek request */
545
if (gz_zero(state, state->skip) == -1)
549
/* flush, free memory, and close file */
551
if (gz_comp(state, Z_FINISH) == -1)
553
if (!state->direct) {
554
(void)deflateEnd(&(state->strm));
559
gz_error(state, Z_OK, NULL);
561
if (close(state->fd) == -1)