uLong total_in = s->stream.total_in; uLong total_out = s->stream.total_out;
int ZEXPORT gzread (file, buf, len)    gzFile file;    voidp buf;    unsigned len;{    gz_stream *s = (gz_stream*)file;    Bytef *start = (Bytef*)buf; /* starting point for crc computation */    Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */    if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;    if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;    if (s->z_err == Z_STREAM_END) return 0;  /* EOF */    next_out = (Byte*)buf;    s->stream.next_out = (Bytef*)buf;    s->stream.avail_out = len;    while (s->stream.avail_out != 0) {	if (s->transparent) {	    /* Copy first the lookahead bytes: */	    uInt n = s->stream.avail_in;	    if (n > s->stream.avail_out) n = s->stream.avail_out;	    if (n > 0) {		zmemcpy(s->stream.next_out, s->stream.next_in, n);		next_out += n;		s->stream.next_out = next_out;		s->stream.next_in   += n;		s->stream.avail_out -= n;		s->stream.avail_in  -= n;	    }	    if (s->stream.avail_out > 0) {		s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,					     s->file);	    }	    len -= s->stream.avail_out;	    s->stream.total_in  += (uLong)len;	    s->stream.total_out += (uLong)len;            if (len == 0) s->z_eof = 1;	    return (int)len;	}        if (s->stream.avail_in == 0 && !s->z_eof) {            errno = 0;            s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);            if (s->stream.avail_in == 0) {                s->z_eof = 1;		if (ferror(s->file)) {		    s->z_err = Z_ERRNO;		    break;		}            }            s->stream.next_in = s->inbuf;        }        s->z_err = inflate(&(s->stream), Z_NO_FLUSH);	if (s->z_err == Z_STREAM_END) {	    /* Check CRC and original size */	    s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));	    start = s->stream.next_out;	    if (getLong(s) != s->crc) {		s->z_err = Z_DATA_ERROR;	    } else {	        (void)getLong(s);                /* The uncompressed length returned by above getlong() may                 * be different from s->stream.total_out) in case of		 * concatenated .gz files. Check for such files:		 */		check_header(s);		if (s->z_err == Z_OK) {		    uLong total_in = s->stream.total_in;		    uLong total_out = s->stream.total_out;		    inflateReset(&(s->stream));		    s->stream.total_in = total_in;		    s->stream.total_out = total_out;		    s->crc = crc32(0L, Z_NULL, 0);		}	    }	}	if (s->z_err != Z_OK || s->z_eof) break;    }    s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));    return (int)(len - s->stream.avail_out);}