Commit b88f1713 by Edward Thomson Committed by Edward Thomson

zstream: offer inflating, `git_zstream_inflatebuf`

Introduce `git_zstream_inflatebuf` for simple uses.
parent 1cd65991
...@@ -144,7 +144,7 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo) ...@@ -144,7 +144,7 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo)
pb->nr_threads = 1; /* do not spawn any thread by default */ pb->nr_threads = 1; /* do not spawn any thread by default */
if (git_hash_ctx_init(&pb->ctx) < 0 || if (git_hash_ctx_init(&pb->ctx) < 0 ||
git_zstream_init(&pb->zstream) < 0 || git_zstream_init(&pb->zstream, GIT_ZSTREAM_DEFLATE) < 0 ||
git_repository_odb(&pb->odb, repo) < 0 || git_repository_odb(&pb->odb, repo) < 0 ||
packbuilder_config(pb) < 0) packbuilder_config(pb) < 0)
goto on_error; goto on_error;
......
...@@ -28,20 +28,31 @@ static int zstream_seterr(git_zstream *zs) ...@@ -28,20 +28,31 @@ static int zstream_seterr(git_zstream *zs)
return -1; return -1;
} }
int git_zstream_init(git_zstream *zstream) int git_zstream_init(git_zstream *zstream, git_zstream_t type)
{ {
zstream->zerr = deflateInit(&zstream->z, Z_DEFAULT_COMPRESSION); zstream->type = type;
if (zstream->type == GIT_ZSTREAM_INFLATE)
zstream->zerr = inflateInit(&zstream->z);
else
zstream->zerr = deflateInit(&zstream->z, Z_DEFAULT_COMPRESSION);
return zstream_seterr(zstream); return zstream_seterr(zstream);
} }
void git_zstream_free(git_zstream *zstream) void git_zstream_free(git_zstream *zstream)
{ {
deflateEnd(&zstream->z); if (zstream->type == GIT_ZSTREAM_INFLATE)
inflateEnd(&zstream->z);
else
deflateEnd(&zstream->z);
} }
void git_zstream_reset(git_zstream *zstream) void git_zstream_reset(git_zstream *zstream)
{ {
deflateReset(&zstream->z); if (zstream->type == GIT_ZSTREAM_INFLATE)
inflateReset(&zstream->z);
else
deflateReset(&zstream->z);
zstream->in = NULL; zstream->in = NULL;
zstream->in_len = 0; zstream->in_len = 0;
zstream->zerr = Z_STREAM_END; zstream->zerr = Z_STREAM_END;
...@@ -97,7 +108,10 @@ int git_zstream_get_output(void *out, size_t *out_len, git_zstream *zstream) ...@@ -97,7 +108,10 @@ int git_zstream_get_output(void *out, size_t *out_len, git_zstream *zstream)
out_queued = (size_t)zstream->z.avail_out; out_queued = (size_t)zstream->z.avail_out;
/* compress next chunk */ /* compress next chunk */
zstream->zerr = deflate(&zstream->z, zflush); if (zstream->type == GIT_ZSTREAM_INFLATE)
zstream->zerr = inflate(&zstream->z, zflush);
else
zstream->zerr = deflate(&zstream->z, zflush);
if (zstream->zerr == Z_STREAM_ERROR) if (zstream->zerr == Z_STREAM_ERROR)
return zstream_seterr(zstream); return zstream_seterr(zstream);
...@@ -120,12 +134,12 @@ int git_zstream_get_output(void *out, size_t *out_len, git_zstream *zstream) ...@@ -120,12 +134,12 @@ int git_zstream_get_output(void *out, size_t *out_len, git_zstream *zstream)
return 0; return 0;
} }
int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len) static int zstream_buf(git_buf *out, const void *in, size_t in_len, git_zstream_t type)
{ {
git_zstream zs = GIT_ZSTREAM_INIT; git_zstream zs = GIT_ZSTREAM_INIT;
int error = 0; int error = 0;
if ((error = git_zstream_init(&zs)) < 0) if ((error = git_zstream_init(&zs, type)) < 0)
return error; return error;
if ((error = git_zstream_set_input(&zs, in, in_len)) < 0) if ((error = git_zstream_set_input(&zs, in, in_len)) < 0)
...@@ -154,3 +168,13 @@ done: ...@@ -154,3 +168,13 @@ done:
git_zstream_free(&zs); git_zstream_free(&zs);
return error; return error;
} }
int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len)
{
return zstream_buf(out, in, in_len, GIT_ZSTREAM_DEFLATE);
}
int git_zstream_inflatebuf(git_buf *out, const void *in, size_t in_len)
{
return zstream_buf(out, in, in_len, GIT_ZSTREAM_INFLATE);
}
...@@ -12,8 +12,14 @@ ...@@ -12,8 +12,14 @@
#include "common.h" #include "common.h"
#include "buffer.h" #include "buffer.h"
typedef enum {
GIT_ZSTREAM_INFLATE,
GIT_ZSTREAM_DEFLATE,
} git_zstream_t;
typedef struct { typedef struct {
z_stream z; z_stream z;
git_zstream_t type;
const char *in; const char *in;
size_t in_len; size_t in_len;
int zerr; int zerr;
...@@ -21,7 +27,7 @@ typedef struct { ...@@ -21,7 +27,7 @@ typedef struct {
#define GIT_ZSTREAM_INIT {{0}} #define GIT_ZSTREAM_INIT {{0}}
int git_zstream_init(git_zstream *zstream); int git_zstream_init(git_zstream *zstream, git_zstream_t type);
void git_zstream_free(git_zstream *zstream); void git_zstream_free(git_zstream *zstream);
int git_zstream_set_input(git_zstream *zstream, const void *in, size_t in_len); int git_zstream_set_input(git_zstream *zstream, const void *in, size_t in_len);
...@@ -35,5 +41,6 @@ bool git_zstream_done(git_zstream *zstream); ...@@ -35,5 +41,6 @@ bool git_zstream_done(git_zstream *zstream);
void git_zstream_reset(git_zstream *zstream); void git_zstream_reset(git_zstream *zstream);
int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len); int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len);
int git_zstream_inflatebuf(git_buf *out, const void *in, size_t in_len);
#endif /* INCLUDE_zstream_h__ */ #endif /* INCLUDE_zstream_h__ */
...@@ -48,7 +48,7 @@ void test_core_zstream__basic(void) ...@@ -48,7 +48,7 @@ void test_core_zstream__basic(void)
char out[128]; char out[128];
size_t outlen = sizeof(out); size_t outlen = sizeof(out);
cl_git_pass(git_zstream_init(&z)); cl_git_pass(git_zstream_init(&z, GIT_ZSTREAM_DEFLATE));
cl_git_pass(git_zstream_set_input(&z, data, strlen(data) + 1)); cl_git_pass(git_zstream_set_input(&z, data, strlen(data) + 1));
cl_git_pass(git_zstream_get_output(out, &outlen, &z)); cl_git_pass(git_zstream_get_output(out, &outlen, &z));
cl_assert(git_zstream_done(&z)); cl_assert(git_zstream_done(&z));
...@@ -68,9 +68,10 @@ void test_core_zstream__buffer(void) ...@@ -68,9 +68,10 @@ void test_core_zstream__buffer(void)
#define BIG_STRING_PART "Big Data IS Big - Long Data IS Long - We need a buffer larger than 1024 x 1024 to make sure we trigger chunked compression - Big Big Data IS Bigger than Big - Long Long Data IS Longer than Long" #define BIG_STRING_PART "Big Data IS Big - Long Data IS Long - We need a buffer larger than 1024 x 1024 to make sure we trigger chunked compression - Big Big Data IS Bigger than Big - Long Long Data IS Longer than Long"
static void compress_input_various_ways(git_buf *input) static void compress_and_decompress_input_various_ways(git_buf *input)
{ {
git_buf out1 = GIT_BUF_INIT, out2 = GIT_BUF_INIT; git_buf out1 = GIT_BUF_INIT, out2 = GIT_BUF_INIT;
git_buf inflated = GIT_BUF_INIT;
size_t i, fixed_size = max(input->size / 2, 256); size_t i, fixed_size = max(input->size / 2, 256);
char *fixed = git__malloc(fixed_size); char *fixed = git__malloc(fixed_size);
cl_assert(fixed); cl_assert(fixed);
...@@ -93,7 +94,7 @@ static void compress_input_various_ways(git_buf *input) ...@@ -93,7 +94,7 @@ static void compress_input_various_ways(git_buf *input)
} }
cl_assert(use_fixed_size <= fixed_size); cl_assert(use_fixed_size <= fixed_size);
cl_git_pass(git_zstream_init(&zs)); cl_git_pass(git_zstream_init(&zs, GIT_ZSTREAM_DEFLATE));
cl_git_pass(git_zstream_set_input(&zs, input->ptr, input->size)); cl_git_pass(git_zstream_set_input(&zs, input->ptr, input->size));
while (!git_zstream_done(&zs)) { while (!git_zstream_done(&zs)) {
...@@ -112,7 +113,12 @@ static void compress_input_various_ways(git_buf *input) ...@@ -112,7 +113,12 @@ static void compress_input_various_ways(git_buf *input)
git_buf_free(&out2); git_buf_free(&out2);
} }
cl_git_pass(git_zstream_inflatebuf(&inflated, out1.ptr, out1.size));
cl_assert_equal_i(input->size, inflated.size);
cl_assert(memcmp(input->ptr, inflated.ptr, inflated.size) == 0);
git_buf_free(&out1); git_buf_free(&out1);
git_buf_free(&inflated);
git__free(fixed); git__free(fixed);
} }
...@@ -129,14 +135,14 @@ void test_core_zstream__big_data(void) ...@@ -129,14 +135,14 @@ void test_core_zstream__big_data(void)
cl_git_pass( cl_git_pass(
git_buf_put(&in, BIG_STRING_PART, strlen(BIG_STRING_PART))); git_buf_put(&in, BIG_STRING_PART, strlen(BIG_STRING_PART)));
compress_input_various_ways(&in); compress_and_decompress_input_various_ways(&in);
/* make a big string that's hard to compress */ /* make a big string that's hard to compress */
srand(0xabad1dea); srand(0xabad1dea);
for (scan = 0; scan < in.size; ++scan) for (scan = 0; scan < in.size; ++scan)
in.ptr[scan] = (char)rand(); in.ptr[scan] = (char)rand();
compress_input_various_ways(&in); compress_and_decompress_input_various_ways(&in);
} }
git_buf_free(&in); git_buf_free(&in);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment