aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2015-07-05 18:14:53 -0700
committerMark Adler <madler@alumni.caltech.edu>2015-07-05 18:14:53 -0700
commit95698093f023852ca4365df307c19a1d7cfa3687 (patch)
tree743b907c5449f617343e8bec546eabbb650df0a8
parent8a979f6c7986574e37316148cd8ca440c3bc08a3 (diff)
downloadzlib-95698093f023852ca4365df307c19a1d7cfa3687.tar.gz
zlib-95698093f023852ca4365df307c19a1d7cfa3687.tar.bz2
zlib-95698093f023852ca4365df307c19a1d7cfa3687.zip
Improve speed of gzprintf() in transparent mode.
-rw-r--r--gzguts.h2
-rw-r--r--gzlib.c2
-rw-r--r--gzwrite.c110
-rw-r--r--zlib.h7
4 files changed, 70 insertions, 51 deletions
diff --git a/gzguts.h b/gzguts.h
index d87659d..ca13f47 100644
--- a/gzguts.h
+++ b/gzguts.h
@@ -170,7 +170,7 @@ typedef struct {
170 char *path; /* path or fd for error messages */ 170 char *path; /* path or fd for error messages */
171 unsigned size; /* buffer size, zero if not allocated yet */ 171 unsigned size; /* buffer size, zero if not allocated yet */
172 unsigned want; /* requested buffer size, default is GZBUFSIZE */ 172 unsigned want; /* requested buffer size, default is GZBUFSIZE */
173 unsigned char *in; /* input buffer */ 173 unsigned char *in; /* input buffer (double-sized when writing) */
174 unsigned char *out; /* output buffer (double-sized when reading) */ 174 unsigned char *out; /* output buffer (double-sized when reading) */
175 int direct; /* 0 if processing gzip, 1 if transparent */ 175 int direct; /* 0 if processing gzip, 1 if transparent */
176 /* just for reading */ 176 /* just for reading */
diff --git a/gzlib.c b/gzlib.c
index ced2cb8..3e344f9 100644
--- a/gzlib.c
+++ b/gzlib.c
@@ -331,6 +331,8 @@ int ZEXPORT gzbuffer(file, size)
331 return -1; 331 return -1;
332 332
333 /* check and set requested size */ 333 /* check and set requested size */
334 if ((size << 1) < size)
335 return -1; /* need to be able to double it */
334 if (size < 2) 336 if (size < 2)
335 size = 2; /* need two bytes to check magic header */ 337 size = 2; /* need two bytes to check magic header */
336 state->want = size; 338 state->want = size;
diff --git a/gzwrite.c b/gzwrite.c
index aa767fb..ad164b2 100644
--- a/gzwrite.c
+++ b/gzwrite.c
@@ -18,8 +18,8 @@ local int gz_init(state)
18 int ret; 18 int ret;
19 z_streamp strm = &(state->strm); 19 z_streamp strm = &(state->strm);
20 20
21 /* allocate input buffer */ 21 /* allocate input buffer (double size for gzprintf) */
22 state->in = (unsigned char *)malloc(state->want); 22 state->in = (unsigned char *)malloc(state->want << 1);
23 if (state->in == NULL) { 23 if (state->in == NULL) {
24 gz_error(state, Z_MEM_ERROR, "out of memory"); 24 gz_error(state, Z_MEM_ERROR, "out of memory");
25 return -1; 25 return -1;
@@ -309,7 +309,8 @@ int ZEXPORT gzputs(file, str)
309/* -- see zlib.h -- */ 309/* -- see zlib.h -- */
310int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) 310int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
311{ 311{
312 int size, len; 312 unsigned len, left;
313 char *next;
313 gz_statep state; 314 gz_statep state;
314 z_streamp strm; 315 z_streamp strm;
315 316
@@ -334,39 +335,47 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
334 return 0; 335 return 0;
335 } 336 }
336 337
337 /* consume whatever's left in the input buffer */ 338 /* do the printf() into the input buffer, put length in len -- the input
338 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 339 buffer is double-sized just for this function, so there is guaranteed to
339 return 0; 340 be state->size bytes available after the current contents */
340 341 if (strm->avail_in == 0)
341 /* do the printf() into the input buffer, put length in len */ 342 strm->next_in = state->in;
342 size = (int)(state->size); 343 next = (char *)(strm->next_in + strm->avail_in);
343 state->in[size - 1] = 0; 344 next[state->size - 1] = 0;
344#ifdef NO_vsnprintf 345#ifdef NO_vsnprintf
345# ifdef HAS_vsprintf_void 346# ifdef HAS_vsprintf_void
346 (void)vsprintf((char *)(state->in), format, va); 347 (void)vsprintf(next, format, va);
347 for (len = 0; len < size; len++) 348 for (len = 0; len < state->size; len++)
348 if (state->in[len] == 0) break; 349 if (next[len] == 0) break;
349# else 350# else
350 len = vsprintf((char *)(state->in), format, va); 351 len = vsprintf(next, format, va);
351# endif 352# endif
352#else 353#else
353# ifdef HAS_vsnprintf_void 354# ifdef HAS_vsnprintf_void
354 (void)vsnprintf((char *)(state->in), size, format, va); 355 (void)vsnprintf(next, state->size, format, va);
355 len = strlen((char *)(state->in)); 356 len = strlen(next);
356# else 357# else
357 len = vsnprintf((char *)(state->in), size, format, va); 358 len = vsnprintf(next, state->size, format, va);
358# endif 359# endif
359#endif 360#endif
360 361
361 /* check that printf() results fit in buffer */ 362 /* check that printf() results fit in buffer */
362 if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) 363 if (len == 0 || len >= state->size || next[state->size - 1] != 0)
363 return 0; 364 return 0;
364 365
365 /* update buffer and position, defer compression until needed */ 366 /* update buffer and position, compress first half if past that */
366 strm->avail_in = (unsigned)len; 367 strm->avail_in += len;
367 strm->next_in = state->in;
368 state->x.pos += len; 368 state->x.pos += len;
369 return len; 369 if (strm->avail_in >= state->size) {
370 left = strm->avail_in - state->size;
371 strm->avail_in = state->size;
372 if (gz_comp(state, Z_NO_FLUSH) == -1)
373 return 0;
374 memcpy(state->in, state->in + state->size, left);
375 strm->next_in = state->in;
376 strm->avail_in = left;
377 }
378 return (int)len;
370} 379}
371 380
372int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) 381int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
@@ -390,7 +399,8 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
390 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 399 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
391 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; 400 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
392{ 401{
393 int size, len; 402 unsigned len, left;
403 char *next;
394 gz_statep state; 404 gz_statep state;
395 z_streamp strm; 405 z_streamp strm;
396 406
@@ -419,44 +429,52 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
419 return 0; 429 return 0;
420 } 430 }
421 431
422 /* consume whatever's left in the input buffer */ 432 /* do the printf() into the input buffer, put length in len -- the input
423 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 433 buffer is double-sized just for this function, so there is guaranteed to
424 return 0; 434 be state->size bytes available after the current contents */
425 435 if (strm->avail_in == 0)
426 /* do the printf() into the input buffer, put length in len */ 436 strm->next_in = state->in;
427 size = (int)(state->size); 437 next = (char *)(strm->next_in + strm->avail_in);
428 state->in[size - 1] = 0; 438 next[state->size - 1] = 0;
429#ifdef NO_snprintf 439#ifdef NO_snprintf
430# ifdef HAS_sprintf_void 440# ifdef HAS_sprintf_void
431 sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, 441 sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
432 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 442 a13, a14, a15, a16, a17, a18, a19, a20);
433 for (len = 0; len < size; len++) 443 for (len = 0; len < size; len++)
434 if (state->in[len] == 0) break; 444 if (next[len] == 0)
445 break;
435# else 446# else
436 len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, 447 len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
437 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 448 a12, a13, a14, a15, a16, a17, a18, a19, a20);
438# endif 449# endif
439#else 450#else
440# ifdef HAS_snprintf_void 451# ifdef HAS_snprintf_void
441 snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, 452 snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
442 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 453 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
443 len = strlen((char *)(state->in)); 454 len = strlen(next);
444# else 455# else
445 len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, 456 len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
446 a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, 457 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
447 a19, a20);
448# endif 458# endif
449#endif 459#endif
450 460
451 /* check that printf() results fit in buffer */ 461 /* check that printf() results fit in buffer */
452 if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) 462 if (len == 0 || len >= state->size || next[state->size - 1] != 0)
453 return 0; 463 return 0;
454 464
455 /* update buffer and position, defer compression until needed */ 465 /* update buffer and position, compress first half if past that */
456 strm->avail_in = (unsigned)len; 466 strm->avail_in += len;
457 strm->next_in = state->in;
458 state->x.pos += len; 467 state->x.pos += len;
459 return len; 468 if (strm->avail_in >= state->size) {
469 left = strm->avail_in - state->size;
470 strm->avail_in = state->size;
471 if (gz_comp(state, Z_NO_FLUSH) == -1)
472 return 0;
473 memcpy(state->in, state->in + state->size, left);
474 strm->next_in = state->in;
475 strm->avail_in = left;
476 }
477 return (int)len;
460} 478}
461 479
462#endif 480#endif
diff --git a/zlib.h b/zlib.h
index 11a659a..032c2fd 100644
--- a/zlib.h
+++ b/zlib.h
@@ -1291,10 +1291,9 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
1291 default buffer size is 8192 bytes. This function must be called after 1291 default buffer size is 8192 bytes. This function must be called after
1292 gzopen() or gzdopen(), and before any other calls that read or write the 1292 gzopen() or gzdopen(), and before any other calls that read or write the
1293 file. The buffer memory allocation is always deferred to the first read or 1293 file. The buffer memory allocation is always deferred to the first read or
1294 write. Two buffers are allocated, either both of the specified size when 1294 write. Three times that size in buffer space is allocated. A larger buffer
1295 writing, or one of the specified size and the other twice that size when 1295 size of, for example, 64K or 128K bytes will noticeably increase the speed
1296 reading. A larger buffer size of, for example, 64K or 128K bytes will 1296 of decompression (reading).
1297 noticeably increase the speed of decompression (reading).
1298 1297
1299 The new buffer size also affects the maximum length for gzprintf(). 1298 The new buffer size also affects the maximum length for gzprintf().
1300 1299