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