gzwrite.c revision 381716e9396b55b1adb8235b020c37344f60ab07
1381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* gzwrite.c -- zlib functions for writing gzip files 2381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes * Copyright (C) 2004, 2005, 2010 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 21381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* allocate input and output buffers */ 22381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->in = malloc(state->want); 23381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->out = malloc(state->want); 24381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->in == NULL || state->out == NULL) { 25381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->out != NULL) 26381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state->out); 27381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->in != NULL) 28381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state->in); 29381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_error(state, Z_MEM_ERROR, "out of memory"); 30381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 31381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 32381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 33381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* allocate deflate memory, set up for gzip compression */ 34381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->zalloc = Z_NULL; 35381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->zfree = Z_NULL; 36381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->opaque = Z_NULL; 37381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret = deflateInit2(strm, state->level, Z_DEFLATED, 38381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 15 + 16, 8, state->strategy); 39381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (ret != Z_OK) { 40381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state->in); 41381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_error(state, Z_MEM_ERROR, "out of memory"); 42381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 43381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 44381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 45381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* mark state as initialized */ 46381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->size = state->want; 47381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 48381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* initialize write buffer */ 49381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->avail_out = state->size; 50381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_out = state->out; 51381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->next = strm->next_out; 52381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 53381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 54381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 55381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Compress whatever is at avail_in and next_in and write to the output file. 56381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes Return -1 if there is an error writing to the output file, otherwise 0. 57381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, 58381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes then the deflate() state is reset to start a new gzip stream. */ 59381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int gz_comp(state, flush) 60381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 61381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int flush; 62381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 63381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int ret, got; 64381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned have; 65381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_streamp strm = &(state->strm); 66381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 67381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* allocate memory if this is the first time through */ 68381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->size == 0 && gz_init(state) == -1) 69381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 70381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 71381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* run deflate() on provided input until it produces no more output */ 72381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret = Z_OK; 73381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes do { 74381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* write out current buffer contents if full, or if flushing, but if 75381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes doing Z_FINISH then don't write until we get to Z_STREAM_END */ 76381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && 77381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (flush != Z_FINISH || ret == Z_STREAM_END))) { 78381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes have = (unsigned)(strm->next_out - state->next); 79381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (have && ((got = write(state->fd, state->next, have)) < 0 || 80381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (unsigned)got != have)) { 81381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_error(state, Z_ERRNO, zstrerror()); 82381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 83381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 84381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_out == 0) { 85381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->avail_out = state->size; 86381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_out = state->out; 87381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 88381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->next = strm->next_out; 89381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 90381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 91381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* compress */ 92381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes have = strm->avail_out; 93381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret = deflate(strm, flush); 94381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (ret == Z_STREAM_ERROR) { 95381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_error(state, Z_STREAM_ERROR, 96381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes "internal error: deflate stream corrupt"); 97381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 98381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 99381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes have -= strm->avail_out; 100381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } while (have); 101381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 102381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* if that completed a deflate stream, allow another to start */ 103381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (flush == Z_FINISH) 104381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes deflateReset(strm); 105381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 106381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* all done, no errors */ 107381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 108381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 109381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 110381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Compress len zeros to output. Return -1 on error, 0 on success. */ 111381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int gz_zero(state, len) 112381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 113381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t len; 114381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 115381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int first; 116381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned n; 117381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_streamp strm = &(state->strm); 118381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 119381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* consume whatever's left in the input buffer */ 120381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 121381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 122381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 123381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* compress len zeros (len guaranteed > 0) */ 124381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes first = 1; 125381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes while (len) { 126381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes n = GT_OFF(state->size) || (z_off64_t)state->size > len ? 127381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (unsigned)len : state->size; 128381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (first) { 129381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes memset(state->in, 0, n); 130381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes first = 0; 131381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 132381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->avail_in = n; 133381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_in = state->in; 134381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->pos += n; 135381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_comp(state, Z_NO_FLUSH) == -1) 136381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 137381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len -= n; 138381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 139381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 140381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 141381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 142381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 143381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzwrite(file, buf, len) 144381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 145381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes voidpc buf; 146381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned len; 147381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 148381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned put = len; 149381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned n; 150381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 151381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_streamp strm; 152381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 153381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 154381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 155381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 156381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 157381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm = &(state->strm); 158381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 159381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 160381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 161381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 162381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 163381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* since an int is returned, make sure len fits in one, otherwise return 164381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes with an error (this avoids the flaw in the interface) */ 165381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((int)len < 0) { 166381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); 167381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 168381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 169381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 170381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* if len is zero, avoid unnecessary operations */ 171381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (len == 0) 172381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 173381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 174381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* allocate memory if this is the first time through */ 175381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->size == 0 && gz_init(state) == -1) 176381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 177381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 178381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 179381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 180381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 181381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 182381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 183381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 184381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 185381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* for small len, copy to input buffer, otherwise compress directly */ 186381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (len < state->size) { 187381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* copy to input buffer, compress when full */ 188381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes do { 189381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in == 0) 190381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_in = state->in; 191381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes n = state->size - strm->avail_in; 192381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (n > len) 193381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes n = len; 194381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes memcpy(strm->next_in + strm->avail_in, buf, n); 195381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->avail_in += n; 196381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->pos += n; 197381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes buf = (char *)buf + n; 198381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len -= n; 199381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (len && gz_comp(state, Z_NO_FLUSH) == -1) 200381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 201381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } while (len); 202381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 203381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes else { 204381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* consume whatever's left in the input buffer */ 205381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 206381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 207381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 208381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* directly compress user buffer to file */ 209381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->avail_in = len; 210381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_in = (voidp)buf; 211381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->pos += len; 212381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_comp(state, Z_NO_FLUSH) == -1) 213381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 214381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 215381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 216381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* input was all buffered or compressed (put will fit in int) */ 217381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return (int)put; 218381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 219381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 220381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 221381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzputc(file, c) 222381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 223381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int c; 224381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 225381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned char buf[1]; 226381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 227381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_streamp strm; 228381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 229381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 230381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 231381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 232381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 233381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm = &(state->strm); 234381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 235381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 236381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 237381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 238381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 239381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 240381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 241381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 242381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 243381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 244381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 245381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 246381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* try writing to input buffer for speed (state->size == 0 if buffer not 247381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes initialized) */ 248381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in < state->size) { 249381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in == 0) 250381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_in = state->in; 251381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_in[strm->avail_in++] = c; 252381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->pos++; 253381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return c; 254381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 255381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 256381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* no room in buffer or not initialized, use gz_write() */ 257381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes buf[0] = c; 258381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gzwrite(file, buf, 1) != 1) 259381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 260381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return c; 261381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 262381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 263381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 264381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzputs(file, str) 265381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 266381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *str; 267381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 268381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int ret; 269381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned len; 270381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 271381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* write string */ 272381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = (unsigned)strlen(str); 273381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret = gzwrite(file, str, len); 274381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return ret == 0 && len != 0 ? -1 : ret; 275381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 276381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 277381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef STDC 278381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#include <stdarg.h> 279381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 280381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 281381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORTVA gzprintf (gzFile file, const char *format, ...) 282381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 283381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int size, len; 284381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 285381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_streamp strm; 286381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes va_list va; 287381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 288381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 289381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 290381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 291381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 292381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm = &(state->strm); 293381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 294381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 295381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 296381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 297381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 298381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* make sure we have some buffer space */ 299381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->size == 0 && gz_init(state) == -1) 300381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 301381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 302381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 303381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 304381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 305381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 306381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 307381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 308381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 309381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* consume whatever's left in the input buffer */ 310381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 311381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 312381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 313381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* do the printf() into the input buffer, put length in len */ 314381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes size = (int)(state->size); 315381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->in[size - 1] = 0; 316381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes va_start(va, format); 317381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef NO_vsnprintf 318381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# ifdef HAS_vsprintf_void 319381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (void)vsprintf(state->in, format, va); 320381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes va_end(va); 321381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes for (len = 0; len < size; len++) 322381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->in[len] == 0) break; 323381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# else 324381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = vsprintf(state->in, format, va); 325381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes va_end(va); 326381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# endif 327381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#else 328381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# ifdef HAS_vsnprintf_void 329381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (void)vsnprintf(state->in, size, format, va); 330381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes va_end(va); 331381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = strlen(state->in); 332381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# else 333381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = vsnprintf((char *)(state->in), size, format, va); 334381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes va_end(va); 335381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# endif 336381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 337381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 338381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that printf() results fit in buffer */ 339381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) 340381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 341381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 342381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* update buffer and position, defer compression until needed */ 343381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->avail_in = (unsigned)len; 344381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_in = state->in; 345381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->pos += len; 346381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return len; 347381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 348381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 349381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#else /* !STDC */ 350381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 351381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 352381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 353381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) 354381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 355381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *format; 356381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 357381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; 358381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 359381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int size, len; 360381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 361381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_streamp strm; 362381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 363381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 364381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 365381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 366381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 367381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm = &(state->strm); 368381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 369381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 370381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 371381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 372381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 373381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* make sure we have some buffer space */ 374381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->size == 0 && gz_init(state) == -1) 375381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 376381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 377381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 378381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 379381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 380381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 381381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 382381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 383381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 384381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* consume whatever's left in the input buffer */ 385381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 386381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 387381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 388381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* do the printf() into the input buffer, put length in len */ 389381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes size = (int)(state->size); 390381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->in[size - 1] = 0; 391381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef NO_snprintf 392381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# ifdef HAS_sprintf_void 393381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, 394381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 395381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes for (len = 0; len < size; len++) 396381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->in[len] == 0) break; 397381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# else 398381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, 399381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 400381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# endif 401381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#else 402381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# ifdef HAS_snprintf_void 403381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, 404381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 405381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = strlen(state->in); 406381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# else 407381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, 408381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 409381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# endif 410381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 411381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 412381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that printf() results fit in buffer */ 413381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) 414381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 415381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 416381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* update buffer and position, defer compression until needed */ 417381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->avail_in = (unsigned)len; 418381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->next_in = state->in; 419381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->pos += len; 420381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return len; 421381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 422381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 423381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 424381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 425381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 426381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzflush(file, flush) 427381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 428381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int flush; 429381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 430381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 431381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 432381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 433381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 434381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 435381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 436381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 437381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 438381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 439381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 440381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 441381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check flush parameter */ 442381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (flush < 0 || flush > Z_FINISH) 443381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 444381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 445381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 446381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 447381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 448381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 449381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 450381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 451381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 452381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* compress remaining data with requested flush */ 453381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_comp(state, flush); 454381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return state->err; 455381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 456381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 457381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 458381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzsetparams(file, level, strategy) 459381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 460381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int level; 461381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int strategy; 462381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 463381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 464381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_streamp strm; 465381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 466381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 467381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 468381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 469381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 470381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm = &(state->strm); 471381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 472381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing and that there's no error */ 473381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE || state->err != Z_OK) 474381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 475381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 476381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* if no change is requested, then do nothing */ 477381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (level == state->level && strategy == state->strategy) 478381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_OK; 479381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 480381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 481381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 482381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 483381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gz_zero(state, state->skip) == -1) 484381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 485381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 486381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 487381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* change compression parameters for subsequent input */ 488381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->size) { 489381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* flush previous input with previous parameters before changing */ 490381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) 491381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return state->err; 492381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes deflateParams(strm, level, strategy); 493381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 494381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->level = level; 495381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strategy = strategy; 496381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_OK; 497381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 498381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 499381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 500381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzclose_w(file) 501381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 502381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 503381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int ret = 0; 504381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 505381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 506381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 507381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 508381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 509381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 510381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 511381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're writing */ 512381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_WRITE) 513381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 514381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 515381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for seek request */ 516381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->seek) { 517381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 518381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret += gz_zero(state, state->skip); 519381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 520381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 521381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* flush, free memory, and close file */ 522381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret += gz_comp(state, Z_FINISH); 523381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (void)deflateEnd(&(state->strm)); 524381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state->out); 525381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state->in); 526381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_error(state, Z_OK, NULL); 527381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state->path); 528381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret += close(state->fd); 529381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state); 530381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return ret ? Z_ERRNO : Z_OK; 531381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 532