199767f8919635c4928607450d9e0abb932109ceToomas Soome/* gzwrite.c -- zlib functions for writing gzip files
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
199767f8919635c4928607450d9e0abb932109ceToomas Soome * For conditions of distribution and use, see copyright notice in zlib.h
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* $FreeBSD$ */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "gzguts.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <unistd.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Local functions */
199767f8919635c4928607450d9e0abb932109ceToomas Soomelocal int gz_init OF((gz_statep));
199767f8919635c4928607450d9e0abb932109ceToomas Soomelocal int gz_comp OF((gz_statep, int));
199767f8919635c4928607450d9e0abb932109ceToomas Soomelocal int gz_zero OF((gz_statep, z_off64_t));
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Initialize state for writing a gzip file. Mark initialization by setting
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->size to non-zero. Return -1 on failure or 0 on success. */
199767f8919635c4928607450d9e0abb932109ceToomas Soomelocal int gz_init(state)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int ret;
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_streamp strm = &(state->strm);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* allocate input buffer */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->in = (unsigned char *)malloc(state->want);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->in == NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_error(state, Z_MEM_ERROR, "out of memory");
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* only need output buffer and deflate state if compressing */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!state->direct) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* allocate output buffer */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->out = (unsigned char *)malloc(state->want);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->out == NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state->in);
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_error(state, Z_MEM_ERROR, "out of memory");
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* allocate deflate memory, set up for gzip compression */
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->zalloc = Z_NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->zfree = Z_NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->opaque = Z_NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = deflateInit2(strm, state->level, Z_DEFLATED,
199767f8919635c4928607450d9e0abb932109ceToomas Soome MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (ret != Z_OK) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state->out);
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state->in);
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_error(state, Z_MEM_ERROR, "out of memory");
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* mark state as initialized */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->size = state->want;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* initialize write buffer if compressing */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!state->direct) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->avail_out = state->size;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->next_out = state->out;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.next = strm->next_out;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Compress whatever is at avail_in and next_in and write to the output file.
199767f8919635c4928607450d9e0abb932109ceToomas Soome Return -1 if there is an error writing to the output file, otherwise 0.
199767f8919635c4928607450d9e0abb932109ceToomas Soome flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
199767f8919635c4928607450d9e0abb932109ceToomas Soome then the deflate() state is reset to start a new gzip stream. If gz->direct
199767f8919635c4928607450d9e0abb932109ceToomas Soome is true, then simply write to the output file without compressing, and
199767f8919635c4928607450d9e0abb932109ceToomas Soome ignore flush. */
199767f8919635c4928607450d9e0abb932109ceToomas Soomelocal int gz_comp(state, flush)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int flush;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int ret, got;
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned have;
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_streamp strm = &(state->strm);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* allocate memory if this is the first time through */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->size == 0 && gz_init(state) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* write directly if requested */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->direct) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome got = write(state->fd, strm->next_in, strm->avail_in);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (got < 0 || (unsigned)got != strm->avail_in) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_error(state, Z_ERRNO, zstrerror());
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->avail_in = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* run deflate() on provided input until it produces no more output */
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = Z_OK;
199767f8919635c4928607450d9e0abb932109ceToomas Soome do {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* write out current buffer contents if full, or if flushing, but if
199767f8919635c4928607450d9e0abb932109ceToomas Soome doing Z_FINISH then don't write until we get to Z_STREAM_END */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
199767f8919635c4928607450d9e0abb932109ceToomas Soome (flush != Z_FINISH || ret == Z_STREAM_END))) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome have = (unsigned)(strm->next_out - state->x.next);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
199767f8919635c4928607450d9e0abb932109ceToomas Soome (unsigned)got != have)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_error(state, Z_ERRNO, zstrerror());
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (strm->avail_out == 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->avail_out = state->size;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->next_out = state->out;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.next = strm->next_out;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* compress */
199767f8919635c4928607450d9e0abb932109ceToomas Soome have = strm->avail_out;
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = deflate(strm, flush);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (ret == Z_STREAM_ERROR) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_error(state, Z_STREAM_ERROR,
199767f8919635c4928607450d9e0abb932109ceToomas Soome "internal error: deflate stream corrupt");
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome have -= strm->avail_out;
199767f8919635c4928607450d9e0abb932109ceToomas Soome } while (have);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* if that completed a deflate stream, allow another to start */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (flush == Z_FINISH)
199767f8919635c4928607450d9e0abb932109ceToomas Soome deflateReset(strm);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* all done, no errors */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Compress len zeros to output. Return -1 on error, 0 on success. */
199767f8919635c4928607450d9e0abb932109ceToomas Soomelocal int gz_zero(state, len)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_off64_t len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int first;
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned n;
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_streamp strm = &(state->strm);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* consume whatever's left in the input buffer */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* compress len zeros (len guaranteed > 0) */
199767f8919635c4928607450d9e0abb932109ceToomas Soome first = 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (len) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
199767f8919635c4928607450d9e0abb932109ceToomas Soome (unsigned)len : state->size;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (first) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome memset(state->in, 0, n);
199767f8919635c4928607450d9e0abb932109ceToomas Soome first = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->avail_in = n;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->next_in = state->in;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.pos += n;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (gz_comp(state, Z_NO_FLUSH) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome len -= n;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint ZEXPORT gzwrite(file, buf, len)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome voidpc buf;
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned put = len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_streamp strm;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm = &(state->strm);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check that we're writing and that there's no error */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_WRITE || state->err != Z_OK)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* since an int is returned, make sure len fits in one, otherwise return
199767f8919635c4928607450d9e0abb932109ceToomas Soome with an error (this avoids the flaw in the interface) */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((int)len < 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* if len is zero, avoid unnecessary operations */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (len == 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* allocate memory if this is the first time through */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->size == 0 && gz_init(state) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check for seek request */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->seek) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->seek = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (gz_zero(state, state->skip) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* for small len, copy to input buffer, otherwise compress directly */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (len < state->size) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* copy to input buffer, compress when full */
199767f8919635c4928607450d9e0abb932109ceToomas Soome do {
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned have, copy;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (strm->avail_in == 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->next_in = state->in;
199767f8919635c4928607450d9e0abb932109ceToomas Soome have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
199767f8919635c4928607450d9e0abb932109ceToomas Soome copy = state->size - have;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (copy > len)
199767f8919635c4928607450d9e0abb932109ceToomas Soome copy = len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome memcpy(state->in + have, buf, copy);
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->avail_in += copy;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.pos += copy;
199767f8919635c4928607450d9e0abb932109ceToomas Soome buf = (const char *)buf + copy;
199767f8919635c4928607450d9e0abb932109ceToomas Soome len -= copy;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (len && gz_comp(state, Z_NO_FLUSH) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome } while (len);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome else {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* consume whatever's left in the input buffer */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* directly compress user buffer to file */
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->avail_in = len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->next_in = (z_const Bytef *)buf;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.pos += len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (gz_comp(state, Z_NO_FLUSH) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* input was all buffered or compressed (put will fit in int) */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (int)put;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint ZEXPORT gzputc(file, c)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int c;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned have;
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned char buf[1];
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_streamp strm;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm = &(state->strm);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check that we're writing and that there's no error */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_WRITE || state->err != Z_OK)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check for seek request */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->seek) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->seek = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (gz_zero(state, state->skip) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* try writing to input buffer for speed (state->size == 0 if buffer not
199767f8919635c4928607450d9e0abb932109ceToomas Soome initialized) */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->size) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (strm->avail_in == 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->next_in = state->in;
199767f8919635c4928607450d9e0abb932109ceToomas Soome have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (have < state->size) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->in[have] = c;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->avail_in++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.pos++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return c & 0xff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* no room in buffer or not initialized, use gz_write() */
199767f8919635c4928607450d9e0abb932109ceToomas Soome buf[0] = c;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (gzwrite(file, buf, 1) != 1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return c & 0xff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint ZEXPORT gzputs(file, str)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *str;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int ret;
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* write string */
199767f8919635c4928607450d9e0abb932109ceToomas Soome len = (unsigned)strlen(str);
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = gzwrite(file, str, len);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return ret == 0 && len != 0 ? -1 : ret;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#if defined(STDC) || defined(Z_HAVE_STDARG_H)
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <stdarg.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int size, len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_streamp strm;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm = &(state->strm);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check that we're writing and that there's no error */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_WRITE || state->err != Z_OK)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* make sure we have some buffer space */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->size == 0 && gz_init(state) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check for seek request */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->seek) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->seek = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (gz_zero(state, state->skip) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* consume whatever's left in the input buffer */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* do the printf() into the input buffer, put length in len */
199767f8919635c4928607450d9e0abb932109ceToomas Soome size = (int)(state->size);
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->in[size - 1] = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef NO_vsnprintf
199767f8919635c4928607450d9e0abb932109ceToomas Soome# ifdef HAS_vsprintf_void
199767f8919635c4928607450d9e0abb932109ceToomas Soome (void)vsprintf((char *)(state->in), format, va);
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (len = 0; len < size; len++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->in[len] == 0) break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome# else
199767f8919635c4928607450d9e0abb932109ceToomas Soome len = vsprintf((char *)(state->in), format, va);
199767f8919635c4928607450d9e0abb932109ceToomas Soome# endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome#else
199767f8919635c4928607450d9e0abb932109ceToomas Soome# ifdef HAS_vsnprintf_void
199767f8919635c4928607450d9e0abb932109ceToomas Soome (void)vsnprintf((char *)(state->in), size, format, va);
199767f8919635c4928607450d9e0abb932109ceToomas Soome len = strlen((char *)(state->in));
199767f8919635c4928607450d9e0abb932109ceToomas Soome# else
199767f8919635c4928607450d9e0abb932109ceToomas Soome len = vsnprintf((char *)(state->in), size, format, va);
199767f8919635c4928607450d9e0abb932109ceToomas Soome# endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check that printf() results fit in buffer */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* update buffer and position, defer compression until needed */
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->avail_in = (unsigned)len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->next_in = state->in;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.pos += len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome va_list va;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int ret;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome va_start(va, format);
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = gzvprintf(file, format, va);
199767f8919635c4928607450d9e0abb932109ceToomas Soome va_end(va);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return ret;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#else /* !STDC && !Z_HAVE_STDARG_H */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
199767f8919635c4928607450d9e0abb932109ceToomas Soome a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *format;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
199767f8919635c4928607450d9e0abb932109ceToomas Soome a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int size, len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_streamp strm;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm = &(state->strm);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check that can really pass pointer in ints */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (sizeof(int) != sizeof(void *))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check that we're writing and that there's no error */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_WRITE || state->err != Z_OK)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* make sure we have some buffer space */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->size == 0 && gz_init(state) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check for seek request */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->seek) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->seek = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (gz_zero(state, state->skip) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* consume whatever's left in the input buffer */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* do the printf() into the input buffer, put length in len */
199767f8919635c4928607450d9e0abb932109ceToomas Soome size = (int)(state->size);
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->in[size - 1] = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef NO_snprintf
199767f8919635c4928607450d9e0abb932109ceToomas Soome# ifdef HAS_sprintf_void
199767f8919635c4928607450d9e0abb932109ceToomas Soome sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
199767f8919635c4928607450d9e0abb932109ceToomas Soome a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (len = 0; len < size; len++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->in[len] == 0) break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome# else
199767f8919635c4928607450d9e0abb932109ceToomas Soome len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
199767f8919635c4928607450d9e0abb932109ceToomas Soome a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
199767f8919635c4928607450d9e0abb932109ceToomas Soome# endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome#else
199767f8919635c4928607450d9e0abb932109ceToomas Soome# ifdef HAS_snprintf_void
199767f8919635c4928607450d9e0abb932109ceToomas Soome snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
199767f8919635c4928607450d9e0abb932109ceToomas Soome a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
199767f8919635c4928607450d9e0abb932109ceToomas Soome len = strlen((char *)(state->in));
199767f8919635c4928607450d9e0abb932109ceToomas Soome# else
199767f8919635c4928607450d9e0abb932109ceToomas Soome len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
199767f8919635c4928607450d9e0abb932109ceToomas Soome a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
199767f8919635c4928607450d9e0abb932109ceToomas Soome a19, a20);
199767f8919635c4928607450d9e0abb932109ceToomas Soome# endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check that printf() results fit in buffer */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* update buffer and position, defer compression until needed */
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->avail_in = (unsigned)len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm->next_in = state->in;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.pos += len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint ZEXPORT gzflush(file, flush)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int flush;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check that we're writing and that there's no error */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_WRITE || state->err != Z_OK)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return Z_STREAM_ERROR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check flush parameter */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (flush < 0 || flush > Z_FINISH)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return Z_STREAM_ERROR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check for seek request */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->seek) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->seek = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (gz_zero(state, state->skip) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* compress remaining data with requested flush */
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_comp(state, flush);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return state->err;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint ZEXPORT gzsetparams(file, level, strategy)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int level;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int strategy;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_streamp strm;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return Z_STREAM_ERROR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome strm = &(state->strm);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check that we're writing and that there's no error */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_WRITE || state->err != Z_OK)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return Z_STREAM_ERROR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* if no change is requested, then do nothing */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (level == state->level && strategy == state->strategy)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return Z_OK;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check for seek request */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->seek) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->seek = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (gz_zero(state, state->skip) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* change compression parameters for subsequent input */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->size) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* flush previous input with previous parameters before changing */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return state->err;
199767f8919635c4928607450d9e0abb932109ceToomas Soome deflateParams(strm, level, strategy);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->level = level;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->strategy = strategy;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return Z_OK;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint ZEXPORT gzclose_w(file)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int ret = Z_OK;
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return Z_STREAM_ERROR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check that we're writing */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_WRITE)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return Z_STREAM_ERROR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check for seek request */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->seek) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->seek = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (gz_zero(state, state->skip) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = state->err;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* flush, free memory, and close file */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (gz_comp(state, Z_FINISH) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = state->err;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->size) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!state->direct) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome (void)deflateEnd(&(state->strm));
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state->out);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state->in);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_error(state, Z_OK, NULL);
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state->path);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (close(state->fd) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = Z_ERRNO;
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return ret;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}