17eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* gzwrite.c -- zlib functions for writing gzip files
27eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
37eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * For conditions of distribution and use, see copyright notice in zlib.h
47eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
57eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
67eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "gzguts.h"
77eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
87eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Local functions */
97eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal int gz_init OF((gz_statep));
107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal int gz_comp OF((gz_statep, int));
117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal int gz_zero OF((gz_statep, z_off64_t));
127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Initialize state for writing a gzip file.  Mark initialization by setting
147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   state->size to non-zero.  Return -1 on failure or 0 on success. */
157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal int gz_init(state)
167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gz_statep state;
177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ret;
197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    z_streamp strm = &(state->strm);
207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* allocate input buffer */
227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->in = (unsigned char *)malloc(state->want);
237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->in == NULL) {
247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        gz_error(state, Z_MEM_ERROR, "out of memory");
257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* only need output buffer and deflate state if compressing */
297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!state->direct) {
307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* allocate output buffer */
317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->out = (unsigned char *)malloc(state->want);
327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (state->out == NULL) {
337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            free(state->in);
347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            gz_error(state, Z_MEM_ERROR, "out of memory");
357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* allocate deflate memory, set up for gzip compression */
397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->zalloc = Z_NULL;
407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->zfree = Z_NULL;
417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->opaque = Z_NULL;
427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ret = deflateInit2(strm, state->level, Z_DEFLATED,
437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                           MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (ret != Z_OK) {
457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            free(state->out);
467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            free(state->in);
477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            gz_error(state, Z_MEM_ERROR, "out of memory");
487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* mark state as initialized */
537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->size = state->want;
547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* initialize write buffer if compressing */
567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!state->direct) {
577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->avail_out = state->size;
587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->next_out = state->out;
597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->x.next = strm->next_out;
607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 0;
627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Compress whatever is at avail_in and next_in and write to the output file.
657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Return -1 if there is an error writing to the output file, otherwise 0.
667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   flush is assumed to be a valid deflate() flush value.  If flush is Z_FINISH,
677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   then the deflate() state is reset to start a new gzip stream.  If gz->direct
687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   is true, then simply write to the output file without compressing, and
697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   ignore flush. */
707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal int gz_comp(state, flush)
717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gz_statep state;
727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int flush;
737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ret, got;
757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned have;
767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    z_streamp strm = &(state->strm);
777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* allocate memory if this is the first time through */
797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->size == 0 && gz_init(state) == -1)
807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* write directly if requested */
837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->direct) {
847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        got = write(state->fd, strm->next_in, strm->avail_in);
857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (got < 0 || (unsigned)got != strm->avail_in) {
867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            gz_error(state, Z_ERRNO, zstrerror());
877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->avail_in = 0;
907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* run deflate() on provided input until it produces no more output */
947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ret = Z_OK;
957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    do {
967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* write out current buffer contents if full, or if flushing, but if
977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           doing Z_FINISH then don't write until we get to Z_STREAM_END */
987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            (flush != Z_FINISH || ret == Z_STREAM_END))) {
1007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            have = (unsigned)(strm->next_out - state->x.next);
1017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
1027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                         (unsigned)got != have)) {
1037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                gz_error(state, Z_ERRNO, zstrerror());
1047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return -1;
1057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
1067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (strm->avail_out == 0) {
1077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->avail_out = state->size;
1087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->next_out = state->out;
1097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
1107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->x.next = strm->next_out;
1117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
1127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* compress */
1147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        have = strm->avail_out;
1157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ret = deflate(strm, flush);
1167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (ret == Z_STREAM_ERROR) {
1177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            gz_error(state, Z_STREAM_ERROR,
1187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                      "internal error: deflate stream corrupt");
1197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
1207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
1217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        have -= strm->avail_out;
1227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    } while (have);
1237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* if that completed a deflate stream, allow another to start */
1257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (flush == Z_FINISH)
1267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        deflateReset(strm);
1277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* all done, no errors */
1297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 0;
1307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Compress len zeros to output.  Return -1 on error, 0 on success. */
1337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal int gz_zero(state, len)
1347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gz_statep state;
1357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    z_off64_t len;
1367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int first;
1387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned n;
1397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    z_streamp strm = &(state->strm);
1407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* consume whatever's left in the input buffer */
1427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
1437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
1447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* compress len zeros (len guaranteed > 0) */
1467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    first = 1;
1477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (len) {
1487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
1497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            (unsigned)len : state->size;
1507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (first) {
1517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            memset(state->in, 0, n);
1527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            first = 0;
1537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
1547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->avail_in = n;
1557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->next_in = state->in;
1567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->x.pos += n;
1577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (gz_comp(state, Z_NO_FLUSH) == -1)
1587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
1597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        len -= n;
1607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 0;
1627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* -- see zlib.h -- */
1657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT gzwrite(file, buf, len)
1667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gzFile file;
1677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    voidpc buf;
1687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned len;
1697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned put = len;
1717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gz_statep state;
1727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    z_streamp strm;
1737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* get internal structure */
1757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (file == NULL)
1767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
1777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (gz_statep)file;
1787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm = &(state->strm);
1797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check that we're writing and that there's no error */
1817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->mode != GZ_WRITE || state->err != Z_OK)
1827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
1837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* since an int is returned, make sure len fits in one, otherwise return
1857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       with an error (this avoids the flaw in the interface) */
1867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if ((int)len < 0) {
1877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
1887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
1897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* if len is zero, avoid unnecessary operations */
1927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (len == 0)
1937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
1947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* allocate memory if this is the first time through */
1967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->size == 0 && gz_init(state) == -1)
1977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
1987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check for seek request */
2007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->seek) {
2017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->seek = 0;
2027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (gz_zero(state, state->skip) == -1)
2037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return 0;
2047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* for small len, copy to input buffer, otherwise compress directly */
2077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (len < state->size) {
2087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* copy to input buffer, compress when full */
2097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        do {
2107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            unsigned have, copy;
2117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (strm->avail_in == 0)
2137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->next_in = state->in;
2147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
2157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            copy = state->size - have;
2167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (copy > len)
2177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                copy = len;
2187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            memcpy(state->in + have, buf, copy);
2197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            strm->avail_in += copy;
2207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->x.pos += copy;
2217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            buf = (const char *)buf + copy;
2227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            len -= copy;
2237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (len && gz_comp(state, Z_NO_FLUSH) == -1)
2247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return 0;
2257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        } while (len);
2267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
2287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* consume whatever's left in the input buffer */
2297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
2307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return 0;
2317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* directly compress user buffer to file */
2337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->avail_in = len;
2347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->next_in = (z_const Bytef *)buf;
2357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->x.pos += len;
2367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (gz_comp(state, Z_NO_FLUSH) == -1)
2377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return 0;
2387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* input was all buffered or compressed (put will fit in int) */
2417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (int)put;
2427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* -- see zlib.h -- */
2457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT gzputc(file, c)
2467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gzFile file;
2477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int c;
2487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned have;
2507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned char buf[1];
2517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gz_statep state;
2527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    z_streamp strm;
2537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* get internal structure */
2557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (file == NULL)
2567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
2577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (gz_statep)file;
2587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm = &(state->strm);
2597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check that we're writing and that there's no error */
2617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->mode != GZ_WRITE || state->err != Z_OK)
2627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
2637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check for seek request */
2657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->seek) {
2667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->seek = 0;
2677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (gz_zero(state, state->skip) == -1)
2687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
2697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* try writing to input buffer for speed (state->size == 0 if buffer not
2727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       initialized) */
2737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->size) {
2747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strm->avail_in == 0)
2757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            strm->next_in = state->in;
2767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
2777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (have < state->size) {
2787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->in[have] = c;
2797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            strm->avail_in++;
2807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->x.pos++;
2817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return c & 0xff;
2827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
2837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* no room in buffer or not initialized, use gz_write() */
2867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    buf[0] = c;
2877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (gzwrite(file, buf, 1) != 1)
2887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
2897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return c & 0xff;
2907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* -- see zlib.h -- */
2937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT gzputs(file, str)
2947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gzFile file;
2957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    const char *str;
2967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ret;
2987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned len;
2997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* write string */
3017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    len = (unsigned)strlen(str);
3027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ret = gzwrite(file, str, len);
3037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ret == 0 && len != 0 ? -1 : ret;
3047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if defined(STDC) || defined(Z_HAVE_STDARG_H)
3077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include <stdarg.h>
3087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* -- see zlib.h -- */
3107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
3117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int size, len;
3137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gz_statep state;
3147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    z_streamp strm;
3157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* get internal structure */
3177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (file == NULL)
3187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
3197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (gz_statep)file;
3207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm = &(state->strm);
3217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check that we're writing and that there's no error */
3237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->mode != GZ_WRITE || state->err != Z_OK)
3247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
3257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* make sure we have some buffer space */
3277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->size == 0 && gz_init(state) == -1)
3287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
3297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check for seek request */
3317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->seek) {
3327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->seek = 0;
3337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (gz_zero(state, state->skip) == -1)
3347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return 0;
3357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* consume whatever's left in the input buffer */
3387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
3397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
3407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* do the printf() into the input buffer, put length in len */
3427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    size = (int)(state->size);
3437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->in[size - 1] = 0;
3447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef NO_vsnprintf
3457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  ifdef HAS_vsprintf_void
3467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    (void)vsprintf((char *)(state->in), format, va);
3477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (len = 0; len < size; len++)
3487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (state->in[len] == 0) break;
3497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  else
3507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    len = vsprintf((char *)(state->in), format, va);
3517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  endif
3527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
3537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  ifdef HAS_vsnprintf_void
3547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    (void)vsnprintf((char *)(state->in), size, format, va);
3557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    len = strlen((char *)(state->in));
3567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  else
3577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    len = vsnprintf((char *)(state->in), size, format, va);
3587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  endif
3597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
3607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check that printf() results fit in buffer */
3627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
3637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
3647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* update buffer and position, defer compression until needed */
3667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->avail_in = (unsigned)len;
3677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->next_in = state->in;
3687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->x.pos += len;
3697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return len;
3707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
3737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    va_list va;
3757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ret;
3767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    va_start(va, format);
3787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ret = gzvprintf(file, format, va);
3797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    va_end(va);
3807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ret;
3817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else /* !STDC && !Z_HAVE_STDARG_H */
3847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* -- see zlib.h -- */
3867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
3877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
3887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gzFile file;
3897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    const char *format;
3907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
3917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
3927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int size, len;
3947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gz_statep state;
3957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    z_streamp strm;
3967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* get internal structure */
3987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (file == NULL)
3997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
4007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (gz_statep)file;
4017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm = &(state->strm);
4027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check that can really pass pointer in ints */
4047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (sizeof(int) != sizeof(void *))
4057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
4067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check that we're writing and that there's no error */
4087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->mode != GZ_WRITE || state->err != Z_OK)
4097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
4107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* make sure we have some buffer space */
4127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->size == 0 && gz_init(state) == -1)
4137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
4147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check for seek request */
4167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->seek) {
4177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->seek = 0;
4187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (gz_zero(state, state->skip) == -1)
4197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return 0;
4207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* consume whatever's left in the input buffer */
4237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
4247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
4257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* do the printf() into the input buffer, put length in len */
4277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    size = (int)(state->size);
4287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->in[size - 1] = 0;
4297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef NO_snprintf
4307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  ifdef HAS_sprintf_void
4317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
4327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
4337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (len = 0; len < size; len++)
4347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (state->in[len] == 0) break;
4357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  else
4367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
4377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
4387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  endif
4397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
4407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  ifdef HAS_snprintf_void
4417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
4427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
4437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    len = strlen((char *)(state->in));
4447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  else
4457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
4467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
4477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   a19, a20);
4487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  endif
4497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
4507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check that printf() results fit in buffer */
4527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
4537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
4547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* update buffer and position, defer compression until needed */
4567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->avail_in = (unsigned)len;
4577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->next_in = state->in;
4587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->x.pos += len;
4597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return len;
4607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
4637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* -- see zlib.h -- */
4657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT gzflush(file, flush)
4667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gzFile file;
4677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int flush;
4687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
4697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gz_statep state;
4707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* get internal structure */
4727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (file == NULL)
4737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
4747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (gz_statep)file;
4757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check that we're writing and that there's no error */
4777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->mode != GZ_WRITE || state->err != Z_OK)
4787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_STREAM_ERROR;
4797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check flush parameter */
4817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (flush < 0 || flush > Z_FINISH)
4827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_STREAM_ERROR;
4837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check for seek request */
4857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->seek) {
4867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->seek = 0;
4877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (gz_zero(state, state->skip) == -1)
4887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
4897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* compress remaining data with requested flush */
4927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gz_comp(state, flush);
4937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return state->err;
4947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* -- see zlib.h -- */
4977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT gzsetparams(file, level, strategy)
4987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gzFile file;
4997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int level;
5007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int strategy;
5017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
5027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gz_statep state;
5037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    z_streamp strm;
5047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* get internal structure */
5067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (file == NULL)
5077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_STREAM_ERROR;
5087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (gz_statep)file;
5097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm = &(state->strm);
5107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check that we're writing and that there's no error */
5127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->mode != GZ_WRITE || state->err != Z_OK)
5137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_STREAM_ERROR;
5147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* if no change is requested, then do nothing */
5167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (level == state->level && strategy == state->strategy)
5177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_OK;
5187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check for seek request */
5207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->seek) {
5217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->seek = 0;
5227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (gz_zero(state, state->skip) == -1)
5237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
5247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* change compression parameters for subsequent input */
5277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->size) {
5287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* flush previous input with previous parameters before changing */
5297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
5307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return state->err;
5317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        deflateParams(strm, level, strategy);
5327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->level = level;
5347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->strategy = strategy;
5357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Z_OK;
5367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
5377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* -- see zlib.h -- */
5397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT gzclose_w(file)
5407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gzFile file;
5417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
5427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ret = Z_OK;
5437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gz_statep state;
5447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* get internal structure */
5467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (file == NULL)
5477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_STREAM_ERROR;
5487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (gz_statep)file;
5497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check that we're writing */
5517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->mode != GZ_WRITE)
5527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_STREAM_ERROR;
5537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check for seek request */
5557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->seek) {
5567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->seek = 0;
5577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (gz_zero(state, state->skip) == -1)
5587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ret = state->err;
5597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* flush, free memory, and close file */
5627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (gz_comp(state, Z_FINISH) == -1)
5637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ret = state->err;
5647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->size) {
5657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (!state->direct) {
5667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            (void)deflateEnd(&(state->strm));
5677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            free(state->out);
5687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
5697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        free(state->in);
5707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    gz_error(state, Z_OK, NULL);
5727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    free(state->path);
5737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (close(state->fd) == -1)
5747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ret = Z_ERRNO;
5757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    free(state);
5767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ret;
5777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
578