LCOV - code coverage report
Current view: top level - modules/zlib/src - gzread.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 309 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 15 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* gzread.c -- zlib functions for reading gzip files
       2             :  * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
       3             :  * For conditions of distribution and use, see copyright notice in zlib.h
       4             :  */
       5             : 
       6             : #include "gzguts.h"
       7             : 
       8             : /* Local functions */
       9             : local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
      10             : local int gz_avail OF((gz_statep));
      11             : local int gz_look OF((gz_statep));
      12             : local int gz_decomp OF((gz_statep));
      13             : local int gz_fetch OF((gz_statep));
      14             : local int gz_skip OF((gz_statep, z_off64_t));
      15             : local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
      16             : 
      17             : /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
      18             :    state->fd, and update state->eof, state->err, and state->msg as appropriate.
      19             :    This function needs to loop on read(), since read() is not guaranteed to
      20             :    read the number of bytes requested, depending on the type of descriptor. */
      21           0 : local int gz_load(state, buf, len, have)
      22             :     gz_statep state;
      23             :     unsigned char *buf;
      24             :     unsigned len;
      25             :     unsigned *have;
      26             : {
      27             :     int ret;
      28           0 :     unsigned get, max = ((unsigned)-1 >> 2) + 1;
      29             : 
      30           0 :     *have = 0;
      31             :     do {
      32           0 :         get = len - *have;
      33           0 :         if (get > max)
      34           0 :             get = max;
      35           0 :         ret = read(state->fd, buf + *have, get);
      36           0 :         if (ret <= 0)
      37           0 :             break;
      38           0 :         *have += (unsigned)ret;
      39           0 :     } while (*have < len);
      40           0 :     if (ret < 0) {
      41           0 :         gz_error(state, Z_ERRNO, zstrerror());
      42           0 :         return -1;
      43             :     }
      44           0 :     if (ret == 0)
      45           0 :         state->eof = 1;
      46           0 :     return 0;
      47             : }
      48             : 
      49             : /* Load up input buffer and set eof flag if last data loaded -- return -1 on
      50             :    error, 0 otherwise.  Note that the eof flag is set when the end of the input
      51             :    file is reached, even though there may be unused data in the buffer.  Once
      52             :    that data has been used, no more attempts will be made to read the file.
      53             :    If strm->avail_in != 0, then the current data is moved to the beginning of
      54             :    the input buffer, and then the remainder of the buffer is loaded with the
      55             :    available data from the input file. */
      56           0 : local int gz_avail(state)
      57             :     gz_statep state;
      58             : {
      59             :     unsigned got;
      60           0 :     z_streamp strm = &(state->strm);
      61             : 
      62           0 :     if (state->err != Z_OK && state->err != Z_BUF_ERROR)
      63           0 :         return -1;
      64           0 :     if (state->eof == 0) {
      65           0 :         if (strm->avail_in) {       /* copy what's there to the start */
      66           0 :             unsigned char *p = state->in;
      67           0 :             unsigned const char *q = strm->next_in;
      68           0 :             unsigned n = strm->avail_in;
      69             :             do {
      70           0 :                 *p++ = *q++;
      71           0 :             } while (--n);
      72             :         }
      73           0 :         if (gz_load(state, state->in + strm->avail_in,
      74           0 :                     state->size - strm->avail_in, &got) == -1)
      75           0 :             return -1;
      76           0 :         strm->avail_in += got;
      77           0 :         strm->next_in = state->in;
      78             :     }
      79           0 :     return 0;
      80             : }
      81             : 
      82             : /* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.
      83             :    If this is the first time in, allocate required memory.  state->how will be
      84             :    left unchanged if there is no more input data available, will be set to COPY
      85             :    if there is no gzip header and direct copying will be performed, or it will
      86             :    be set to GZIP for decompression.  If direct copying, then leftover input
      87             :    data from the input buffer will be copied to the output buffer.  In that
      88             :    case, all further file reads will be directly to either the output buffer or
      89             :    a user buffer.  If decompressing, the inflate state will be initialized.
      90             :    gz_look() will return 0 on success or -1 on failure. */
      91           0 : local int gz_look(state)
      92             :     gz_statep state;
      93             : {
      94           0 :     z_streamp strm = &(state->strm);
      95             : 
      96             :     /* allocate read buffers and inflate memory */
      97           0 :     if (state->size == 0) {
      98             :         /* allocate buffers */
      99           0 :         state->in = (unsigned char *)malloc(state->want);
     100           0 :         state->out = (unsigned char *)malloc(state->want << 1);
     101           0 :         if (state->in == NULL || state->out == NULL) {
     102           0 :             free(state->out);
     103           0 :             free(state->in);
     104           0 :             gz_error(state, Z_MEM_ERROR, "out of memory");
     105           0 :             return -1;
     106             :         }
     107           0 :         state->size = state->want;
     108             : 
     109             :         /* allocate inflate memory */
     110           0 :         state->strm.zalloc = Z_NULL;
     111           0 :         state->strm.zfree = Z_NULL;
     112           0 :         state->strm.opaque = Z_NULL;
     113           0 :         state->strm.avail_in = 0;
     114           0 :         state->strm.next_in = Z_NULL;
     115           0 :         if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */
     116           0 :             free(state->out);
     117           0 :             free(state->in);
     118           0 :             state->size = 0;
     119           0 :             gz_error(state, Z_MEM_ERROR, "out of memory");
     120           0 :             return -1;
     121             :         }
     122             :     }
     123             : 
     124             :     /* get at least the magic bytes in the input buffer */
     125           0 :     if (strm->avail_in < 2) {
     126           0 :         if (gz_avail(state) == -1)
     127           0 :             return -1;
     128           0 :         if (strm->avail_in == 0)
     129           0 :             return 0;
     130             :     }
     131             : 
     132             :     /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
     133             :        a logical dilemma here when considering the case of a partially written
     134             :        gzip file, to wit, if a single 31 byte is written, then we cannot tell
     135             :        whether this is a single-byte file, or just a partially written gzip
     136             :        file -- for here we assume that if a gzip file is being written, then
     137             :        the header will be written in a single operation, so that reading a
     138             :        single byte is sufficient indication that it is not a gzip file) */
     139           0 :     if (strm->avail_in > 1 &&
     140           0 :             strm->next_in[0] == 31 && strm->next_in[1] == 139) {
     141           0 :         inflateReset(strm);
     142           0 :         state->how = GZIP;
     143           0 :         state->direct = 0;
     144           0 :         return 0;
     145             :     }
     146             : 
     147             :     /* no gzip header -- if we were decoding gzip before, then this is trailing
     148             :        garbage.  Ignore the trailing garbage and finish. */
     149           0 :     if (state->direct == 0) {
     150           0 :         strm->avail_in = 0;
     151           0 :         state->eof = 1;
     152           0 :         state->x.have = 0;
     153           0 :         return 0;
     154             :     }
     155             : 
     156             :     /* doing raw i/o, copy any leftover input to output -- this assumes that
     157             :        the output buffer is larger than the input buffer, which also assures
     158             :        space for gzungetc() */
     159           0 :     state->x.next = state->out;
     160           0 :     if (strm->avail_in) {
     161           0 :         memcpy(state->x.next, strm->next_in, strm->avail_in);
     162           0 :         state->x.have = strm->avail_in;
     163           0 :         strm->avail_in = 0;
     164             :     }
     165           0 :     state->how = COPY;
     166           0 :     state->direct = 1;
     167           0 :     return 0;
     168             : }
     169             : 
     170             : /* Decompress from input to the provided next_out and avail_out in the state.
     171             :    On return, state->x.have and state->x.next point to the just decompressed
     172             :    data.  If the gzip stream completes, state->how is reset to LOOK to look for
     173             :    the next gzip stream or raw data, once state->x.have is depleted.  Returns 0
     174             :    on success, -1 on failure. */
     175           0 : local int gz_decomp(state)
     176             :     gz_statep state;
     177             : {
     178           0 :     int ret = Z_OK;
     179             :     unsigned had;
     180           0 :     z_streamp strm = &(state->strm);
     181             : 
     182             :     /* fill output buffer up to end of deflate stream */
     183           0 :     had = strm->avail_out;
     184             :     do {
     185             :         /* get more input for inflate() */
     186           0 :         if (strm->avail_in == 0 && gz_avail(state) == -1)
     187           0 :             return -1;
     188           0 :         if (strm->avail_in == 0) {
     189           0 :             gz_error(state, Z_BUF_ERROR, "unexpected end of file");
     190           0 :             break;
     191             :         }
     192             : 
     193             :         /* decompress and handle errors */
     194           0 :         ret = inflate(strm, Z_NO_FLUSH);
     195           0 :         if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
     196           0 :             gz_error(state, Z_STREAM_ERROR,
     197             :                      "internal error: inflate stream corrupt");
     198           0 :             return -1;
     199             :         }
     200           0 :         if (ret == Z_MEM_ERROR) {
     201           0 :             gz_error(state, Z_MEM_ERROR, "out of memory");
     202           0 :             return -1;
     203             :         }
     204           0 :         if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */
     205           0 :             gz_error(state, Z_DATA_ERROR,
     206           0 :                      strm->msg == NULL ? "compressed data error" : strm->msg);
     207           0 :             return -1;
     208             :         }
     209           0 :     } while (strm->avail_out && ret != Z_STREAM_END);
     210             : 
     211             :     /* update available output */
     212           0 :     state->x.have = had - strm->avail_out;
     213           0 :     state->x.next = strm->next_out - state->x.have;
     214             : 
     215             :     /* if the gzip stream completed successfully, look for another */
     216           0 :     if (ret == Z_STREAM_END)
     217           0 :         state->how = LOOK;
     218             : 
     219             :     /* good decompression */
     220           0 :     return 0;
     221             : }
     222             : 
     223             : /* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.
     224             :    Data is either copied from the input file or decompressed from the input
     225             :    file depending on state->how.  If state->how is LOOK, then a gzip header is
     226             :    looked for to determine whether to copy or decompress.  Returns -1 on error,
     227             :    otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
     228             :    end of the input file has been reached and all data has been processed.  */
     229           0 : local int gz_fetch(state)
     230             :     gz_statep state;
     231             : {
     232           0 :     z_streamp strm = &(state->strm);
     233             : 
     234             :     do {
     235           0 :         switch(state->how) {
     236             :         case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */
     237           0 :             if (gz_look(state) == -1)
     238           0 :                 return -1;
     239           0 :             if (state->how == LOOK)
     240           0 :                 return 0;
     241           0 :             break;
     242             :         case COPY:      /* -> COPY */
     243           0 :             if (gz_load(state, state->out, state->size << 1, &(state->x.have))
     244             :                     == -1)
     245           0 :                 return -1;
     246           0 :             state->x.next = state->out;
     247           0 :             return 0;
     248             :         case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */
     249           0 :             strm->avail_out = state->size << 1;
     250           0 :             strm->next_out = state->out;
     251           0 :             if (gz_decomp(state) == -1)
     252           0 :                 return -1;
     253             :         }
     254           0 :     } while (state->x.have == 0 && (!state->eof || strm->avail_in));
     255           0 :     return 0;
     256             : }
     257             : 
     258             : /* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */
     259           0 : local int gz_skip(state, len)
     260             :     gz_statep state;
     261             :     z_off64_t len;
     262             : {
     263             :     unsigned n;
     264             : 
     265             :     /* skip over len bytes or reach end-of-file, whichever comes first */
     266           0 :     while (len)
     267             :         /* skip over whatever is in output buffer */
     268           0 :         if (state->x.have) {
     269           0 :             n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
     270           0 :                 (unsigned)len : state->x.have;
     271           0 :             state->x.have -= n;
     272           0 :             state->x.next += n;
     273           0 :             state->x.pos += n;
     274           0 :             len -= n;
     275             :         }
     276             : 
     277             :         /* output buffer empty -- return if we're at the end of the input */
     278           0 :         else if (state->eof && state->strm.avail_in == 0)
     279             :             break;
     280             : 
     281             :         /* need more data to skip -- load up output buffer */
     282             :         else {
     283             :             /* get more output, looking for header if required */
     284           0 :             if (gz_fetch(state) == -1)
     285           0 :                 return -1;
     286             :         }
     287           0 :     return 0;
     288             : }
     289             : 
     290             : /* Read len bytes into buf from file, or less than len up to the end of the
     291             :    input.  Return the number of bytes read.  If zero is returned, either the
     292             :    end of file was reached, or there was an error.  state->err must be
     293             :    consulted in that case to determine which. */
     294           0 : local z_size_t gz_read(state, buf, len)
     295             :     gz_statep state;
     296             :     voidp buf;
     297             :     z_size_t len;
     298             : {
     299             :     z_size_t got;
     300             :     unsigned n;
     301             : 
     302             :     /* if len is zero, avoid unnecessary operations */
     303           0 :     if (len == 0)
     304           0 :         return 0;
     305             : 
     306             :     /* process a skip request */
     307           0 :     if (state->seek) {
     308           0 :         state->seek = 0;
     309           0 :         if (gz_skip(state, state->skip) == -1)
     310           0 :             return 0;
     311             :     }
     312             : 
     313             :     /* get len bytes to buf, or less than len if at the end */
     314           0 :     got = 0;
     315             :     do {
     316             :         /* set n to the maximum amount of len that fits in an unsigned int */
     317           0 :         n = -1;
     318           0 :         if (n > len)
     319           0 :             n = len;
     320             : 
     321             :         /* first just try copying data from the output buffer */
     322           0 :         if (state->x.have) {
     323           0 :             if (state->x.have < n)
     324           0 :                 n = state->x.have;
     325           0 :             memcpy(buf, state->x.next, n);
     326           0 :             state->x.next += n;
     327           0 :             state->x.have -= n;
     328             :         }
     329             : 
     330             :         /* output buffer empty -- return if we're at the end of the input */
     331           0 :         else if (state->eof && state->strm.avail_in == 0) {
     332           0 :             state->past = 1;        /* tried to read past end */
     333           0 :             break;
     334             :         }
     335             : 
     336             :         /* need output data -- for small len or new stream load up our output
     337             :            buffer */
     338           0 :         else if (state->how == LOOK || n < (state->size << 1)) {
     339             :             /* get more output, looking for header if required */
     340           0 :             if (gz_fetch(state) == -1)
     341           0 :                 return 0;
     342           0 :             continue;       /* no progress yet -- go back to copy above */
     343             :             /* the copy above assures that we will leave with space in the
     344             :                output buffer, allowing at least one gzungetc() to succeed */
     345             :         }
     346             : 
     347             :         /* large len -- read directly into user buffer */
     348           0 :         else if (state->how == COPY) {      /* read directly */
     349           0 :             if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
     350           0 :                 return 0;
     351             :         }
     352             : 
     353             :         /* large len -- decompress directly into user buffer */
     354             :         else {  /* state->how == GZIP */
     355           0 :             state->strm.avail_out = n;
     356           0 :             state->strm.next_out = (unsigned char *)buf;
     357           0 :             if (gz_decomp(state) == -1)
     358           0 :                 return 0;
     359           0 :             n = state->x.have;
     360           0 :             state->x.have = 0;
     361             :         }
     362             : 
     363             :         /* update progress */
     364           0 :         len -= n;
     365           0 :         buf = (char *)buf + n;
     366           0 :         got += n;
     367           0 :         state->x.pos += n;
     368           0 :     } while (len);
     369             : 
     370             :     /* return number of bytes read into user buffer */
     371           0 :     return got;
     372             : }
     373             : 
     374             : /* -- see zlib.h -- */
     375           0 : int ZEXPORT gzread(file, buf, len)
     376             :     gzFile file;
     377             :     voidp buf;
     378             :     unsigned len;
     379             : {
     380             :     gz_statep state;
     381             : 
     382             :     /* get internal structure */
     383           0 :     if (file == NULL)
     384           0 :         return -1;
     385           0 :     state = (gz_statep)file;
     386             : 
     387             :     /* check that we're reading and that there's no (serious) error */
     388           0 :     if (state->mode != GZ_READ ||
     389           0 :             (state->err != Z_OK && state->err != Z_BUF_ERROR))
     390           0 :         return -1;
     391             : 
     392             :     /* since an int is returned, make sure len fits in one, otherwise return
     393             :        with an error (this avoids a flaw in the interface) */
     394           0 :     if ((int)len < 0) {
     395           0 :         gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
     396           0 :         return -1;
     397             :     }
     398             : 
     399             :     /* read len or fewer bytes to buf */
     400           0 :     len = gz_read(state, buf, len);
     401             : 
     402             :     /* check for an error */
     403           0 :     if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
     404           0 :         return -1;
     405             : 
     406             :     /* return the number of bytes read (this is assured to fit in an int) */
     407           0 :     return (int)len;
     408             : }
     409             : 
     410             : /* -- see zlib.h -- */
     411           0 : z_size_t ZEXPORT gzfread(buf, size, nitems, file)
     412             :     voidp buf;
     413             :     z_size_t size;
     414             :     z_size_t nitems;
     415             :     gzFile file;
     416             : {
     417             :     z_size_t len;
     418             :     gz_statep state;
     419             : 
     420             :     /* get internal structure */
     421           0 :     if (file == NULL)
     422           0 :         return 0;
     423           0 :     state = (gz_statep)file;
     424             : 
     425             :     /* check that we're reading and that there's no (serious) error */
     426           0 :     if (state->mode != GZ_READ ||
     427           0 :             (state->err != Z_OK && state->err != Z_BUF_ERROR))
     428           0 :         return 0;
     429             : 
     430             :     /* compute bytes to read -- error on overflow */
     431           0 :     len = nitems * size;
     432           0 :     if (size && len / size != nitems) {
     433           0 :         gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
     434           0 :         return 0;
     435             :     }
     436             : 
     437             :     /* read len or fewer bytes to buf, return the number of full items read */
     438           0 :     return len ? gz_read(state, buf, len) / size : 0;
     439             : }
     440             : 
     441             : /* -- see zlib.h -- */
     442             : #ifdef Z_PREFIX_SET
     443             : #  undef z_gzgetc
     444             : #else
     445             : #  undef gzgetc
     446             : #endif
     447           0 : int ZEXPORT gzgetc(file)
     448             :     gzFile file;
     449             : {
     450             :     int ret;
     451             :     unsigned char buf[1];
     452             :     gz_statep state;
     453             : 
     454             :     /* get internal structure */
     455           0 :     if (file == NULL)
     456           0 :         return -1;
     457           0 :     state = (gz_statep)file;
     458             : 
     459             :     /* check that we're reading and that there's no (serious) error */
     460           0 :     if (state->mode != GZ_READ ||
     461           0 :         (state->err != Z_OK && state->err != Z_BUF_ERROR))
     462           0 :         return -1;
     463             : 
     464             :     /* try output buffer (no need to check for skip request) */
     465           0 :     if (state->x.have) {
     466           0 :         state->x.have--;
     467           0 :         state->x.pos++;
     468           0 :         return *(state->x.next)++;
     469             :     }
     470             : 
     471             :     /* nothing there -- try gz_read() */
     472           0 :     ret = gz_read(state, buf, 1);
     473           0 :     return ret < 1 ? -1 : buf[0];
     474             : }
     475             : 
     476           0 : int ZEXPORT gzgetc_(file)
     477             : gzFile file;
     478             : {
     479           0 :     return gzgetc(file);
     480             : }
     481             : 
     482             : /* -- see zlib.h -- */
     483           0 : int ZEXPORT gzungetc(c, file)
     484             :     int c;
     485             :     gzFile file;
     486             : {
     487             :     gz_statep state;
     488             : 
     489             :     /* get internal structure */
     490           0 :     if (file == NULL)
     491           0 :         return -1;
     492           0 :     state = (gz_statep)file;
     493             : 
     494             :     /* check that we're reading and that there's no (serious) error */
     495           0 :     if (state->mode != GZ_READ ||
     496           0 :         (state->err != Z_OK && state->err != Z_BUF_ERROR))
     497           0 :         return -1;
     498             : 
     499             :     /* process a skip request */
     500           0 :     if (state->seek) {
     501           0 :         state->seek = 0;
     502           0 :         if (gz_skip(state, state->skip) == -1)
     503           0 :             return -1;
     504             :     }
     505             : 
     506             :     /* can't push EOF */
     507           0 :     if (c < 0)
     508           0 :         return -1;
     509             : 
     510             :     /* if output buffer empty, put byte at end (allows more pushing) */
     511           0 :     if (state->x.have == 0) {
     512           0 :         state->x.have = 1;
     513           0 :         state->x.next = state->out + (state->size << 1) - 1;
     514           0 :         state->x.next[0] = (unsigned char)c;
     515           0 :         state->x.pos--;
     516           0 :         state->past = 0;
     517           0 :         return c;
     518             :     }
     519             : 
     520             :     /* if no room, give up (must have already done a gzungetc()) */
     521           0 :     if (state->x.have == (state->size << 1)) {
     522           0 :         gz_error(state, Z_DATA_ERROR, "out of room to push characters");
     523           0 :         return -1;
     524             :     }
     525             : 
     526             :     /* slide output data if needed and insert byte before existing data */
     527           0 :     if (state->x.next == state->out) {
     528           0 :         unsigned char *src = state->out + state->x.have;
     529           0 :         unsigned char *dest = state->out + (state->size << 1);
     530           0 :         while (src > state->out)
     531           0 :             *--dest = *--src;
     532           0 :         state->x.next = dest;
     533             :     }
     534           0 :     state->x.have++;
     535           0 :     state->x.next--;
     536           0 :     state->x.next[0] = (unsigned char)c;
     537           0 :     state->x.pos--;
     538           0 :     state->past = 0;
     539           0 :     return c;
     540             : }
     541             : 
     542             : /* -- see zlib.h -- */
     543           0 : char * ZEXPORT gzgets(file, buf, len)
     544             :     gzFile file;
     545             :     char *buf;
     546             :     int len;
     547             : {
     548             :     unsigned left, n;
     549             :     char *str;
     550             :     unsigned char *eol;
     551             :     gz_statep state;
     552             : 
     553             :     /* check parameters and get internal structure */
     554           0 :     if (file == NULL || buf == NULL || len < 1)
     555           0 :         return NULL;
     556           0 :     state = (gz_statep)file;
     557             : 
     558             :     /* check that we're reading and that there's no (serious) error */
     559           0 :     if (state->mode != GZ_READ ||
     560           0 :         (state->err != Z_OK && state->err != Z_BUF_ERROR))
     561           0 :         return NULL;
     562             : 
     563             :     /* process a skip request */
     564           0 :     if (state->seek) {
     565           0 :         state->seek = 0;
     566           0 :         if (gz_skip(state, state->skip) == -1)
     567           0 :             return NULL;
     568             :     }
     569             : 
     570             :     /* copy output bytes up to new line or len - 1, whichever comes first --
     571             :        append a terminating zero to the string (we don't check for a zero in
     572             :        the contents, let the user worry about that) */
     573           0 :     str = buf;
     574           0 :     left = (unsigned)len - 1;
     575           0 :     if (left) do {
     576             :         /* assure that something is in the output buffer */
     577           0 :         if (state->x.have == 0 && gz_fetch(state) == -1)
     578           0 :             return NULL;                /* error */
     579           0 :         if (state->x.have == 0) {       /* end of file */
     580           0 :             state->past = 1;            /* read past end */
     581           0 :             break;                      /* return what we have */
     582             :         }
     583             : 
     584             :         /* look for end-of-line in current output buffer */
     585           0 :         n = state->x.have > left ? left : state->x.have;
     586           0 :         eol = (unsigned char *)memchr(state->x.next, '\n', n);
     587           0 :         if (eol != NULL)
     588           0 :             n = (unsigned)(eol - state->x.next) + 1;
     589             : 
     590             :         /* copy through end-of-line, or remainder if not found */
     591           0 :         memcpy(buf, state->x.next, n);
     592           0 :         state->x.have -= n;
     593           0 :         state->x.next += n;
     594           0 :         state->x.pos += n;
     595           0 :         left -= n;
     596           0 :         buf += n;
     597           0 :     } while (left && eol == NULL);
     598             : 
     599             :     /* return terminated string, or if nothing, end of file */
     600           0 :     if (buf == str)
     601           0 :         return NULL;
     602           0 :     buf[0] = 0;
     603           0 :     return str;
     604             : }
     605             : 
     606             : /* -- see zlib.h -- */
     607           0 : int ZEXPORT gzdirect(file)
     608             :     gzFile file;
     609             : {
     610             :     gz_statep state;
     611             : 
     612             :     /* get internal structure */
     613           0 :     if (file == NULL)
     614           0 :         return 0;
     615           0 :     state = (gz_statep)file;
     616             : 
     617             :     /* if the state is not known, but we can find out, then do so (this is
     618             :        mainly for right after a gzopen() or gzdopen()) */
     619           0 :     if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
     620           0 :         (void)gz_look(state);
     621             : 
     622             :     /* return 1 if transparent, 0 if processing a gzip stream */
     623           0 :     return state->direct;
     624             : }
     625             : 
     626             : /* -- see zlib.h -- */
     627           0 : int ZEXPORT gzclose_r(file)
     628             :     gzFile file;
     629             : {
     630             :     int ret, err;
     631             :     gz_statep state;
     632             : 
     633             :     /* get internal structure */
     634           0 :     if (file == NULL)
     635           0 :         return Z_STREAM_ERROR;
     636           0 :     state = (gz_statep)file;
     637             : 
     638             :     /* check that we're reading */
     639           0 :     if (state->mode != GZ_READ)
     640           0 :         return Z_STREAM_ERROR;
     641             : 
     642             :     /* free memory and close file */
     643           0 :     if (state->size) {
     644           0 :         inflateEnd(&(state->strm));
     645           0 :         free(state->out);
     646           0 :         free(state->in);
     647             :     }
     648           0 :     err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
     649           0 :     gz_error(state, Z_OK, NULL);
     650           0 :     free(state->path);
     651           0 :     ret = close(state->fd);
     652           0 :     free(state);
     653           0 :     return ret ? Z_ERRNO : err;
     654             : }

Generated by: LCOV version 1.13