gzwrite.c revision ee9e11d0d4e3361533860bf04896abb86a291bfb
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 341381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (void)vsprintf(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 346381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = vsprintf(state->in, format, va); 347381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes va_end(va); 348381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# endif 349381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#else 350381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# ifdef HAS_vsnprintf_void 351381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (void)vsnprintf(state->in, size, format, va); 352381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes va_end(va); 353381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = strlen(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 419381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes sprintf(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 424381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, 425381716e9396b55b1adb8235b020c37344f60ab07Elliott 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 429381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes snprintf(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); 431381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = strlen(state->in); 432381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# else 433381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, 434381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 435381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# endif 436381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 437381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 438381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that printf() results fit in buffer */ 439381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) 440381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 441381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 442381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* update buffer and position, defer compression until needed */ 443381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->avail_in = (unsigned)len; 444381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_in = state->in; 445ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.pos += len; 446381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return len; 447381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 448381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 449381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 450381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 451381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 452381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzflush(file, flush) 453381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 454381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int flush; 455381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 456381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 457381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 458381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 459381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 460381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 461381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 462381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 463381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 464381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 465381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 466381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 467381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check flush parameter */ 468381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (flush < 0 || flush > Z_FINISH) 469381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 470381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 471381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 472381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 473381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 474381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 475381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 476381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 477381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 478381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* compress remaining data with requested flush */ 479381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_comp(state, flush); 480381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return state->err; 481381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 482381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 483381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 484381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzsetparams(file, level, strategy) 485381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 486381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int level; 487381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int strategy; 488381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 489381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 490381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_streamp strm; 491381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 492381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 493381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 494381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 495381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 496381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm = &(state->strm); 497381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 498381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 499381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 500381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 501381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 502381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* if no change is requested, then do nothing */ 503381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (level == state->level && strategy == state->strategy) 504381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_OK; 505381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 506381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 507381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 508381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 509381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 510381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 511381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 512381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 513381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* change compression parameters for subsequent input */ 514381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->size) { 515381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* flush previous input with previous parameters before changing */ 516381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) 517381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return state->err; 518381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes deflateParams(strm, level, strategy); 519381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 520381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->level = level; 521381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strategy = strategy; 522381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_OK; 523381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 524381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 525381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 526381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzclose_w(file) 527381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 528381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 529ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes int ret = Z_OK; 530381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 531381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 532381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 533381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 534381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 535381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 536381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 537381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing */ 538381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE) 539381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 540381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 541381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 542381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 543381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 544ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (gz_zero(state, state->skip) == -1) 545ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes ret = state->err; 546381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 547381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 548381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* flush, free memory, and close file */ 549ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (gz_comp(state, Z_FINISH) == -1) 550ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes ret = state->err; 551ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (!state->direct) { 552ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes (void)deflateEnd(&(state->strm)); 553ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes free(state->out); 554ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes } 555381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state->in); 556381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_error(state, Z_OK, NULL); 557381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state->path); 558ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (close(state->fd) == -1) 559ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes ret = Z_ERRNO; 560381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state); 561ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return ret; 562ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes} 563ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes 564ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes/* used by zlibVersion() to get the vsnprintf story from the horse's mouth */ 565ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesunsigned long ZEXPORT gzflags() 566ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{ 567ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes unsigned long flags = 0; 568ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#if defined(STDC) || defined(Z_HAVE_STDARG_H) 569ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# ifdef NO_vsnprintf 570ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes flags += 1L << 25; 571ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# ifdef HAS_vsprintf_void 572ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes flags += 1L << 26; 573ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# endif 574ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# else 575ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# ifdef HAS_vsnprintf_void 576ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes flags += 1L << 26; 577ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# endif 578ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# endif 579ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#else 580ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes flags += 1L << 24; 581ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# ifdef NO_snprintf 582ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes flags += 1L << 25; 583ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# ifdef HAS_sprintf_void 584ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes flags += 1L << 26; 585ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# endif 586ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# else 587ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# ifdef HAS_snprintf_void 588ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes flags += 1L << 26; 589ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# endif 590ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# endif 591ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#endif 592ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return flags; 593381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 594