1381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* gzwrite.c -- zlib functions for writing gzip files 204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 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 */ 2204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes state->in = (unsigned char *)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 */ 3104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes state->out = (unsigned char *)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 gz_statep state; 172381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_streamp strm; 173381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 174381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 175381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 176381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 177381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 178381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm = &(state->strm); 179381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 180381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 181381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 182381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 183381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 184381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* since an int is returned, make sure len fits in one, otherwise return 185381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes with an error (this avoids the flaw in the interface) */ 186381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((int)len < 0) { 187ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); 188381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 189381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 190381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 191381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* if len is zero, avoid unnecessary operations */ 192381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (len == 0) 193381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 194381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 195381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* allocate memory if this is the first time through */ 196381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->size == 0 && gz_init(state) == -1) 197381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 198381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 199381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 200381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 201381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 202381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 203381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 204381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 205381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 206381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* for small len, copy to input buffer, otherwise compress directly */ 207381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (len < state->size) { 208381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* copy to input buffer, compress when full */ 209381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes do { 21004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes unsigned have, copy; 21104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes 212381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in == 0) 213381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_in = state->in; 21404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes have = (unsigned)((strm->next_in + strm->avail_in) - state->in); 21504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes copy = state->size - have; 21604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes if (copy > len) 21704351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes copy = len; 21804351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes memcpy(state->in + have, buf, copy); 21904351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes strm->avail_in += copy; 22004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes state->x.pos += copy; 22104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes buf = (const char *)buf + copy; 22204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes len -= copy; 223381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (len && gz_comp(state, Z_NO_FLUSH) == -1) 224381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 225381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } while (len); 226381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 227381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes else { 228381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* consume whatever's left in the input buffer */ 229381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 230381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 231381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 232381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* directly compress user buffer to file */ 233381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->avail_in = len; 23404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes strm->next_in = (z_const Bytef *)buf; 235ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.pos += len; 236381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_comp(state, Z_NO_FLUSH) == -1) 237381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 238381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 239381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 240381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* input was all buffered or compressed (put will fit in int) */ 241381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return (int)put; 242381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 243381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 244381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 245381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzputc(file, c) 246381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 247381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int c; 248381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 24904351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes unsigned have; 250381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned char buf[1]; 251381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 252381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_streamp strm; 253381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 254381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 255381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 256381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 257381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 258381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm = &(state->strm); 259381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 260381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 261381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 262381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 263381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 264381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 265381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 266381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 267381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 268381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 269381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 270381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 271381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* try writing to input buffer for speed (state->size == 0 if buffer not 272381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes initialized) */ 27304351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes if (state->size) { 274381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in == 0) 275381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_in = state->in; 27604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes have = (unsigned)((strm->next_in + strm->avail_in) - state->in); 27704351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes if (have < state->size) { 27804351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes state->in[have] = c; 27904351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes strm->avail_in++; 28004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes state->x.pos++; 28104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes return c & 0xff; 28204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes } 283381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 284381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 285381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* no room in buffer or not initialized, use gz_write() */ 286381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes buf[0] = c; 287381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gzwrite(file, buf, 1) != 1) 288381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 289ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return c & 0xff; 290381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 291381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 292381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 293381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzputs(file, str) 294381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 295381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *str; 296381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 297381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int ret; 298381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned len; 299381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 300381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* write string */ 301381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = (unsigned)strlen(str); 302381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret = gzwrite(file, str, len); 303381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return ret == 0 && len != 0 ? -1 : ret; 304381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 305381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 306ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#if defined(STDC) || defined(Z_HAVE_STDARG_H) 307381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#include <stdarg.h> 308381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 309381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 31004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughesint ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) 311381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 312381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int size, len; 313381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 314381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_streamp strm; 315381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 316381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 317381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 318381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 319381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 320381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm = &(state->strm); 321381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 322381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 323381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 324381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 325381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 326381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* make sure we have some buffer space */ 327381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->size == 0 && gz_init(state) == -1) 328381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 329381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 330381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 331381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 332381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 333381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 334381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 335381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 336381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 337381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* consume whatever's left in the input buffer */ 338381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 339381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 340381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 341381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* do the printf() into the input buffer, put length in len */ 342381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes size = (int)(state->size); 343381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->in[size - 1] = 0; 344381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef NO_vsnprintf 345381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# ifdef HAS_vsprintf_void 34609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes (void)vsprintf((char *)(state->in), format, va); 347381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes for (len = 0; len < size; len++) 348381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->in[len] == 0) break; 349381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# else 35009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes len = vsprintf((char *)(state->in), format, va); 351381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# endif 352381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#else 353381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# ifdef HAS_vsnprintf_void 35409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes (void)vsnprintf((char *)(state->in), size, format, va); 35509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes len = strlen((char *)(state->in)); 356381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# else 357381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = vsnprintf((char *)(state->in), size, format, va); 358381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# endif 359381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 360381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 361381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that printf() results fit in buffer */ 362381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) 363381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 364381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 365381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* update buffer and position, defer compression until needed */ 366381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->avail_in = (unsigned)len; 367381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_in = state->in; 368ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.pos += len; 369381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return len; 370381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 371381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 37204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughesint ZEXPORTVA gzprintf(gzFile file, const char *format, ...) 37304351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes{ 37404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes va_list va; 37504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes int ret; 37604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes 37704351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes va_start(va, format); 37804351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes ret = gzvprintf(file, format, va); 37904351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes va_end(va); 38004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes return ret; 38104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes} 38204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes 383ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#else /* !STDC && !Z_HAVE_STDARG_H */ 384381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 385381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 386381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 387381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) 388381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 389381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *format; 390381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 391381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; 392381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 393381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int size, len; 394381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 395381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_streamp strm; 396381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 397381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 398381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 399381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 400381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 401381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm = &(state->strm); 402381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 403ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes /* check that can really pass pointer in ints */ 404ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (sizeof(int) != sizeof(void *)) 405ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return 0; 406ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes 407381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 408381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 409381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 410381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 411381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* make sure we have some buffer space */ 412381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->size == 0 && gz_init(state) == -1) 413381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 414381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 415381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 416381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 417381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 418381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 419381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 420381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 421381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 422381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* consume whatever's left in the input buffer */ 423381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 424381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 425381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 426381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* do the printf() into the input buffer, put length in len */ 427381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes size = (int)(state->size); 428381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->in[size - 1] = 0; 429381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef NO_snprintf 430381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# ifdef HAS_sprintf_void 43109eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, 432381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 433381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes for (len = 0; len < size; len++) 434381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->in[len] == 0) break; 435381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# else 43609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, 43709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 438381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# endif 439381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#else 440381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# ifdef HAS_snprintf_void 44109eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, 442381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 44309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes len = strlen((char *)(state->in)); 444381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# else 44509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, 44609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, 44709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes a19, a20); 448381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# endif 449381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 450381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 451381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that printf() results fit in buffer */ 452381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) 453381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 454381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 455381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* update buffer and position, defer compression until needed */ 456381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->avail_in = (unsigned)len; 457381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_in = state->in; 458ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.pos += len; 459381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return len; 460381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 461381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 462381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 463381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 464381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 465381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzflush(file, flush) 466381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 467381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int flush; 468381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 469381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 470381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 471381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 472381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 473381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 474381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 475381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 476381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 477381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 478381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 479381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 480381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check flush parameter */ 481381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (flush < 0 || flush > Z_FINISH) 482381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 483381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 484381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 485381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 486381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 487381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 488381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 489381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 490381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 491381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* compress remaining data with requested flush */ 492381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_comp(state, flush); 493381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return state->err; 494381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 495381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 496381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 497381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzsetparams(file, level, strategy) 498381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 499381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int level; 500381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int strategy; 501381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 502381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 503381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_streamp strm; 504381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 505381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 506381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 507381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 508381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 509381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm = &(state->strm); 510381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 511381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 512381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 513381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 514381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 515381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* if no change is requested, then do nothing */ 516381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (level == state->level && strategy == state->strategy) 517381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_OK; 518381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 519381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 520381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 521381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 522381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 523381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 524381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 525381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 526381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* change compression parameters for subsequent input */ 527381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->size) { 528381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* flush previous input with previous parameters before changing */ 529381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) 530381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return state->err; 531381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes deflateParams(strm, level, strategy); 532381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 533381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->level = level; 534381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strategy = strategy; 535381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_OK; 536381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 537381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 538381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 539381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzclose_w(file) 540381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 541381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 542ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes int ret = Z_OK; 543381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 544381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 545381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 546381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 547381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 548381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 549381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 550381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing */ 551381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE) 552381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 553381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 554381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 555381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 556381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 557ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (gz_zero(state, state->skip) == -1) 558ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes ret = state->err; 559381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 560381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 561381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* flush, free memory, and close file */ 56204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes if (gz_comp(state, Z_FINISH) == -1) 56304351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes ret = state->err; 56409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes if (state->size) { 56509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes if (!state->direct) { 56609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes (void)deflateEnd(&(state->strm)); 56709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes free(state->out); 56809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes } 56909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes free(state->in); 570ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes } 571381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_error(state, Z_OK, NULL); 572381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state->path); 573ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (close(state->fd) == -1) 574ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes ret = Z_ERRNO; 575381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state); 576ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return ret; 577ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes} 578