diff options
Diffstat (limited to 'gzwrite.c')
-rw-r--r-- | gzwrite.c | 110 |
1 files changed, 64 insertions, 46 deletions
@@ -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 -- */ |
310 | int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) | 310 | int 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 | ||
372 | int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) | 381 | int 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 |