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