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)