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