gzwrite.c revision 09eb358bbbb9aad3fe48dd3368c8a7a481cbda1c
1381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* gzwrite.c -- zlib functions for writing gzip files
2ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler
3381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes * For conditions of distribution and use, see copyright notice in zlib.h
4381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes */
5381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
6381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#include "gzguts.h"
7381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
8381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Local functions */
9381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int gz_init OF((gz_statep));
10381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int gz_comp OF((gz_statep, int));
11381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int gz_zero OF((gz_statep, z_off64_t));
12381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
13381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Initialize state for writing a gzip file.  Mark initialization by setting
14381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   state->size to non-zero.  Return -1 on failure or 0 on success. */
15381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int gz_init(state)
16381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gz_statep state;
17381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
18381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int ret;
19381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    z_streamp strm = &(state->strm);
20381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
21ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    /* allocate input buffer */
22381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    state->in = malloc(state->want);
23ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (state->in == NULL) {
24381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        gz_error(state, Z_MEM_ERROR, "out of memory");
25381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return -1;
26381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
27381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
28ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    /* only need output buffer and deflate state if compressing */
29ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (!state->direct) {
30ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        /* allocate output buffer */
31ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        state->out = malloc(state->want);
32ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        if (state->out == NULL) {
33ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            free(state->in);
34ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            gz_error(state, Z_MEM_ERROR, "out of memory");
35ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            return -1;
36ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        }
37ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
38ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        /* allocate deflate memory, set up for gzip compression */
39ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->zalloc = Z_NULL;
40ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->zfree = Z_NULL;
41ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->opaque = Z_NULL;
42ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        ret = deflateInit2(strm, state->level, Z_DEFLATED,
43ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes                           MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
44ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        if (ret != Z_OK) {
45ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            free(state->out);
46ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            free(state->in);
47ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            gz_error(state, Z_MEM_ERROR, "out of memory");
48ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            return -1;
49ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        }
50381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
51381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
52381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* mark state as initialized */
53381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    state->size = state->want;
54381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
55ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    /* initialize write buffer if compressing */
56ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (!state->direct) {
57ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->avail_out = state->size;
58ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->next_out = state->out;
59ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        state->x.next = strm->next_out;
60ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    }
61381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
62381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
63381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
64381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Compress whatever is at avail_in and next_in and write to the output file.
65381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   Return -1 if there is an error writing to the output file, otherwise 0.
66381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   flush is assumed to be a valid deflate() flush value.  If flush is Z_FINISH,
67ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes   then the deflate() state is reset to start a new gzip stream.  If gz->direct
68ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes   is true, then simply write to the output file without compressing, and
69ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes   ignore flush. */
70381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int gz_comp(state, flush)
71381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gz_statep state;
72381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int flush;
73381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
74381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int ret, got;
75381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    unsigned have;
76381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    z_streamp strm = &(state->strm);
77381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
78381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* allocate memory if this is the first time through */
79381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->size == 0 && gz_init(state) == -1)
80381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return -1;
81381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
82ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    /* write directly if requested */
83ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (state->direct) {
84ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        got = write(state->fd, strm->next_in, strm->avail_in);
85ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        if (got < 0 || (unsigned)got != strm->avail_in) {
86ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            gz_error(state, Z_ERRNO, zstrerror());
87ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            return -1;
88ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        }
89ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        strm->avail_in = 0;
90ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return 0;
91ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    }
92ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
93381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* run deflate() on provided input until it produces no more output */
94381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ret = Z_OK;
95381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    do {
96381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        /* write out current buffer contents if full, or if flushing, but if
97381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes           doing Z_FINISH then don't write until we get to Z_STREAM_END */
98381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
99381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            (flush != Z_FINISH || ret == Z_STREAM_END))) {
100ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            have = (unsigned)(strm->next_out - state->x.next);
101ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
102381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                         (unsigned)got != have)) {
103381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                gz_error(state, Z_ERRNO, zstrerror());
104381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                return -1;
105381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            }
106381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            if (strm->avail_out == 0) {
107381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                strm->avail_out = state->size;
108381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                strm->next_out = state->out;
109381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            }
110ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            state->x.next = strm->next_out;
111381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        }
112381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
113381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        /* compress */
114381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        have = strm->avail_out;
115381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        ret = deflate(strm, flush);
116381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (ret == Z_STREAM_ERROR) {
117381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            gz_error(state, Z_STREAM_ERROR,
118381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                      "internal error: deflate stream corrupt");
119381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            return -1;
120381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        }
121381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        have -= strm->avail_out;
122381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    } while (have);
123381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
124381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* if that completed a deflate stream, allow another to start */
125381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (flush == Z_FINISH)
126381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        deflateReset(strm);
127381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
128381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* all done, no errors */
129381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
130381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
131381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
132381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Compress len zeros to output.  Return -1 on error, 0 on success. */
133381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int gz_zero(state, len)
134381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gz_statep state;
135381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    z_off64_t len;
136381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
137381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int first;
138381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    unsigned n;
139381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    z_streamp strm = &(state->strm);
140381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
141381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* consume whatever's left in the input buffer */
142381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
143381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return -1;
144381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
145381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* compress len zeros (len guaranteed > 0) */
146381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    first = 1;
147381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    while (len) {
148381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
149381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            (unsigned)len : state->size;
150381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (first) {
151381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            memset(state->in, 0, n);
152381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            first = 0;
153381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        }
154381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        strm->avail_in = n;
155381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        strm->next_in = state->in;
156ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        state->x.pos += n;
157381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (gz_comp(state, Z_NO_FLUSH) == -1)
158381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            return -1;
159381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        len -= n;
160381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
161381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
162381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
163381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
164381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */
165381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzwrite(file, buf, len)
166381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gzFile file;
167381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    voidpc buf;
168381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    unsigned len;
169381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
170381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    unsigned put = len;
171381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    unsigned n;
172381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gz_statep state;
173381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    z_streamp strm;
174381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
175381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* get internal structure */
176381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (file == NULL)
177381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return 0;
178381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    state = (gz_statep)file;
179381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    strm = &(state->strm);
180381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
181381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check that we're writing and that there's no error */
182381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->mode != GZ_WRITE || state->err != Z_OK)
183381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return 0;
184381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
185381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* since an int is returned, make sure len fits in one, otherwise return
186381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes       with an error (this avoids the flaw in the interface) */
187381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if ((int)len < 0) {
188ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
189381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return 0;
190381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
191381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
192381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* if len is zero, avoid unnecessary operations */
193381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (len == 0)
194381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return 0;
195381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
196381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* allocate memory if this is the first time through */
197381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->size == 0 && gz_init(state) == -1)
198381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return 0;
199381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
200381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check for seek request */
201381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->seek) {
202381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        state->seek = 0;
203381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (gz_zero(state, state->skip) == -1)
204381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            return 0;
205381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
206381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
207381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* for small len, copy to input buffer, otherwise compress directly */
208381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (len < state->size) {
209381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        /* copy to input buffer, compress when full */
210381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        do {
211381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            if (strm->avail_in == 0)
212381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                strm->next_in = state->in;
213381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            n = state->size - strm->avail_in;
214381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            if (n > len)
215381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                n = len;
216381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            memcpy(strm->next_in + strm->avail_in, buf, n);
217381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            strm->avail_in += n;
218ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            state->x.pos += n;
219381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            buf = (char *)buf + n;
220381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            len -= n;
221381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            if (len && gz_comp(state, Z_NO_FLUSH) == -1)
222381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                return 0;
223381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        } while (len);
224381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
225381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else {
226381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        /* consume whatever's left in the input buffer */
227381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
228381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            return 0;
229381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
230381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        /* directly compress user buffer to file */
231381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        strm->avail_in = len;
232381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        strm->next_in = (voidp)buf;
233ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        state->x.pos += len;
234381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (gz_comp(state, Z_NO_FLUSH) == -1)
235381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            return 0;
236381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
237381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
238381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* input was all buffered or compressed (put will fit in int) */
239381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return (int)put;
240381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
241381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
242381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */
243381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzputc(file, c)
244381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gzFile file;
245381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int c;
246381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
247381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    unsigned char buf[1];
248381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gz_statep state;
249381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    z_streamp strm;
250381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
251381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* get internal structure */
252381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (file == NULL)
253381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return -1;
254381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    state = (gz_statep)file;
255381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    strm = &(state->strm);
256381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
257381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check that we're writing and that there's no error */
258381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->mode != GZ_WRITE || state->err != Z_OK)
259381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return -1;
260381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
261381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check for seek request */
262381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->seek) {
263381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        state->seek = 0;
264381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (gz_zero(state, state->skip) == -1)
265381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            return -1;
266381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
267381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
268381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* try writing to input buffer for speed (state->size == 0 if buffer not
269381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes       initialized) */
270381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (strm->avail_in < state->size) {
271381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (strm->avail_in == 0)
272381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            strm->next_in = state->in;
273381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        strm->next_in[strm->avail_in++] = c;
274ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        state->x.pos++;
275ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return c & 0xff;
276381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
277381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
278381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* no room in buffer or not initialized, use gz_write() */
279381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    buf[0] = c;
280381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (gzwrite(file, buf, 1) != 1)
281381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return -1;
282ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return c & 0xff;
283381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
284381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
285381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */
286381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzputs(file, str)
287381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gzFile file;
288381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    const char *str;
289381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
290381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int ret;
291381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    unsigned len;
292381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
293381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* write string */
294381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    len = (unsigned)strlen(str);
295381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ret = gzwrite(file, str, len);
296381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return ret == 0 && len != 0 ? -1 : ret;
297381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
298381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
299ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#if defined(STDC) || defined(Z_HAVE_STDARG_H)
300381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#include <stdarg.h>
301381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
302381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */
303381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
304381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
305381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int size, len;
306381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gz_statep state;
307381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    z_streamp strm;
308381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    va_list va;
309381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
310381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* get internal structure */
311381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (file == NULL)
312381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return -1;
313381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    state = (gz_statep)file;
314381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    strm = &(state->strm);
315381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
316381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check that we're writing and that there's no error */
317381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->mode != GZ_WRITE || state->err != Z_OK)
318381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return 0;
319381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
320381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* make sure we have some buffer space */
321381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->size == 0 && gz_init(state) == -1)
322381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return 0;
323381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
324381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check for seek request */
325381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->seek) {
326381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        state->seek = 0;
327381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (gz_zero(state, state->skip) == -1)
328381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            return 0;
329381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
330381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
331381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* consume whatever's left in the input buffer */
332381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
333381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return 0;
334381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
335381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* do the printf() into the input buffer, put length in len */
336381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    size = (int)(state->size);
337381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    state->in[size - 1] = 0;
338381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    va_start(va, format);
339381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef NO_vsnprintf
340381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  ifdef HAS_vsprintf_void
34109eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    (void)vsprintf((char *)(state->in), format, va);
342381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    va_end(va);
343381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    for (len = 0; len < size; len++)
344381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (state->in[len] == 0) break;
345381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  else
34609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    len = vsprintf((char *)(state->in), format, va);
347381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    va_end(va);
348381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  endif
349381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#else
350381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  ifdef HAS_vsnprintf_void
35109eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    (void)vsnprintf((char *)(state->in), size, format, va);
352381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    va_end(va);
35309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    len = strlen((char *)(state->in));
354381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  else
355381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    len = vsnprintf((char *)(state->in), size, format, va);
356381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    va_end(va);
357381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  endif
358381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
359381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
360381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check that printf() results fit in buffer */
361381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
362381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return 0;
363381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
364381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* update buffer and position, defer compression until needed */
365381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    strm->avail_in = (unsigned)len;
366381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    strm->next_in = state->in;
367ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    state->x.pos += len;
368381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return len;
369381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
370381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
371ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#else /* !STDC && !Z_HAVE_STDARG_H */
372381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
373381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */
374381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
375381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                       a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
376381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gzFile file;
377381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    const char *format;
378381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
379381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
380381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
381381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int size, len;
382381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gz_statep state;
383381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    z_streamp strm;
384381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
385381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* get internal structure */
386381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (file == NULL)
387381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return -1;
388381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    state = (gz_statep)file;
389381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    strm = &(state->strm);
390381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
391ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    /* check that can really pass pointer in ints */
392ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (sizeof(int) != sizeof(void *))
393ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        return 0;
394ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes
395381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check that we're writing and that there's no error */
396381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->mode != GZ_WRITE || state->err != Z_OK)
397381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return 0;
398381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
399381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* make sure we have some buffer space */
400381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->size == 0 && gz_init(state) == -1)
401381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return 0;
402381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
403381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check for seek request */
404381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->seek) {
405381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        state->seek = 0;
406381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (gz_zero(state, state->skip) == -1)
407381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            return 0;
408381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
409381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
410381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* consume whatever's left in the input buffer */
411381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
412381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return 0;
413381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
414381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* do the printf() into the input buffer, put length in len */
415381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    size = (int)(state->size);
416381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    state->in[size - 1] = 0;
417381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef NO_snprintf
418381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  ifdef HAS_sprintf_void
41909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
420381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
421381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    for (len = 0; len < size; len++)
422381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (state->in[len] == 0) break;
423381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  else
42409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
42509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes                  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
426381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  endif
427381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#else
428381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  ifdef HAS_snprintf_void
42909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
430381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
43109eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    len = strlen((char *)(state->in));
432381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  else
43309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
43409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes                   a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
43509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes                   a19, a20);
436381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#  endif
437381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
438381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
439381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check that printf() results fit in buffer */
440381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
441381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return 0;
442381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
443381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* update buffer and position, defer compression until needed */
444381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    strm->avail_in = (unsigned)len;
445381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    strm->next_in = state->in;
446ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    state->x.pos += len;
447381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return len;
448381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
449381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
450381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
451381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
452381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */
453381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzflush(file, flush)
454381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gzFile file;
455381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int flush;
456381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
457381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gz_statep state;
458381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
459381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* get internal structure */
460381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (file == NULL)
461381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return -1;
462381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    state = (gz_statep)file;
463381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
464381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check that we're writing and that there's no error */
465381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->mode != GZ_WRITE || state->err != Z_OK)
466381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return Z_STREAM_ERROR;
467381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
468381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check flush parameter */
469381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (flush < 0 || flush > Z_FINISH)
470381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return Z_STREAM_ERROR;
471381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
472381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check for seek request */
473381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->seek) {
474381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        state->seek = 0;
475381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (gz_zero(state, state->skip) == -1)
476381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            return -1;
477381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
478381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
479381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* compress remaining data with requested flush */
480381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gz_comp(state, flush);
481381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return state->err;
482381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
483381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
484381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */
485381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzsetparams(file, level, strategy)
486381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gzFile file;
487381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int level;
488381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int strategy;
489381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
490381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gz_statep state;
491381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    z_streamp strm;
492381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
493381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* get internal structure */
494381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (file == NULL)
495381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return Z_STREAM_ERROR;
496381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    state = (gz_statep)file;
497381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    strm = &(state->strm);
498381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
499381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check that we're writing and that there's no error */
500381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->mode != GZ_WRITE || state->err != Z_OK)
501381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return Z_STREAM_ERROR;
502381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
503381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* if no change is requested, then do nothing */
504381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (level == state->level && strategy == state->strategy)
505381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return Z_OK;
506381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
507381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check for seek request */
508381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->seek) {
509381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        state->seek = 0;
510381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (gz_zero(state, state->skip) == -1)
511381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            return -1;
512381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
513381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
514381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* change compression parameters for subsequent input */
515381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->size) {
516381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        /* flush previous input with previous parameters before changing */
517381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
518381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            return state->err;
519381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        deflateParams(strm, level, strategy);
520381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
521381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    state->level = level;
522381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    state->strategy = strategy;
523381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return Z_OK;
524381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
525381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
526381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */
527381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzclose_w(file)
528381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gzFile file;
529381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
530ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    int ret = Z_OK;
531381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gz_statep state;
532381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
533381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* get internal structure */
534381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (file == NULL)
535381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return Z_STREAM_ERROR;
536381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    state = (gz_statep)file;
537381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
538381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check that we're writing */
539381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->mode != GZ_WRITE)
540381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return Z_STREAM_ERROR;
541381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
542381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* check for seek request */
543381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (state->seek) {
544381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        state->seek = 0;
545ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        if (gz_zero(state, state->skip) == -1)
546ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes            ret = state->err;
547381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
548381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
549381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* flush, free memory, and close file */
55009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    if (state->size) {
55109eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes        if (gz_comp(state, Z_FINISH) == -1)
55209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes            ret = state->err;
55309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes        if (!state->direct) {
55409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes            (void)deflateEnd(&(state->strm));
55509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes            free(state->out);
55609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes        }
55709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes        free(state->in);
558ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    }
559381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    gz_error(state, Z_OK, NULL);
560381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    free(state->path);
561ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if (close(state->fd) == -1)
562ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        ret = Z_ERRNO;
563381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    free(state);
564ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    return ret;
565ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes}
566