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