1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/modules/zlib/src/gzread.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,594 @@ 1.4 +/* gzread.c -- zlib functions for reading 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_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); 1.13 +local int gz_avail OF((gz_statep)); 1.14 +local int gz_look OF((gz_statep)); 1.15 +local int gz_decomp OF((gz_statep)); 1.16 +local int gz_fetch OF((gz_statep)); 1.17 +local int gz_skip OF((gz_statep, z_off64_t)); 1.18 + 1.19 +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from 1.20 + state->fd, and update state->eof, state->err, and state->msg as appropriate. 1.21 + This function needs to loop on read(), since read() is not guaranteed to 1.22 + read the number of bytes requested, depending on the type of descriptor. */ 1.23 +local int gz_load(state, buf, len, have) 1.24 + gz_statep state; 1.25 + unsigned char *buf; 1.26 + unsigned len; 1.27 + unsigned *have; 1.28 +{ 1.29 + int ret; 1.30 + 1.31 + *have = 0; 1.32 + do { 1.33 + ret = read(state->fd, buf + *have, len - *have); 1.34 + if (ret <= 0) 1.35 + break; 1.36 + *have += ret; 1.37 + } while (*have < len); 1.38 + if (ret < 0) { 1.39 + gz_error(state, Z_ERRNO, zstrerror()); 1.40 + return -1; 1.41 + } 1.42 + if (ret == 0) 1.43 + state->eof = 1; 1.44 + return 0; 1.45 +} 1.46 + 1.47 +/* Load up input buffer and set eof flag if last data loaded -- return -1 on 1.48 + error, 0 otherwise. Note that the eof flag is set when the end of the input 1.49 + file is reached, even though there may be unused data in the buffer. Once 1.50 + that data has been used, no more attempts will be made to read the file. 1.51 + If strm->avail_in != 0, then the current data is moved to the beginning of 1.52 + the input buffer, and then the remainder of the buffer is loaded with the 1.53 + available data from the input file. */ 1.54 +local int gz_avail(state) 1.55 + gz_statep state; 1.56 +{ 1.57 + unsigned got; 1.58 + z_streamp strm = &(state->strm); 1.59 + 1.60 + if (state->err != Z_OK && state->err != Z_BUF_ERROR) 1.61 + return -1; 1.62 + if (state->eof == 0) { 1.63 + if (strm->avail_in) { /* copy what's there to the start */ 1.64 + unsigned char *p = state->in; 1.65 + unsigned const char *q = strm->next_in; 1.66 + unsigned n = strm->avail_in; 1.67 + do { 1.68 + *p++ = *q++; 1.69 + } while (--n); 1.70 + } 1.71 + if (gz_load(state, state->in + strm->avail_in, 1.72 + state->size - strm->avail_in, &got) == -1) 1.73 + return -1; 1.74 + strm->avail_in += got; 1.75 + strm->next_in = state->in; 1.76 + } 1.77 + return 0; 1.78 +} 1.79 + 1.80 +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. 1.81 + If this is the first time in, allocate required memory. state->how will be 1.82 + left unchanged if there is no more input data available, will be set to COPY 1.83 + if there is no gzip header and direct copying will be performed, or it will 1.84 + be set to GZIP for decompression. If direct copying, then leftover input 1.85 + data from the input buffer will be copied to the output buffer. In that 1.86 + case, all further file reads will be directly to either the output buffer or 1.87 + a user buffer. If decompressing, the inflate state will be initialized. 1.88 + gz_look() will return 0 on success or -1 on failure. */ 1.89 +local int gz_look(state) 1.90 + gz_statep state; 1.91 +{ 1.92 + z_streamp strm = &(state->strm); 1.93 + 1.94 + /* allocate read buffers and inflate memory */ 1.95 + if (state->size == 0) { 1.96 + /* allocate buffers */ 1.97 + state->in = (unsigned char *)malloc(state->want); 1.98 + state->out = (unsigned char *)malloc(state->want << 1); 1.99 + if (state->in == NULL || state->out == NULL) { 1.100 + if (state->out != NULL) 1.101 + free(state->out); 1.102 + if (state->in != NULL) 1.103 + free(state->in); 1.104 + gz_error(state, Z_MEM_ERROR, "out of memory"); 1.105 + return -1; 1.106 + } 1.107 + state->size = state->want; 1.108 + 1.109 + /* allocate inflate memory */ 1.110 + state->strm.zalloc = Z_NULL; 1.111 + state->strm.zfree = Z_NULL; 1.112 + state->strm.opaque = Z_NULL; 1.113 + state->strm.avail_in = 0; 1.114 + state->strm.next_in = Z_NULL; 1.115 + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ 1.116 + free(state->out); 1.117 + free(state->in); 1.118 + state->size = 0; 1.119 + gz_error(state, Z_MEM_ERROR, "out of memory"); 1.120 + return -1; 1.121 + } 1.122 + } 1.123 + 1.124 + /* get at least the magic bytes in the input buffer */ 1.125 + if (strm->avail_in < 2) { 1.126 + if (gz_avail(state) == -1) 1.127 + return -1; 1.128 + if (strm->avail_in == 0) 1.129 + return 0; 1.130 + } 1.131 + 1.132 + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is 1.133 + a logical dilemma here when considering the case of a partially written 1.134 + gzip file, to wit, if a single 31 byte is written, then we cannot tell 1.135 + whether this is a single-byte file, or just a partially written gzip 1.136 + file -- for here we assume that if a gzip file is being written, then 1.137 + the header will be written in a single operation, so that reading a 1.138 + single byte is sufficient indication that it is not a gzip file) */ 1.139 + if (strm->avail_in > 1 && 1.140 + strm->next_in[0] == 31 && strm->next_in[1] == 139) { 1.141 + inflateReset(strm); 1.142 + state->how = GZIP; 1.143 + state->direct = 0; 1.144 + return 0; 1.145 + } 1.146 + 1.147 + /* no gzip header -- if we were decoding gzip before, then this is trailing 1.148 + garbage. Ignore the trailing garbage and finish. */ 1.149 + if (state->direct == 0) { 1.150 + strm->avail_in = 0; 1.151 + state->eof = 1; 1.152 + state->x.have = 0; 1.153 + return 0; 1.154 + } 1.155 + 1.156 + /* doing raw i/o, copy any leftover input to output -- this assumes that 1.157 + the output buffer is larger than the input buffer, which also assures 1.158 + space for gzungetc() */ 1.159 + state->x.next = state->out; 1.160 + if (strm->avail_in) { 1.161 + memcpy(state->x.next, strm->next_in, strm->avail_in); 1.162 + state->x.have = strm->avail_in; 1.163 + strm->avail_in = 0; 1.164 + } 1.165 + state->how = COPY; 1.166 + state->direct = 1; 1.167 + return 0; 1.168 +} 1.169 + 1.170 +/* Decompress from input to the provided next_out and avail_out in the state. 1.171 + On return, state->x.have and state->x.next point to the just decompressed 1.172 + data. If the gzip stream completes, state->how is reset to LOOK to look for 1.173 + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 1.174 + on success, -1 on failure. */ 1.175 +local int gz_decomp(state) 1.176 + gz_statep state; 1.177 +{ 1.178 + int ret = Z_OK; 1.179 + unsigned had; 1.180 + z_streamp strm = &(state->strm); 1.181 + 1.182 + /* fill output buffer up to end of deflate stream */ 1.183 + had = strm->avail_out; 1.184 + do { 1.185 + /* get more input for inflate() */ 1.186 + if (strm->avail_in == 0 && gz_avail(state) == -1) 1.187 + return -1; 1.188 + if (strm->avail_in == 0) { 1.189 + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); 1.190 + break; 1.191 + } 1.192 + 1.193 + /* decompress and handle errors */ 1.194 + ret = inflate(strm, Z_NO_FLUSH); 1.195 + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { 1.196 + gz_error(state, Z_STREAM_ERROR, 1.197 + "internal error: inflate stream corrupt"); 1.198 + return -1; 1.199 + } 1.200 + if (ret == Z_MEM_ERROR) { 1.201 + gz_error(state, Z_MEM_ERROR, "out of memory"); 1.202 + return -1; 1.203 + } 1.204 + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ 1.205 + gz_error(state, Z_DATA_ERROR, 1.206 + strm->msg == NULL ? "compressed data error" : strm->msg); 1.207 + return -1; 1.208 + } 1.209 + } while (strm->avail_out && ret != Z_STREAM_END); 1.210 + 1.211 + /* update available output */ 1.212 + state->x.have = had - strm->avail_out; 1.213 + state->x.next = strm->next_out - state->x.have; 1.214 + 1.215 + /* if the gzip stream completed successfully, look for another */ 1.216 + if (ret == Z_STREAM_END) 1.217 + state->how = LOOK; 1.218 + 1.219 + /* good decompression */ 1.220 + return 0; 1.221 +} 1.222 + 1.223 +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. 1.224 + Data is either copied from the input file or decompressed from the input 1.225 + file depending on state->how. If state->how is LOOK, then a gzip header is 1.226 + looked for to determine whether to copy or decompress. Returns -1 on error, 1.227 + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the 1.228 + end of the input file has been reached and all data has been processed. */ 1.229 +local int gz_fetch(state) 1.230 + gz_statep state; 1.231 +{ 1.232 + z_streamp strm = &(state->strm); 1.233 + 1.234 + do { 1.235 + switch(state->how) { 1.236 + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ 1.237 + if (gz_look(state) == -1) 1.238 + return -1; 1.239 + if (state->how == LOOK) 1.240 + return 0; 1.241 + break; 1.242 + case COPY: /* -> COPY */ 1.243 + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) 1.244 + == -1) 1.245 + return -1; 1.246 + state->x.next = state->out; 1.247 + return 0; 1.248 + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ 1.249 + strm->avail_out = state->size << 1; 1.250 + strm->next_out = state->out; 1.251 + if (gz_decomp(state) == -1) 1.252 + return -1; 1.253 + } 1.254 + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); 1.255 + return 0; 1.256 +} 1.257 + 1.258 +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ 1.259 +local int gz_skip(state, len) 1.260 + gz_statep state; 1.261 + z_off64_t len; 1.262 +{ 1.263 + unsigned n; 1.264 + 1.265 + /* skip over len bytes or reach end-of-file, whichever comes first */ 1.266 + while (len) 1.267 + /* skip over whatever is in output buffer */ 1.268 + if (state->x.have) { 1.269 + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? 1.270 + (unsigned)len : state->x.have; 1.271 + state->x.have -= n; 1.272 + state->x.next += n; 1.273 + state->x.pos += n; 1.274 + len -= n; 1.275 + } 1.276 + 1.277 + /* output buffer empty -- return if we're at the end of the input */ 1.278 + else if (state->eof && state->strm.avail_in == 0) 1.279 + break; 1.280 + 1.281 + /* need more data to skip -- load up output buffer */ 1.282 + else { 1.283 + /* get more output, looking for header if required */ 1.284 + if (gz_fetch(state) == -1) 1.285 + return -1; 1.286 + } 1.287 + return 0; 1.288 +} 1.289 + 1.290 +/* -- see zlib.h -- */ 1.291 +int ZEXPORT gzread(file, buf, len) 1.292 + gzFile file; 1.293 + voidp buf; 1.294 + unsigned len; 1.295 +{ 1.296 + unsigned got, n; 1.297 + gz_statep state; 1.298 + z_streamp strm; 1.299 + 1.300 + /* get internal structure */ 1.301 + if (file == NULL) 1.302 + return -1; 1.303 + state = (gz_statep)file; 1.304 + strm = &(state->strm); 1.305 + 1.306 + /* check that we're reading and that there's no (serious) error */ 1.307 + if (state->mode != GZ_READ || 1.308 + (state->err != Z_OK && state->err != Z_BUF_ERROR)) 1.309 + return -1; 1.310 + 1.311 + /* since an int is returned, make sure len fits in one, otherwise return 1.312 + with an error (this avoids the flaw in the interface) */ 1.313 + if ((int)len < 0) { 1.314 + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); 1.315 + return -1; 1.316 + } 1.317 + 1.318 + /* if len is zero, avoid unnecessary operations */ 1.319 + if (len == 0) 1.320 + return 0; 1.321 + 1.322 + /* process a skip request */ 1.323 + if (state->seek) { 1.324 + state->seek = 0; 1.325 + if (gz_skip(state, state->skip) == -1) 1.326 + return -1; 1.327 + } 1.328 + 1.329 + /* get len bytes to buf, or less than len if at the end */ 1.330 + got = 0; 1.331 + do { 1.332 + /* first just try copying data from the output buffer */ 1.333 + if (state->x.have) { 1.334 + n = state->x.have > len ? len : state->x.have; 1.335 + memcpy(buf, state->x.next, n); 1.336 + state->x.next += n; 1.337 + state->x.have -= n; 1.338 + } 1.339 + 1.340 + /* output buffer empty -- return if we're at the end of the input */ 1.341 + else if (state->eof && strm->avail_in == 0) { 1.342 + state->past = 1; /* tried to read past end */ 1.343 + break; 1.344 + } 1.345 + 1.346 + /* need output data -- for small len or new stream load up our output 1.347 + buffer */ 1.348 + else if (state->how == LOOK || len < (state->size << 1)) { 1.349 + /* get more output, looking for header if required */ 1.350 + if (gz_fetch(state) == -1) 1.351 + return -1; 1.352 + continue; /* no progress yet -- go back to copy above */ 1.353 + /* the copy above assures that we will leave with space in the 1.354 + output buffer, allowing at least one gzungetc() to succeed */ 1.355 + } 1.356 + 1.357 + /* large len -- read directly into user buffer */ 1.358 + else if (state->how == COPY) { /* read directly */ 1.359 + if (gz_load(state, (unsigned char *)buf, len, &n) == -1) 1.360 + return -1; 1.361 + } 1.362 + 1.363 + /* large len -- decompress directly into user buffer */ 1.364 + else { /* state->how == GZIP */ 1.365 + strm->avail_out = len; 1.366 + strm->next_out = (unsigned char *)buf; 1.367 + if (gz_decomp(state) == -1) 1.368 + return -1; 1.369 + n = state->x.have; 1.370 + state->x.have = 0; 1.371 + } 1.372 + 1.373 + /* update progress */ 1.374 + len -= n; 1.375 + buf = (char *)buf + n; 1.376 + got += n; 1.377 + state->x.pos += n; 1.378 + } while (len); 1.379 + 1.380 + /* return number of bytes read into user buffer (will fit in int) */ 1.381 + return (int)got; 1.382 +} 1.383 + 1.384 +/* -- see zlib.h -- */ 1.385 +#ifdef Z_PREFIX_SET 1.386 +# undef z_gzgetc 1.387 +#else 1.388 +# undef gzgetc 1.389 +#endif 1.390 +int ZEXPORT gzgetc(file) 1.391 + gzFile file; 1.392 +{ 1.393 + int ret; 1.394 + unsigned char buf[1]; 1.395 + gz_statep state; 1.396 + 1.397 + /* get internal structure */ 1.398 + if (file == NULL) 1.399 + return -1; 1.400 + state = (gz_statep)file; 1.401 + 1.402 + /* check that we're reading and that there's no (serious) error */ 1.403 + if (state->mode != GZ_READ || 1.404 + (state->err != Z_OK && state->err != Z_BUF_ERROR)) 1.405 + return -1; 1.406 + 1.407 + /* try output buffer (no need to check for skip request) */ 1.408 + if (state->x.have) { 1.409 + state->x.have--; 1.410 + state->x.pos++; 1.411 + return *(state->x.next)++; 1.412 + } 1.413 + 1.414 + /* nothing there -- try gzread() */ 1.415 + ret = gzread(file, buf, 1); 1.416 + return ret < 1 ? -1 : buf[0]; 1.417 +} 1.418 + 1.419 +int ZEXPORT gzgetc_(file) 1.420 +gzFile file; 1.421 +{ 1.422 + return gzgetc(file); 1.423 +} 1.424 + 1.425 +/* -- see zlib.h -- */ 1.426 +int ZEXPORT gzungetc(c, file) 1.427 + int c; 1.428 + gzFile file; 1.429 +{ 1.430 + gz_statep state; 1.431 + 1.432 + /* get internal structure */ 1.433 + if (file == NULL) 1.434 + return -1; 1.435 + state = (gz_statep)file; 1.436 + 1.437 + /* check that we're reading and that there's no (serious) error */ 1.438 + if (state->mode != GZ_READ || 1.439 + (state->err != Z_OK && state->err != Z_BUF_ERROR)) 1.440 + return -1; 1.441 + 1.442 + /* process a skip request */ 1.443 + if (state->seek) { 1.444 + state->seek = 0; 1.445 + if (gz_skip(state, state->skip) == -1) 1.446 + return -1; 1.447 + } 1.448 + 1.449 + /* can't push EOF */ 1.450 + if (c < 0) 1.451 + return -1; 1.452 + 1.453 + /* if output buffer empty, put byte at end (allows more pushing) */ 1.454 + if (state->x.have == 0) { 1.455 + state->x.have = 1; 1.456 + state->x.next = state->out + (state->size << 1) - 1; 1.457 + state->x.next[0] = c; 1.458 + state->x.pos--; 1.459 + state->past = 0; 1.460 + return c; 1.461 + } 1.462 + 1.463 + /* if no room, give up (must have already done a gzungetc()) */ 1.464 + if (state->x.have == (state->size << 1)) { 1.465 + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); 1.466 + return -1; 1.467 + } 1.468 + 1.469 + /* slide output data if needed and insert byte before existing data */ 1.470 + if (state->x.next == state->out) { 1.471 + unsigned char *src = state->out + state->x.have; 1.472 + unsigned char *dest = state->out + (state->size << 1); 1.473 + while (src > state->out) 1.474 + *--dest = *--src; 1.475 + state->x.next = dest; 1.476 + } 1.477 + state->x.have++; 1.478 + state->x.next--; 1.479 + state->x.next[0] = c; 1.480 + state->x.pos--; 1.481 + state->past = 0; 1.482 + return c; 1.483 +} 1.484 + 1.485 +/* -- see zlib.h -- */ 1.486 +char * ZEXPORT gzgets(file, buf, len) 1.487 + gzFile file; 1.488 + char *buf; 1.489 + int len; 1.490 +{ 1.491 + unsigned left, n; 1.492 + char *str; 1.493 + unsigned char *eol; 1.494 + gz_statep state; 1.495 + 1.496 + /* check parameters and get internal structure */ 1.497 + if (file == NULL || buf == NULL || len < 1) 1.498 + return NULL; 1.499 + state = (gz_statep)file; 1.500 + 1.501 + /* check that we're reading and that there's no (serious) error */ 1.502 + if (state->mode != GZ_READ || 1.503 + (state->err != Z_OK && state->err != Z_BUF_ERROR)) 1.504 + return NULL; 1.505 + 1.506 + /* process a skip request */ 1.507 + if (state->seek) { 1.508 + state->seek = 0; 1.509 + if (gz_skip(state, state->skip) == -1) 1.510 + return NULL; 1.511 + } 1.512 + 1.513 + /* copy output bytes up to new line or len - 1, whichever comes first -- 1.514 + append a terminating zero to the string (we don't check for a zero in 1.515 + the contents, let the user worry about that) */ 1.516 + str = buf; 1.517 + left = (unsigned)len - 1; 1.518 + if (left) do { 1.519 + /* assure that something is in the output buffer */ 1.520 + if (state->x.have == 0 && gz_fetch(state) == -1) 1.521 + return NULL; /* error */ 1.522 + if (state->x.have == 0) { /* end of file */ 1.523 + state->past = 1; /* read past end */ 1.524 + break; /* return what we have */ 1.525 + } 1.526 + 1.527 + /* look for end-of-line in current output buffer */ 1.528 + n = state->x.have > left ? left : state->x.have; 1.529 + eol = (unsigned char *)memchr(state->x.next, '\n', n); 1.530 + if (eol != NULL) 1.531 + n = (unsigned)(eol - state->x.next) + 1; 1.532 + 1.533 + /* copy through end-of-line, or remainder if not found */ 1.534 + memcpy(buf, state->x.next, n); 1.535 + state->x.have -= n; 1.536 + state->x.next += n; 1.537 + state->x.pos += n; 1.538 + left -= n; 1.539 + buf += n; 1.540 + } while (left && eol == NULL); 1.541 + 1.542 + /* return terminated string, or if nothing, end of file */ 1.543 + if (buf == str) 1.544 + return NULL; 1.545 + buf[0] = 0; 1.546 + return str; 1.547 +} 1.548 + 1.549 +/* -- see zlib.h -- */ 1.550 +int ZEXPORT gzdirect(file) 1.551 + gzFile file; 1.552 +{ 1.553 + gz_statep state; 1.554 + 1.555 + /* get internal structure */ 1.556 + if (file == NULL) 1.557 + return 0; 1.558 + state = (gz_statep)file; 1.559 + 1.560 + /* if the state is not known, but we can find out, then do so (this is 1.561 + mainly for right after a gzopen() or gzdopen()) */ 1.562 + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) 1.563 + (void)gz_look(state); 1.564 + 1.565 + /* return 1 if transparent, 0 if processing a gzip stream */ 1.566 + return state->direct; 1.567 +} 1.568 + 1.569 +/* -- see zlib.h -- */ 1.570 +int ZEXPORT gzclose_r(file) 1.571 + gzFile file; 1.572 +{ 1.573 + int ret, err; 1.574 + gz_statep state; 1.575 + 1.576 + /* get internal structure */ 1.577 + if (file == NULL) 1.578 + return Z_STREAM_ERROR; 1.579 + state = (gz_statep)file; 1.580 + 1.581 + /* check that we're reading */ 1.582 + if (state->mode != GZ_READ) 1.583 + return Z_STREAM_ERROR; 1.584 + 1.585 + /* free memory and close file */ 1.586 + if (state->size) { 1.587 + inflateEnd(&(state->strm)); 1.588 + free(state->out); 1.589 + free(state->in); 1.590 + } 1.591 + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; 1.592 + gz_error(state, Z_OK, NULL); 1.593 + free(state->path); 1.594 + ret = close(state->fd); 1.595 + free(state); 1.596 + return ret ? Z_ERRNO : err; 1.597 +}