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