1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/modules/zlib/src/gzwrite.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,577 @@ 1.4 +/* gzwrite.c -- zlib functions for writing gzip files 1.5 + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler 1.6 + * For conditions of distribution and use, see copyright notice in zlib.h 1.7 + */ 1.8 + 1.9 +#include "gzguts.h" 1.10 + 1.11 +/* Local functions */ 1.12 +local int gz_init OF((gz_statep)); 1.13 +local int gz_comp OF((gz_statep, int)); 1.14 +local int gz_zero OF((gz_statep, z_off64_t)); 1.15 + 1.16 +/* Initialize state for writing a gzip file. Mark initialization by setting 1.17 + state->size to non-zero. Return -1 on failure or 0 on success. */ 1.18 +local int gz_init(state) 1.19 + gz_statep state; 1.20 +{ 1.21 + int ret; 1.22 + z_streamp strm = &(state->strm); 1.23 + 1.24 + /* allocate input buffer */ 1.25 + state->in = (unsigned char *)malloc(state->want); 1.26 + if (state->in == NULL) { 1.27 + gz_error(state, Z_MEM_ERROR, "out of memory"); 1.28 + return -1; 1.29 + } 1.30 + 1.31 + /* only need output buffer and deflate state if compressing */ 1.32 + if (!state->direct) { 1.33 + /* allocate output buffer */ 1.34 + state->out = (unsigned char *)malloc(state->want); 1.35 + if (state->out == NULL) { 1.36 + free(state->in); 1.37 + gz_error(state, Z_MEM_ERROR, "out of memory"); 1.38 + return -1; 1.39 + } 1.40 + 1.41 + /* allocate deflate memory, set up for gzip compression */ 1.42 + strm->zalloc = Z_NULL; 1.43 + strm->zfree = Z_NULL; 1.44 + strm->opaque = Z_NULL; 1.45 + ret = deflateInit2(strm, state->level, Z_DEFLATED, 1.46 + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); 1.47 + if (ret != Z_OK) { 1.48 + free(state->out); 1.49 + free(state->in); 1.50 + gz_error(state, Z_MEM_ERROR, "out of memory"); 1.51 + return -1; 1.52 + } 1.53 + } 1.54 + 1.55 + /* mark state as initialized */ 1.56 + state->size = state->want; 1.57 + 1.58 + /* initialize write buffer if compressing */ 1.59 + if (!state->direct) { 1.60 + strm->avail_out = state->size; 1.61 + strm->next_out = state->out; 1.62 + state->x.next = strm->next_out; 1.63 + } 1.64 + return 0; 1.65 +} 1.66 + 1.67 +/* Compress whatever is at avail_in and next_in and write to the output file. 1.68 + Return -1 if there is an error writing to the output file, otherwise 0. 1.69 + flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, 1.70 + then the deflate() state is reset to start a new gzip stream. If gz->direct 1.71 + is true, then simply write to the output file without compressing, and 1.72 + ignore flush. */ 1.73 +local int gz_comp(state, flush) 1.74 + gz_statep state; 1.75 + int flush; 1.76 +{ 1.77 + int ret, got; 1.78 + unsigned have; 1.79 + z_streamp strm = &(state->strm); 1.80 + 1.81 + /* allocate memory if this is the first time through */ 1.82 + if (state->size == 0 && gz_init(state) == -1) 1.83 + return -1; 1.84 + 1.85 + /* write directly if requested */ 1.86 + if (state->direct) { 1.87 + got = write(state->fd, strm->next_in, strm->avail_in); 1.88 + if (got < 0 || (unsigned)got != strm->avail_in) { 1.89 + gz_error(state, Z_ERRNO, zstrerror()); 1.90 + return -1; 1.91 + } 1.92 + strm->avail_in = 0; 1.93 + return 0; 1.94 + } 1.95 + 1.96 + /* run deflate() on provided input until it produces no more output */ 1.97 + ret = Z_OK; 1.98 + do { 1.99 + /* write out current buffer contents if full, or if flushing, but if 1.100 + doing Z_FINISH then don't write until we get to Z_STREAM_END */ 1.101 + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && 1.102 + (flush != Z_FINISH || ret == Z_STREAM_END))) { 1.103 + have = (unsigned)(strm->next_out - state->x.next); 1.104 + if (have && ((got = write(state->fd, state->x.next, have)) < 0 || 1.105 + (unsigned)got != have)) { 1.106 + gz_error(state, Z_ERRNO, zstrerror()); 1.107 + return -1; 1.108 + } 1.109 + if (strm->avail_out == 0) { 1.110 + strm->avail_out = state->size; 1.111 + strm->next_out = state->out; 1.112 + } 1.113 + state->x.next = strm->next_out; 1.114 + } 1.115 + 1.116 + /* compress */ 1.117 + have = strm->avail_out; 1.118 + ret = deflate(strm, flush); 1.119 + if (ret == Z_STREAM_ERROR) { 1.120 + gz_error(state, Z_STREAM_ERROR, 1.121 + "internal error: deflate stream corrupt"); 1.122 + return -1; 1.123 + } 1.124 + have -= strm->avail_out; 1.125 + } while (have); 1.126 + 1.127 + /* if that completed a deflate stream, allow another to start */ 1.128 + if (flush == Z_FINISH) 1.129 + deflateReset(strm); 1.130 + 1.131 + /* all done, no errors */ 1.132 + return 0; 1.133 +} 1.134 + 1.135 +/* Compress len zeros to output. Return -1 on error, 0 on success. */ 1.136 +local int gz_zero(state, len) 1.137 + gz_statep state; 1.138 + z_off64_t len; 1.139 +{ 1.140 + int first; 1.141 + unsigned n; 1.142 + z_streamp strm = &(state->strm); 1.143 + 1.144 + /* consume whatever's left in the input buffer */ 1.145 + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 1.146 + return -1; 1.147 + 1.148 + /* compress len zeros (len guaranteed > 0) */ 1.149 + first = 1; 1.150 + while (len) { 1.151 + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? 1.152 + (unsigned)len : state->size; 1.153 + if (first) { 1.154 + memset(state->in, 0, n); 1.155 + first = 0; 1.156 + } 1.157 + strm->avail_in = n; 1.158 + strm->next_in = state->in; 1.159 + state->x.pos += n; 1.160 + if (gz_comp(state, Z_NO_FLUSH) == -1) 1.161 + return -1; 1.162 + len -= n; 1.163 + } 1.164 + return 0; 1.165 +} 1.166 + 1.167 +/* -- see zlib.h -- */ 1.168 +int ZEXPORT gzwrite(file, buf, len) 1.169 + gzFile file; 1.170 + voidpc buf; 1.171 + unsigned len; 1.172 +{ 1.173 + unsigned put = len; 1.174 + gz_statep state; 1.175 + z_streamp strm; 1.176 + 1.177 + /* get internal structure */ 1.178 + if (file == NULL) 1.179 + return 0; 1.180 + state = (gz_statep)file; 1.181 + strm = &(state->strm); 1.182 + 1.183 + /* check that we're writing and that there's no error */ 1.184 + if (state->mode != GZ_WRITE || state->err != Z_OK) 1.185 + return 0; 1.186 + 1.187 + /* since an int is returned, make sure len fits in one, otherwise return 1.188 + with an error (this avoids the flaw in the interface) */ 1.189 + if ((int)len < 0) { 1.190 + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); 1.191 + return 0; 1.192 + } 1.193 + 1.194 + /* if len is zero, avoid unnecessary operations */ 1.195 + if (len == 0) 1.196 + return 0; 1.197 + 1.198 + /* allocate memory if this is the first time through */ 1.199 + if (state->size == 0 && gz_init(state) == -1) 1.200 + return 0; 1.201 + 1.202 + /* check for seek request */ 1.203 + if (state->seek) { 1.204 + state->seek = 0; 1.205 + if (gz_zero(state, state->skip) == -1) 1.206 + return 0; 1.207 + } 1.208 + 1.209 + /* for small len, copy to input buffer, otherwise compress directly */ 1.210 + if (len < state->size) { 1.211 + /* copy to input buffer, compress when full */ 1.212 + do { 1.213 + unsigned have, copy; 1.214 + 1.215 + if (strm->avail_in == 0) 1.216 + strm->next_in = state->in; 1.217 + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); 1.218 + copy = state->size - have; 1.219 + if (copy > len) 1.220 + copy = len; 1.221 + memcpy(state->in + have, buf, copy); 1.222 + strm->avail_in += copy; 1.223 + state->x.pos += copy; 1.224 + buf = (const char *)buf + copy; 1.225 + len -= copy; 1.226 + if (len && gz_comp(state, Z_NO_FLUSH) == -1) 1.227 + return 0; 1.228 + } while (len); 1.229 + } 1.230 + else { 1.231 + /* consume whatever's left in the input buffer */ 1.232 + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 1.233 + return 0; 1.234 + 1.235 + /* directly compress user buffer to file */ 1.236 + strm->avail_in = len; 1.237 + strm->next_in = (z_const Bytef *)buf; 1.238 + state->x.pos += len; 1.239 + if (gz_comp(state, Z_NO_FLUSH) == -1) 1.240 + return 0; 1.241 + } 1.242 + 1.243 + /* input was all buffered or compressed (put will fit in int) */ 1.244 + return (int)put; 1.245 +} 1.246 + 1.247 +/* -- see zlib.h -- */ 1.248 +int ZEXPORT gzputc(file, c) 1.249 + gzFile file; 1.250 + int c; 1.251 +{ 1.252 + unsigned have; 1.253 + unsigned char buf[1]; 1.254 + gz_statep state; 1.255 + z_streamp strm; 1.256 + 1.257 + /* get internal structure */ 1.258 + if (file == NULL) 1.259 + return -1; 1.260 + state = (gz_statep)file; 1.261 + strm = &(state->strm); 1.262 + 1.263 + /* check that we're writing and that there's no error */ 1.264 + if (state->mode != GZ_WRITE || state->err != Z_OK) 1.265 + return -1; 1.266 + 1.267 + /* check for seek request */ 1.268 + if (state->seek) { 1.269 + state->seek = 0; 1.270 + if (gz_zero(state, state->skip) == -1) 1.271 + return -1; 1.272 + } 1.273 + 1.274 + /* try writing to input buffer for speed (state->size == 0 if buffer not 1.275 + initialized) */ 1.276 + if (state->size) { 1.277 + if (strm->avail_in == 0) 1.278 + strm->next_in = state->in; 1.279 + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); 1.280 + if (have < state->size) { 1.281 + state->in[have] = c; 1.282 + strm->avail_in++; 1.283 + state->x.pos++; 1.284 + return c & 0xff; 1.285 + } 1.286 + } 1.287 + 1.288 + /* no room in buffer or not initialized, use gz_write() */ 1.289 + buf[0] = c; 1.290 + if (gzwrite(file, buf, 1) != 1) 1.291 + return -1; 1.292 + return c & 0xff; 1.293 +} 1.294 + 1.295 +/* -- see zlib.h -- */ 1.296 +int ZEXPORT gzputs(file, str) 1.297 + gzFile file; 1.298 + const char *str; 1.299 +{ 1.300 + int ret; 1.301 + unsigned len; 1.302 + 1.303 + /* write string */ 1.304 + len = (unsigned)strlen(str); 1.305 + ret = gzwrite(file, str, len); 1.306 + return ret == 0 && len != 0 ? -1 : ret; 1.307 +} 1.308 + 1.309 +#if defined(STDC) || defined(Z_HAVE_STDARG_H) 1.310 +#include <stdarg.h> 1.311 + 1.312 +/* -- see zlib.h -- */ 1.313 +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) 1.314 +{ 1.315 + int size, len; 1.316 + gz_statep state; 1.317 + z_streamp strm; 1.318 + 1.319 + /* get internal structure */ 1.320 + if (file == NULL) 1.321 + return -1; 1.322 + state = (gz_statep)file; 1.323 + strm = &(state->strm); 1.324 + 1.325 + /* check that we're writing and that there's no error */ 1.326 + if (state->mode != GZ_WRITE || state->err != Z_OK) 1.327 + return 0; 1.328 + 1.329 + /* make sure we have some buffer space */ 1.330 + if (state->size == 0 && gz_init(state) == -1) 1.331 + return 0; 1.332 + 1.333 + /* check for seek request */ 1.334 + if (state->seek) { 1.335 + state->seek = 0; 1.336 + if (gz_zero(state, state->skip) == -1) 1.337 + return 0; 1.338 + } 1.339 + 1.340 + /* consume whatever's left in the input buffer */ 1.341 + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 1.342 + return 0; 1.343 + 1.344 + /* do the printf() into the input buffer, put length in len */ 1.345 + size = (int)(state->size); 1.346 + state->in[size - 1] = 0; 1.347 +#ifdef NO_vsnprintf 1.348 +# ifdef HAS_vsprintf_void 1.349 + (void)vsprintf((char *)(state->in), format, va); 1.350 + for (len = 0; len < size; len++) 1.351 + if (state->in[len] == 0) break; 1.352 +# else 1.353 + len = vsprintf((char *)(state->in), format, va); 1.354 +# endif 1.355 +#else 1.356 +# ifdef HAS_vsnprintf_void 1.357 + (void)vsnprintf((char *)(state->in), size, format, va); 1.358 + len = strlen((char *)(state->in)); 1.359 +# else 1.360 + len = vsnprintf((char *)(state->in), size, format, va); 1.361 +# endif 1.362 +#endif 1.363 + 1.364 + /* check that printf() results fit in buffer */ 1.365 + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) 1.366 + return 0; 1.367 + 1.368 + /* update buffer and position, defer compression until needed */ 1.369 + strm->avail_in = (unsigned)len; 1.370 + strm->next_in = state->in; 1.371 + state->x.pos += len; 1.372 + return len; 1.373 +} 1.374 + 1.375 +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) 1.376 +{ 1.377 + va_list va; 1.378 + int ret; 1.379 + 1.380 + va_start(va, format); 1.381 + ret = gzvprintf(file, format, va); 1.382 + va_end(va); 1.383 + return ret; 1.384 +} 1.385 + 1.386 +#else /* !STDC && !Z_HAVE_STDARG_H */ 1.387 + 1.388 +/* -- see zlib.h -- */ 1.389 +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 1.390 + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) 1.391 + gzFile file; 1.392 + const char *format; 1.393 + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 1.394 + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; 1.395 +{ 1.396 + int size, len; 1.397 + gz_statep state; 1.398 + z_streamp strm; 1.399 + 1.400 + /* get internal structure */ 1.401 + if (file == NULL) 1.402 + return -1; 1.403 + state = (gz_statep)file; 1.404 + strm = &(state->strm); 1.405 + 1.406 + /* check that can really pass pointer in ints */ 1.407 + if (sizeof(int) != sizeof(void *)) 1.408 + return 0; 1.409 + 1.410 + /* check that we're writing and that there's no error */ 1.411 + if (state->mode != GZ_WRITE || state->err != Z_OK) 1.412 + return 0; 1.413 + 1.414 + /* make sure we have some buffer space */ 1.415 + if (state->size == 0 && gz_init(state) == -1) 1.416 + return 0; 1.417 + 1.418 + /* check for seek request */ 1.419 + if (state->seek) { 1.420 + state->seek = 0; 1.421 + if (gz_zero(state, state->skip) == -1) 1.422 + return 0; 1.423 + } 1.424 + 1.425 + /* consume whatever's left in the input buffer */ 1.426 + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 1.427 + return 0; 1.428 + 1.429 + /* do the printf() into the input buffer, put length in len */ 1.430 + size = (int)(state->size); 1.431 + state->in[size - 1] = 0; 1.432 +#ifdef NO_snprintf 1.433 +# ifdef HAS_sprintf_void 1.434 + sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, 1.435 + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 1.436 + for (len = 0; len < size; len++) 1.437 + if (state->in[len] == 0) break; 1.438 +# else 1.439 + len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, 1.440 + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 1.441 +# endif 1.442 +#else 1.443 +# ifdef HAS_snprintf_void 1.444 + snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, 1.445 + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 1.446 + len = strlen((char *)(state->in)); 1.447 +# else 1.448 + len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, 1.449 + a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, 1.450 + a19, a20); 1.451 +# endif 1.452 +#endif 1.453 + 1.454 + /* check that printf() results fit in buffer */ 1.455 + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) 1.456 + return 0; 1.457 + 1.458 + /* update buffer and position, defer compression until needed */ 1.459 + strm->avail_in = (unsigned)len; 1.460 + strm->next_in = state->in; 1.461 + state->x.pos += len; 1.462 + return len; 1.463 +} 1.464 + 1.465 +#endif 1.466 + 1.467 +/* -- see zlib.h -- */ 1.468 +int ZEXPORT gzflush(file, flush) 1.469 + gzFile file; 1.470 + int flush; 1.471 +{ 1.472 + gz_statep state; 1.473 + 1.474 + /* get internal structure */ 1.475 + if (file == NULL) 1.476 + return -1; 1.477 + state = (gz_statep)file; 1.478 + 1.479 + /* check that we're writing and that there's no error */ 1.480 + if (state->mode != GZ_WRITE || state->err != Z_OK) 1.481 + return Z_STREAM_ERROR; 1.482 + 1.483 + /* check flush parameter */ 1.484 + if (flush < 0 || flush > Z_FINISH) 1.485 + return Z_STREAM_ERROR; 1.486 + 1.487 + /* check for seek request */ 1.488 + if (state->seek) { 1.489 + state->seek = 0; 1.490 + if (gz_zero(state, state->skip) == -1) 1.491 + return -1; 1.492 + } 1.493 + 1.494 + /* compress remaining data with requested flush */ 1.495 + gz_comp(state, flush); 1.496 + return state->err; 1.497 +} 1.498 + 1.499 +/* -- see zlib.h -- */ 1.500 +int ZEXPORT gzsetparams(file, level, strategy) 1.501 + gzFile file; 1.502 + int level; 1.503 + int strategy; 1.504 +{ 1.505 + gz_statep state; 1.506 + z_streamp strm; 1.507 + 1.508 + /* get internal structure */ 1.509 + if (file == NULL) 1.510 + return Z_STREAM_ERROR; 1.511 + state = (gz_statep)file; 1.512 + strm = &(state->strm); 1.513 + 1.514 + /* check that we're writing and that there's no error */ 1.515 + if (state->mode != GZ_WRITE || state->err != Z_OK) 1.516 + return Z_STREAM_ERROR; 1.517 + 1.518 + /* if no change is requested, then do nothing */ 1.519 + if (level == state->level && strategy == state->strategy) 1.520 + return Z_OK; 1.521 + 1.522 + /* check for seek request */ 1.523 + if (state->seek) { 1.524 + state->seek = 0; 1.525 + if (gz_zero(state, state->skip) == -1) 1.526 + return -1; 1.527 + } 1.528 + 1.529 + /* change compression parameters for subsequent input */ 1.530 + if (state->size) { 1.531 + /* flush previous input with previous parameters before changing */ 1.532 + if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) 1.533 + return state->err; 1.534 + deflateParams(strm, level, strategy); 1.535 + } 1.536 + state->level = level; 1.537 + state->strategy = strategy; 1.538 + return Z_OK; 1.539 +} 1.540 + 1.541 +/* -- see zlib.h -- */ 1.542 +int ZEXPORT gzclose_w(file) 1.543 + gzFile file; 1.544 +{ 1.545 + int ret = Z_OK; 1.546 + gz_statep state; 1.547 + 1.548 + /* get internal structure */ 1.549 + if (file == NULL) 1.550 + return Z_STREAM_ERROR; 1.551 + state = (gz_statep)file; 1.552 + 1.553 + /* check that we're writing */ 1.554 + if (state->mode != GZ_WRITE) 1.555 + return Z_STREAM_ERROR; 1.556 + 1.557 + /* check for seek request */ 1.558 + if (state->seek) { 1.559 + state->seek = 0; 1.560 + if (gz_zero(state, state->skip) == -1) 1.561 + ret = state->err; 1.562 + } 1.563 + 1.564 + /* flush, free memory, and close file */ 1.565 + if (gz_comp(state, Z_FINISH) == -1) 1.566 + ret = state->err; 1.567 + if (state->size) { 1.568 + if (!state->direct) { 1.569 + (void)deflateEnd(&(state->strm)); 1.570 + free(state->out); 1.571 + } 1.572 + free(state->in); 1.573 + } 1.574 + gz_error(state, Z_OK, NULL); 1.575 + free(state->path); 1.576 + if (close(state->fd) == -1) 1.577 + ret = Z_ERRNO; 1.578 + free(state); 1.579 + return ret; 1.580 +}