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 */
22 state
->in
= (unsigned char *)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
= (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");
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
)
174 /* get internal structure */
177 state
= (gz_statep
)file
;
178 strm
= &(state
->strm
);
180 /* check that we're writing and that there's no error */
181 if (state
->mode
!= GZ_WRITE
|| state
->err
!= Z_OK
)
184 /* since an int is returned, make sure len fits in one, otherwise return
185 with an error (this avoids the flaw in the interface) */
187 gz_error(state
, Z_DATA_ERROR
, "requested length does not fit in int");
191 /* if len is zero, avoid unnecessary operations */
195 /* allocate memory if this is the first time through */
196 if (state
->size
== 0 && gz_init(state
) == -1)
199 /* check for seek request */
202 if (gz_zero(state
, state
->skip
) == -1)
206 /* for small len, copy to input buffer, otherwise compress directly */
207 if (len
< state
->size
) {
208 /* copy to input buffer, compress when full */
212 if (strm
->avail_in
== 0)
213 strm
->next_in
= state
->in
;
214 have
= (unsigned)((strm
->next_in
+ strm
->avail_in
) - state
->in
);
215 copy
= state
->size
- have
;
218 memcpy(state
->in
+ have
, buf
, copy
);
219 strm
->avail_in
+= copy
;
220 state
->x
.pos
+= copy
;
221 buf
= (const char *)buf
+ copy
;
223 if (len
&& gz_comp(state
, Z_NO_FLUSH
) == -1)
228 /* consume whatever's left in the input buffer */
229 if (strm
->avail_in
&& gz_comp(state
, Z_NO_FLUSH
) == -1)
232 /* directly compress user buffer to file */
233 strm
->avail_in
= len
;
234 strm
->next_in
= (z_const Bytef
*)buf
;
236 if (gz_comp(state
, Z_NO_FLUSH
) == -1)
240 /* input was all buffered or compressed (put will fit in int) */
244 /* -- see zlib.h -- */
245 int ZEXPORT
gzputc(file
, c
)
250 unsigned char buf
[1];
254 /* get internal structure */
257 state
= (gz_statep
)file
;
258 strm
= &(state
->strm
);
260 /* check that we're writing and that there's no error */
261 if (state
->mode
!= GZ_WRITE
|| state
->err
!= Z_OK
)
264 /* check for seek request */
267 if (gz_zero(state
, state
->skip
) == -1)
271 /* try writing to input buffer for speed (state->size == 0 if buffer not
274 if (strm
->avail_in
== 0)
275 strm
->next_in
= state
->in
;
276 have
= (unsigned)((strm
->next_in
+ strm
->avail_in
) - state
->in
);
277 if (have
< state
->size
) {
285 /* no room in buffer or not initialized, use gz_write() */
287 if (gzwrite(file
, buf
, 1) != 1)
292 /* -- see zlib.h -- */
293 int ZEXPORT
gzputs(file
, str
)
301 len
= (unsigned)strlen(str
);
302 ret
= gzwrite(file
, str
, len
);
303 return ret
== 0 && len
!= 0 ? -1 : ret
;
306 #if defined(STDC) || defined(Z_HAVE_STDARG_H)
309 /* -- see zlib.h -- */
310 int ZEXPORTVA
gzvprintf(gzFile file
, const char *format
, va_list va
)
316 /* get internal structure */
319 state
= (gz_statep
)file
;
320 strm
= &(state
->strm
);
322 /* check that we're writing and that there's no error */
323 if (state
->mode
!= GZ_WRITE
|| state
->err
!= Z_OK
)
326 /* make sure we have some buffer space */
327 if (state
->size
== 0 && gz_init(state
) == -1)
330 /* check for seek request */
333 if (gz_zero(state
, state
->skip
) == -1)
337 /* consume whatever's left in the input buffer */
338 if (strm
->avail_in
&& gz_comp(state
, Z_NO_FLUSH
) == -1)
341 /* do the printf() into the input buffer, put length in len */
342 size
= (int)(state
->size
);
343 state
->in
[size
- 1] = 0;
345 # ifdef HAS_vsprintf_void
346 (void)vsprintf((char *)(state
->in
), format
, va
);
347 for (len
= 0; len
< size
; len
++)
348 if (state
->in
[len
] == 0) break;
350 len
= vsprintf((char *)(state
->in
), format
, va
);
353 # ifdef HAS_vsnprintf_void
354 (void)vsnprintf((char *)(state
->in
), size
, format
, va
);
355 len
= strlen((char *)(state
->in
));
357 len
= vsnprintf((char *)(state
->in
), size
, format
, va
);
361 /* check that printf() results fit in buffer */
362 if (len
<= 0 || len
>= (int)size
|| state
->in
[size
- 1] != 0)
365 /* update buffer and position, defer compression until needed */
366 strm
->avail_in
= (unsigned)len
;
367 strm
->next_in
= state
->in
;
372 int ZEXPORTVA
gzprintf(gzFile file
, const char *format
, ...)
377 va_start(va
, format
);
378 ret
= gzvprintf(file
, format
, va
);
383 #else /* !STDC && !Z_HAVE_STDARG_H */
385 /* -- see zlib.h -- */
386 int ZEXPORTVA
gzprintf (file
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
, a10
,
387 a11
, a12
, a13
, a14
, a15
, a16
, a17
, a18
, a19
, a20
)
390 int a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
, a10
,
391 a11
, a12
, a13
, a14
, a15
, a16
, a17
, a18
, a19
, a20
;
397 /* get internal structure */
400 state
= (gz_statep
)file
;
401 strm
= &(state
->strm
);
403 /* check that can really pass pointer in ints */
404 if (sizeof(int) != sizeof(void *))
407 /* check that we're writing and that there's no error */
408 if (state
->mode
!= GZ_WRITE
|| state
->err
!= Z_OK
)
411 /* make sure we have some buffer space */
412 if (state
->size
== 0 && gz_init(state
) == -1)
415 /* check for seek request */
418 if (gz_zero(state
, state
->skip
) == -1)
422 /* consume whatever's left in the input buffer */
423 if (strm
->avail_in
&& gz_comp(state
, Z_NO_FLUSH
) == -1)
426 /* do the printf() into the input buffer, put length in len */
427 size
= (int)(state
->size
);
428 state
->in
[size
- 1] = 0;
430 # ifdef HAS_sprintf_void
431 sprintf((char *)(state
->in
), format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
,
432 a9
, a10
, a11
, a12
, a13
, a14
, a15
, a16
, a17
, a18
, a19
, a20
);
433 for (len
= 0; len
< size
; len
++)
434 if (state
->in
[len
] == 0) break;
436 len
= sprintf((char *)(state
->in
), format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
,
437 a9
, a10
, a11
, a12
, a13
, a14
, a15
, a16
, a17
, a18
, a19
, a20
);
440 # ifdef HAS_snprintf_void
441 snprintf((char *)(state
->in
), size
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
,
442 a9
, a10
, a11
, a12
, a13
, a14
, a15
, a16
, a17
, a18
, a19
, a20
);
443 len
= strlen((char *)(state
->in
));
445 len
= snprintf((char *)(state
->in
), size
, format
, a1
, a2
, a3
, a4
, a5
, a6
,
446 a7
, a8
, a9
, a10
, a11
, a12
, a13
, a14
, a15
, a16
, a17
, a18
,
451 /* check that printf() results fit in buffer */
452 if (len
<= 0 || len
>= (int)size
|| state
->in
[size
- 1] != 0)
455 /* update buffer and position, defer compression until needed */
456 strm
->avail_in
= (unsigned)len
;
457 strm
->next_in
= state
->in
;
464 /* -- see zlib.h -- */
465 int ZEXPORT
gzflush(file
, flush
)
471 /* get internal structure */
474 state
= (gz_statep
)file
;
476 /* check that we're writing and that there's no error */
477 if (state
->mode
!= GZ_WRITE
|| state
->err
!= Z_OK
)
478 return Z_STREAM_ERROR
;
480 /* check flush parameter */
481 if (flush
< 0 || flush
> Z_FINISH
)
482 return Z_STREAM_ERROR
;
484 /* check for seek request */
487 if (gz_zero(state
, state
->skip
) == -1)
491 /* compress remaining data with requested flush */
492 gz_comp(state
, flush
);
496 /* -- see zlib.h -- */
497 int ZEXPORT
gzsetparams(file
, level
, strategy
)
505 /* get internal structure */
507 return Z_STREAM_ERROR
;
508 state
= (gz_statep
)file
;
509 strm
= &(state
->strm
);
511 /* check that we're writing and that there's no error */
512 if (state
->mode
!= GZ_WRITE
|| state
->err
!= Z_OK
)
513 return Z_STREAM_ERROR
;
515 /* if no change is requested, then do nothing */
516 if (level
== state
->level
&& strategy
== state
->strategy
)
519 /* check for seek request */
522 if (gz_zero(state
, state
->skip
) == -1)
526 /* change compression parameters for subsequent input */
528 /* flush previous input with previous parameters before changing */
529 if (strm
->avail_in
&& gz_comp(state
, Z_PARTIAL_FLUSH
) == -1)
531 deflateParams(strm
, level
, strategy
);
533 state
->level
= level
;
534 state
->strategy
= strategy
;
538 /* -- see zlib.h -- */
539 int ZEXPORT
gzclose_w(file
)
545 /* get internal structure */
547 return Z_STREAM_ERROR
;
548 state
= (gz_statep
)file
;
550 /* check that we're writing */
551 if (state
->mode
!= GZ_WRITE
)
552 return Z_STREAM_ERROR
;
554 /* check for seek request */
557 if (gz_zero(state
, state
->skip
) == -1)
561 /* flush, free memory, and close file */
562 if (gz_comp(state
, Z_FINISH
) == -1)
565 if (!state
->direct
) {
566 (void)deflateEnd(&(state
->strm
));
571 gz_error(state
, Z_OK
, NULL
);
573 if (close(state
->fd
) == -1)