#include "gzip.h" #include <stdio.h> #include <stdlib.h> #include <string.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) { 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; } bool is_gzip(FILE* F) { unsigned char magic[2]; bool b = !fseek(F, 0, SEEK_SET) && fread(magic, 1, 2, F) == 2 && magic[0] == 0x1F && magic[1] == 0x8B; fseek(F, 0, SEEK_SET); return b; }