From: Mark Adler Date: Tue, 3 Nov 2015 17:42:14 +0000 (+0100) Subject: Improve speed of gzprintf() in transparent mode. X-Git-Tag: 1.9.9-b1~793^2~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=48e985b618b95a0e49587cbe6b18aea7f9117075;p=thirdparty%2Fzlib-ng.git Improve speed of gzprintf() in transparent mode. A few minor modifications done to help with conflicts. --- diff --git a/gzguts.h b/gzguts.h index 17d8732dc..a2698ee7d 100644 --- 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 50e2c5025..28732020e 100644 --- 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; diff --git a/gzwrite.c b/gzwrite.c index 8c8078177..f0c4ed61d 100644 --- 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 92016ba4e..08429cbdd 100644 --- 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().