pack: refactor streams to use `git_zstream` While we do have a `git_zstream` abstraction that encapsulates all the calls to zlib as well as its error handling, we do not use it in our pack file code. Refactor it to make the code a lot easier to understand.
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
diff --git a/src/pack.c b/src/pack.c
index 92a3abe..7c6fc2c 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -13,9 +13,6 @@
#include "odb.h"
#include "oid.h"
#include "sha1_lookup.h"
-#include "zstream.h"
-
-#include <zlib.h>
/* Option to bypass checking existence of '.keep' files */
bool git_disable_pack_keep_file_checks = false;
@@ -766,31 +763,13 @@ cleanup:
return error;
}
-static void *use_git_alloc(void *opaq, unsigned int count, unsigned int size)
-{
- GIT_UNUSED(opaq);
- return git__calloc(count, size);
-}
-
-static void use_git_free(void *opaq, void *ptr)
-{
- GIT_UNUSED(opaq);
- git__free(ptr);
-}
-
int git_packfile_stream_open(git_packfile_stream *obj, struct git_pack_file *p, off64_t curpos)
{
- int st;
-
memset(obj, 0, sizeof(git_packfile_stream));
obj->curpos = curpos;
obj->p = p;
- obj->zstream.zalloc = use_git_alloc;
- obj->zstream.zfree = use_git_free;
- obj->zstream.next_in = Z_NULL;
- obj->zstream.next_out = Z_NULL;
- st = inflateInit(&obj->zstream);
- if (st != Z_OK) {
+
+ if (git_zstream_init(&obj->zstream, GIT_ZSTREAM_INFLATE) < 0) {
git_error_set(GIT_ERROR_ZLIB, "failed to init packfile stream");
return -1;
}
@@ -800,47 +779,41 @@ int git_packfile_stream_open(git_packfile_stream *obj, struct git_pack_file *p,
ssize_t git_packfile_stream_read(git_packfile_stream *obj, void *buffer, size_t len)
{
+ unsigned int window_len;
unsigned char *in;
- size_t written;
- int st;
+ int error;
if (obj->done)
return 0;
- in = pack_window_open(obj->p, &obj->mw, obj->curpos, &obj->zstream.avail_in);
- if (in == NULL)
+ if ((in = pack_window_open(obj->p, &obj->mw, obj->curpos, &window_len)) == NULL)
return GIT_EBUFS;
- obj->zstream.next_out = buffer;
- obj->zstream.avail_out = (unsigned int)len;
- obj->zstream.next_in = in;
-
- st = inflate(&obj->zstream, Z_SYNC_FLUSH);
- git_mwindow_close(&obj->mw);
-
- obj->curpos += obj->zstream.next_in - in;
- written = len - obj->zstream.avail_out;
-
- if (st != Z_OK && st != Z_STREAM_END) {
+ if ((error = git_zstream_set_input(&obj->zstream, in, window_len)) < 0 ||
+ (error = git_zstream_get_output_chunk(buffer, &len, &obj->zstream)) < 0) {
+ git_mwindow_close(&obj->mw);
git_error_set(GIT_ERROR_ZLIB, "error reading from the zlib stream");
return -1;
}
- if (st == Z_STREAM_END)
- obj->done = 1;
+ git_mwindow_close(&obj->mw);
+ obj->curpos += window_len - obj->zstream.in_len;
+
+ if (git_zstream_eos(&obj->zstream))
+ obj->done = 1;
/* If we didn't write anything out but we're not done, we need more data */
- if (!written && st != Z_STREAM_END)
+ if (!len && !git_zstream_eos(&obj->zstream))
return GIT_EBUFS;
- return written;
+ return len;
}
void git_packfile_stream_dispose(git_packfile_stream *obj)
{
- inflateEnd(&obj->zstream);
+ git_zstream_free(&obj->zstream);
}
static int packfile_unpack_compressed(
diff --git a/src/pack.h b/src/pack.h
index a294ecd..a6a32ff 100644
--- a/src/pack.h
+++ b/src/pack.h
@@ -10,16 +10,15 @@
#include "common.h"
-#include <zlib.h>
-
#include "git2/oid.h"
+#include "array.h"
#include "map.h"
#include "mwindow.h"
#include "odb.h"
#include "offmap.h"
#include "oidmap.h"
-#include "array.h"
+#include "zstream.h"
#define GIT_PACK_FILE_MODE 0444
@@ -116,7 +115,7 @@ struct git_pack_entry {
typedef struct git_packfile_stream {
off64_t curpos;
int done;
- z_stream zstream;
+ git_zstream zstream;
struct git_pack_file *p;
git_mwindow *mw;
} git_packfile_stream;