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