zlib: wrap deflate side of the API
authorJunio C Hamano <gitster@pobox.com>
Fri, 10 Jun 2011 17:55:10 +0000 (10:55 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 10 Jun 2011 18:10:29 +0000 (11:10 -0700)
Wrap deflateInit, deflate, and deflateEnd for everybody, and the sole use
of deflateInit2 in remote-curl.c to tell the library to use gzip header
and trailer in git_deflate_init_gzip().

There is only one caller that cares about the status from deflateEnd().
Introduce git_deflate_end_gently() to let that sole caller retrieve the
status and act on it (i.e. die) for now, but we would probably want to
make inflate_end/deflate_end die when they ran out of memory and get
rid of the _gently() kind.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
archive-zip.c
builtin/index-pack.c
builtin/pack-objects.c
cache.h
diff.c
fast-import.c
http-push.c
remote-curl.c
sha1_file.c
zlib.c

index cf285044e3576d0127c3215cb1253443d67517dc..081ff830c8b2345d2cf843f07496365934da0d6b 100644 (file)
@@ -96,7 +96,7 @@ static void *zlib_deflate(void *data, unsigned long size,
        int result;
 
        memset(&stream, 0, sizeof(stream));
-       deflateInit(&stream, compression_level);
+       git_deflate_init(&stream, compression_level);
        maxsize = deflateBound(&stream, size);
        buffer = xmalloc(maxsize);
 
@@ -106,7 +106,7 @@ static void *zlib_deflate(void *data, unsigned long size,
        stream.avail_out = maxsize;
 
        do {
-               result = deflate(&stream, Z_FINISH);
+               result = git_deflate(&stream, Z_FINISH);
        } while (result == Z_OK);
 
        if (result != Z_STREAM_END) {
@@ -114,7 +114,7 @@ static void *zlib_deflate(void *data, unsigned long size,
                return NULL;
        }
 
-       deflateEnd(&stream);
+       git_deflate_end(&stream);
        *compressed_size = stream.total_out;
 
        return buffer;
index 31f001f1059ec533ee62d6bd951b068d7f924f50..dbfb5da52a9f9bf097c6336ab5bdc55eccf9caae 100644 (file)
@@ -671,21 +671,21 @@ static int write_compressed(struct sha1file *f, void *in, unsigned int size)
        unsigned char outbuf[4096];
 
        memset(&stream, 0, sizeof(stream));
-       deflateInit(&stream, zlib_compression_level);
+       git_deflate_init(&stream, zlib_compression_level);
        stream.next_in = in;
        stream.avail_in = size;
 
        do {
                stream.next_out = outbuf;
                stream.avail_out = sizeof(outbuf);
-               status = deflate(&stream, Z_FINISH);
+               status = git_deflate(&stream, Z_FINISH);
                sha1write(f, outbuf, sizeof(outbuf) - stream.avail_out);
        } while (status == Z_OK);
 
        if (status != Z_STREAM_END)
                die("unable to deflate appended object (%d)", status);
        size = stream.total_out;
-       deflateEnd(&stream);
+       git_deflate_end(&stream);
        return size;
 }
 
index f402a843bb5ee23360d29bdbbc6cc9c5b9c72008..61f975585daf6fb28d635ce2899c2e5085dbb9d9 100644 (file)
@@ -131,7 +131,7 @@ static unsigned long do_compress(void **pptr, unsigned long size)
        unsigned long maxsize;
 
        memset(&stream, 0, sizeof(stream));
-       deflateInit(&stream, pack_compression_level);
+       git_deflate_init(&stream, pack_compression_level);
        maxsize = deflateBound(&stream, size);
 
        in = *pptr;
@@ -142,9 +142,9 @@ static unsigned long do_compress(void **pptr, unsigned long size)
        stream.avail_in = size;
        stream.next_out = out;
        stream.avail_out = maxsize;
-       while (deflate(&stream, Z_FINISH) == Z_OK)
+       while (git_deflate(&stream, Z_FINISH) == Z_OK)
                ; /* nothing */
-       deflateEnd(&stream);
+       git_deflate_end(&stream);
 
        free(in);
        return stream.total_out;
diff --git a/cache.h b/cache.h
index 50f09d05d4596ec62179444c0b8165254ebee5c5..5eb61ac04ef7cdab4050db243aa226b4302ba56d 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -25,6 +25,12 @@ void git_inflate_init_gzip_only(z_streamp strm);
 void git_inflate_end(z_streamp strm);
 int git_inflate(z_streamp strm, int flush);
 
+void git_deflate_init(z_streamp strm, int level);
+void git_deflate_init_gzip(z_streamp strm, int level);
+void git_deflate_end(z_streamp strm);
+int git_deflate_end_gently(z_streamp strm);
+int git_deflate(z_streamp strm, int flush);
+
 #if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT)
 #define DTYPE(de)      ((de)->d_type)
 #else
diff --git a/diff.c b/diff.c
index 559bf574a88f97402f32e1bd4ab51f6f0c9d5026..c15c70f977150e6f8ac9d1d4d468c9592a2b059e 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1732,7 +1732,7 @@ static unsigned char *deflate_it(char *data,
        z_stream stream;
 
        memset(&stream, 0, sizeof(stream));
-       deflateInit(&stream, zlib_compression_level);
+       git_deflate_init(&stream, zlib_compression_level);
        bound = deflateBound(&stream, size);
        deflated = xmalloc(bound);
        stream.next_out = deflated;
@@ -1740,9 +1740,9 @@ static unsigned char *deflate_it(char *data,
 
        stream.next_in = (unsigned char *)data;
        stream.avail_in = size;
-       while (deflate(&stream, Z_FINISH) == Z_OK)
+       while (git_deflate(&stream, Z_FINISH) == Z_OK)
                ; /* nothing */
-       deflateEnd(&stream);
+       git_deflate_end(&stream);
        *result_size = stream.total_out;
        return deflated;
 }
index 78d978684da2e2b79340c138e1b6300100df1221..42979e6db05a2f23bfdc76c923215906d61ddacc 100644 (file)
@@ -1050,7 +1050,7 @@ static int store_object(
                delta = NULL;
 
        memset(&s, 0, sizeof(s));
-       deflateInit(&s, pack_compression_level);
+       git_deflate_init(&s, pack_compression_level);
        if (delta) {
                s.next_in = delta;
                s.avail_in = deltalen;
@@ -1060,9 +1060,9 @@ static int store_object(
        }
        s.avail_out = deflateBound(&s, s.avail_in);
        s.next_out = out = xmalloc(s.avail_out);
-       while (deflate(&s, Z_FINISH) == Z_OK)
-               /* nothing */;
-       deflateEnd(&s);
+       while (git_deflate(&s, Z_FINISH) == Z_OK)
+               ; /* nothing */
+       git_deflate_end(&s);
 
        /* Determine if we should auto-checkpoint. */
        if ((max_packsize && (pack_size + 60 + s.total_out) > max_packsize)
@@ -1078,14 +1078,14 @@ static int store_object(
                        delta = NULL;
 
                        memset(&s, 0, sizeof(s));
-                       deflateInit(&s, pack_compression_level);
+                       git_deflate_init(&s, pack_compression_level);
                        s.next_in = (void *)dat->buf;
                        s.avail_in = dat->len;
                        s.avail_out = deflateBound(&s, s.avail_in);
                        s.next_out = out = xrealloc(out, s.avail_out);
-                       while (deflate(&s, Z_FINISH) == Z_OK)
-                               /* nothing */;
-                       deflateEnd(&s);
+                       while (git_deflate(&s, Z_FINISH) == Z_OK)
+                               ; /* nothing */
+                       git_deflate_end(&s);
                }
        }
 
@@ -1187,7 +1187,7 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
        crc32_begin(pack_file);
 
        memset(&s, 0, sizeof(s));
-       deflateInit(&s, pack_compression_level);
+       git_deflate_init(&s, pack_compression_level);
 
        hdrlen = encode_in_pack_object_header(OBJ_BLOB, len, out_buf);
        if (out_sz <= hdrlen)
@@ -1209,7 +1209,7 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
                        len -= n;
                }
 
-               status = deflate(&s, len ? 0 : Z_FINISH);
+               status = git_deflate(&s, len ? 0 : Z_FINISH);
 
                if (!s.avail_out || status == Z_STREAM_END) {
                        size_t n = s.next_out - out_buf;
@@ -1228,7 +1228,7 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
                        die("unexpected deflate failure: %d", status);
                }
        }
-       deflateEnd(&s);
+       git_deflate_end(&s);
        git_SHA1_Final(sha1, &c);
 
        if (sha1out)
index d18346c0f5c9ce73f3fe9a1efc7b1b63e7380bb8..46e68c80e5f4982c5737746e296388735470691d 100644 (file)
@@ -359,7 +359,7 @@ static void start_put(struct transfer_request *request)
 
        /* Set it up */
        memset(&stream, 0, sizeof(stream));
-       deflateInit(&stream, zlib_compression_level);
+       git_deflate_init(&stream, zlib_compression_level);
        size = deflateBound(&stream, len + hdrlen);
        strbuf_init(&request->buffer.buf, size);
        request->buffer.posn = 0;
@@ -371,15 +371,15 @@ static void start_put(struct transfer_request *request)
        /* First header.. */
        stream.next_in = (void *)hdr;
        stream.avail_in = hdrlen;
-       while (deflate(&stream, 0) == Z_OK)
-               /* nothing */;
+       while (git_deflate(&stream, 0) == Z_OK)
+               ; /* nothing */
 
        /* Then the data itself.. */
        stream.next_in = unpacked;
        stream.avail_in = len;
-       while (deflate(&stream, Z_FINISH) == Z_OK)
-               /* nothing */;
-       deflateEnd(&stream);
+       while (git_deflate(&stream, Z_FINISH) == Z_OK)
+               ; /* nothing */
+       git_deflate_end(&stream);
        free(unpacked);
 
        request->buffer.buf.len = stream.total_out;
index 775d6143037aa4573c0202715fe1b1a0f99e2799..3c7621aa06ab9462a119ba3002b52e58f6428f0d 100644 (file)
@@ -475,11 +475,7 @@ static int post_rpc(struct rpc_state *rpc)
                int ret;
 
                memset(&stream, 0, sizeof(stream));
-               ret = deflateInit2(&stream, Z_BEST_COMPRESSION,
-                               Z_DEFLATED, (15 + 16),
-                               8, Z_DEFAULT_STRATEGY);
-               if (ret != Z_OK)
-                       die("cannot deflate request; zlib init error %d", ret);
+               git_deflate_init_gzip(&stream, Z_BEST_COMPRESSION);
                size = deflateBound(&stream, rpc->len);
                gzip_body = xmalloc(size);
 
@@ -488,11 +484,11 @@ static int post_rpc(struct rpc_state *rpc)
                stream.next_out = (unsigned char *)gzip_body;
                stream.avail_out = size;
 
-               ret = deflate(&stream, Z_FINISH);
+               ret = git_deflate(&stream, Z_FINISH);
                if (ret != Z_STREAM_END)
                        die("cannot deflate request; zlib deflate error %d", ret);
 
-               ret = deflateEnd(&stream);
+               ret = git_deflate_end_gently(&stream);
                if (ret != Z_OK)
                        die("cannot deflate request; zlib end error %d", ret);
 
index 1a7e41070efa6327859d3c09ede07317cc91ba7d..0eefb6194e177fc36a70da1a90e416389edc7708 100644 (file)
@@ -2442,7 +2442,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
 
        /* Set it up */
        memset(&stream, 0, sizeof(stream));
-       deflateInit(&stream, zlib_compression_level);
+       git_deflate_init(&stream, zlib_compression_level);
        stream.next_out = compressed;
        stream.avail_out = sizeof(compressed);
        git_SHA1_Init(&c);
@@ -2450,8 +2450,8 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
        /* First header.. */
        stream.next_in = (unsigned char *)hdr;
        stream.avail_in = hdrlen;
-       while (deflate(&stream, 0) == Z_OK)
-               /* nothing */;
+       while (git_deflate(&stream, 0) == Z_OK)
+               ; /* nothing */
        git_SHA1_Update(&c, hdr, hdrlen);
 
        /* Then the data itself.. */
@@ -2459,7 +2459,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
        stream.avail_in = len;
        do {
                unsigned char *in0 = stream.next_in;
-               ret = deflate(&stream, Z_FINISH);
+               ret = git_deflate(&stream, Z_FINISH);
                git_SHA1_Update(&c, in0, stream.next_in - in0);
                if (write_buffer(fd, compressed, stream.next_out - compressed) < 0)
                        die("unable to write sha1 file");
@@ -2469,7 +2469,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
 
        if (ret != Z_STREAM_END)
                die("unable to deflate new object %s (%d)", sha1_to_hex(sha1), ret);
-       ret = deflateEnd(&stream);
+       ret = git_deflate_end_gently(&stream);
        if (ret != Z_OK)
                die("deflateEnd on object %s failed (%d)", sha1_to_hex(sha1), ret);
        git_SHA1_Final(parano_sha1, &c);
diff --git a/zlib.c b/zlib.c
index b613cbd75085384df2ec87fcf2475f7d154f55ff..ee47a3a4a9b9e01fbd0e30a326b208d7a492ceb1 100644 (file)
--- a/zlib.c
+++ b/zlib.c
@@ -77,3 +77,65 @@ int git_inflate(z_streamp strm, int flush)
              strm->msg ? strm->msg : "no message");
        return status;
 }
+
+void git_deflate_init(z_streamp strm, int level)
+{
+       int status = deflateInit(strm, level);
+
+       if (status == Z_OK)
+               return;
+       die("deflateInit: %s (%s)", zerr_to_string(status),
+           strm->msg ? strm->msg : "no message");
+}
+
+void git_deflate_init_gzip(z_streamp strm, int level)
+{
+       /*
+        * Use default 15 bits, +16 is to generate gzip header/trailer
+        * instead of the zlib wrapper.
+        */
+       const int windowBits = 15 + 16;
+       int status = deflateInit2(strm, level,
+                                 Z_DEFLATED, windowBits,
+                                 8, Z_DEFAULT_STRATEGY);
+       if (status == Z_OK)
+               return;
+       die("deflateInit2: %s (%s)", zerr_to_string(status),
+           strm->msg ? strm->msg : "no message");
+}
+
+void git_deflate_end(z_streamp strm)
+{
+       int status = deflateEnd(strm);
+
+       if (status == Z_OK)
+               return;
+       error("deflateEnd: %s (%s)", zerr_to_string(status),
+             strm->msg ? strm->msg : "no message");
+}
+
+int git_deflate_end_gently(z_streamp strm)
+{
+       return deflateEnd(strm);
+}
+
+int git_deflate(z_streamp strm, int flush)
+{
+       int status = deflate(strm, flush);
+
+       switch (status) {
+       /* Z_BUF_ERROR: normal, needs more space in the output buffer */
+       case Z_BUF_ERROR:
+       case Z_OK:
+       case Z_STREAM_END:
+               return status;
+
+       case Z_MEM_ERROR:
+               die("deflate: out of memory");
+       default:
+               break;
+       }
+       error("deflate: %s (%s)", zerr_to_string(status),
+             strm->msg ? strm->msg : "no message");
+       return status;
+}