jdk/src/share/native/java/util/zip/zlib-1.2.5/gzread.c
changeset 24714 e2e5f24869d5
parent 24684 33d6a56861bb
parent 24713 5451c8499988
child 24715 67f8ba8e7841
equal deleted inserted replaced
24684:33d6a56861bb 24714:e2e5f24869d5
     1 /*
       
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     3  *
       
     4  * This code is free software; you can redistribute it and/or modify it
       
     5  * under the terms of the GNU General Public License version 2 only, as
       
     6  * published by the Free Software Foundation.  Oracle designates this
       
     7  * particular file as subject to the "Classpath" exception as provided
       
     8  * by Oracle in the LICENSE file that accompanied this code.
       
     9  *
       
    10  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    13  * version 2 for more details (a copy is included in the LICENSE file that
       
    14  * accompanied this code).
       
    15  *
       
    16  * You should have received a copy of the GNU General Public License version
       
    17  * 2 along with this work; if not, write to the Free Software Foundation,
       
    18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    19  *
       
    20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    21  * or visit www.oracle.com if you need additional information or have any
       
    22  * questions.
       
    23  */
       
    24 
       
    25 /* gzread.c -- zlib functions for reading gzip files
       
    26  * Copyright (C) 2004, 2005, 2010 Mark Adler
       
    27  * For conditions of distribution and use, see copyright notice in zlib.h
       
    28  */
       
    29 
       
    30 #include "gzguts.h"
       
    31 
       
    32 /* Local functions */
       
    33 local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
       
    34 local int gz_avail OF((gz_statep));
       
    35 local int gz_next4 OF((gz_statep, unsigned long *));
       
    36 local int gz_head OF((gz_statep));
       
    37 local int gz_decomp OF((gz_statep));
       
    38 local int gz_make OF((gz_statep));
       
    39 local int gz_skip OF((gz_statep, z_off64_t));
       
    40 
       
    41 /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
       
    42    state->fd, and update state->eof, state->err, and state->msg as appropriate.
       
    43    This function needs to loop on read(), since read() is not guaranteed to
       
    44    read the number of bytes requested, depending on the type of descriptor. */
       
    45 local int gz_load(state, buf, len, have)
       
    46     gz_statep state;
       
    47     unsigned char *buf;
       
    48     unsigned len;
       
    49     unsigned *have;
       
    50 {
       
    51     int ret;
       
    52 
       
    53     *have = 0;
       
    54     do {
       
    55         ret = read(state->fd, buf + *have, len - *have);
       
    56         if (ret <= 0)
       
    57             break;
       
    58         *have += ret;
       
    59     } while (*have < len);
       
    60     if (ret < 0) {
       
    61         gz_error(state, Z_ERRNO, zstrerror());
       
    62         return -1;
       
    63     }
       
    64     if (ret == 0)
       
    65         state->eof = 1;
       
    66     return 0;
       
    67 }
       
    68 
       
    69 /* Load up input buffer and set eof flag if last data loaded -- return -1 on
       
    70    error, 0 otherwise.  Note that the eof flag is set when the end of the input
       
    71    file is reached, even though there may be unused data in the buffer.  Once
       
    72    that data has been used, no more attempts will be made to read the file.
       
    73    gz_avail() assumes that strm->avail_in == 0. */
       
    74 local int gz_avail(state)
       
    75     gz_statep state;
       
    76 {
       
    77     z_streamp strm = &(state->strm);
       
    78 
       
    79     if (state->err != Z_OK)
       
    80         return -1;
       
    81     if (state->eof == 0) {
       
    82         if (gz_load(state, state->in, state->size,
       
    83                 (unsigned *)&(strm->avail_in)) == -1)
       
    84             return -1;
       
    85         strm->next_in = state->in;
       
    86     }
       
    87     return 0;
       
    88 }
       
    89 
       
    90 /* Get next byte from input, or -1 if end or error. */
       
    91 #define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \
       
    92                 (strm->avail_in == 0 ? -1 : \
       
    93                  (strm->avail_in--, *(strm->next_in)++)))
       
    94 
       
    95 /* Get a four-byte little-endian integer and return 0 on success and the value
       
    96    in *ret.  Otherwise -1 is returned and *ret is not modified. */
       
    97 local int gz_next4(state, ret)
       
    98     gz_statep state;
       
    99     unsigned long *ret;
       
   100 {
       
   101     int ch;
       
   102     unsigned long val;
       
   103     z_streamp strm = &(state->strm);
       
   104 
       
   105     val = NEXT();
       
   106     val += (unsigned)NEXT() << 8;
       
   107     val += (unsigned long)NEXT() << 16;
       
   108     ch = NEXT();
       
   109     if (ch == -1)
       
   110         return -1;
       
   111     val += (unsigned long)ch << 24;
       
   112     *ret = val;
       
   113     return 0;
       
   114 }
       
   115 
       
   116 /* Look for gzip header, set up for inflate or copy.  state->have must be zero.
       
   117    If this is the first time in, allocate required memory.  state->how will be
       
   118    left unchanged if there is no more input data available, will be set to COPY
       
   119    if there is no gzip header and direct copying will be performed, or it will
       
   120    be set to GZIP for decompression, and the gzip header will be skipped so
       
   121    that the next available input data is the raw deflate stream.  If direct
       
   122    copying, then leftover input data from the input buffer will be copied to
       
   123    the output buffer.  In that case, all further file reads will be directly to
       
   124    either the output buffer or a user buffer.  If decompressing, the inflate
       
   125    state and the check value will be initialized.  gz_head() will return 0 on
       
   126    success or -1 on failure.  Failures may include read errors or gzip header
       
   127    errors.  */
       
   128 local int gz_head(state)
       
   129     gz_statep state;
       
   130 {
       
   131     z_streamp strm = &(state->strm);
       
   132     int flags;
       
   133     unsigned len;
       
   134 
       
   135     /* allocate read buffers and inflate memory */
       
   136     if (state->size == 0) {
       
   137         /* allocate buffers */
       
   138         state->in = malloc(state->want);
       
   139         state->out = malloc(state->want << 1);
       
   140         if (state->in == NULL || state->out == NULL) {
       
   141             if (state->out != NULL)
       
   142                 free(state->out);
       
   143             if (state->in != NULL)
       
   144                 free(state->in);
       
   145             gz_error(state, Z_MEM_ERROR, "out of memory");
       
   146             return -1;
       
   147         }
       
   148         state->size = state->want;
       
   149 
       
   150         /* allocate inflate memory */
       
   151         state->strm.zalloc = Z_NULL;
       
   152         state->strm.zfree = Z_NULL;
       
   153         state->strm.opaque = Z_NULL;
       
   154         state->strm.avail_in = 0;
       
   155         state->strm.next_in = Z_NULL;
       
   156         if (inflateInit2(&(state->strm), -15) != Z_OK) {    /* raw inflate */
       
   157             free(state->out);
       
   158             free(state->in);
       
   159             state->size = 0;
       
   160             gz_error(state, Z_MEM_ERROR, "out of memory");
       
   161             return -1;
       
   162         }
       
   163     }
       
   164 
       
   165     /* get some data in the input buffer */
       
   166     if (strm->avail_in == 0) {
       
   167         if (gz_avail(state) == -1)
       
   168             return -1;
       
   169         if (strm->avail_in == 0)
       
   170             return 0;
       
   171     }
       
   172 
       
   173     /* look for the gzip magic header bytes 31 and 139 */
       
   174     if (strm->next_in[0] == 31) {
       
   175         strm->avail_in--;
       
   176         strm->next_in++;
       
   177         if (strm->avail_in == 0 && gz_avail(state) == -1)
       
   178             return -1;
       
   179         if (strm->avail_in && strm->next_in[0] == 139) {
       
   180             /* we have a gzip header, woo hoo! */
       
   181             strm->avail_in--;
       
   182             strm->next_in++;
       
   183 
       
   184             /* skip rest of header */
       
   185             if (NEXT() != 8) {      /* compression method */
       
   186                 gz_error(state, Z_DATA_ERROR, "unknown compression method");
       
   187                 return -1;
       
   188             }
       
   189             flags = NEXT();
       
   190             if (flags & 0xe0) {     /* reserved flag bits */
       
   191                 gz_error(state, Z_DATA_ERROR, "unknown header flags set");
       
   192                 return -1;
       
   193             }
       
   194             NEXT();                 /* modification time */
       
   195             NEXT();
       
   196             NEXT();
       
   197             NEXT();
       
   198             NEXT();                 /* extra flags */
       
   199             NEXT();                 /* operating system */
       
   200             if (flags & 4) {        /* extra field */
       
   201                 len = (unsigned)NEXT();
       
   202                 len += (unsigned)NEXT() << 8;
       
   203                 while (len--)
       
   204                     if (NEXT() < 0)
       
   205                         break;
       
   206             }
       
   207             if (flags & 8)          /* file name */
       
   208                 while (NEXT() > 0)
       
   209                     ;
       
   210             if (flags & 16)         /* comment */
       
   211                 while (NEXT() > 0)
       
   212                     ;
       
   213             if (flags & 2) {        /* header crc */
       
   214                 NEXT();
       
   215                 NEXT();
       
   216             }
       
   217             /* an unexpected end of file is not checked for here -- it will be
       
   218                noticed on the first request for uncompressed data */
       
   219 
       
   220             /* set up for decompression */
       
   221             inflateReset(strm);
       
   222             strm->adler = crc32(0L, Z_NULL, 0);
       
   223             state->how = GZIP;
       
   224             state->direct = 0;
       
   225             return 0;
       
   226         }
       
   227         else {
       
   228             /* not a gzip file -- save first byte (31) and fall to raw i/o */
       
   229             state->out[0] = 31;
       
   230             state->have = 1;
       
   231         }
       
   232     }
       
   233 
       
   234     /* doing raw i/o, save start of raw data for seeking, copy any leftover
       
   235        input to output -- this assumes that the output buffer is larger than
       
   236        the input buffer, which also assures space for gzungetc() */
       
   237     state->raw = state->pos;
       
   238     state->next = state->out;
       
   239     if (strm->avail_in) {
       
   240         memcpy(state->next + state->have, strm->next_in, strm->avail_in);
       
   241         state->have += strm->avail_in;
       
   242         strm->avail_in = 0;
       
   243     }
       
   244     state->how = COPY;
       
   245     state->direct = 1;
       
   246     return 0;
       
   247 }
       
   248 
       
   249 /* Decompress from input to the provided next_out and avail_out in the state.
       
   250    If the end of the compressed data is reached, then verify the gzip trailer
       
   251    check value and length (modulo 2^32).  state->have and state->next are set
       
   252    to point to the just decompressed data, and the crc is updated.  If the
       
   253    trailer is verified, state->how is reset to LOOK to look for the next gzip
       
   254    stream or raw data, once state->have is depleted.  Returns 0 on success, -1
       
   255    on failure.  Failures may include invalid compressed data or a failed gzip
       
   256    trailer verification. */
       
   257 local int gz_decomp(state)
       
   258     gz_statep state;
       
   259 {
       
   260     int ret;
       
   261     unsigned had;
       
   262     unsigned long crc, len;
       
   263     z_streamp strm = &(state->strm);
       
   264 
       
   265     /* fill output buffer up to end of deflate stream */
       
   266     had = strm->avail_out;
       
   267     do {
       
   268         /* get more input for inflate() */
       
   269         if (strm->avail_in == 0 && gz_avail(state) == -1)
       
   270             return -1;
       
   271         if (strm->avail_in == 0) {
       
   272             gz_error(state, Z_DATA_ERROR, "unexpected end of file");
       
   273             return -1;
       
   274         }
       
   275 
       
   276         /* decompress and handle errors */
       
   277         ret = inflate(strm, Z_NO_FLUSH);
       
   278         if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
       
   279             gz_error(state, Z_STREAM_ERROR,
       
   280                       "internal error: inflate stream corrupt");
       
   281             return -1;
       
   282         }
       
   283         if (ret == Z_MEM_ERROR) {
       
   284             gz_error(state, Z_MEM_ERROR, "out of memory");
       
   285             return -1;
       
   286         }
       
   287         if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */
       
   288             gz_error(state, Z_DATA_ERROR,
       
   289                       strm->msg == NULL ? "compressed data error" : strm->msg);
       
   290             return -1;
       
   291         }
       
   292     } while (strm->avail_out && ret != Z_STREAM_END);
       
   293 
       
   294     /* update available output and crc check value */
       
   295     state->have = had - strm->avail_out;
       
   296     state->next = strm->next_out - state->have;
       
   297     strm->adler = crc32(strm->adler, state->next, state->have);
       
   298 
       
   299     /* check gzip trailer if at end of deflate stream */
       
   300     if (ret == Z_STREAM_END) {
       
   301         if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) {
       
   302             gz_error(state, Z_DATA_ERROR, "unexpected end of file");
       
   303             return -1;
       
   304         }
       
   305         if (crc != strm->adler) {
       
   306             gz_error(state, Z_DATA_ERROR, "incorrect data check");
       
   307             return -1;
       
   308         }
       
   309         if (len != (strm->total_out & 0xffffffffL)) {
       
   310             gz_error(state, Z_DATA_ERROR, "incorrect length check");
       
   311             return -1;
       
   312         }
       
   313         state->how = LOOK;      /* ready for next stream, once have is 0 (leave
       
   314                                    state->direct unchanged to remember how) */
       
   315     }
       
   316 
       
   317     /* good decompression */
       
   318     return 0;
       
   319 }
       
   320 
       
   321 /* Make data and put in the output buffer.  Assumes that state->have == 0.
       
   322    Data is either copied from the input file or decompressed from the input
       
   323    file depending on state->how.  If state->how is LOOK, then a gzip header is
       
   324    looked for (and skipped if found) to determine wither to copy or decompress.
       
   325    Returns -1 on error, otherwise 0.  gz_make() will leave state->have as COPY
       
   326    or GZIP unless the end of the input file has been reached and all data has
       
   327    been processed.  */
       
   328 local int gz_make(state)
       
   329     gz_statep state;
       
   330 {
       
   331     z_streamp strm = &(state->strm);
       
   332 
       
   333     if (state->how == LOOK) {           /* look for gzip header */
       
   334         if (gz_head(state) == -1)
       
   335             return -1;
       
   336         if (state->have)                /* got some data from gz_head() */
       
   337             return 0;
       
   338     }
       
   339     if (state->how == COPY) {           /* straight copy */
       
   340         if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)
       
   341             return -1;
       
   342         state->next = state->out;
       
   343     }
       
   344     else if (state->how == GZIP) {      /* decompress */
       
   345         strm->avail_out = state->size << 1;
       
   346         strm->next_out = state->out;
       
   347         if (gz_decomp(state) == -1)
       
   348             return -1;
       
   349     }
       
   350     return 0;
       
   351 }
       
   352 
       
   353 /* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */
       
   354 local int gz_skip(state, len)
       
   355     gz_statep state;
       
   356     z_off64_t len;
       
   357 {
       
   358     unsigned n;
       
   359 
       
   360     /* skip over len bytes or reach end-of-file, whichever comes first */
       
   361     while (len)
       
   362         /* skip over whatever is in output buffer */
       
   363         if (state->have) {
       
   364             n = GT_OFF(state->have) || (z_off64_t)state->have > len ?
       
   365                 (unsigned)len : state->have;
       
   366             state->have -= n;
       
   367             state->next += n;
       
   368             state->pos += n;
       
   369             len -= n;
       
   370         }
       
   371 
       
   372         /* output buffer empty -- return if we're at the end of the input */
       
   373         else if (state->eof && state->strm.avail_in == 0)
       
   374             break;
       
   375 
       
   376         /* need more data to skip -- load up output buffer */
       
   377         else {
       
   378             /* get more output, looking for header if required */
       
   379             if (gz_make(state) == -1)
       
   380                 return -1;
       
   381         }
       
   382     return 0;
       
   383 }
       
   384 
       
   385 /* -- see zlib.h -- */
       
   386 int ZEXPORT gzread(file, buf, len)
       
   387     gzFile file;
       
   388     voidp buf;
       
   389     unsigned len;
       
   390 {
       
   391     unsigned got, n;
       
   392     gz_statep state;
       
   393     z_streamp strm;
       
   394 
       
   395     /* get internal structure */
       
   396     if (file == NULL)
       
   397         return -1;
       
   398     state = (gz_statep)file;
       
   399     strm = &(state->strm);
       
   400 
       
   401     /* check that we're reading and that there's no error */
       
   402     if (state->mode != GZ_READ || state->err != Z_OK)
       
   403         return -1;
       
   404 
       
   405     /* since an int is returned, make sure len fits in one, otherwise return
       
   406        with an error (this avoids the flaw in the interface) */
       
   407     if ((int)len < 0) {
       
   408         gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
       
   409         return -1;
       
   410     }
       
   411 
       
   412     /* if len is zero, avoid unnecessary operations */
       
   413     if (len == 0)
       
   414         return 0;
       
   415 
       
   416     /* process a skip request */
       
   417     if (state->seek) {
       
   418         state->seek = 0;
       
   419         if (gz_skip(state, state->skip) == -1)
       
   420             return -1;
       
   421     }
       
   422 
       
   423     /* get len bytes to buf, or less than len if at the end */
       
   424     got = 0;
       
   425     do {
       
   426         /* first just try copying data from the output buffer */
       
   427         if (state->have) {
       
   428             n = state->have > len ? len : state->have;
       
   429             memcpy(buf, state->next, n);
       
   430             state->next += n;
       
   431             state->have -= n;
       
   432         }
       
   433 
       
   434         /* output buffer empty -- return if we're at the end of the input */
       
   435         else if (state->eof && strm->avail_in == 0)
       
   436             break;
       
   437 
       
   438         /* need output data -- for small len or new stream load up our output
       
   439            buffer */
       
   440         else if (state->how == LOOK || len < (state->size << 1)) {
       
   441             /* get more output, looking for header if required */
       
   442             if (gz_make(state) == -1)
       
   443                 return -1;
       
   444             continue;       /* no progress yet -- go back to memcpy() above */
       
   445             /* the copy above assures that we will leave with space in the
       
   446                output buffer, allowing at least one gzungetc() to succeed */
       
   447         }
       
   448 
       
   449         /* large len -- read directly into user buffer */
       
   450         else if (state->how == COPY) {      /* read directly */
       
   451             if (gz_load(state, buf, len, &n) == -1)
       
   452                 return -1;
       
   453         }
       
   454 
       
   455         /* large len -- decompress directly into user buffer */
       
   456         else {  /* state->how == GZIP */
       
   457             strm->avail_out = len;
       
   458             strm->next_out = buf;
       
   459             if (gz_decomp(state) == -1)
       
   460                 return -1;
       
   461             n = state->have;
       
   462             state->have = 0;
       
   463         }
       
   464 
       
   465         /* update progress */
       
   466         len -= n;
       
   467         buf = (char *)buf + n;
       
   468         got += n;
       
   469         state->pos += n;
       
   470     } while (len);
       
   471 
       
   472     /* return number of bytes read into user buffer (will fit in int) */
       
   473     return (int)got;
       
   474 }
       
   475 
       
   476 /* -- see zlib.h -- */
       
   477 int ZEXPORT gzgetc(file)
       
   478     gzFile file;
       
   479 {
       
   480     int ret;
       
   481     unsigned char buf[1];
       
   482     gz_statep state;
       
   483 
       
   484     /* get internal structure */
       
   485     if (file == NULL)
       
   486         return -1;
       
   487     state = (gz_statep)file;
       
   488 
       
   489     /* check that we're reading and that there's no error */
       
   490     if (state->mode != GZ_READ || state->err != Z_OK)
       
   491         return -1;
       
   492 
       
   493     /* try output buffer (no need to check for skip request) */
       
   494     if (state->have) {
       
   495         state->have--;
       
   496         state->pos++;
       
   497         return *(state->next)++;
       
   498     }
       
   499 
       
   500     /* nothing there -- try gzread() */
       
   501     ret = gzread(file, buf, 1);
       
   502     return ret < 1 ? -1 : buf[0];
       
   503 }
       
   504 
       
   505 /* -- see zlib.h -- */
       
   506 int ZEXPORT gzungetc(c, file)
       
   507     int c;
       
   508     gzFile file;
       
   509 {
       
   510     gz_statep state;
       
   511 
       
   512     /* get internal structure */
       
   513     if (file == NULL)
       
   514         return -1;
       
   515     state = (gz_statep)file;
       
   516 
       
   517     /* check that we're reading and that there's no error */
       
   518     if (state->mode != GZ_READ || state->err != Z_OK)
       
   519         return -1;
       
   520 
       
   521     /* process a skip request */
       
   522     if (state->seek) {
       
   523         state->seek = 0;
       
   524         if (gz_skip(state, state->skip) == -1)
       
   525             return -1;
       
   526     }
       
   527 
       
   528     /* can't push EOF */
       
   529     if (c < 0)
       
   530         return -1;
       
   531 
       
   532     /* if output buffer empty, put byte at end (allows more pushing) */
       
   533     if (state->have == 0) {
       
   534         state->have = 1;
       
   535         state->next = state->out + (state->size << 1) - 1;
       
   536         state->next[0] = c;
       
   537         state->pos--;
       
   538         return c;
       
   539     }
       
   540 
       
   541     /* if no room, give up (must have already done a gzungetc()) */
       
   542     if (state->have == (state->size << 1)) {
       
   543         gz_error(state, Z_BUF_ERROR, "out of room to push characters");
       
   544         return -1;
       
   545     }
       
   546 
       
   547     /* slide output data if needed and insert byte before existing data */
       
   548     if (state->next == state->out) {
       
   549         unsigned char *src = state->out + state->have;
       
   550         unsigned char *dest = state->out + (state->size << 1);
       
   551         while (src > state->out)
       
   552             *--dest = *--src;
       
   553         state->next = dest;
       
   554     }
       
   555     state->have++;
       
   556     state->next--;
       
   557     state->next[0] = c;
       
   558     state->pos--;
       
   559     return c;
       
   560 }
       
   561 
       
   562 /* -- see zlib.h -- */
       
   563 char * ZEXPORT gzgets(file, buf, len)
       
   564     gzFile file;
       
   565     char *buf;
       
   566     int len;
       
   567 {
       
   568     unsigned left, n;
       
   569     char *str;
       
   570     unsigned char *eol;
       
   571     gz_statep state;
       
   572 
       
   573     /* check parameters and get internal structure */
       
   574     if (file == NULL || buf == NULL || len < 1)
       
   575         return NULL;
       
   576     state = (gz_statep)file;
       
   577 
       
   578     /* check that we're reading and that there's no error */
       
   579     if (state->mode != GZ_READ || state->err != Z_OK)
       
   580         return NULL;
       
   581 
       
   582     /* process a skip request */
       
   583     if (state->seek) {
       
   584         state->seek = 0;
       
   585         if (gz_skip(state, state->skip) == -1)
       
   586             return NULL;
       
   587     }
       
   588 
       
   589     /* copy output bytes up to new line or len - 1, whichever comes first --
       
   590        append a terminating zero to the string (we don't check for a zero in
       
   591        the contents, let the user worry about that) */
       
   592     str = buf;
       
   593     left = (unsigned)len - 1;
       
   594     if (left) do {
       
   595         /* assure that something is in the output buffer */
       
   596         if (state->have == 0) {
       
   597             if (gz_make(state) == -1)
       
   598                 return NULL;            /* error */
       
   599             if (state->have == 0) {     /* end of file */
       
   600                 if (buf == str)         /* got bupkus */
       
   601                     return NULL;
       
   602                 break;                  /* got something -- return it */
       
   603             }
       
   604         }
       
   605 
       
   606         /* look for end-of-line in current output buffer */
       
   607         n = state->have > left ? left : state->have;
       
   608         eol = memchr(state->next, '\n', n);
       
   609         if (eol != NULL)
       
   610             n = (unsigned)(eol - state->next) + 1;
       
   611 
       
   612         /* copy through end-of-line, or remainder if not found */
       
   613         memcpy(buf, state->next, n);
       
   614         state->have -= n;
       
   615         state->next += n;
       
   616         state->pos += n;
       
   617         left -= n;
       
   618         buf += n;
       
   619     } while (left && eol == NULL);
       
   620 
       
   621     /* found end-of-line or out of space -- terminate string and return it */
       
   622     buf[0] = 0;
       
   623     return str;
       
   624 }
       
   625 
       
   626 /* -- see zlib.h -- */
       
   627 int ZEXPORT gzdirect(file)
       
   628     gzFile file;
       
   629 {
       
   630     gz_statep state;
       
   631 
       
   632     /* get internal structure */
       
   633     if (file == NULL)
       
   634         return 0;
       
   635     state = (gz_statep)file;
       
   636 
       
   637     /* check that we're reading */
       
   638     if (state->mode != GZ_READ)
       
   639         return 0;
       
   640 
       
   641     /* if the state is not known, but we can find out, then do so (this is
       
   642        mainly for right after a gzopen() or gzdopen()) */
       
   643     if (state->how == LOOK && state->have == 0)
       
   644         (void)gz_head(state);
       
   645 
       
   646     /* return 1 if reading direct, 0 if decompressing a gzip stream */
       
   647     return state->direct;
       
   648 }
       
   649 
       
   650 /* -- see zlib.h -- */
       
   651 int ZEXPORT gzclose_r(file)
       
   652     gzFile file;
       
   653 {
       
   654     int ret;
       
   655     gz_statep state;
       
   656 
       
   657     /* get internal structure */
       
   658     if (file == NULL)
       
   659         return Z_STREAM_ERROR;
       
   660     state = (gz_statep)file;
       
   661 
       
   662     /* check that we're reading */
       
   663     if (state->mode != GZ_READ)
       
   664         return Z_STREAM_ERROR;
       
   665 
       
   666     /* free memory and close file */
       
   667     if (state->size) {
       
   668         inflateEnd(&(state->strm));
       
   669         free(state->out);
       
   670         free(state->in);
       
   671     }
       
   672     gz_error(state, Z_OK, NULL);
       
   673     free(state->path);
       
   674     ret = close(state->fd);
       
   675     free(state);
       
   676     return ret ? Z_ERRNO : Z_OK;
       
   677 }