diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2015-11-03 18:42:14 +0100 |
---|---|---|
committer | Hans Kristian Rosbach <hk-git@circlestorm.org> | 2015-11-03 18:43:48 +0100 |
commit | 48e985b618b95a0e49587cbe6b18aea7f9117075 (patch) | |
tree | b9b85f8a4ca1b9dca427ea930e067088f3134bcd /gzwrite.c | |
parent | 0c1581a5171b6793deccb9632a92f05d9691b3bb (diff) |
Improve speed of gzprintf() in transparent mode.
A few minor modifications done to help with conflicts.
Diffstat (limited to 'gzwrite.c')
-rw-r--r-- | gzwrite.c | 41 |
1 files changed, 25 insertions, 16 deletions
@@ -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, ...) { |