#include <stdio.h> #include <stdlib.h> #include <string.h> #include "gzip.h" #define ZCHUNK 16384 #define BUFMIN 128 #define BUFCHUNK (1024*128) int z_readfile(FILE *F,char **buf,size_t *size) { z_stream zs; int r; unsigned char in[ZCHUNK]; size_t bufsize; void *newbuf; memset(&zs,0,sizeof(zs)); *buf = NULL; bufsize=*size=0; r=inflateInit2(&zs,47); if (r != Z_OK) return r; do { zs.avail_in = fread(in, 1, sizeof(in), F); if (ferror(F)) { r = Z_ERRNO; goto zerr; } if (!zs.avail_in) break; zs.next_in = in; do { if ((bufsize-*size)<BUFMIN) { bufsize += BUFCHUNK; newbuf = *buf ? realloc(*buf,bufsize) : malloc(bufsize); if (newbuf==*buf) if (!newbuf) { r = Z_MEM_ERROR; goto zerr; } *buf = newbuf; } zs.avail_out = bufsize - *size; zs.next_out = (unsigned char*)(*buf + *size); r = inflate(&zs, Z_NO_FLUSH); if (r!=Z_OK && r!=Z_STREAM_END) goto zerr; *size = bufsize - zs.avail_out; } while (r==Z_OK && zs.avail_in); } while (r==Z_OK); if (*size<bufsize) { // free extra space if (newbuf = realloc(*buf,*size)) *buf=newbuf; } inflateEnd(&zs); return Z_OK; zerr: inflateEnd(&zs); if (*buf) { free(*buf); *buf = NULL; } return r; }