annotate src/zlib-1.2.8/gzwrite.c @ 43:5ea0608b923f

Current zlib source
author Chris Cannam
date Tue, 18 Oct 2016 14:33:52 +0100
parents
children
rev   line source
Chris@43 1 /* gzwrite.c -- zlib functions for writing gzip files
Chris@43 2 * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
Chris@43 3 * For conditions of distribution and use, see copyright notice in zlib.h
Chris@43 4 */
Chris@43 5
Chris@43 6 #include "gzguts.h"
Chris@43 7
Chris@43 8 /* Local functions */
Chris@43 9 local int gz_init OF((gz_statep));
Chris@43 10 local int gz_comp OF((gz_statep, int));
Chris@43 11 local int gz_zero OF((gz_statep, z_off64_t));
Chris@43 12
Chris@43 13 /* Initialize state for writing a gzip file. Mark initialization by setting
Chris@43 14 state->size to non-zero. Return -1 on failure or 0 on success. */
Chris@43 15 local int gz_init(state)
Chris@43 16 gz_statep state;
Chris@43 17 {
Chris@43 18 int ret;
Chris@43 19 z_streamp strm = &(state->strm);
Chris@43 20
Chris@43 21 /* allocate input buffer */
Chris@43 22 state->in = (unsigned char *)malloc(state->want);
Chris@43 23 if (state->in == NULL) {
Chris@43 24 gz_error(state, Z_MEM_ERROR, "out of memory");
Chris@43 25 return -1;
Chris@43 26 }
Chris@43 27
Chris@43 28 /* only need output buffer and deflate state if compressing */
Chris@43 29 if (!state->direct) {
Chris@43 30 /* allocate output buffer */
Chris@43 31 state->out = (unsigned char *)malloc(state->want);
Chris@43 32 if (state->out == NULL) {
Chris@43 33 free(state->in);
Chris@43 34 gz_error(state, Z_MEM_ERROR, "out of memory");
Chris@43 35 return -1;
Chris@43 36 }
Chris@43 37
Chris@43 38 /* allocate deflate memory, set up for gzip compression */
Chris@43 39 strm->zalloc = Z_NULL;
Chris@43 40 strm->zfree = Z_NULL;
Chris@43 41 strm->opaque = Z_NULL;
Chris@43 42 ret = deflateInit2(strm, state->level, Z_DEFLATED,
Chris@43 43 MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
Chris@43 44 if (ret != Z_OK) {
Chris@43 45 free(state->out);
Chris@43 46 free(state->in);
Chris@43 47 gz_error(state, Z_MEM_ERROR, "out of memory");
Chris@43 48 return -1;
Chris@43 49 }
Chris@43 50 }
Chris@43 51
Chris@43 52 /* mark state as initialized */
Chris@43 53 state->size = state->want;
Chris@43 54
Chris@43 55 /* initialize write buffer if compressing */
Chris@43 56 if (!state->direct) {
Chris@43 57 strm->avail_out = state->size;
Chris@43 58 strm->next_out = state->out;
Chris@43 59 state->x.next = strm->next_out;
Chris@43 60 }
Chris@43 61 return 0;
Chris@43 62 }
Chris@43 63
Chris@43 64 /* Compress whatever is at avail_in and next_in and write to the output file.
Chris@43 65 Return -1 if there is an error writing to the output file, otherwise 0.
Chris@43 66 flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
Chris@43 67 then the deflate() state is reset to start a new gzip stream. If gz->direct
Chris@43 68 is true, then simply write to the output file without compressing, and
Chris@43 69 ignore flush. */
Chris@43 70 local int gz_comp(state, flush)
Chris@43 71 gz_statep state;
Chris@43 72 int flush;
Chris@43 73 {
Chris@43 74 int ret, got;
Chris@43 75 unsigned have;
Chris@43 76 z_streamp strm = &(state->strm);
Chris@43 77
Chris@43 78 /* allocate memory if this is the first time through */
Chris@43 79 if (state->size == 0 && gz_init(state) == -1)
Chris@43 80 return -1;
Chris@43 81
Chris@43 82 /* write directly if requested */
Chris@43 83 if (state->direct) {
Chris@43 84 got = write(state->fd, strm->next_in, strm->avail_in);
Chris@43 85 if (got < 0 || (unsigned)got != strm->avail_in) {
Chris@43 86 gz_error(state, Z_ERRNO, zstrerror());
Chris@43 87 return -1;
Chris@43 88 }
Chris@43 89 strm->avail_in = 0;
Chris@43 90 return 0;
Chris@43 91 }
Chris@43 92
Chris@43 93 /* run deflate() on provided input until it produces no more output */
Chris@43 94 ret = Z_OK;
Chris@43 95 do {
Chris@43 96 /* write out current buffer contents if full, or if flushing, but if
Chris@43 97 doing Z_FINISH then don't write until we get to Z_STREAM_END */
Chris@43 98 if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
Chris@43 99 (flush != Z_FINISH || ret == Z_STREAM_END))) {
Chris@43 100 have = (unsigned)(strm->next_out - state->x.next);
Chris@43 101 if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
Chris@43 102 (unsigned)got != have)) {
Chris@43 103 gz_error(state, Z_ERRNO, zstrerror());
Chris@43 104 return -1;
Chris@43 105 }
Chris@43 106 if (strm->avail_out == 0) {
Chris@43 107 strm->avail_out = state->size;
Chris@43 108 strm->next_out = state->out;
Chris@43 109 }
Chris@43 110 state->x.next = strm->next_out;
Chris@43 111 }
Chris@43 112
Chris@43 113 /* compress */
Chris@43 114 have = strm->avail_out;
Chris@43 115 ret = deflate(strm, flush);
Chris@43 116 if (ret == Z_STREAM_ERROR) {
Chris@43 117 gz_error(state, Z_STREAM_ERROR,
Chris@43 118 "internal error: deflate stream corrupt");
Chris@43 119 return -1;
Chris@43 120 }
Chris@43 121 have -= strm->avail_out;
Chris@43 122 } while (have);
Chris@43 123
Chris@43 124 /* if that completed a deflate stream, allow another to start */
Chris@43 125 if (flush == Z_FINISH)
Chris@43 126 deflateReset(strm);
Chris@43 127
Chris@43 128 /* all done, no errors */
Chris@43 129 return 0;
Chris@43 130 }
Chris@43 131
Chris@43 132 /* Compress len zeros to output. Return -1 on error, 0 on success. */
Chris@43 133 local int gz_zero(state, len)
Chris@43 134 gz_statep state;
Chris@43 135 z_off64_t len;
Chris@43 136 {
Chris@43 137 int first;
Chris@43 138 unsigned n;
Chris@43 139 z_streamp strm = &(state->strm);
Chris@43 140
Chris@43 141 /* consume whatever's left in the input buffer */
Chris@43 142 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
Chris@43 143 return -1;
Chris@43 144
Chris@43 145 /* compress len zeros (len guaranteed > 0) */
Chris@43 146 first = 1;
Chris@43 147 while (len) {
Chris@43 148 n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
Chris@43 149 (unsigned)len : state->size;
Chris@43 150 if (first) {
Chris@43 151 memset(state->in, 0, n);
Chris@43 152 first = 0;
Chris@43 153 }
Chris@43 154 strm->avail_in = n;
Chris@43 155 strm->next_in = state->in;
Chris@43 156 state->x.pos += n;
Chris@43 157 if (gz_comp(state, Z_NO_FLUSH) == -1)
Chris@43 158 return -1;
Chris@43 159 len -= n;
Chris@43 160 }
Chris@43 161 return 0;
Chris@43 162 }
Chris@43 163
Chris@43 164 /* -- see zlib.h -- */
Chris@43 165 int ZEXPORT gzwrite(file, buf, len)
Chris@43 166 gzFile file;
Chris@43 167 voidpc buf;
Chris@43 168 unsigned len;
Chris@43 169 {
Chris@43 170 unsigned put = len;
Chris@43 171 gz_statep state;
Chris@43 172 z_streamp strm;
Chris@43 173
Chris@43 174 /* get internal structure */
Chris@43 175 if (file == NULL)
Chris@43 176 return 0;
Chris@43 177 state = (gz_statep)file;
Chris@43 178 strm = &(state->strm);
Chris@43 179
Chris@43 180 /* check that we're writing and that there's no error */
Chris@43 181 if (state->mode != GZ_WRITE || state->err != Z_OK)
Chris@43 182 return 0;
Chris@43 183
Chris@43 184 /* since an int is returned, make sure len fits in one, otherwise return
Chris@43 185 with an error (this avoids the flaw in the interface) */
Chris@43 186 if ((int)len < 0) {
Chris@43 187 gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
Chris@43 188 return 0;
Chris@43 189 }
Chris@43 190
Chris@43 191 /* if len is zero, avoid unnecessary operations */
Chris@43 192 if (len == 0)
Chris@43 193 return 0;
Chris@43 194
Chris@43 195 /* allocate memory if this is the first time through */
Chris@43 196 if (state->size == 0 && gz_init(state) == -1)
Chris@43 197 return 0;
Chris@43 198
Chris@43 199 /* check for seek request */
Chris@43 200 if (state->seek) {
Chris@43 201 state->seek = 0;
Chris@43 202 if (gz_zero(state, state->skip) == -1)
Chris@43 203 return 0;
Chris@43 204 }
Chris@43 205
Chris@43 206 /* for small len, copy to input buffer, otherwise compress directly */
Chris@43 207 if (len < state->size) {
Chris@43 208 /* copy to input buffer, compress when full */
Chris@43 209 do {
Chris@43 210 unsigned have, copy;
Chris@43 211
Chris@43 212 if (strm->avail_in == 0)
Chris@43 213 strm->next_in = state->in;
Chris@43 214 have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
Chris@43 215 copy = state->size - have;
Chris@43 216 if (copy > len)
Chris@43 217 copy = len;
Chris@43 218 memcpy(state->in + have, buf, copy);
Chris@43 219 strm->avail_in += copy;
Chris@43 220 state->x.pos += copy;
Chris@43 221 buf = (const char *)buf + copy;
Chris@43 222 len -= copy;
Chris@43 223 if (len && gz_comp(state, Z_NO_FLUSH) == -1)
Chris@43 224 return 0;
Chris@43 225 } while (len);
Chris@43 226 }
Chris@43 227 else {
Chris@43 228 /* consume whatever's left in the input buffer */
Chris@43 229 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
Chris@43 230 return 0;
Chris@43 231
Chris@43 232 /* directly compress user buffer to file */
Chris@43 233 strm->avail_in = len;
Chris@43 234 strm->next_in = (z_const Bytef *)buf;
Chris@43 235 state->x.pos += len;
Chris@43 236 if (gz_comp(state, Z_NO_FLUSH) == -1)
Chris@43 237 return 0;
Chris@43 238 }
Chris@43 239
Chris@43 240 /* input was all buffered or compressed (put will fit in int) */
Chris@43 241 return (int)put;
Chris@43 242 }
Chris@43 243
Chris@43 244 /* -- see zlib.h -- */
Chris@43 245 int ZEXPORT gzputc(file, c)
Chris@43 246 gzFile file;
Chris@43 247 int c;
Chris@43 248 {
Chris@43 249 unsigned have;
Chris@43 250 unsigned char buf[1];
Chris@43 251 gz_statep state;
Chris@43 252 z_streamp strm;
Chris@43 253
Chris@43 254 /* get internal structure */
Chris@43 255 if (file == NULL)
Chris@43 256 return -1;
Chris@43 257 state = (gz_statep)file;
Chris@43 258 strm = &(state->strm);
Chris@43 259
Chris@43 260 /* check that we're writing and that there's no error */
Chris@43 261 if (state->mode != GZ_WRITE || state->err != Z_OK)
Chris@43 262 return -1;
Chris@43 263
Chris@43 264 /* check for seek request */
Chris@43 265 if (state->seek) {
Chris@43 266 state->seek = 0;
Chris@43 267 if (gz_zero(state, state->skip) == -1)
Chris@43 268 return -1;
Chris@43 269 }
Chris@43 270
Chris@43 271 /* try writing to input buffer for speed (state->size == 0 if buffer not
Chris@43 272 initialized) */
Chris@43 273 if (state->size) {
Chris@43 274 if (strm->avail_in == 0)
Chris@43 275 strm->next_in = state->in;
Chris@43 276 have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
Chris@43 277 if (have < state->size) {
Chris@43 278 state->in[have] = c;
Chris@43 279 strm->avail_in++;
Chris@43 280 state->x.pos++;
Chris@43 281 return c & 0xff;
Chris@43 282 }
Chris@43 283 }
Chris@43 284
Chris@43 285 /* no room in buffer or not initialized, use gz_write() */
Chris@43 286 buf[0] = c;
Chris@43 287 if (gzwrite(file, buf, 1) != 1)
Chris@43 288 return -1;
Chris@43 289 return c & 0xff;
Chris@43 290 }
Chris@43 291
Chris@43 292 /* -- see zlib.h -- */
Chris@43 293 int ZEXPORT gzputs(file, str)
Chris@43 294 gzFile file;
Chris@43 295 const char *str;
Chris@43 296 {
Chris@43 297 int ret;
Chris@43 298 unsigned len;
Chris@43 299
Chris@43 300 /* write string */
Chris@43 301 len = (unsigned)strlen(str);
Chris@43 302 ret = gzwrite(file, str, len);
Chris@43 303 return ret == 0 && len != 0 ? -1 : ret;
Chris@43 304 }
Chris@43 305
Chris@43 306 #if defined(STDC) || defined(Z_HAVE_STDARG_H)
Chris@43 307 #include <stdarg.h>
Chris@43 308
Chris@43 309 /* -- see zlib.h -- */
Chris@43 310 int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
Chris@43 311 {
Chris@43 312 int size, len;
Chris@43 313 gz_statep state;
Chris@43 314 z_streamp strm;
Chris@43 315
Chris@43 316 /* get internal structure */
Chris@43 317 if (file == NULL)
Chris@43 318 return -1;
Chris@43 319 state = (gz_statep)file;
Chris@43 320 strm = &(state->strm);
Chris@43 321
Chris@43 322 /* check that we're writing and that there's no error */
Chris@43 323 if (state->mode != GZ_WRITE || state->err != Z_OK)
Chris@43 324 return 0;
Chris@43 325
Chris@43 326 /* make sure we have some buffer space */
Chris@43 327 if (state->size == 0 && gz_init(state) == -1)
Chris@43 328 return 0;
Chris@43 329
Chris@43 330 /* check for seek request */
Chris@43 331 if (state->seek) {
Chris@43 332 state->seek = 0;
Chris@43 333 if (gz_zero(state, state->skip) == -1)
Chris@43 334 return 0;
Chris@43 335 }
Chris@43 336
Chris@43 337 /* consume whatever's left in the input buffer */
Chris@43 338 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
Chris@43 339 return 0;
Chris@43 340
Chris@43 341 /* do the printf() into the input buffer, put length in len */
Chris@43 342 size = (int)(state->size);
Chris@43 343 state->in[size - 1] = 0;
Chris@43 344 #ifdef NO_vsnprintf
Chris@43 345 # ifdef HAS_vsprintf_void
Chris@43 346 (void)vsprintf((char *)(state->in), format, va);
Chris@43 347 for (len = 0; len < size; len++)
Chris@43 348 if (state->in[len] == 0) break;
Chris@43 349 # else
Chris@43 350 len = vsprintf((char *)(state->in), format, va);
Chris@43 351 # endif
Chris@43 352 #else
Chris@43 353 # ifdef HAS_vsnprintf_void
Chris@43 354 (void)vsnprintf((char *)(state->in), size, format, va);
Chris@43 355 len = strlen((char *)(state->in));
Chris@43 356 # else
Chris@43 357 len = vsnprintf((char *)(state->in), size, format, va);
Chris@43 358 # endif
Chris@43 359 #endif
Chris@43 360
Chris@43 361 /* check that printf() results fit in buffer */
Chris@43 362 if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
Chris@43 363 return 0;
Chris@43 364
Chris@43 365 /* update buffer and position, defer compression until needed */
Chris@43 366 strm->avail_in = (unsigned)len;
Chris@43 367 strm->next_in = state->in;
Chris@43 368 state->x.pos += len;
Chris@43 369 return len;
Chris@43 370 }
Chris@43 371
Chris@43 372 int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
Chris@43 373 {
Chris@43 374 va_list va;
Chris@43 375 int ret;
Chris@43 376
Chris@43 377 va_start(va, format);
Chris@43 378 ret = gzvprintf(file, format, va);
Chris@43 379 va_end(va);
Chris@43 380 return ret;
Chris@43 381 }
Chris@43 382
Chris@43 383 #else /* !STDC && !Z_HAVE_STDARG_H */
Chris@43 384
Chris@43 385 /* -- see zlib.h -- */
Chris@43 386 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
Chris@43 387 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
Chris@43 388 gzFile file;
Chris@43 389 const char *format;
Chris@43 390 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
Chris@43 391 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
Chris@43 392 {
Chris@43 393 int size, len;
Chris@43 394 gz_statep state;
Chris@43 395 z_streamp strm;
Chris@43 396
Chris@43 397 /* get internal structure */
Chris@43 398 if (file == NULL)
Chris@43 399 return -1;
Chris@43 400 state = (gz_statep)file;
Chris@43 401 strm = &(state->strm);
Chris@43 402
Chris@43 403 /* check that can really pass pointer in ints */
Chris@43 404 if (sizeof(int) != sizeof(void *))
Chris@43 405 return 0;
Chris@43 406
Chris@43 407 /* check that we're writing and that there's no error */
Chris@43 408 if (state->mode != GZ_WRITE || state->err != Z_OK)
Chris@43 409 return 0;
Chris@43 410
Chris@43 411 /* make sure we have some buffer space */
Chris@43 412 if (state->size == 0 && gz_init(state) == -1)
Chris@43 413 return 0;
Chris@43 414
Chris@43 415 /* check for seek request */
Chris@43 416 if (state->seek) {
Chris@43 417 state->seek = 0;
Chris@43 418 if (gz_zero(state, state->skip) == -1)
Chris@43 419 return 0;
Chris@43 420 }
Chris@43 421
Chris@43 422 /* consume whatever's left in the input buffer */
Chris@43 423 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
Chris@43 424 return 0;
Chris@43 425
Chris@43 426 /* do the printf() into the input buffer, put length in len */
Chris@43 427 size = (int)(state->size);
Chris@43 428 state->in[size - 1] = 0;
Chris@43 429 #ifdef NO_snprintf
Chris@43 430 # ifdef HAS_sprintf_void
Chris@43 431 sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
Chris@43 432 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
Chris@43 433 for (len = 0; len < size; len++)
Chris@43 434 if (state->in[len] == 0) break;
Chris@43 435 # else
Chris@43 436 len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
Chris@43 437 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
Chris@43 438 # endif
Chris@43 439 #else
Chris@43 440 # ifdef HAS_snprintf_void
Chris@43 441 snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
Chris@43 442 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
Chris@43 443 len = strlen((char *)(state->in));
Chris@43 444 # else
Chris@43 445 len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
Chris@43 446 a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
Chris@43 447 a19, a20);
Chris@43 448 # endif
Chris@43 449 #endif
Chris@43 450
Chris@43 451 /* check that printf() results fit in buffer */
Chris@43 452 if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
Chris@43 453 return 0;
Chris@43 454
Chris@43 455 /* update buffer and position, defer compression until needed */
Chris@43 456 strm->avail_in = (unsigned)len;
Chris@43 457 strm->next_in = state->in;
Chris@43 458 state->x.pos += len;
Chris@43 459 return len;
Chris@43 460 }
Chris@43 461
Chris@43 462 #endif
Chris@43 463
Chris@43 464 /* -- see zlib.h -- */
Chris@43 465 int ZEXPORT gzflush(file, flush)
Chris@43 466 gzFile file;
Chris@43 467 int flush;
Chris@43 468 {
Chris@43 469 gz_statep state;
Chris@43 470
Chris@43 471 /* get internal structure */
Chris@43 472 if (file == NULL)
Chris@43 473 return -1;
Chris@43 474 state = (gz_statep)file;
Chris@43 475
Chris@43 476 /* check that we're writing and that there's no error */
Chris@43 477 if (state->mode != GZ_WRITE || state->err != Z_OK)
Chris@43 478 return Z_STREAM_ERROR;
Chris@43 479
Chris@43 480 /* check flush parameter */
Chris@43 481 if (flush < 0 || flush > Z_FINISH)
Chris@43 482 return Z_STREAM_ERROR;
Chris@43 483
Chris@43 484 /* check for seek request */
Chris@43 485 if (state->seek) {
Chris@43 486 state->seek = 0;
Chris@43 487 if (gz_zero(state, state->skip) == -1)
Chris@43 488 return -1;
Chris@43 489 }
Chris@43 490
Chris@43 491 /* compress remaining data with requested flush */
Chris@43 492 gz_comp(state, flush);
Chris@43 493 return state->err;
Chris@43 494 }
Chris@43 495
Chris@43 496 /* -- see zlib.h -- */
Chris@43 497 int ZEXPORT gzsetparams(file, level, strategy)
Chris@43 498 gzFile file;
Chris@43 499 int level;
Chris@43 500 int strategy;
Chris@43 501 {
Chris@43 502 gz_statep state;
Chris@43 503 z_streamp strm;
Chris@43 504
Chris@43 505 /* get internal structure */
Chris@43 506 if (file == NULL)
Chris@43 507 return Z_STREAM_ERROR;
Chris@43 508 state = (gz_statep)file;
Chris@43 509 strm = &(state->strm);
Chris@43 510
Chris@43 511 /* check that we're writing and that there's no error */
Chris@43 512 if (state->mode != GZ_WRITE || state->err != Z_OK)
Chris@43 513 return Z_STREAM_ERROR;
Chris@43 514
Chris@43 515 /* if no change is requested, then do nothing */
Chris@43 516 if (level == state->level && strategy == state->strategy)
Chris@43 517 return Z_OK;
Chris@43 518
Chris@43 519 /* check for seek request */
Chris@43 520 if (state->seek) {
Chris@43 521 state->seek = 0;
Chris@43 522 if (gz_zero(state, state->skip) == -1)
Chris@43 523 return -1;
Chris@43 524 }
Chris@43 525
Chris@43 526 /* change compression parameters for subsequent input */
Chris@43 527 if (state->size) {
Chris@43 528 /* flush previous input with previous parameters before changing */
Chris@43 529 if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
Chris@43 530 return state->err;
Chris@43 531 deflateParams(strm, level, strategy);
Chris@43 532 }
Chris@43 533 state->level = level;
Chris@43 534 state->strategy = strategy;
Chris@43 535 return Z_OK;
Chris@43 536 }
Chris@43 537
Chris@43 538 /* -- see zlib.h -- */
Chris@43 539 int ZEXPORT gzclose_w(file)
Chris@43 540 gzFile file;
Chris@43 541 {
Chris@43 542 int ret = Z_OK;
Chris@43 543 gz_statep state;
Chris@43 544
Chris@43 545 /* get internal structure */
Chris@43 546 if (file == NULL)
Chris@43 547 return Z_STREAM_ERROR;
Chris@43 548 state = (gz_statep)file;
Chris@43 549
Chris@43 550 /* check that we're writing */
Chris@43 551 if (state->mode != GZ_WRITE)
Chris@43 552 return Z_STREAM_ERROR;
Chris@43 553
Chris@43 554 /* check for seek request */
Chris@43 555 if (state->seek) {
Chris@43 556 state->seek = 0;
Chris@43 557 if (gz_zero(state, state->skip) == -1)
Chris@43 558 ret = state->err;
Chris@43 559 }
Chris@43 560
Chris@43 561 /* flush, free memory, and close file */
Chris@43 562 if (gz_comp(state, Z_FINISH) == -1)
Chris@43 563 ret = state->err;
Chris@43 564 if (state->size) {
Chris@43 565 if (!state->direct) {
Chris@43 566 (void)deflateEnd(&(state->strm));
Chris@43 567 free(state->out);
Chris@43 568 }
Chris@43 569 free(state->in);
Chris@43 570 }
Chris@43 571 gz_error(state, Z_OK, NULL);
Chris@43 572 free(state->path);
Chris@43 573 if (close(state->fd) == -1)
Chris@43 574 ret = Z_ERRNO;
Chris@43 575 free(state);
Chris@43 576 return ret;
Chris@43 577 }