zstream: offer inflating, `git_zstream_inflatebuf` Introduce `git_zstream_inflatebuf` for simple uses.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
diff --git a/src/pack-objects.c b/src/pack-objects.c
index 6f86deb..ec15970 100644
--- a/src/pack-objects.c
+++ b/src/pack-objects.c
@@ -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 */
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 ||
packbuilder_config(pb) < 0)
goto on_error;
diff --git a/src/zstream.c b/src/zstream.c
index 2130bc3..6533449 100644
--- a/src/zstream.c
+++ b/src/zstream.c
@@ -28,20 +28,31 @@ static int zstream_seterr(git_zstream *zs)
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);
}
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)
{
- deflateReset(&zstream->z);
+ if (zstream->type == GIT_ZSTREAM_INFLATE)
+ inflateReset(&zstream->z);
+ else
+ deflateReset(&zstream->z);
zstream->in = NULL;
zstream->in_len = 0;
zstream->zerr = Z_STREAM_END;
@@ -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;
/* 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)
return zstream_seterr(zstream);
@@ -120,12 +134,12 @@ int git_zstream_get_output(void *out, size_t *out_len, git_zstream *zstream)
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;
int error = 0;
- if ((error = git_zstream_init(&zs)) < 0)
+ if ((error = git_zstream_init(&zs, type)) < 0)
return error;
if ((error = git_zstream_set_input(&zs, in, in_len)) < 0)
@@ -154,3 +168,13 @@ done:
git_zstream_free(&zs);
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);
+}
diff --git a/src/zstream.h b/src/zstream.h
index 9b5bf6a..f0006d3 100644
--- a/src/zstream.h
+++ b/src/zstream.h
@@ -12,8 +12,14 @@
#include "common.h"
#include "buffer.h"
+typedef enum {
+ GIT_ZSTREAM_INFLATE,
+ GIT_ZSTREAM_DEFLATE,
+} git_zstream_t;
+
typedef struct {
z_stream z;
+ git_zstream_t type;
const char *in;
size_t in_len;
int zerr;
@@ -21,7 +27,7 @@ typedef struct {
#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);
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);
void git_zstream_reset(git_zstream *zstream);
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__ */
diff --git a/tests/core/zstream.c b/tests/core/zstream.c
index 7ba9424..b13429b 100644
--- a/tests/core/zstream.c
+++ b/tests/core/zstream.c
@@ -48,7 +48,7 @@ void test_core_zstream__basic(void)
char out[128];
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_get_output(out, &outlen, &z));
cl_assert(git_zstream_done(&z));
@@ -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"
-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 inflated = GIT_BUF_INIT;
size_t i, fixed_size = max(input->size / 2, 256);
char *fixed = git__malloc(fixed_size);
cl_assert(fixed);
@@ -93,7 +94,7 @@ static void compress_input_various_ways(git_buf *input)
}
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));
while (!git_zstream_done(&zs)) {
@@ -112,7 +113,12 @@ static void compress_input_various_ways(git_buf *input)
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(&inflated);
git__free(fixed);
}
@@ -129,14 +135,14 @@ void test_core_zstream__big_data(void)
cl_git_pass(
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 */
srand(0xabad1dea);
for (scan = 0; scan < in.size; ++scan)
in.ptr[scan] = (char)rand();
- compress_input_various_ways(&in);
+ compress_and_decompress_input_various_ways(&in);
}
git_buf_free(&in);