xref: /dflybsd-src/contrib/zlib-1.2/gzwrite.c (revision c6c68a82af3a48187337cc9b7e0c859413b34a27)
1fe927c51SPeter Avalos /* gzwrite.c -- zlib functions for writing gzip files
2*e041647aSSascha Wildner  * Copyright (C) 2004-2017 Mark Adler
3fe927c51SPeter Avalos  * For conditions of distribution and use, see copyright notice in zlib.h
4fe927c51SPeter Avalos  */
5fe927c51SPeter Avalos 
6fe927c51SPeter Avalos #include "gzguts.h"
7fe927c51SPeter Avalos 
8fe927c51SPeter Avalos /* Local functions */
9fe927c51SPeter Avalos local int gz_init OF((gz_statep));
10fe927c51SPeter Avalos local int gz_comp OF((gz_statep, int));
11fe927c51SPeter Avalos local int gz_zero OF((gz_statep, z_off64_t));
12*e041647aSSascha Wildner local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
13fe927c51SPeter Avalos 
14fe927c51SPeter Avalos /* Initialize state for writing a gzip file.  Mark initialization by setting
15*e041647aSSascha Wildner    state->size to non-zero.  Return -1 on a memory allocation failure, or 0 on
16*e041647aSSascha Wildner    success. */
gz_init(state)17fe927c51SPeter Avalos local int gz_init(state)
18fe927c51SPeter Avalos     gz_statep state;
19fe927c51SPeter Avalos {
20fe927c51SPeter Avalos     int ret;
21fe927c51SPeter Avalos     z_streamp strm = &(state->strm);
22fe927c51SPeter Avalos 
23*e041647aSSascha Wildner     /* allocate input buffer (double size for gzprintf) */
24*e041647aSSascha Wildner     state->in = (unsigned char *)malloc(state->want << 1);
25712f98b7SJohn Marino     if (state->in == NULL) {
26712f98b7SJohn Marino         gz_error(state, Z_MEM_ERROR, "out of memory");
27712f98b7SJohn Marino         return -1;
28712f98b7SJohn Marino     }
29712f98b7SJohn Marino 
30712f98b7SJohn Marino     /* only need output buffer and deflate state if compressing */
31712f98b7SJohn Marino     if (!state->direct) {
32712f98b7SJohn Marino         /* allocate output buffer */
3353ddf67cSJohn Marino         state->out = (unsigned char *)malloc(state->want);
34712f98b7SJohn Marino         if (state->out == NULL) {
35fe927c51SPeter Avalos             free(state->in);
36fe927c51SPeter Avalos             gz_error(state, Z_MEM_ERROR, "out of memory");
37fe927c51SPeter Avalos             return -1;
38fe927c51SPeter Avalos         }
39fe927c51SPeter Avalos 
40fe927c51SPeter Avalos         /* allocate deflate memory, set up for gzip compression */
41fe927c51SPeter Avalos         strm->zalloc = Z_NULL;
42fe927c51SPeter Avalos         strm->zfree = Z_NULL;
43fe927c51SPeter Avalos         strm->opaque = Z_NULL;
44fe927c51SPeter Avalos         ret = deflateInit2(strm, state->level, Z_DEFLATED,
45712f98b7SJohn Marino                            MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
46fe927c51SPeter Avalos         if (ret != Z_OK) {
47712f98b7SJohn Marino             free(state->out);
48fe927c51SPeter Avalos             free(state->in);
49fe927c51SPeter Avalos             gz_error(state, Z_MEM_ERROR, "out of memory");
50fe927c51SPeter Avalos             return -1;
51fe927c51SPeter Avalos         }
52*e041647aSSascha Wildner         strm->next_in = NULL;
53712f98b7SJohn Marino     }
54fe927c51SPeter Avalos 
55fe927c51SPeter Avalos     /* mark state as initialized */
56fe927c51SPeter Avalos     state->size = state->want;
57fe927c51SPeter Avalos 
58712f98b7SJohn Marino     /* initialize write buffer if compressing */
59712f98b7SJohn Marino     if (!state->direct) {
60fe927c51SPeter Avalos         strm->avail_out = state->size;
61fe927c51SPeter Avalos         strm->next_out = state->out;
62712f98b7SJohn Marino         state->x.next = strm->next_out;
63712f98b7SJohn Marino     }
64fe927c51SPeter Avalos     return 0;
65fe927c51SPeter Avalos }
66fe927c51SPeter Avalos 
67fe927c51SPeter Avalos /* Compress whatever is at avail_in and next_in and write to the output file.
68*e041647aSSascha Wildner    Return -1 if there is an error writing to the output file or if gz_init()
69*e041647aSSascha Wildner    fails to allocate memory, otherwise 0.  flush is assumed to be a valid
70*e041647aSSascha Wildner    deflate() flush value.  If flush is Z_FINISH, then the deflate() state is
71*e041647aSSascha Wildner    reset to start a new gzip stream.  If gz->direct is true, then simply write
72*e041647aSSascha Wildner    to the output file without compressing, and ignore flush. */
gz_comp(state,flush)73fe927c51SPeter Avalos local int gz_comp(state, flush)
74fe927c51SPeter Avalos     gz_statep state;
75fe927c51SPeter Avalos     int flush;
76fe927c51SPeter Avalos {
77*e041647aSSascha Wildner     int ret, writ;
78*e041647aSSascha Wildner     unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
79fe927c51SPeter Avalos     z_streamp strm = &(state->strm);
80fe927c51SPeter Avalos 
81fe927c51SPeter Avalos     /* allocate memory if this is the first time through */
82fe927c51SPeter Avalos     if (state->size == 0 && gz_init(state) == -1)
83fe927c51SPeter Avalos         return -1;
84fe927c51SPeter Avalos 
85712f98b7SJohn Marino     /* write directly if requested */
86712f98b7SJohn Marino     if (state->direct) {
87*e041647aSSascha Wildner         while (strm->avail_in) {
88*e041647aSSascha Wildner             put = strm->avail_in > max ? max : strm->avail_in;
89*e041647aSSascha Wildner             writ = write(state->fd, strm->next_in, put);
90*e041647aSSascha Wildner             if (writ < 0) {
91712f98b7SJohn Marino                 gz_error(state, Z_ERRNO, zstrerror());
92712f98b7SJohn Marino                 return -1;
93712f98b7SJohn Marino             }
94*e041647aSSascha Wildner             strm->avail_in -= (unsigned)writ;
95*e041647aSSascha Wildner             strm->next_in += writ;
96*e041647aSSascha Wildner         }
97712f98b7SJohn Marino         return 0;
98712f98b7SJohn Marino     }
99712f98b7SJohn Marino 
100fe927c51SPeter Avalos     /* run deflate() on provided input until it produces no more output */
101fe927c51SPeter Avalos     ret = Z_OK;
102fe927c51SPeter Avalos     do {
103fe927c51SPeter Avalos         /* write out current buffer contents if full, or if flushing, but if
104fe927c51SPeter Avalos            doing Z_FINISH then don't write until we get to Z_STREAM_END */
105fe927c51SPeter Avalos         if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
106fe927c51SPeter Avalos             (flush != Z_FINISH || ret == Z_STREAM_END))) {
107*e041647aSSascha Wildner             while (strm->next_out > state->x.next) {
108*e041647aSSascha Wildner                 put = strm->next_out - state->x.next > (int)max ? max :
109*e041647aSSascha Wildner                       (unsigned)(strm->next_out - state->x.next);
110*e041647aSSascha Wildner                 writ = write(state->fd, state->x.next, put);
111*e041647aSSascha Wildner                 if (writ < 0) {
112fe927c51SPeter Avalos                     gz_error(state, Z_ERRNO, zstrerror());
113fe927c51SPeter Avalos                     return -1;
114fe927c51SPeter Avalos                 }
115*e041647aSSascha Wildner                 state->x.next += writ;
116*e041647aSSascha Wildner             }
117fe927c51SPeter Avalos             if (strm->avail_out == 0) {
118fe927c51SPeter Avalos                 strm->avail_out = state->size;
119fe927c51SPeter Avalos                 strm->next_out = state->out;
120*e041647aSSascha Wildner                 state->x.next = state->out;
121fe927c51SPeter Avalos             }
122fe927c51SPeter Avalos         }
123fe927c51SPeter Avalos 
124fe927c51SPeter Avalos         /* compress */
125fe927c51SPeter Avalos         have = strm->avail_out;
126fe927c51SPeter Avalos         ret = deflate(strm, flush);
127fe927c51SPeter Avalos         if (ret == Z_STREAM_ERROR) {
128fe927c51SPeter Avalos             gz_error(state, Z_STREAM_ERROR,
129fe927c51SPeter Avalos                       "internal error: deflate stream corrupt");
130fe927c51SPeter Avalos             return -1;
131fe927c51SPeter Avalos         }
132fe927c51SPeter Avalos         have -= strm->avail_out;
133fe927c51SPeter Avalos     } while (have);
134fe927c51SPeter Avalos 
135fe927c51SPeter Avalos     /* if that completed a deflate stream, allow another to start */
136fe927c51SPeter Avalos     if (flush == Z_FINISH)
137fe927c51SPeter Avalos         deflateReset(strm);
138fe927c51SPeter Avalos 
139fe927c51SPeter Avalos     /* all done, no errors */
140fe927c51SPeter Avalos     return 0;
141fe927c51SPeter Avalos }
142fe927c51SPeter Avalos 
143*e041647aSSascha Wildner /* Compress len zeros to output.  Return -1 on a write error or memory
144*e041647aSSascha Wildner    allocation failure by gz_comp(), or 0 on success. */
gz_zero(state,len)145fe927c51SPeter Avalos local int gz_zero(state, len)
146fe927c51SPeter Avalos     gz_statep state;
147fe927c51SPeter Avalos     z_off64_t len;
148fe927c51SPeter Avalos {
149fe927c51SPeter Avalos     int first;
150fe927c51SPeter Avalos     unsigned n;
151fe927c51SPeter Avalos     z_streamp strm = &(state->strm);
152fe927c51SPeter Avalos 
153fe927c51SPeter Avalos     /* consume whatever's left in the input buffer */
154fe927c51SPeter Avalos     if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
155fe927c51SPeter Avalos         return -1;
156fe927c51SPeter Avalos 
157fe927c51SPeter Avalos     /* compress len zeros (len guaranteed > 0) */
158fe927c51SPeter Avalos     first = 1;
159fe927c51SPeter Avalos     while (len) {
160fe927c51SPeter Avalos         n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
161fe927c51SPeter Avalos             (unsigned)len : state->size;
162fe927c51SPeter Avalos         if (first) {
163fe927c51SPeter Avalos             memset(state->in, 0, n);
164fe927c51SPeter Avalos             first = 0;
165fe927c51SPeter Avalos         }
166fe927c51SPeter Avalos         strm->avail_in = n;
167fe927c51SPeter Avalos         strm->next_in = state->in;
168712f98b7SJohn Marino         state->x.pos += n;
169fe927c51SPeter Avalos         if (gz_comp(state, Z_NO_FLUSH) == -1)
170fe927c51SPeter Avalos             return -1;
171fe927c51SPeter Avalos         len -= n;
172fe927c51SPeter Avalos     }
173fe927c51SPeter Avalos     return 0;
174fe927c51SPeter Avalos }
175fe927c51SPeter Avalos 
176*e041647aSSascha Wildner /* Write len bytes from buf to file.  Return the number of bytes written.  If
177*e041647aSSascha Wildner    the returned value is less than len, then there was an error. */
gz_write(state,buf,len)178*e041647aSSascha Wildner local z_size_t gz_write(state, buf, len)
179fe927c51SPeter Avalos     gz_statep state;
180*e041647aSSascha Wildner     voidpc buf;
181*e041647aSSascha Wildner     z_size_t len;
182*e041647aSSascha Wildner {
183*e041647aSSascha Wildner     z_size_t put = len;
184fe927c51SPeter Avalos 
185fe927c51SPeter Avalos     /* if len is zero, avoid unnecessary operations */
186fe927c51SPeter Avalos     if (len == 0)
187fe927c51SPeter Avalos         return 0;
188fe927c51SPeter Avalos 
189fe927c51SPeter Avalos     /* allocate memory if this is the first time through */
190fe927c51SPeter Avalos     if (state->size == 0 && gz_init(state) == -1)
191fe927c51SPeter Avalos         return 0;
192fe927c51SPeter Avalos 
193fe927c51SPeter Avalos     /* check for seek request */
194fe927c51SPeter Avalos     if (state->seek) {
195fe927c51SPeter Avalos         state->seek = 0;
196fe927c51SPeter Avalos         if (gz_zero(state, state->skip) == -1)
197fe927c51SPeter Avalos             return 0;
198fe927c51SPeter Avalos     }
199fe927c51SPeter Avalos 
200fe927c51SPeter Avalos     /* for small len, copy to input buffer, otherwise compress directly */
201fe927c51SPeter Avalos     if (len < state->size) {
202fe927c51SPeter Avalos         /* copy to input buffer, compress when full */
203fe927c51SPeter Avalos         do {
20453ddf67cSJohn Marino             unsigned have, copy;
20553ddf67cSJohn Marino 
206*e041647aSSascha Wildner             if (state->strm.avail_in == 0)
207*e041647aSSascha Wildner                 state->strm.next_in = state->in;
208*e041647aSSascha Wildner             have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
209*e041647aSSascha Wildner                               state->in);
21053ddf67cSJohn Marino             copy = state->size - have;
21153ddf67cSJohn Marino             if (copy > len)
21253ddf67cSJohn Marino                 copy = len;
21353ddf67cSJohn Marino             memcpy(state->in + have, buf, copy);
214*e041647aSSascha Wildner             state->strm.avail_in += copy;
21553ddf67cSJohn Marino             state->x.pos += copy;
21653ddf67cSJohn Marino             buf = (const char *)buf + copy;
21753ddf67cSJohn Marino             len -= copy;
218fe927c51SPeter Avalos             if (len && gz_comp(state, Z_NO_FLUSH) == -1)
219fe927c51SPeter Avalos                 return 0;
220fe927c51SPeter Avalos         } while (len);
221fe927c51SPeter Avalos     }
222fe927c51SPeter Avalos     else {
223fe927c51SPeter Avalos         /* consume whatever's left in the input buffer */
224*e041647aSSascha Wildner         if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
225fe927c51SPeter Avalos             return 0;
226fe927c51SPeter Avalos 
227fe927c51SPeter Avalos         /* directly compress user buffer to file */
228*e041647aSSascha Wildner         state->strm.next_in = (z_const Bytef *)buf;
229*e041647aSSascha Wildner         do {
230*e041647aSSascha Wildner             unsigned n = (unsigned)-1;
231*e041647aSSascha Wildner             if (n > len)
232*e041647aSSascha Wildner                 n = len;
233*e041647aSSascha Wildner             state->strm.avail_in = n;
234*e041647aSSascha Wildner             state->x.pos += n;
235fe927c51SPeter Avalos             if (gz_comp(state, Z_NO_FLUSH) == -1)
236fe927c51SPeter Avalos                 return 0;
237*e041647aSSascha Wildner             len -= n;
238*e041647aSSascha Wildner         } while (len);
239*e041647aSSascha Wildner     }
240*e041647aSSascha Wildner 
241*e041647aSSascha Wildner     /* input was all buffered or compressed */
242*e041647aSSascha Wildner     return put;
243*e041647aSSascha Wildner }
244*e041647aSSascha Wildner 
245*e041647aSSascha Wildner /* -- see zlib.h -- */
gzwrite(file,buf,len)246*e041647aSSascha Wildner int ZEXPORT gzwrite(file, buf, len)
247*e041647aSSascha Wildner     gzFile file;
248*e041647aSSascha Wildner     voidpc buf;
249*e041647aSSascha Wildner     unsigned len;
250*e041647aSSascha Wildner {
251*e041647aSSascha Wildner     gz_statep state;
252*e041647aSSascha Wildner 
253*e041647aSSascha Wildner     /* get internal structure */
254*e041647aSSascha Wildner     if (file == NULL)
255*e041647aSSascha Wildner         return 0;
256*e041647aSSascha Wildner     state = (gz_statep)file;
257*e041647aSSascha Wildner 
258*e041647aSSascha Wildner     /* check that we're writing and that there's no error */
259*e041647aSSascha Wildner     if (state->mode != GZ_WRITE || state->err != Z_OK)
260*e041647aSSascha Wildner         return 0;
261*e041647aSSascha Wildner 
262*e041647aSSascha Wildner     /* since an int is returned, make sure len fits in one, otherwise return
263*e041647aSSascha Wildner        with an error (this avoids a flaw in the interface) */
264*e041647aSSascha Wildner     if ((int)len < 0) {
265*e041647aSSascha Wildner         gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
266*e041647aSSascha Wildner         return 0;
267fe927c51SPeter Avalos     }
268fe927c51SPeter Avalos 
269*e041647aSSascha Wildner     /* write len bytes from buf (the return value will fit in an int) */
270*e041647aSSascha Wildner     return (int)gz_write(state, buf, len);
271*e041647aSSascha Wildner }
272*e041647aSSascha Wildner 
273*e041647aSSascha Wildner /* -- see zlib.h -- */
gzfwrite(buf,size,nitems,file)274*e041647aSSascha Wildner z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
275*e041647aSSascha Wildner     voidpc buf;
276*e041647aSSascha Wildner     z_size_t size;
277*e041647aSSascha Wildner     z_size_t nitems;
278*e041647aSSascha Wildner     gzFile file;
279*e041647aSSascha Wildner {
280*e041647aSSascha Wildner     z_size_t len;
281*e041647aSSascha Wildner     gz_statep state;
282*e041647aSSascha Wildner 
283*e041647aSSascha Wildner     /* get internal structure */
284*e041647aSSascha Wildner     if (file == NULL)
285*e041647aSSascha Wildner         return 0;
286*e041647aSSascha Wildner     state = (gz_statep)file;
287*e041647aSSascha Wildner 
288*e041647aSSascha Wildner     /* check that we're writing and that there's no error */
289*e041647aSSascha Wildner     if (state->mode != GZ_WRITE || state->err != Z_OK)
290*e041647aSSascha Wildner         return 0;
291*e041647aSSascha Wildner 
292*e041647aSSascha Wildner     /* compute bytes to read -- error on overflow */
293*e041647aSSascha Wildner     len = nitems * size;
294*e041647aSSascha Wildner     if (size && len / size != nitems) {
295*e041647aSSascha Wildner         gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
296*e041647aSSascha Wildner         return 0;
297*e041647aSSascha Wildner     }
298*e041647aSSascha Wildner 
299*e041647aSSascha Wildner     /* write len bytes to buf, return the number of full items written */
300*e041647aSSascha Wildner     return len ? gz_write(state, buf, len) / size : 0;
301fe927c51SPeter Avalos }
302fe927c51SPeter Avalos 
303fe927c51SPeter Avalos /* -- see zlib.h -- */
gzputc(file,c)304fe927c51SPeter Avalos int ZEXPORT gzputc(file, c)
305fe927c51SPeter Avalos     gzFile file;
306fe927c51SPeter Avalos     int c;
307fe927c51SPeter Avalos {
30853ddf67cSJohn Marino     unsigned have;
309fe927c51SPeter Avalos     unsigned char buf[1];
310fe927c51SPeter Avalos     gz_statep state;
311fe927c51SPeter Avalos     z_streamp strm;
312fe927c51SPeter Avalos 
313fe927c51SPeter Avalos     /* get internal structure */
314fe927c51SPeter Avalos     if (file == NULL)
315fe927c51SPeter Avalos         return -1;
316fe927c51SPeter Avalos     state = (gz_statep)file;
317fe927c51SPeter Avalos     strm = &(state->strm);
318fe927c51SPeter Avalos 
319fe927c51SPeter Avalos     /* check that we're writing and that there's no error */
320fe927c51SPeter Avalos     if (state->mode != GZ_WRITE || state->err != Z_OK)
321fe927c51SPeter Avalos         return -1;
322fe927c51SPeter Avalos 
323fe927c51SPeter Avalos     /* check for seek request */
324fe927c51SPeter Avalos     if (state->seek) {
325fe927c51SPeter Avalos         state->seek = 0;
326fe927c51SPeter Avalos         if (gz_zero(state, state->skip) == -1)
327fe927c51SPeter Avalos             return -1;
328fe927c51SPeter Avalos     }
329fe927c51SPeter Avalos 
330fe927c51SPeter Avalos     /* try writing to input buffer for speed (state->size == 0 if buffer not
331fe927c51SPeter Avalos        initialized) */
33253ddf67cSJohn Marino     if (state->size) {
333fe927c51SPeter Avalos         if (strm->avail_in == 0)
334fe927c51SPeter Avalos             strm->next_in = state->in;
33553ddf67cSJohn Marino         have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
33653ddf67cSJohn Marino         if (have < state->size) {
337*e041647aSSascha Wildner             state->in[have] = (unsigned char)c;
33853ddf67cSJohn Marino             strm->avail_in++;
339712f98b7SJohn Marino             state->x.pos++;
340712f98b7SJohn Marino             return c & 0xff;
341fe927c51SPeter Avalos         }
34253ddf67cSJohn Marino     }
343fe927c51SPeter Avalos 
344fe927c51SPeter Avalos     /* no room in buffer or not initialized, use gz_write() */
345*e041647aSSascha Wildner     buf[0] = (unsigned char)c;
346*e041647aSSascha Wildner     if (gz_write(state, buf, 1) != 1)
347fe927c51SPeter Avalos         return -1;
348712f98b7SJohn Marino     return c & 0xff;
349fe927c51SPeter Avalos }
350fe927c51SPeter Avalos 
351fe927c51SPeter Avalos /* -- see zlib.h -- */
gzputs(file,str)352fe927c51SPeter Avalos int ZEXPORT gzputs(file, str)
353fe927c51SPeter Avalos     gzFile file;
354fe927c51SPeter Avalos     const char *str;
355fe927c51SPeter Avalos {
356fe927c51SPeter Avalos     int ret;
357*e041647aSSascha Wildner     z_size_t len;
358*e041647aSSascha Wildner     gz_statep state;
359*e041647aSSascha Wildner 
360*e041647aSSascha Wildner     /* get internal structure */
361*e041647aSSascha Wildner     if (file == NULL)
362*e041647aSSascha Wildner         return -1;
363*e041647aSSascha Wildner     state = (gz_statep)file;
364*e041647aSSascha Wildner 
365*e041647aSSascha Wildner     /* check that we're writing and that there's no error */
366*e041647aSSascha Wildner     if (state->mode != GZ_WRITE || state->err != Z_OK)
367*e041647aSSascha Wildner         return -1;
368fe927c51SPeter Avalos 
369fe927c51SPeter Avalos     /* write string */
370*e041647aSSascha Wildner     len = strlen(str);
371*e041647aSSascha Wildner     ret = gz_write(state, str, len);
372fe927c51SPeter Avalos     return ret == 0 && len != 0 ? -1 : ret;
373fe927c51SPeter Avalos }
374fe927c51SPeter Avalos 
375712f98b7SJohn Marino #if defined(STDC) || defined(Z_HAVE_STDARG_H)
376fe927c51SPeter Avalos #include <stdarg.h>
377fe927c51SPeter Avalos 
378fe927c51SPeter Avalos /* -- see zlib.h -- */
gzvprintf(gzFile file,const char * format,va_list va)37953ddf67cSJohn Marino int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
380fe927c51SPeter Avalos {
381*e041647aSSascha Wildner     int len;
382*e041647aSSascha Wildner     unsigned left;
383*e041647aSSascha Wildner     char *next;
384fe927c51SPeter Avalos     gz_statep state;
385fe927c51SPeter Avalos     z_streamp strm;
386fe927c51SPeter Avalos 
387fe927c51SPeter Avalos     /* get internal structure */
388fe927c51SPeter Avalos     if (file == NULL)
389*e041647aSSascha Wildner         return Z_STREAM_ERROR;
390fe927c51SPeter Avalos     state = (gz_statep)file;
391fe927c51SPeter Avalos     strm = &(state->strm);
392fe927c51SPeter Avalos 
393fe927c51SPeter Avalos     /* check that we're writing and that there's no error */
394fe927c51SPeter Avalos     if (state->mode != GZ_WRITE || state->err != Z_OK)
395*e041647aSSascha Wildner         return Z_STREAM_ERROR;
396fe927c51SPeter Avalos 
397fe927c51SPeter Avalos     /* make sure we have some buffer space */
398fe927c51SPeter Avalos     if (state->size == 0 && gz_init(state) == -1)
399*e041647aSSascha Wildner         return state->err;
400fe927c51SPeter Avalos 
401fe927c51SPeter Avalos     /* check for seek request */
402fe927c51SPeter Avalos     if (state->seek) {
403fe927c51SPeter Avalos         state->seek = 0;
404fe927c51SPeter Avalos         if (gz_zero(state, state->skip) == -1)
405*e041647aSSascha Wildner             return state->err;
406fe927c51SPeter Avalos     }
407fe927c51SPeter Avalos 
408*e041647aSSascha Wildner     /* do the printf() into the input buffer, put length in len -- the input
409*e041647aSSascha Wildner        buffer is double-sized just for this function, so there is guaranteed to
410*e041647aSSascha Wildner        be state->size bytes available after the current contents */
411*e041647aSSascha Wildner     if (strm->avail_in == 0)
412*e041647aSSascha Wildner         strm->next_in = state->in;
413*e041647aSSascha Wildner     next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
414*e041647aSSascha Wildner     next[state->size - 1] = 0;
415fe927c51SPeter Avalos #ifdef NO_vsnprintf
416fe927c51SPeter Avalos #  ifdef HAS_vsprintf_void
417*e041647aSSascha Wildner     (void)vsprintf(next, format, va);
418*e041647aSSascha Wildner     for (len = 0; len < state->size; len++)
419*e041647aSSascha Wildner         if (next[len] == 0) break;
420fe927c51SPeter Avalos #  else
421*e041647aSSascha Wildner     len = vsprintf(next, format, va);
422fe927c51SPeter Avalos #  endif
423fe927c51SPeter Avalos #else
424fe927c51SPeter Avalos #  ifdef HAS_vsnprintf_void
425*e041647aSSascha Wildner     (void)vsnprintf(next, state->size, format, va);
426*e041647aSSascha Wildner     len = strlen(next);
427fe927c51SPeter Avalos #  else
428*e041647aSSascha Wildner     len = vsnprintf(next, state->size, format, va);
429fe927c51SPeter Avalos #  endif
430fe927c51SPeter Avalos #endif
431fe927c51SPeter Avalos 
432fe927c51SPeter Avalos     /* check that printf() results fit in buffer */
433*e041647aSSascha Wildner     if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
434fe927c51SPeter Avalos         return 0;
435fe927c51SPeter Avalos 
436*e041647aSSascha Wildner     /* update buffer and position, compress first half if past that */
437*e041647aSSascha Wildner     strm->avail_in += (unsigned)len;
438712f98b7SJohn Marino     state->x.pos += len;
439*e041647aSSascha Wildner     if (strm->avail_in >= state->size) {
440*e041647aSSascha Wildner         left = strm->avail_in - state->size;
441*e041647aSSascha Wildner         strm->avail_in = state->size;
442*e041647aSSascha Wildner         if (gz_comp(state, Z_NO_FLUSH) == -1)
443*e041647aSSascha Wildner             return state->err;
444*e041647aSSascha Wildner         memcpy(state->in, state->in + state->size, left);
445*e041647aSSascha Wildner         strm->next_in = state->in;
446*e041647aSSascha Wildner         strm->avail_in = left;
447*e041647aSSascha Wildner     }
448fe927c51SPeter Avalos     return len;
449fe927c51SPeter Avalos }
450fe927c51SPeter Avalos 
gzprintf(gzFile file,const char * format,...)45153ddf67cSJohn Marino int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
45253ddf67cSJohn Marino {
45353ddf67cSJohn Marino     va_list va;
45453ddf67cSJohn Marino     int ret;
45553ddf67cSJohn Marino 
45653ddf67cSJohn Marino     va_start(va, format);
45753ddf67cSJohn Marino     ret = gzvprintf(file, format, va);
45853ddf67cSJohn Marino     va_end(va);
45953ddf67cSJohn Marino     return ret;
46053ddf67cSJohn Marino }
46153ddf67cSJohn Marino 
462712f98b7SJohn Marino #else /* !STDC && !Z_HAVE_STDARG_H */
463fe927c51SPeter Avalos 
464fe927c51SPeter Avalos /* -- see zlib.h -- */
gzprintf(file,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)465fe927c51SPeter Avalos int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
466fe927c51SPeter Avalos                        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
467fe927c51SPeter Avalos     gzFile file;
468fe927c51SPeter Avalos     const char *format;
469fe927c51SPeter Avalos     int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
470fe927c51SPeter Avalos         a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
471fe927c51SPeter Avalos {
472*e041647aSSascha Wildner     unsigned len, left;
473*e041647aSSascha Wildner     char *next;
474fe927c51SPeter Avalos     gz_statep state;
475fe927c51SPeter Avalos     z_streamp strm;
476fe927c51SPeter Avalos 
477fe927c51SPeter Avalos     /* get internal structure */
478fe927c51SPeter Avalos     if (file == NULL)
479*e041647aSSascha Wildner         return Z_STREAM_ERROR;
480fe927c51SPeter Avalos     state = (gz_statep)file;
481fe927c51SPeter Avalos     strm = &(state->strm);
482fe927c51SPeter Avalos 
483712f98b7SJohn Marino     /* check that can really pass pointer in ints */
484712f98b7SJohn Marino     if (sizeof(int) != sizeof(void *))
485*e041647aSSascha Wildner         return Z_STREAM_ERROR;
486712f98b7SJohn Marino 
487fe927c51SPeter Avalos     /* check that we're writing and that there's no error */
488fe927c51SPeter Avalos     if (state->mode != GZ_WRITE || state->err != Z_OK)
489*e041647aSSascha Wildner         return Z_STREAM_ERROR;
490fe927c51SPeter Avalos 
491fe927c51SPeter Avalos     /* make sure we have some buffer space */
492fe927c51SPeter Avalos     if (state->size == 0 && gz_init(state) == -1)
493*e041647aSSascha Wildner         return state->error;
494fe927c51SPeter Avalos 
495fe927c51SPeter Avalos     /* check for seek request */
496fe927c51SPeter Avalos     if (state->seek) {
497fe927c51SPeter Avalos         state->seek = 0;
498fe927c51SPeter Avalos         if (gz_zero(state, state->skip) == -1)
499*e041647aSSascha Wildner             return state->error;
500fe927c51SPeter Avalos     }
501fe927c51SPeter Avalos 
502*e041647aSSascha Wildner     /* do the printf() into the input buffer, put length in len -- the input
503*e041647aSSascha Wildner        buffer is double-sized just for this function, so there is guaranteed to
504*e041647aSSascha Wildner        be state->size bytes available after the current contents */
505*e041647aSSascha Wildner     if (strm->avail_in == 0)
506*e041647aSSascha Wildner         strm->next_in = state->in;
507*e041647aSSascha Wildner     next = (char *)(strm->next_in + strm->avail_in);
508*e041647aSSascha Wildner     next[state->size - 1] = 0;
509fe927c51SPeter Avalos #ifdef NO_snprintf
510fe927c51SPeter Avalos #  ifdef HAS_sprintf_void
511*e041647aSSascha Wildner     sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
512*e041647aSSascha Wildner             a13, a14, a15, a16, a17, a18, a19, a20);
513fe927c51SPeter Avalos     for (len = 0; len < size; len++)
514*e041647aSSascha Wildner         if (next[len] == 0)
515*e041647aSSascha Wildner             break;
516fe927c51SPeter Avalos #  else
517*e041647aSSascha Wildner     len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
518*e041647aSSascha Wildner                   a12, a13, a14, a15, a16, a17, a18, a19, a20);
519fe927c51SPeter Avalos #  endif
520fe927c51SPeter Avalos #else
521fe927c51SPeter Avalos #  ifdef HAS_snprintf_void
522*e041647aSSascha Wildner     snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
523*e041647aSSascha Wildner              a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
524*e041647aSSascha Wildner     len = strlen(next);
525fe927c51SPeter Avalos #  else
526*e041647aSSascha Wildner     len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
527*e041647aSSascha Wildner                    a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
528fe927c51SPeter Avalos #  endif
529fe927c51SPeter Avalos #endif
530fe927c51SPeter Avalos 
531fe927c51SPeter Avalos     /* check that printf() results fit in buffer */
532*e041647aSSascha Wildner     if (len == 0 || len >= state->size || next[state->size - 1] != 0)
533fe927c51SPeter Avalos         return 0;
534fe927c51SPeter Avalos 
535*e041647aSSascha Wildner     /* update buffer and position, compress first half if past that */
536*e041647aSSascha Wildner     strm->avail_in += len;
537712f98b7SJohn Marino     state->x.pos += len;
538*e041647aSSascha Wildner     if (strm->avail_in >= state->size) {
539*e041647aSSascha Wildner         left = strm->avail_in - state->size;
540*e041647aSSascha Wildner         strm->avail_in = state->size;
541*e041647aSSascha Wildner         if (gz_comp(state, Z_NO_FLUSH) == -1)
542*e041647aSSascha Wildner             return state->err;
543*e041647aSSascha Wildner         memcpy(state->in, state->in + state->size, left);
544*e041647aSSascha Wildner         strm->next_in = state->in;
545*e041647aSSascha Wildner         strm->avail_in = left;
546*e041647aSSascha Wildner     }
547*e041647aSSascha Wildner     return (int)len;
548fe927c51SPeter Avalos }
549fe927c51SPeter Avalos 
550fe927c51SPeter Avalos #endif
551fe927c51SPeter Avalos 
552fe927c51SPeter Avalos /* -- see zlib.h -- */
gzflush(file,flush)553fe927c51SPeter Avalos int ZEXPORT gzflush(file, flush)
554fe927c51SPeter Avalos     gzFile file;
555fe927c51SPeter Avalos     int flush;
556fe927c51SPeter Avalos {
557fe927c51SPeter Avalos     gz_statep state;
558fe927c51SPeter Avalos 
559fe927c51SPeter Avalos     /* get internal structure */
560fe927c51SPeter Avalos     if (file == NULL)
561*e041647aSSascha Wildner         return Z_STREAM_ERROR;
562fe927c51SPeter Avalos     state = (gz_statep)file;
563fe927c51SPeter Avalos 
564fe927c51SPeter Avalos     /* check that we're writing and that there's no error */
565fe927c51SPeter Avalos     if (state->mode != GZ_WRITE || state->err != Z_OK)
566fe927c51SPeter Avalos         return Z_STREAM_ERROR;
567fe927c51SPeter Avalos 
568fe927c51SPeter Avalos     /* check flush parameter */
569fe927c51SPeter Avalos     if (flush < 0 || flush > Z_FINISH)
570fe927c51SPeter Avalos         return Z_STREAM_ERROR;
571fe927c51SPeter Avalos 
572fe927c51SPeter Avalos     /* check for seek request */
573fe927c51SPeter Avalos     if (state->seek) {
574fe927c51SPeter Avalos         state->seek = 0;
575fe927c51SPeter Avalos         if (gz_zero(state, state->skip) == -1)
576*e041647aSSascha Wildner             return state->err;
577fe927c51SPeter Avalos     }
578fe927c51SPeter Avalos 
579fe927c51SPeter Avalos     /* compress remaining data with requested flush */
580*e041647aSSascha Wildner     (void)gz_comp(state, flush);
581fe927c51SPeter Avalos     return state->err;
582fe927c51SPeter Avalos }
583fe927c51SPeter Avalos 
584fe927c51SPeter Avalos /* -- see zlib.h -- */
gzsetparams(file,level,strategy)585fe927c51SPeter Avalos int ZEXPORT gzsetparams(file, level, strategy)
586fe927c51SPeter Avalos     gzFile file;
587fe927c51SPeter Avalos     int level;
588fe927c51SPeter Avalos     int strategy;
589fe927c51SPeter Avalos {
590fe927c51SPeter Avalos     gz_statep state;
591fe927c51SPeter Avalos     z_streamp strm;
592fe927c51SPeter Avalos 
593fe927c51SPeter Avalos     /* get internal structure */
594fe927c51SPeter Avalos     if (file == NULL)
595fe927c51SPeter Avalos         return Z_STREAM_ERROR;
596fe927c51SPeter Avalos     state = (gz_statep)file;
597fe927c51SPeter Avalos     strm = &(state->strm);
598fe927c51SPeter Avalos 
599fe927c51SPeter Avalos     /* check that we're writing and that there's no error */
600fe927c51SPeter Avalos     if (state->mode != GZ_WRITE || state->err != Z_OK)
601fe927c51SPeter Avalos         return Z_STREAM_ERROR;
602fe927c51SPeter Avalos 
603fe927c51SPeter Avalos     /* if no change is requested, then do nothing */
604fe927c51SPeter Avalos     if (level == state->level && strategy == state->strategy)
605fe927c51SPeter Avalos         return Z_OK;
606fe927c51SPeter Avalos 
607fe927c51SPeter Avalos     /* check for seek request */
608fe927c51SPeter Avalos     if (state->seek) {
609fe927c51SPeter Avalos         state->seek = 0;
610fe927c51SPeter Avalos         if (gz_zero(state, state->skip) == -1)
611*e041647aSSascha Wildner             return state->err;
612fe927c51SPeter Avalos     }
613fe927c51SPeter Avalos 
614fe927c51SPeter Avalos     /* change compression parameters for subsequent input */
615fe927c51SPeter Avalos     if (state->size) {
616fe927c51SPeter Avalos         /* flush previous input with previous parameters before changing */
617*e041647aSSascha Wildner         if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
618fe927c51SPeter Avalos             return state->err;
619fe927c51SPeter Avalos         deflateParams(strm, level, strategy);
620fe927c51SPeter Avalos     }
621fe927c51SPeter Avalos     state->level = level;
622fe927c51SPeter Avalos     state->strategy = strategy;
623fe927c51SPeter Avalos     return Z_OK;
624fe927c51SPeter Avalos }
625fe927c51SPeter Avalos 
626fe927c51SPeter Avalos /* -- see zlib.h -- */
gzclose_w(file)627fe927c51SPeter Avalos int ZEXPORT gzclose_w(file)
628fe927c51SPeter Avalos     gzFile file;
629fe927c51SPeter Avalos {
630712f98b7SJohn Marino     int ret = Z_OK;
631fe927c51SPeter Avalos     gz_statep state;
632fe927c51SPeter Avalos 
633fe927c51SPeter Avalos     /* get internal structure */
634fe927c51SPeter Avalos     if (file == NULL)
635fe927c51SPeter Avalos         return Z_STREAM_ERROR;
636fe927c51SPeter Avalos     state = (gz_statep)file;
637fe927c51SPeter Avalos 
638fe927c51SPeter Avalos     /* check that we're writing */
639fe927c51SPeter Avalos     if (state->mode != GZ_WRITE)
640fe927c51SPeter Avalos         return Z_STREAM_ERROR;
641fe927c51SPeter Avalos 
642fe927c51SPeter Avalos     /* check for seek request */
643fe927c51SPeter Avalos     if (state->seek) {
644fe927c51SPeter Avalos         state->seek = 0;
645712f98b7SJohn Marino         if (gz_zero(state, state->skip) == -1)
646712f98b7SJohn Marino             ret = state->err;
647fe927c51SPeter Avalos     }
648fe927c51SPeter Avalos 
649fe927c51SPeter Avalos     /* flush, free memory, and close file */
650712f98b7SJohn Marino     if (gz_comp(state, Z_FINISH) == -1)
651712f98b7SJohn Marino         ret = state->err;
65253ddf67cSJohn Marino     if (state->size) {
653712f98b7SJohn Marino         if (!state->direct) {
654fe927c51SPeter Avalos             (void)deflateEnd(&(state->strm));
655fe927c51SPeter Avalos             free(state->out);
656712f98b7SJohn Marino         }
657fe927c51SPeter Avalos         free(state->in);
658712f98b7SJohn Marino     }
659fe927c51SPeter Avalos     gz_error(state, Z_OK, NULL);
660fe927c51SPeter Avalos     free(state->path);
661712f98b7SJohn Marino     if (close(state->fd) == -1)
662712f98b7SJohn Marino         ret = Z_ERRNO;
663fe927c51SPeter Avalos     free(state);
664712f98b7SJohn Marino     return ret;
665fe927c51SPeter Avalos }
666