aboutsummaryrefslogtreecommitdiff
path: root/gzwrite.c
diff options
context:
space:
mode:
Diffstat (limited to 'gzwrite.c')
-rw-r--r--gzwrite.c110
1 files changed, 64 insertions, 46 deletions
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