Home | History | Annotate | Line # | Download | only in zlib
gzwrite.c revision 1.1.1.2
      1      1.1  christos /* gzwrite.c -- zlib functions for writing gzip files
      2  1.1.1.2  christos  * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 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.1.2  christos     state->in = (unsigned char *)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.1.2  christos         state->out = (unsigned char *)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     gz_statep state;
    172      1.1  christos     z_streamp strm;
    173      1.1  christos 
    174      1.1  christos     /* get internal structure */
    175      1.1  christos     if (file == NULL)
    176      1.1  christos         return 0;
    177      1.1  christos     state = (gz_statep)file;
    178      1.1  christos     strm = &(state->strm);
    179      1.1  christos 
    180      1.1  christos     /* check that we're writing and that there's no error */
    181      1.1  christos     if (state->mode != GZ_WRITE || state->err != Z_OK)
    182      1.1  christos         return 0;
    183      1.1  christos 
    184      1.1  christos     /* since an int is returned, make sure len fits in one, otherwise return
    185      1.1  christos        with an error (this avoids the flaw in the interface) */
    186      1.1  christos     if ((int)len < 0) {
    187      1.1  christos         gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
    188      1.1  christos         return 0;
    189      1.1  christos     }
    190      1.1  christos 
    191      1.1  christos     /* if len is zero, avoid unnecessary operations */
    192      1.1  christos     if (len == 0)
    193      1.1  christos         return 0;
    194      1.1  christos 
    195      1.1  christos     /* allocate memory if this is the first time through */
    196      1.1  christos     if (state->size == 0 && gz_init(state) == -1)
    197      1.1  christos         return 0;
    198      1.1  christos 
    199      1.1  christos     /* check for seek request */
    200      1.1  christos     if (state->seek) {
    201      1.1  christos         state->seek = 0;
    202      1.1  christos         if (gz_zero(state, state->skip) == -1)
    203      1.1  christos             return 0;
    204      1.1  christos     }
    205      1.1  christos 
    206      1.1  christos     /* for small len, copy to input buffer, otherwise compress directly */
    207      1.1  christos     if (len < state->size) {
    208      1.1  christos         /* copy to input buffer, compress when full */
    209      1.1  christos         do {
    210  1.1.1.2  christos             unsigned have, copy;
    211  1.1.1.2  christos 
    212      1.1  christos             if (strm->avail_in == 0)
    213      1.1  christos                 strm->next_in = state->in;
    214  1.1.1.2  christos             have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
    215  1.1.1.2  christos             copy = state->size - have;
    216  1.1.1.2  christos             if (copy > len)
    217  1.1.1.2  christos                 copy = len;
    218  1.1.1.2  christos             memcpy(state->in + have, buf, copy);
    219  1.1.1.2  christos             strm->avail_in += copy;
    220  1.1.1.2  christos             state->x.pos += copy;
    221  1.1.1.2  christos             buf = (const char *)buf + copy;
    222  1.1.1.2  christos             len -= copy;
    223      1.1  christos             if (len && gz_comp(state, Z_NO_FLUSH) == -1)
    224      1.1  christos                 return 0;
    225      1.1  christos         } while (len);
    226      1.1  christos     }
    227      1.1  christos     else {
    228      1.1  christos         /* consume whatever's left in the input buffer */
    229      1.1  christos         if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
    230      1.1  christos             return 0;
    231      1.1  christos 
    232      1.1  christos         /* directly compress user buffer to file */
    233      1.1  christos         strm->avail_in = len;
    234  1.1.1.2  christos         strm->next_in = (z_const Bytef *)buf;
    235      1.1  christos         state->x.pos += len;
    236      1.1  christos         if (gz_comp(state, Z_NO_FLUSH) == -1)
    237      1.1  christos             return 0;
    238      1.1  christos     }
    239      1.1  christos 
    240      1.1  christos     /* input was all buffered or compressed (put will fit in int) */
    241      1.1  christos     return (int)put;
    242      1.1  christos }
    243      1.1  christos 
    244      1.1  christos /* -- see zlib.h -- */
    245      1.1  christos int ZEXPORT gzputc(file, c)
    246      1.1  christos     gzFile file;
    247      1.1  christos     int c;
    248      1.1  christos {
    249  1.1.1.2  christos     unsigned have;
    250      1.1  christos     unsigned char buf[1];
    251      1.1  christos     gz_statep state;
    252      1.1  christos     z_streamp strm;
    253      1.1  christos 
    254      1.1  christos     /* get internal structure */
    255      1.1  christos     if (file == NULL)
    256      1.1  christos         return -1;
    257      1.1  christos     state = (gz_statep)file;
    258      1.1  christos     strm = &(state->strm);
    259      1.1  christos 
    260      1.1  christos     /* check that we're writing and that there's no error */
    261      1.1  christos     if (state->mode != GZ_WRITE || state->err != Z_OK)
    262      1.1  christos         return -1;
    263      1.1  christos 
    264      1.1  christos     /* check for seek request */
    265      1.1  christos     if (state->seek) {
    266      1.1  christos         state->seek = 0;
    267      1.1  christos         if (gz_zero(state, state->skip) == -1)
    268      1.1  christos             return -1;
    269      1.1  christos     }
    270      1.1  christos 
    271      1.1  christos     /* try writing to input buffer for speed (state->size == 0 if buffer not
    272      1.1  christos        initialized) */
    273  1.1.1.2  christos     if (state->size) {
    274      1.1  christos         if (strm->avail_in == 0)
    275      1.1  christos             strm->next_in = state->in;
    276  1.1.1.2  christos         have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
    277  1.1.1.2  christos         if (have < state->size) {
    278  1.1.1.2  christos             state->in[have] = c;
    279  1.1.1.2  christos             strm->avail_in++;
    280  1.1.1.2  christos             state->x.pos++;
    281  1.1.1.2  christos             return c & 0xff;
    282  1.1.1.2  christos         }
    283      1.1  christos     }
    284      1.1  christos 
    285      1.1  christos     /* no room in buffer or not initialized, use gz_write() */
    286      1.1  christos     buf[0] = c;
    287      1.1  christos     if (gzwrite(file, buf, 1) != 1)
    288      1.1  christos         return -1;
    289      1.1  christos     return c & 0xff;
    290      1.1  christos }
    291      1.1  christos 
    292      1.1  christos /* -- see zlib.h -- */
    293      1.1  christos int ZEXPORT gzputs(file, str)
    294      1.1  christos     gzFile file;
    295      1.1  christos     const char *str;
    296      1.1  christos {
    297      1.1  christos     int ret;
    298      1.1  christos     unsigned len;
    299      1.1  christos 
    300      1.1  christos     /* write string */
    301      1.1  christos     len = (unsigned)strlen(str);
    302      1.1  christos     ret = gzwrite(file, str, len);
    303      1.1  christos     return ret == 0 && len != 0 ? -1 : ret;
    304      1.1  christos }
    305      1.1  christos 
    306      1.1  christos #if defined(STDC) || defined(Z_HAVE_STDARG_H)
    307      1.1  christos #include <stdarg.h>
    308      1.1  christos 
    309      1.1  christos /* -- see zlib.h -- */
    310  1.1.1.2  christos int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
    311      1.1  christos {
    312      1.1  christos     int size, len;
    313      1.1  christos     gz_statep state;
    314      1.1  christos     z_streamp strm;
    315      1.1  christos 
    316      1.1  christos     /* get internal structure */
    317      1.1  christos     if (file == NULL)
    318      1.1  christos         return -1;
    319      1.1  christos     state = (gz_statep)file;
    320      1.1  christos     strm = &(state->strm);
    321      1.1  christos 
    322      1.1  christos     /* check that we're writing and that there's no error */
    323      1.1  christos     if (state->mode != GZ_WRITE || state->err != Z_OK)
    324      1.1  christos         return 0;
    325      1.1  christos 
    326      1.1  christos     /* make sure we have some buffer space */
    327      1.1  christos     if (state->size == 0 && gz_init(state) == -1)
    328      1.1  christos         return 0;
    329      1.1  christos 
    330      1.1  christos     /* check for seek request */
    331      1.1  christos     if (state->seek) {
    332      1.1  christos         state->seek = 0;
    333      1.1  christos         if (gz_zero(state, state->skip) == -1)
    334      1.1  christos             return 0;
    335      1.1  christos     }
    336      1.1  christos 
    337      1.1  christos     /* consume whatever's left in the input buffer */
    338      1.1  christos     if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
    339      1.1  christos         return 0;
    340      1.1  christos 
    341      1.1  christos     /* do the printf() into the input buffer, put length in len */
    342      1.1  christos     size = (int)(state->size);
    343      1.1  christos     state->in[size - 1] = 0;
    344      1.1  christos #ifdef NO_vsnprintf
    345      1.1  christos #  ifdef HAS_vsprintf_void
    346      1.1  christos     (void)vsprintf((char *)(state->in), format, va);
    347      1.1  christos     for (len = 0; len < size; len++)
    348      1.1  christos         if (state->in[len] == 0) break;
    349      1.1  christos #  else
    350      1.1  christos     len = vsprintf((char *)(state->in), format, va);
    351      1.1  christos #  endif
    352      1.1  christos #else
    353      1.1  christos #  ifdef HAS_vsnprintf_void
    354      1.1  christos     (void)vsnprintf((char *)(state->in), size, format, va);
    355      1.1  christos     len = strlen((char *)(state->in));
    356      1.1  christos #  else
    357      1.1  christos     len = vsnprintf((char *)(state->in), size, format, va);
    358      1.1  christos #  endif
    359      1.1  christos #endif
    360      1.1  christos 
    361      1.1  christos     /* check that printf() results fit in buffer */
    362      1.1  christos     if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
    363      1.1  christos         return 0;
    364      1.1  christos 
    365      1.1  christos     /* update buffer and position, defer compression until needed */
    366      1.1  christos     strm->avail_in = (unsigned)len;
    367      1.1  christos     strm->next_in = state->in;
    368      1.1  christos     state->x.pos += len;
    369      1.1  christos     return len;
    370      1.1  christos }
    371      1.1  christos 
    372  1.1.1.2  christos int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
    373  1.1.1.2  christos {
    374  1.1.1.2  christos     va_list va;
    375  1.1.1.2  christos     int ret;
    376  1.1.1.2  christos 
    377  1.1.1.2  christos     va_start(va, format);
    378  1.1.1.2  christos     ret = gzvprintf(file, format, va);
    379  1.1.1.2  christos     va_end(va);
    380  1.1.1.2  christos     return ret;
    381  1.1.1.2  christos }
    382  1.1.1.2  christos 
    383      1.1  christos #else /* !STDC && !Z_HAVE_STDARG_H */
    384      1.1  christos 
    385      1.1  christos /* -- see zlib.h -- */
    386      1.1  christos int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
    387      1.1  christos                        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
    388      1.1  christos     gzFile file;
    389      1.1  christos     const char *format;
    390      1.1  christos     int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
    391      1.1  christos         a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
    392      1.1  christos {
    393      1.1  christos     int size, len;
    394      1.1  christos     gz_statep state;
    395      1.1  christos     z_streamp strm;
    396      1.1  christos 
    397      1.1  christos     /* get internal structure */
    398      1.1  christos     if (file == NULL)
    399      1.1  christos         return -1;
    400      1.1  christos     state = (gz_statep)file;
    401      1.1  christos     strm = &(state->strm);
    402      1.1  christos 
    403      1.1  christos     /* check that can really pass pointer in ints */
    404      1.1  christos     if (sizeof(int) != sizeof(void *))
    405      1.1  christos         return 0;
    406      1.1  christos 
    407      1.1  christos     /* check that we're writing and that there's no error */
    408      1.1  christos     if (state->mode != GZ_WRITE || state->err != Z_OK)
    409      1.1  christos         return 0;
    410      1.1  christos 
    411      1.1  christos     /* make sure we have some buffer space */
    412      1.1  christos     if (state->size == 0 && gz_init(state) == -1)
    413      1.1  christos         return 0;
    414      1.1  christos 
    415      1.1  christos     /* check for seek request */
    416      1.1  christos     if (state->seek) {
    417      1.1  christos         state->seek = 0;
    418      1.1  christos         if (gz_zero(state, state->skip) == -1)
    419      1.1  christos             return 0;
    420      1.1  christos     }
    421      1.1  christos 
    422      1.1  christos     /* consume whatever's left in the input buffer */
    423      1.1  christos     if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
    424      1.1  christos         return 0;
    425      1.1  christos 
    426      1.1  christos     /* do the printf() into the input buffer, put length in len */
    427      1.1  christos     size = (int)(state->size);
    428      1.1  christos     state->in[size - 1] = 0;
    429      1.1  christos #ifdef NO_snprintf
    430      1.1  christos #  ifdef HAS_sprintf_void
    431      1.1  christos     sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
    432      1.1  christos             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
    433      1.1  christos     for (len = 0; len < size; len++)
    434      1.1  christos         if (state->in[len] == 0) break;
    435      1.1  christos #  else
    436      1.1  christos     len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
    437      1.1  christos                   a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
    438      1.1  christos #  endif
    439      1.1  christos #else
    440      1.1  christos #  ifdef HAS_snprintf_void
    441      1.1  christos     snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
    442      1.1  christos              a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
    443      1.1  christos     len = strlen((char *)(state->in));
    444      1.1  christos #  else
    445      1.1  christos     len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
    446      1.1  christos                    a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
    447      1.1  christos                    a19, a20);
    448      1.1  christos #  endif
    449      1.1  christos #endif
    450      1.1  christos 
    451      1.1  christos     /* check that printf() results fit in buffer */
    452      1.1  christos     if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
    453      1.1  christos         return 0;
    454      1.1  christos 
    455      1.1  christos     /* update buffer and position, defer compression until needed */
    456      1.1  christos     strm->avail_in = (unsigned)len;
    457      1.1  christos     strm->next_in = state->in;
    458      1.1  christos     state->x.pos += len;
    459      1.1  christos     return len;
    460      1.1  christos }
    461      1.1  christos 
    462      1.1  christos #endif
    463      1.1  christos 
    464      1.1  christos /* -- see zlib.h -- */
    465      1.1  christos int ZEXPORT gzflush(file, flush)
    466      1.1  christos     gzFile file;
    467      1.1  christos     int flush;
    468      1.1  christos {
    469      1.1  christos     gz_statep state;
    470      1.1  christos 
    471      1.1  christos     /* get internal structure */
    472      1.1  christos     if (file == NULL)
    473      1.1  christos         return -1;
    474      1.1  christos     state = (gz_statep)file;
    475      1.1  christos 
    476      1.1  christos     /* check that we're writing and that there's no error */
    477      1.1  christos     if (state->mode != GZ_WRITE || state->err != Z_OK)
    478      1.1  christos         return Z_STREAM_ERROR;
    479      1.1  christos 
    480      1.1  christos     /* check flush parameter */
    481      1.1  christos     if (flush < 0 || flush > Z_FINISH)
    482      1.1  christos         return Z_STREAM_ERROR;
    483      1.1  christos 
    484      1.1  christos     /* check for seek request */
    485      1.1  christos     if (state->seek) {
    486      1.1  christos         state->seek = 0;
    487      1.1  christos         if (gz_zero(state, state->skip) == -1)
    488      1.1  christos             return -1;
    489      1.1  christos     }
    490      1.1  christos 
    491      1.1  christos     /* compress remaining data with requested flush */
    492      1.1  christos     gz_comp(state, flush);
    493      1.1  christos     return state->err;
    494      1.1  christos }
    495      1.1  christos 
    496      1.1  christos /* -- see zlib.h -- */
    497      1.1  christos int ZEXPORT gzsetparams(file, level, strategy)
    498      1.1  christos     gzFile file;
    499      1.1  christos     int level;
    500      1.1  christos     int strategy;
    501      1.1  christos {
    502      1.1  christos     gz_statep state;
    503      1.1  christos     z_streamp strm;
    504      1.1  christos 
    505      1.1  christos     /* get internal structure */
    506      1.1  christos     if (file == NULL)
    507      1.1  christos         return Z_STREAM_ERROR;
    508      1.1  christos     state = (gz_statep)file;
    509      1.1  christos     strm = &(state->strm);
    510      1.1  christos 
    511      1.1  christos     /* check that we're writing and that there's no error */
    512      1.1  christos     if (state->mode != GZ_WRITE || state->err != Z_OK)
    513      1.1  christos         return Z_STREAM_ERROR;
    514      1.1  christos 
    515      1.1  christos     /* if no change is requested, then do nothing */
    516      1.1  christos     if (level == state->level && strategy == state->strategy)
    517      1.1  christos         return Z_OK;
    518      1.1  christos 
    519      1.1  christos     /* check for seek request */
    520      1.1  christos     if (state->seek) {
    521      1.1  christos         state->seek = 0;
    522      1.1  christos         if (gz_zero(state, state->skip) == -1)
    523      1.1  christos             return -1;
    524      1.1  christos     }
    525      1.1  christos 
    526      1.1  christos     /* change compression parameters for subsequent input */
    527      1.1  christos     if (state->size) {
    528      1.1  christos         /* flush previous input with previous parameters before changing */
    529      1.1  christos         if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
    530      1.1  christos             return state->err;
    531      1.1  christos         deflateParams(strm, level, strategy);
    532      1.1  christos     }
    533      1.1  christos     state->level = level;
    534      1.1  christos     state->strategy = strategy;
    535      1.1  christos     return Z_OK;
    536      1.1  christos }
    537      1.1  christos 
    538      1.1  christos /* -- see zlib.h -- */
    539      1.1  christos int ZEXPORT gzclose_w(file)
    540      1.1  christos     gzFile file;
    541      1.1  christos {
    542      1.1  christos     int ret = Z_OK;
    543      1.1  christos     gz_statep state;
    544      1.1  christos 
    545      1.1  christos     /* get internal structure */
    546      1.1  christos     if (file == NULL)
    547      1.1  christos         return Z_STREAM_ERROR;
    548      1.1  christos     state = (gz_statep)file;
    549      1.1  christos 
    550      1.1  christos     /* check that we're writing */
    551      1.1  christos     if (state->mode != GZ_WRITE)
    552      1.1  christos         return Z_STREAM_ERROR;
    553      1.1  christos 
    554      1.1  christos     /* check for seek request */
    555      1.1  christos     if (state->seek) {
    556      1.1  christos         state->seek = 0;
    557      1.1  christos         if (gz_zero(state, state->skip) == -1)
    558      1.1  christos             ret = state->err;
    559      1.1  christos     }
    560      1.1  christos 
    561      1.1  christos     /* flush, free memory, and close file */
    562  1.1.1.2  christos     if (gz_comp(state, Z_FINISH) == -1)
    563  1.1.1.2  christos         ret = state->err;
    564      1.1  christos     if (state->size) {
    565      1.1  christos         if (!state->direct) {
    566      1.1  christos             (void)deflateEnd(&(state->strm));
    567      1.1  christos             free(state->out);
    568      1.1  christos         }
    569      1.1  christos         free(state->in);
    570      1.1  christos     }
    571      1.1  christos     gz_error(state, Z_OK, NULL);
    572      1.1  christos     free(state->path);
    573      1.1  christos     if (close(state->fd) == -1)
    574      1.1  christos         ret = Z_ERRNO;
    575      1.1  christos     free(state);
    576      1.1  christos     return ret;
    577      1.1  christos }
    578