odb_loose: read_header should use zstream Make `read_header` use the common zstream implementation. Remove the now unnecessary zlib wrapper in odb_loose.
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
diff --git a/src/odb_loose.c b/src/odb_loose.c
index 156586f..f01debf 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -131,7 +131,10 @@ static int parse_header_packlike(
}
out->size = size;
- *out_len = used;
+
+ if (out_len)
+ *out_len = used;
+
return 0;
on_error:
@@ -192,67 +195,6 @@ on_error:
return -1;
}
-/***********************************************************
- *
- * ZLIB RELATED FUNCTIONS
- *
- ***********************************************************/
-
-static void init_stream(z_stream *s, void *out, size_t len)
-{
- memset(s, 0, sizeof(*s));
- s->next_out = out;
- s->avail_out = (uInt)len;
-}
-
-static void set_stream_input(z_stream *s, void *in, size_t len)
-{
- s->next_in = in;
- s->avail_in = (uInt)len;
-}
-
-static void set_stream_output(z_stream *s, void *out, size_t len)
-{
- s->next_out = out;
- s->avail_out = (uInt)len;
-}
-
-
-static int start_inflate(z_stream *s, git_buf *obj, void *out, size_t len)
-{
- int status;
-
- init_stream(s, out, len);
- set_stream_input(s, obj->ptr, git_buf_len(obj));
-
- if ((status = inflateInit(s)) < Z_OK)
- return status;
-
- return inflate(s, 0);
-}
-
-static void abort_inflate(z_stream *s)
-{
- inflateEnd(s);
-}
-
-static int finish_inflate(z_stream *s)
-{
- int status = Z_OK;
-
- while (status == Z_OK)
- status = inflate(s, Z_FINISH);
-
- inflateEnd(s);
-
- if ((status != Z_STREAM_END) || (s->avail_in != 0)) {
- giterr_set(GITERR_ZLIB, "failed to finish zlib inflation; stream aborted prematurely");
- return -1;
- }
-
- return 0;
-}
-
static int is_zlib_compressed_data(unsigned char *data)
{
unsigned int w;
@@ -423,12 +365,11 @@ done:
static int read_header_loose(git_rawobj *out, git_buf *loc)
{
- int error = 0, z_return = Z_ERRNO, read_bytes;
- git_file fd;
- z_stream zs;
- obj_hdr header_obj;
- size_t header_len;
- unsigned char raw_buffer[16], inflated_buffer[HEADER_LEN];
+ git_zstream zs = GIT_ZSTREAM_INIT;
+ unsigned char obj[1024], inflated[HEADER_LEN];
+ size_t inflated_len, header_len;
+ obj_hdr hdr;
+ int fd, obj_len, error;
assert(out && loc);
@@ -440,30 +381,28 @@ static int read_header_loose(git_rawobj *out, git_buf *loc)
if ((fd = git_futils_open_ro(loc->ptr)) < 0)
return fd;
- init_stream(&zs, inflated_buffer, sizeof(inflated_buffer));
+ if ((error = obj_len = p_read(fd, obj, sizeof(obj))) < 0)
+ goto done;
- z_return = inflateInit(&zs);
+ inflated_len = sizeof(inflated);
- while (z_return == Z_OK) {
- if ((read_bytes = p_read(fd, raw_buffer, sizeof(raw_buffer))) > 0) {
- set_stream_input(&zs, raw_buffer, read_bytes);
- z_return = inflate(&zs, 0);
- } else
- z_return = Z_STREAM_END;
- }
+ if ((error = git_zstream_init(&zs, GIT_ZSTREAM_INFLATE)) < 0 ||
+ (error = git_zstream_set_input(&zs, obj, obj_len)) < 0 ||
+ (error = git_zstream_get_output_chunk(inflated, &inflated_len, &zs)) < 0 ||
+ (error = parse_header(&hdr, &header_len, inflated, inflated_len)) < 0)
+ goto done;
- if ((z_return != Z_STREAM_END && z_return != Z_BUF_ERROR)
- || parse_header(&header_obj, &header_len, inflated_buffer, sizeof(inflated_buffer)) < 0
- || git_object_typeisloose(header_obj.type) == 0)
- {
+ if (!git_object_typeisloose(hdr.type)) {
giterr_set(GITERR_ZLIB, "failed to read loose object header");
error = -1;
- } else {
- out->len = header_obj.size;
- out->type = header_obj.type;
+ goto done;
}
- finish_inflate(&zs);
+ out->len = hdr.size;
+ out->type = hdr.type;
+
+done:
+ git_zstream_free(&zs);
p_close(fd);
return error;