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)