From 3d66ed53786cf9eba7e26622dc74a72bf963397b Mon Sep 17 00:00:00 2001 From: pancake Date: Sun, 10 Aug 2014 18:13:12 +0200 Subject: [PATCH] Add r_file_gzslurp() to read GZIPped files easily --- libr/util/Makefile | 8 +++++- libr/util/file.c | 11 ++++++++ libr/util/gzip.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 libr/util/gzip.c diff --git a/libr/util/Makefile b/libr/util/Makefile index 39dddeb6ed..0febd85a99 100644 --- a/libr/util/Makefile +++ b/libr/util/Makefile @@ -9,7 +9,7 @@ OBJS+=list.o flist.o ht.o ht64.o mixed.o btree.o chmod.o graph.o OBJS+=regex/regcomp.o regex/regerror.o regex/regexec.o uleb128.o OBJS+=sandbox.o calc.o thread.o lock.o strpool.o bitmap.o strht.o OBJS+=p_date.o p_format.o print.o p_seven.o slist.o randomart.o -OBJS+=utf8.o strbuf.o lib.o name.o log.o +OBJS+=utf8.o strbuf.o lib.o name.o log.o gzip.o # DO NOT BUILD r_big api (not yet used and its buggy) ifeq (1,0) @@ -24,6 +24,12 @@ else endif endif +ifeq ($(USE_LIB_ZIP),1) + LINK+=$(LIBZIP) +else + LINK+=$(SHLR)/zip/librz.a +endif + LDFLAGS+=${BN_LIBS} LDFLAGS+=${TH_LIBS} LDFLAGS+=${DL_LIBS} diff --git a/libr/util/file.c b/libr/util/file.c index 76e9a475eb..656c7a3d26 100644 --- a/libr/util/file.c +++ b/libr/util/file.c @@ -165,6 +165,17 @@ R_API char *r_file_slurp(const char *str, int *usz) { return ret; } +R_API char *r_file_gzslurp(const char *str, int *outlen) { + int sz; + char *in, *out; + if (outlen) *outlen = 0; + in = r_file_slurp (str, &sz); + if (!in) return NULL; + out = r_gunzip (in, sz, outlen); + free (in); + return out; +} + R_API ut8 *r_file_slurp_hexpairs(const char *str, int *usz) { ut8 *ret; long sz; diff --git a/libr/util/gzip.c b/libr/util/gzip.c new file mode 100644 index 0000000000..5d5b88ab90 --- /dev/null +++ b/libr/util/gzip.c @@ -0,0 +1,69 @@ +/* radare - LGPL - Copyright 2014 - pancake */ + +#include +#include + +// TODO: r_gzip + +R_API ut8 *r_gunzip(const void *src, int srcLen, int *dstLen) { + ut8 *dst = NULL, *dst2; + z_stream strm; + int tryLen = 1+(srcLen * 4); + // TODO: optimize this using an incremental method + retrygunzip: + free (dst); + if (tryLen<1) + return NULL; + memset (&strm, 0, sizeof (z_stream)); + dst = malloc (tryLen+1); + strm.total_in = strm.avail_in = srcLen; + strm.total_out = strm.avail_out = tryLen; + strm.next_in = (Bytef *) src; + strm.next_out = (Bytef *) dst; + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + + int err = -1; + int ret = -1; + + // ZLIB + //err = inflateInit2(&strm, (15 + 32)); //15 window bits, and the +32 tells zlib to to detect if using gzip or zlib + // GZIP + err = inflateInit2(&strm, 16+MAX_WBITS); + if (err == Z_OK) { + err = inflate(&strm, Z_FINISH); + if (err == Z_STREAM_END) { + ret = strm.total_out; + if (dstLen) + *dstLen = ret; + dst[ret] = 0; + dst2 = realloc (dst, ret+1); + if (dst2) + dst = dst2; + return dst; + } else { + inflateEnd(&strm); + if (err == Z_BUF_ERROR) { + tryLen *= 2; + goto retrygunzip; + } + return NULL; + } + } else { + inflateEnd(&strm); + if (err == Z_BUF_ERROR) { + tryLen *= 2; + goto retrygunzip; + } + return NULL; + } + + inflateEnd(&strm); + if (err == Z_BUF_ERROR) { + tryLen *= 2; + goto retrygunzip; + } + return NULL; +}