comparison zlib/gzwrite.c @ 2690:9ef72ee5c0b0

Update vendored zlib to 1.3.1
author Michael Pavone <pavone@retrodev.com>
date Sun, 15 Jun 2025 15:39:33 -0700
parents 00d788dac91a
children
comparison
equal deleted inserted replaced
2689:bd6e33de0972 2690:9ef72ee5c0b0
1 /* gzwrite.c -- zlib functions for writing gzip files 1 /* gzwrite.c -- zlib functions for writing gzip files
2 * Copyright (C) 2004-2017 Mark Adler 2 * Copyright (C) 2004-2019 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
6 #include "gzguts.h" 6 #include "gzguts.h"
7
8 /* Local functions */
9 local int gz_init OF((gz_statep));
10 local int gz_comp OF((gz_statep, int));
11 local int gz_zero OF((gz_statep, z_off64_t));
12 local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
13 7
14 /* Initialize state for writing a gzip file. Mark initialization by setting 8 /* Initialize state for writing a gzip file. Mark initialization by setting
15 state->size to non-zero. Return -1 on a memory allocation failure, or 0 on 9 state->size to non-zero. Return -1 on a memory allocation failure, or 0 on
16 success. */ 10 success. */
17 local int gz_init(state) 11 local int gz_init(gz_statep state) {
18 gz_statep state;
19 {
20 int ret; 12 int ret;
21 z_streamp strm = &(state->strm); 13 z_streamp strm = &(state->strm);
22 14
23 /* allocate input buffer (double size for gzprintf) */ 15 /* allocate input buffer (double size for gzprintf) */
24 state->in = (unsigned char *)malloc(state->want << 1); 16 state->in = (unsigned char *)malloc(state->want << 1);
68 Return -1 if there is an error writing to the output file or if gz_init() 60 Return -1 if there is an error writing to the output file or if gz_init()
69 fails to allocate memory, otherwise 0. flush is assumed to be a valid 61 fails to allocate memory, otherwise 0. flush is assumed to be a valid
70 deflate() flush value. If flush is Z_FINISH, then the deflate() state is 62 deflate() flush value. If flush is Z_FINISH, then the deflate() state is
71 reset to start a new gzip stream. If gz->direct is true, then simply write 63 reset to start a new gzip stream. If gz->direct is true, then simply write
72 to the output file without compressing, and ignore flush. */ 64 to the output file without compressing, and ignore flush. */
73 local int gz_comp(state, flush) 65 local int gz_comp(gz_statep state, int flush) {
74 gz_statep state;
75 int flush;
76 {
77 int ret, writ; 66 int ret, writ;
78 unsigned have, put, max = ((unsigned)-1 >> 2) + 1; 67 unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
79 z_streamp strm = &(state->strm); 68 z_streamp strm = &(state->strm);
80 69
81 /* allocate memory if this is the first time through */ 70 /* allocate memory if this is the first time through */
93 } 82 }
94 strm->avail_in -= (unsigned)writ; 83 strm->avail_in -= (unsigned)writ;
95 strm->next_in += writ; 84 strm->next_in += writ;
96 } 85 }
97 return 0; 86 return 0;
87 }
88
89 /* check for a pending reset */
90 if (state->reset) {
91 /* don't start a new gzip member unless there is data to write */
92 if (strm->avail_in == 0)
93 return 0;
94 deflateReset(strm);
95 state->reset = 0;
98 } 96 }
99 97
100 /* run deflate() on provided input until it produces no more output */ 98 /* run deflate() on provided input until it produces no more output */
101 ret = Z_OK; 99 ret = Z_OK;
102 do { 100 do {
132 have -= strm->avail_out; 130 have -= strm->avail_out;
133 } while (have); 131 } while (have);
134 132
135 /* if that completed a deflate stream, allow another to start */ 133 /* if that completed a deflate stream, allow another to start */
136 if (flush == Z_FINISH) 134 if (flush == Z_FINISH)
137 deflateReset(strm); 135 state->reset = 1;
138 136
139 /* all done, no errors */ 137 /* all done, no errors */
140 return 0; 138 return 0;
141 } 139 }
142 140
143 /* Compress len zeros to output. Return -1 on a write error or memory 141 /* Compress len zeros to output. Return -1 on a write error or memory
144 allocation failure by gz_comp(), or 0 on success. */ 142 allocation failure by gz_comp(), or 0 on success. */
145 local int gz_zero(state, len) 143 local int gz_zero(gz_statep state, z_off64_t len) {
146 gz_statep state;
147 z_off64_t len;
148 {
149 int first; 144 int first;
150 unsigned n; 145 unsigned n;
151 z_streamp strm = &(state->strm); 146 z_streamp strm = &(state->strm);
152 147
153 /* consume whatever's left in the input buffer */ 148 /* consume whatever's left in the input buffer */
173 return 0; 168 return 0;
174 } 169 }
175 170
176 /* Write len bytes from buf to file. Return the number of bytes written. If 171 /* Write len bytes from buf to file. Return the number of bytes written. If
177 the returned value is less than len, then there was an error. */ 172 the returned value is less than len, then there was an error. */
178 local z_size_t gz_write(state, buf, len) 173 local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
179 gz_statep state;
180 voidpc buf;
181 z_size_t len;
182 {
183 z_size_t put = len; 174 z_size_t put = len;
184 175
185 /* if len is zero, avoid unnecessary operations */ 176 /* if len is zero, avoid unnecessary operations */
186 if (len == 0) 177 if (len == 0)
187 return 0; 178 return 0;
207 state->strm.next_in = state->in; 198 state->strm.next_in = state->in;
208 have = (unsigned)((state->strm.next_in + state->strm.avail_in) - 199 have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
209 state->in); 200 state->in);
210 copy = state->size - have; 201 copy = state->size - have;
211 if (copy > len) 202 if (copy > len)
212 copy = len; 203 copy = (unsigned)len;
213 memcpy(state->in + have, buf, copy); 204 memcpy(state->in + have, buf, copy);
214 state->strm.avail_in += copy; 205 state->strm.avail_in += copy;
215 state->x.pos += copy; 206 state->x.pos += copy;
216 buf = (const char *)buf + copy; 207 buf = (const char *)buf + copy;
217 len -= copy; 208 len -= copy;
227 /* directly compress user buffer to file */ 218 /* directly compress user buffer to file */
228 state->strm.next_in = (z_const Bytef *)buf; 219 state->strm.next_in = (z_const Bytef *)buf;
229 do { 220 do {
230 unsigned n = (unsigned)-1; 221 unsigned n = (unsigned)-1;
231 if (n > len) 222 if (n > len)
232 n = len; 223 n = (unsigned)len;
233 state->strm.avail_in = n; 224 state->strm.avail_in = n;
234 state->x.pos += n; 225 state->x.pos += n;
235 if (gz_comp(state, Z_NO_FLUSH) == -1) 226 if (gz_comp(state, Z_NO_FLUSH) == -1)
236 return 0; 227 return 0;
237 len -= n; 228 len -= n;
241 /* input was all buffered or compressed */ 232 /* input was all buffered or compressed */
242 return put; 233 return put;
243 } 234 }
244 235
245 /* -- see zlib.h -- */ 236 /* -- see zlib.h -- */
246 int ZEXPORT gzwrite(file, buf, len) 237 int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) {
247 gzFile file;
248 voidpc buf;
249 unsigned len;
250 {
251 gz_statep state; 238 gz_statep state;
252 239
253 /* get internal structure */ 240 /* get internal structure */
254 if (file == NULL) 241 if (file == NULL)
255 return 0; 242 return 0;
269 /* write len bytes from buf (the return value will fit in an int) */ 256 /* write len bytes from buf (the return value will fit in an int) */
270 return (int)gz_write(state, buf, len); 257 return (int)gz_write(state, buf, len);
271 } 258 }
272 259
273 /* -- see zlib.h -- */ 260 /* -- see zlib.h -- */
274 z_size_t ZEXPORT gzfwrite(buf, size, nitems, file) 261 z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems,
275 voidpc buf; 262 gzFile file) {
276 z_size_t size;
277 z_size_t nitems;
278 gzFile file;
279 {
280 z_size_t len; 263 z_size_t len;
281 gz_statep state; 264 gz_statep state;
282 265
283 /* get internal structure */ 266 /* get internal structure */
284 if (file == NULL) 267 if (file == NULL)
299 /* write len bytes to buf, return the number of full items written */ 282 /* write len bytes to buf, return the number of full items written */
300 return len ? gz_write(state, buf, len) / size : 0; 283 return len ? gz_write(state, buf, len) / size : 0;
301 } 284 }
302 285
303 /* -- see zlib.h -- */ 286 /* -- see zlib.h -- */
304 int ZEXPORT gzputc(file, c) 287 int ZEXPORT gzputc(gzFile file, int c) {
305 gzFile file;
306 int c;
307 {
308 unsigned have; 288 unsigned have;
309 unsigned char buf[1]; 289 unsigned char buf[1];
310 gz_statep state; 290 gz_statep state;
311 z_streamp strm; 291 z_streamp strm;
312 292
347 return -1; 327 return -1;
348 return c & 0xff; 328 return c & 0xff;
349 } 329 }
350 330
351 /* -- see zlib.h -- */ 331 /* -- see zlib.h -- */
352 int ZEXPORT gzputs(file, str) 332 int ZEXPORT gzputs(gzFile file, const char *s) {
353 gzFile file; 333 z_size_t len, put;
354 const char *str;
355 {
356 int ret;
357 z_size_t len;
358 gz_statep state; 334 gz_statep state;
359 335
360 /* get internal structure */ 336 /* get internal structure */
361 if (file == NULL) 337 if (file == NULL)
362 return -1; 338 return -1;
365 /* check that we're writing and that there's no error */ 341 /* check that we're writing and that there's no error */
366 if (state->mode != GZ_WRITE || state->err != Z_OK) 342 if (state->mode != GZ_WRITE || state->err != Z_OK)
367 return -1; 343 return -1;
368 344
369 /* write string */ 345 /* write string */
370 len = strlen(str); 346 len = strlen(s);
371 ret = gz_write(state, str, len); 347 if ((int)len < 0 || (unsigned)len != len) {
372 return ret == 0 && len != 0 ? -1 : ret; 348 gz_error(state, Z_STREAM_ERROR, "string length does not fit in int");
349 return -1;
350 }
351 put = gz_write(state, s, len);
352 return put < len ? -1 : (int)len;
373 } 353 }
374 354
375 #if defined(STDC) || defined(Z_HAVE_STDARG_H) 355 #if defined(STDC) || defined(Z_HAVE_STDARG_H)
376 #include <stdarg.h> 356 #include <stdarg.h>
377 357
378 /* -- see zlib.h -- */ 358 /* -- see zlib.h -- */
379 int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) 359 int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
380 {
381 int len; 360 int len;
382 unsigned left; 361 unsigned left;
383 char *next; 362 char *next;
384 gz_statep state; 363 gz_statep state;
385 z_streamp strm; 364 z_streamp strm;
439 if (strm->avail_in >= state->size) { 418 if (strm->avail_in >= state->size) {
440 left = strm->avail_in - state->size; 419 left = strm->avail_in - state->size;
441 strm->avail_in = state->size; 420 strm->avail_in = state->size;
442 if (gz_comp(state, Z_NO_FLUSH) == -1) 421 if (gz_comp(state, Z_NO_FLUSH) == -1)
443 return state->err; 422 return state->err;
444 memcpy(state->in, state->in + state->size, left); 423 memmove(state->in, state->in + state->size, left);
445 strm->next_in = state->in; 424 strm->next_in = state->in;
446 strm->avail_in = left; 425 strm->avail_in = left;
447 } 426 }
448 return len; 427 return len;
449 } 428 }
450 429
451 int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) 430 int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) {
452 {
453 va_list va; 431 va_list va;
454 int ret; 432 int ret;
455 433
456 va_start(va, format); 434 va_start(va, format);
457 ret = gzvprintf(file, format, va); 435 ret = gzvprintf(file, format, va);
460 } 438 }
461 439
462 #else /* !STDC && !Z_HAVE_STDARG_H */ 440 #else /* !STDC && !Z_HAVE_STDARG_H */
463 441
464 /* -- see zlib.h -- */ 442 /* -- see zlib.h -- */
465 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 443 int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
466 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) 444 int a4, int a5, int a6, int a7, int a8, int a9, int a10,
467 gzFile file; 445 int a11, int a12, int a13, int a14, int a15, int a16,
468 const char *format; 446 int a17, int a18, int a19, int a20) {
469 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
470 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
471 {
472 unsigned len, left; 447 unsigned len, left;
473 char *next; 448 char *next;
474 gz_statep state; 449 gz_statep state;
475 z_streamp strm; 450 z_streamp strm;
476 451
538 if (strm->avail_in >= state->size) { 513 if (strm->avail_in >= state->size) {
539 left = strm->avail_in - state->size; 514 left = strm->avail_in - state->size;
540 strm->avail_in = state->size; 515 strm->avail_in = state->size;
541 if (gz_comp(state, Z_NO_FLUSH) == -1) 516 if (gz_comp(state, Z_NO_FLUSH) == -1)
542 return state->err; 517 return state->err;
543 memcpy(state->in, state->in + state->size, left); 518 memmove(state->in, state->in + state->size, left);
544 strm->next_in = state->in; 519 strm->next_in = state->in;
545 strm->avail_in = left; 520 strm->avail_in = left;
546 } 521 }
547 return (int)len; 522 return (int)len;
548 } 523 }
549 524
550 #endif 525 #endif
551 526
552 /* -- see zlib.h -- */ 527 /* -- see zlib.h -- */
553 int ZEXPORT gzflush(file, flush) 528 int ZEXPORT gzflush(gzFile file, int flush) {
554 gzFile file;
555 int flush;
556 {
557 gz_statep state; 529 gz_statep state;
558 530
559 /* get internal structure */ 531 /* get internal structure */
560 if (file == NULL) 532 if (file == NULL)
561 return Z_STREAM_ERROR; 533 return Z_STREAM_ERROR;
580 (void)gz_comp(state, flush); 552 (void)gz_comp(state, flush);
581 return state->err; 553 return state->err;
582 } 554 }
583 555
584 /* -- see zlib.h -- */ 556 /* -- see zlib.h -- */
585 int ZEXPORT gzsetparams(file, level, strategy) 557 int ZEXPORT gzsetparams(gzFile file, int level, int strategy) {
586 gzFile file;
587 int level;
588 int strategy;
589 {
590 gz_statep state; 558 gz_statep state;
591 z_streamp strm; 559 z_streamp strm;
592 560
593 /* get internal structure */ 561 /* get internal structure */
594 if (file == NULL) 562 if (file == NULL)
595 return Z_STREAM_ERROR; 563 return Z_STREAM_ERROR;
596 state = (gz_statep)file; 564 state = (gz_statep)file;
597 strm = &(state->strm); 565 strm = &(state->strm);
598 566
599 /* check that we're writing and that there's no error */ 567 /* check that we're writing and that there's no error */
600 if (state->mode != GZ_WRITE || state->err != Z_OK) 568 if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct)
601 return Z_STREAM_ERROR; 569 return Z_STREAM_ERROR;
602 570
603 /* if no change is requested, then do nothing */ 571 /* if no change is requested, then do nothing */
604 if (level == state->level && strategy == state->strategy) 572 if (level == state->level && strategy == state->strategy)
605 return Z_OK; 573 return Z_OK;
622 state->strategy = strategy; 590 state->strategy = strategy;
623 return Z_OK; 591 return Z_OK;
624 } 592 }
625 593
626 /* -- see zlib.h -- */ 594 /* -- see zlib.h -- */
627 int ZEXPORT gzclose_w(file) 595 int ZEXPORT gzclose_w(gzFile file) {
628 gzFile file;
629 {
630 int ret = Z_OK; 596 int ret = Z_OK;
631 gz_statep state; 597 gz_statep state;
632 598
633 /* get internal structure */ 599 /* get internal structure */
634 if (file == NULL) 600 if (file == NULL)