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