annotate src/zlib-1.2.7/gzwrite.c @ 4:e13257ea84a4

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