gpu_neon: revive the old tests
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.6 / zlibWrapper / gzwrite.c
CommitLineData
648db22b 1/* gzwrite.c contains minimal changes required to be compiled with zlibWrapper:
2 * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */
3
4 /* gzwrite.c -- zlib functions for writing gzip files
5 * Copyright (C) 2004-2017 Mark Adler
6 * For conditions of distribution and use, see https://www.zlib.net/zlib_license.html
b24e7fce 7 */
8
648db22b 9#include <assert.h>
10
b24e7fce 11#include "gzguts.h"
12
13/* Local functions */
648db22b 14local int gz_init _Z_OF((gz_statep));
15local int gz_comp _Z_OF((gz_statep, int));
16local int gz_zero _Z_OF((gz_statep, z_off64_t));
17local z_size_t gz_write _Z_OF((gz_statep, voidpc, z_size_t));
b24e7fce 18
19/* Initialize state for writing a gzip file. Mark initialization by setting
648db22b 20 state.state->size to non-zero. Return -1 on a memory allocation failure, or 0 on
b24e7fce 21 success. */
f535537f 22local int gz_init(gz_statep state) {
b24e7fce 23 int ret;
648db22b 24 z_streamp strm = &(state.state->strm);
b24e7fce 25
26 /* allocate input buffer (double size for gzprintf) */
648db22b 27 state.state->in = (unsigned char*)malloc(state.state->want << 1);
28 if (state.state->in == NULL) {
b24e7fce 29 gz_error(state, Z_MEM_ERROR, "out of memory");
30 return -1;
31 }
32
33 /* only need output buffer and deflate state if compressing */
648db22b 34 if (!state.state->direct) {
b24e7fce 35 /* allocate output buffer */
648db22b 36 state.state->out = (unsigned char*)malloc(state.state->want);
37 if (state.state->out == NULL) {
38 free(state.state->in);
b24e7fce 39 gz_error(state, Z_MEM_ERROR, "out of memory");
40 return -1;
41 }
42
43 /* allocate deflate memory, set up for gzip compression */
44 strm->zalloc = Z_NULL;
45 strm->zfree = Z_NULL;
46 strm->opaque = Z_NULL;
648db22b 47 ret = deflateInit2(strm, state.state->level, Z_DEFLATED,
48 MAX_WBITS + 16, DEF_MEM_LEVEL, state.state->strategy);
b24e7fce 49 if (ret != Z_OK) {
648db22b 50 free(state.state->out);
51 free(state.state->in);
b24e7fce 52 gz_error(state, Z_MEM_ERROR, "out of memory");
53 return -1;
54 }
55 strm->next_in = NULL;
56 }
57
58 /* mark state as initialized */
648db22b 59 state.state->size = state.state->want;
b24e7fce 60
61 /* initialize write buffer if compressing */
648db22b 62 if (!state.state->direct) {
63 strm->avail_out = state.state->size;
64 strm->next_out = state.state->out;
65 state.state->x.next = strm->next_out;
b24e7fce 66 }
67 return 0;
68}
69
70/* Compress whatever is at avail_in and next_in and write to the output file.
71 Return -1 if there is an error writing to the output file or if gz_init()
72 fails to allocate memory, otherwise 0. flush is assumed to be a valid
73 deflate() flush value. If flush is Z_FINISH, then the deflate() state is
74 reset to start a new gzip stream. If gz->direct is true, then simply write
75 to the output file without compressing, and ignore flush. */
f535537f 76local int gz_comp(gz_statep state, int flush) {
b24e7fce 77 int ret, writ;
78 unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
648db22b 79 z_streamp strm = &(state.state->strm);
b24e7fce 80
81 /* allocate memory if this is the first time through */
648db22b 82 if (state.state->size == 0 && gz_init(state) == -1)
b24e7fce 83 return -1;
84
85 /* write directly if requested */
648db22b 86 if (state.state->direct) {
b24e7fce 87 while (strm->avail_in) {
88 put = strm->avail_in > max ? max : strm->avail_in;
648db22b 89 writ = (int)write(state.state->fd, strm->next_in, put);
b24e7fce 90 if (writ < 0) {
91 gz_error(state, Z_ERRNO, zstrerror());
92 return -1;
93 }
94 strm->avail_in -= (unsigned)writ;
95 strm->next_in += writ;
96 }
97 return 0;
98 }
99
100 /* run deflate() on provided input until it produces no more output */
101 ret = Z_OK;
102 do {
103 /* write out current buffer contents if full, or if flushing, but if
104 doing Z_FINISH then don't write until we get to Z_STREAM_END */
105 if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
106 (flush != Z_FINISH || ret == Z_STREAM_END))) {
648db22b 107 while (strm->next_out > state.state->x.next) {
108 put = strm->next_out - state.state->x.next > (int)max ? max :
109 (unsigned)(strm->next_out - state.state->x.next);
110 writ = (int)write(state.state->fd, state.state->x.next, put);
b24e7fce 111 if (writ < 0) {
112 gz_error(state, Z_ERRNO, zstrerror());
113 return -1;
114 }
648db22b 115 state.state->x.next += writ;
b24e7fce 116 }
117 if (strm->avail_out == 0) {
648db22b 118 strm->avail_out = state.state->size;
119 strm->next_out = state.state->out;
120 state.state->x.next = state.state->out;
b24e7fce 121 }
122 }
123
124 /* compress */
125 have = strm->avail_out;
126 ret = deflate(strm, flush);
127 if (ret == Z_STREAM_ERROR) {
128 gz_error(state, Z_STREAM_ERROR,
129 "internal error: deflate stream corrupt");
130 return -1;
131 }
132 have -= strm->avail_out;
133 } while (have);
134
135 /* if that completed a deflate stream, allow another to start */
136 if (flush == Z_FINISH)
648db22b 137 deflateReset(strm);
b24e7fce 138
139 /* all done, no errors */
140 return 0;
141}
142
143/* Compress len zeros to output. Return -1 on a write error or memory
144 allocation failure by gz_comp(), or 0 on success. */
f535537f 145local int gz_zero(gz_statep state, z_off64_t len) {
b24e7fce 146 int first;
147 unsigned n;
648db22b 148 z_streamp strm = &(state.state->strm);
b24e7fce 149
150 /* consume whatever's left in the input buffer */
151 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
152 return -1;
153
154 /* compress len zeros (len guaranteed > 0) */
155 first = 1;
156 while (len) {
648db22b 157 n = GT_OFF(state.state->size) || (z_off64_t)state.state->size > len ?
158 (unsigned)len : state.state->size;
b24e7fce 159 if (first) {
648db22b 160 memset(state.state->in, 0, n);
b24e7fce 161 first = 0;
162 }
163 strm->avail_in = n;
648db22b 164 strm->next_in = state.state->in;
165 state.state->x.pos += n;
b24e7fce 166 if (gz_comp(state, Z_NO_FLUSH) == -1)
167 return -1;
168 len -= n;
169 }
170 return 0;
171}
172
173/* Write len bytes from buf to file. Return the number of bytes written. If
174 the returned value is less than len, then there was an error. */
f535537f 175local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
b24e7fce 176 z_size_t put = len;
177
178 /* if len is zero, avoid unnecessary operations */
179 if (len == 0)
180 return 0;
181
182 /* allocate memory if this is the first time through */
648db22b 183 if (state.state->size == 0 && gz_init(state) == -1)
b24e7fce 184 return 0;
185
186 /* check for seek request */
648db22b 187 if (state.state->seek) {
188 state.state->seek = 0;
189 if (gz_zero(state, state.state->skip) == -1)
b24e7fce 190 return 0;
191 }
192
193 /* for small len, copy to input buffer, otherwise compress directly */
648db22b 194 if (len < state.state->size) {
b24e7fce 195 /* copy to input buffer, compress when full */
196 do {
648db22b 197 z_size_t have, copy;
b24e7fce 198
648db22b 199 if (state.state->strm.avail_in == 0)
200 state.state->strm.next_in = state.state->in;
201 have = (unsigned)((state.state->strm.next_in + state.state->strm.avail_in) -
202 state.state->in);
203 copy = state.state->size - have;
b24e7fce 204 if (copy > len)
648db22b 205 copy = len;
206 memcpy(state.state->in + have, buf, copy);
207 state.state->strm.avail_in += copy;
208 state.state->x.pos += copy;
b24e7fce 209 buf = (const char *)buf + copy;
210 len -= copy;
211 if (len && gz_comp(state, Z_NO_FLUSH) == -1)
212 return 0;
213 } while (len);
214 }
215 else {
216 /* consume whatever's left in the input buffer */
648db22b 217 if (state.state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
b24e7fce 218 return 0;
219
220 /* directly compress user buffer to file */
648db22b 221 state.state->strm.next_in = (z_const Bytef *)buf;
b24e7fce 222 do {
648db22b 223 z_size_t n = (unsigned)-1;
b24e7fce 224 if (n > len)
648db22b 225 n = len;
226 state.state->strm.avail_in = (z_uInt)n;
227 state.state->x.pos += n;
b24e7fce 228 if (gz_comp(state, Z_NO_FLUSH) == -1)
229 return 0;
230 len -= n;
231 } while (len);
232 }
233
234 /* input was all buffered or compressed */
235 return put;
236}
237
238/* -- see zlib.h -- */
f535537f 239int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) {
b24e7fce 240 gz_statep state;
241
242 /* get internal structure */
243 if (file == NULL)
244 return 0;
648db22b 245 state.file = file;
b24e7fce 246
247 /* check that we're writing and that there's no error */
648db22b 248 if (state.state->mode != GZ_WRITE || state.state->err != Z_OK)
b24e7fce 249 return 0;
250
251 /* since an int is returned, make sure len fits in one, otherwise return
252 with an error (this avoids a flaw in the interface) */
253 if ((int)len < 0) {
254 gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
255 return 0;
256 }
257
258 /* write len bytes from buf (the return value will fit in an int) */
259 return (int)gz_write(state, buf, len);
260}
261
262/* -- see zlib.h -- */
f535537f 263z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems,
264 gzFile file) {
b24e7fce 265 z_size_t len;
266 gz_statep state;
267
268 /* get internal structure */
648db22b 269 assert(size != 0);
b24e7fce 270 if (file == NULL)
271 return 0;
648db22b 272 state.file = file;
b24e7fce 273
274 /* check that we're writing and that there's no error */
648db22b 275 if (state.state->mode != GZ_WRITE || state.state->err != Z_OK)
b24e7fce 276 return 0;
277
278 /* compute bytes to read -- error on overflow */
279 len = nitems * size;
648db22b 280 if (size && (len / size != nitems)) {
b24e7fce 281 gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
282 return 0;
283 }
284
285 /* write len bytes to buf, return the number of full items written */
286 return len ? gz_write(state, buf, len) / size : 0;
287}
288
289/* -- see zlib.h -- */
f535537f 290int ZEXPORT gzputc(gzFile file, int c) {
b24e7fce 291 unsigned have;
292 unsigned char buf[1];
293 gz_statep state;
294 z_streamp strm;
295
296 /* get internal structure */
297 if (file == NULL)
298 return -1;
648db22b 299 state.file = file;
300 strm = &(state.state->strm);
b24e7fce 301
302 /* check that we're writing and that there's no error */
648db22b 303 if (state.state->mode != GZ_WRITE || state.state->err != Z_OK)
b24e7fce 304 return -1;
305
306 /* check for seek request */
648db22b 307 if (state.state->seek) {
308 state.state->seek = 0;
309 if (gz_zero(state, state.state->skip) == -1)
b24e7fce 310 return -1;
311 }
312
648db22b 313 /* try writing to input buffer for speed (state.state->size == 0 if buffer not
b24e7fce 314 initialized) */
648db22b 315 if (state.state->size) {
b24e7fce 316 if (strm->avail_in == 0)
648db22b 317 strm->next_in = state.state->in;
318 have = (unsigned)((strm->next_in + strm->avail_in) - state.state->in);
319 if (have < state.state->size) {
320 state.state->in[have] = (unsigned char)c;
b24e7fce 321 strm->avail_in++;
648db22b 322 state.state->x.pos++;
b24e7fce 323 return c & 0xff;
324 }
325 }
326
327 /* no room in buffer or not initialized, use gz_write() */
328 buf[0] = (unsigned char)c;
329 if (gz_write(state, buf, 1) != 1)
330 return -1;
331 return c & 0xff;
332}
333
334/* -- see zlib.h -- */
f535537f 335int ZEXPORT gzputs(gzFile file, const char *str) {
648db22b 336 int ret;
337 z_size_t len;
b24e7fce 338 gz_statep state;
339
340 /* get internal structure */
341 if (file == NULL)
342 return -1;
648db22b 343 state.file = file;
b24e7fce 344
345 /* check that we're writing and that there's no error */
648db22b 346 if (state.state->mode != GZ_WRITE || state.state->err != Z_OK)
b24e7fce 347 return -1;
348
349 /* write string */
648db22b 350 len = strlen(str);
351 ret = (int)gz_write(state, str, len);
352 return ret == 0 && len != 0 ? -1 : ret;
b24e7fce 353}
354
355#if defined(STDC) || defined(Z_HAVE_STDARG_H)
356#include <stdarg.h>
357
358/* -- see zlib.h -- */
f535537f 359int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
b24e7fce 360 int len;
361 unsigned left;
362 char *next;
363 gz_statep state;
364 z_streamp strm;
365
366 /* get internal structure */
367 if (file == NULL)
368 return Z_STREAM_ERROR;
648db22b 369 state.file = file;
370 strm = &(state.state->strm);
b24e7fce 371
372 /* check that we're writing and that there's no error */
648db22b 373 if (state.state->mode != GZ_WRITE || state.state->err != Z_OK)
b24e7fce 374 return Z_STREAM_ERROR;
375
376 /* make sure we have some buffer space */
648db22b 377 if (state.state->size == 0 && gz_init(state) == -1)
378 return state.state->err;
b24e7fce 379
380 /* check for seek request */
648db22b 381 if (state.state->seek) {
382 state.state->seek = 0;
383 if (gz_zero(state, state.state->skip) == -1)
384 return state.state->err;
b24e7fce 385 }
386
387 /* do the printf() into the input buffer, put length in len -- the input
388 buffer is double-sized just for this function, so there is guaranteed to
648db22b 389 be state.state->size bytes available after the current contents */
b24e7fce 390 if (strm->avail_in == 0)
648db22b 391 strm->next_in = state.state->in;
392 next = (char *)(state.state->in + (strm->next_in - state.state->in) + strm->avail_in);
393 next[state.state->size - 1] = 0;
b24e7fce 394#ifdef NO_vsnprintf
395# ifdef HAS_vsprintf_void
396 (void)vsprintf(next, format, va);
648db22b 397 for (len = 0; len < state.state->size; len++)
b24e7fce 398 if (next[len] == 0) break;
399# else
400 len = vsprintf(next, format, va);
401# endif
402#else
403# ifdef HAS_vsnprintf_void
648db22b 404 (void)vsnprintf(next, state.state->size, format, va);
b24e7fce 405 len = strlen(next);
406# else
648db22b 407 len = vsnprintf(next, state.state->size, format, va);
b24e7fce 408# endif
409#endif
410
411 /* check that printf() results fit in buffer */
648db22b 412 if (len == 0 || (unsigned)len >= state.state->size || next[state.state->size - 1] != 0)
b24e7fce 413 return 0;
414
415 /* update buffer and position, compress first half if past that */
416 strm->avail_in += (unsigned)len;
648db22b 417 state.state->x.pos += len;
418 if (strm->avail_in >= state.state->size) {
419 left = strm->avail_in - state.state->size;
420 strm->avail_in = state.state->size;
b24e7fce 421 if (gz_comp(state, Z_NO_FLUSH) == -1)
648db22b 422 return state.state->err;
423 memcpy(state.state->in, state.state->in + state.state->size, left);
424 strm->next_in = state.state->in;
b24e7fce 425 strm->avail_in = left;
426 }
427 return len;
428}
429
f535537f 430int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) {
b24e7fce 431 va_list va;
432 int ret;
433
434 va_start(va, format);
435 ret = gzvprintf(file, format, va);
436 va_end(va);
437 return ret;
438}
439
440#else /* !STDC && !Z_HAVE_STDARG_H */
441
442/* -- see zlib.h -- */
f535537f 443int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
444 int a4, int a5, int a6, int a7, int a8, int a9, int a10,
445 int a11, int a12, int a13, int a14, int a15, int a16,
446 int a17, int a18, int a19, int a20) {
b24e7fce 447 unsigned len, left;
448 char *next;
449 gz_statep state;
450 z_streamp strm;
451
452 /* get internal structure */
453 if (file == NULL)
454 return Z_STREAM_ERROR;
455 state = (gz_statep)file;
648db22b 456 strm = &(state.state->strm);
b24e7fce 457
458 /* check that can really pass pointer in ints */
459 if (sizeof(int) != sizeof(void *))
460 return Z_STREAM_ERROR;
461
462 /* check that we're writing and that there's no error */
648db22b 463 if (state.state->mode != GZ_WRITE || state.state->err != Z_OK)
b24e7fce 464 return Z_STREAM_ERROR;
465
466 /* make sure we have some buffer space */
648db22b 467 if (state.state->size == 0 && gz_init(state) == -1)
468 return state.state->error;
b24e7fce 469
470 /* check for seek request */
648db22b 471 if (state.state->seek) {
472 state.state->seek = 0;
473 if (gz_zero(state, state.state->skip) == -1)
474 return state.state->error;
b24e7fce 475 }
476
477 /* do the printf() into the input buffer, put length in len -- the input
478 buffer is double-sized just for this function, so there is guaranteed to
648db22b 479 be state.state->size bytes available after the current contents */
b24e7fce 480 if (strm->avail_in == 0)
648db22b 481 strm->next_in = state.state->in;
b24e7fce 482 next = (char *)(strm->next_in + strm->avail_in);
648db22b 483 next[state.state->size - 1] = 0;
b24e7fce 484#ifdef NO_snprintf
485# ifdef HAS_sprintf_void
486 sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
487 a13, a14, a15, a16, a17, a18, a19, a20);
488 for (len = 0; len < size; len++)
489 if (next[len] == 0)
490 break;
491# else
492 len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
493 a12, a13, a14, a15, a16, a17, a18, a19, a20);
494# endif
495#else
496# ifdef HAS_snprintf_void
648db22b 497 snprintf(next, state.state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
b24e7fce 498 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
499 len = strlen(next);
500# else
648db22b 501 len = snprintf(next, state.state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
b24e7fce 502 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
503# endif
504#endif
505
506 /* check that printf() results fit in buffer */
648db22b 507 if (len == 0 || len >= state.state->size || next[state.state->size - 1] != 0)
b24e7fce 508 return 0;
509
510 /* update buffer and position, compress first half if past that */
511 strm->avail_in += len;
648db22b 512 state.state->x.pos += len;
513 if (strm->avail_in >= state.state->size) {
514 left = strm->avail_in - state.state->size;
515 strm->avail_in = state.state->size;
b24e7fce 516 if (gz_comp(state, Z_NO_FLUSH) == -1)
648db22b 517 return state.state->err;
518 memcpy(state.state->in, state.state->in + state.state->size, left);
519 strm->next_in = state.state->in;
b24e7fce 520 strm->avail_in = left;
521 }
522 return (int)len;
523}
524
525#endif
526
527/* -- see zlib.h -- */
f535537f 528int ZEXPORT gzflush(gzFile file, int flush) {
b24e7fce 529 gz_statep state;
530
531 /* get internal structure */
532 if (file == NULL)
533 return Z_STREAM_ERROR;
648db22b 534 state.file = file;
b24e7fce 535
536 /* check that we're writing and that there's no error */
648db22b 537 if (state.state->mode != GZ_WRITE || state.state->err != Z_OK)
b24e7fce 538 return Z_STREAM_ERROR;
539
540 /* check flush parameter */
541 if (flush < 0 || flush > Z_FINISH)
542 return Z_STREAM_ERROR;
543
544 /* check for seek request */
648db22b 545 if (state.state->seek) {
546 state.state->seek = 0;
547 if (gz_zero(state, state.state->skip) == -1)
548 return state.state->err;
b24e7fce 549 }
550
551 /* compress remaining data with requested flush */
552 (void)gz_comp(state, flush);
648db22b 553 return state.state->err;
b24e7fce 554}
555
556/* -- see zlib.h -- */
f535537f 557int ZEXPORT gzsetparams(gzFile file, int level, int strategy) {
b24e7fce 558 gz_statep state;
559 z_streamp strm;
560
561 /* get internal structure */
562 if (file == NULL)
563 return Z_STREAM_ERROR;
648db22b 564 state.file = file;
565 strm = &(state.state->strm);
b24e7fce 566
567 /* check that we're writing and that there's no error */
648db22b 568 if (state.state->mode != GZ_WRITE || state.state->err != Z_OK)
b24e7fce 569 return Z_STREAM_ERROR;
570
571 /* if no change is requested, then do nothing */
648db22b 572 if (level == state.state->level && strategy == state.state->strategy)
b24e7fce 573 return Z_OK;
574
575 /* check for seek request */
648db22b 576 if (state.state->seek) {
577 state.state->seek = 0;
578 if (gz_zero(state, state.state->skip) == -1)
579 return state.state->err;
b24e7fce 580 }
581
582 /* change compression parameters for subsequent input */
648db22b 583 if (state.state->size) {
b24e7fce 584 /* flush previous input with previous parameters before changing */
585 if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
648db22b 586 return state.state->err;
b24e7fce 587 deflateParams(strm, level, strategy);
588 }
648db22b 589 state.state->level = level;
590 state.state->strategy = strategy;
b24e7fce 591 return Z_OK;
592}
593
594/* -- see zlib.h -- */
f535537f 595int ZEXPORT gzclose_w(gzFile file) {
b24e7fce 596 int ret = Z_OK;
597 gz_statep state;
598
599 /* get internal structure */
600 if (file == NULL)
601 return Z_STREAM_ERROR;
648db22b 602 state.file = file;
b24e7fce 603
604 /* check that we're writing */
648db22b 605 if (state.state->mode != GZ_WRITE)
b24e7fce 606 return Z_STREAM_ERROR;
607
608 /* check for seek request */
648db22b 609 if (state.state->seek) {
610 state.state->seek = 0;
611 if (gz_zero(state, state.state->skip) == -1)
612 ret = state.state->err;
b24e7fce 613 }
614
615 /* flush, free memory, and close file */
616 if (gz_comp(state, Z_FINISH) == -1)
648db22b 617 ret = state.state->err;
618 if (state.state->size) {
619 if (!state.state->direct) {
620 (void)deflateEnd(&(state.state->strm));
621 free(state.state->out);
b24e7fce 622 }
648db22b 623 free(state.state->in);
b24e7fce 624 }
625 gz_error(state, Z_OK, NULL);
648db22b 626 free(state.state->path);
627 if (close(state.state->fd) == -1)
b24e7fce 628 ret = Z_ERRNO;
648db22b 629 free(state.state);
b24e7fce 630 return ret;
631}