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