]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Improve speed of gzprintf() in transparent mode.
authorMark Adler <madler@alumni.caltech.edu>
Tue, 3 Nov 2015 17:42:14 +0000 (18:42 +0100)
committerHans Kristian Rosbach <hk-git@circlestorm.org>
Tue, 3 Nov 2015 17:43:48 +0000 (18:43 +0100)
A few minor modifications done to help with conflicts.

gzguts.h
gzlib.c
gzwrite.c
zlib.h

index 17d8732dc99271b37ed0a46c067c678a99ed2144..a2698ee7d429afd208d7533acf7ccdac4c945207 100644 (file)
--- a/gzguts.h
+++ b/gzguts.h
@@ -114,7 +114,7 @@ typedef struct {
     char *path;             /* path or fd for error messages */
     unsigned size;          /* buffer size, zero if not allocated yet */
     unsigned want;          /* requested buffer size, default is GZBUFSIZE */
-    unsigned char *in;      /* input buffer */
+    unsigned char *in;      /* input buffer (double-sized when writing) */
     unsigned char *out;     /* output buffer (double-sized when reading) */
     int direct;             /* 0 if processing gzip, 1 if transparent */
         /* just for reading */
diff --git a/gzlib.c b/gzlib.c
index 50e2c50254401ce49603805f752daff9af6a10c6..28732020eaefff12561591c1fb5acb24baa4b681 100644 (file)
--- a/gzlib.c
+++ b/gzlib.c
@@ -251,6 +251,8 @@ int ZEXPORT gzbuffer(gzFile file, unsigned size) {
         return -1;
 
     /* check and set requested size */
+    if ((size << 1) < size)
+        return -1;              /* need to be able to double it */
     if (size < 2)
         size = 2;               /* need two bytes to check magic header */
     state->want = size;
index 8c8078177af7d501758e170f2fad35aec296ed80..f0c4ed61dd206d32fcbc4985953ebd965f1af18d 100644 (file)
--- a/gzwrite.c
+++ b/gzwrite.c
@@ -17,8 +17,8 @@ local int gz_init(gz_statep state) {
     int ret;
     z_stream *strm = &(state->strm);
 
-    /* allocate input buffer */
-    state->in = (unsigned char *)malloc(state->want);
+    /* allocate input buffer (double size for gzprintf) */
+    state->in = (unsigned char *)malloc(state->want << 1);
     if (state->in == NULL) {
         gz_error(state, Z_MEM_ERROR, "out of memory");
         return -1;
@@ -283,7 +283,8 @@ int ZEXPORT gzputs(gzFile file, const char *str) {
 
 /* -- see zlib.h -- */
 int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
-    int size, len;
+    int len, left;
+    char *next;
     gz_statep state;
     z_stream *strm;
 
@@ -308,24 +309,32 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
             return 0;
     }
 
-    /* consume whatever's left in the input buffer */
-    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
-        return 0;
-
-    /* do the printf() into the input buffer, put length in len */
-    size = (int)(state->size);
-    state->in[size - 1] = 0;
-    len = vsnprintf((char *)(state->in), size, format, va);
+    /* do the printf() into the input buffer, put length in len -- the input
+       buffer is double-sized just for this function, so there is guaranteed to
+       be state->size bytes available after the current contents */
+    if (strm->avail_in == 0)
+        strm->next_in = state->in;
+    next = (char *)(strm->next_in + strm->avail_in);
+    next[state->size - 1] = 0;
+    len = vsnprintf(next, state->size, format, va);
 
     /* check that printf() results fit in buffer */
-    if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
+    if (len == 0 || len >= state->size || next[state->size - 1] != 0)
         return 0;
 
-    /* update buffer and position, defer compression until needed */
-    strm->avail_in = (unsigned)len;
-    strm->next_in = state->in;
+    /* update buffer and position, compress first half if past that */
+    strm->avail_in += len;
     state->x.pos += len;
-    return len;
+    if (strm->avail_in >= state->size) {
+        left = strm->avail_in - state->size;
+        strm->avail_in = state->size;
+        if (gz_comp(state, Z_NO_FLUSH) == -1)
+            return 0;
+        memcpy(state->in, state->in + state->size, left);
+        strm->next_in = state->in;
+        strm->avail_in = left;
+    }
+    return (int)len;
 }
 
 int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) {
diff --git a/zlib.h b/zlib.h
index 92016ba4ef21aec7432b5e8dc1b6d631f4b838f6..08429cbdd09c80cff0436ba350ddb6f0c0c769b0 100644 (file)
--- a/zlib.h
+++ b/zlib.h
@@ -1265,10 +1265,9 @@ ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size);
    default buffer size is 8192 bytes.  This function must be called after
    gzopen() or gzdopen(), and before any other calls that read or write the
    file.  The buffer memory allocation is always deferred to the first read or
-   write.  Two buffers are allocated, either both of the specified size when
-   writing, or one of the specified size and the other twice that size when
-   reading.  A larger buffer size of, for example, 64K or 128K bytes will
-   noticeably increase the speed of decompression (reading).
+   write.  Three times that size in buffer space is allocated.  A larger buffer
+   size of, for example, 64K or 128K bytes will noticeably increase the speed
+   of decompression (reading).
 
      The new buffer size also affects the maximum length for gzprintf().