git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.6 / zlibWrapper / examples / minigzip.c
CommitLineData
648db22b 1/* minigzip.c contains minimal changes required to be compiled with zlibWrapper:
2 * - #include "zlib.h" was changed to #include "zstd_zlibwrapper.h" */
3
9e052883 4/* minigzip.c -- simulate gzip using the zlib compression library
648db22b 5 * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly.
6 * For conditions of distribution and use, see https://www.zlib.net/zlib_license.html
9e052883 7 */
8
9/*
10 * minigzip is a minimal implementation of the gzip utility. This is
11 * only an example of using zlib and isn't meant to replace the
12 * full-featured gzip. No attempt is made to deal with file systems
13 * limiting names to 14 or 8+3 characters, etc... Error checking is
14 * very limited. So use minigzip only for testing; use gzip for the
15 * real thing. On MSDOS, use only on file names without extension
16 * or in pipe mode.
17 */
18
19/* @(#) $Id$ */
20
648db22b 21#define _POSIX_SOURCE /* fileno */
22
23#include "zstd_zlibwrapper.h"
9e052883 24#include <stdio.h>
25
26#ifdef STDC
27# include <string.h>
28# include <stdlib.h>
29#endif
30
31#ifdef USE_MMAP
32# include <sys/types.h>
33# include <sys/mman.h>
34# include <sys/stat.h>
35#endif
36
f535537f 37#if defined(MSDOS) || defined(OS2) || defined(_WIN32) || defined(__CYGWIN__)
9e052883 38# include <fcntl.h>
39# include <io.h>
40# ifdef UNDER_CE
41# include <stdlib.h>
42# endif
43# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
44#else
45# define SET_BINARY_MODE(file)
46#endif
47
648db22b 48#ifdef _MSC_VER
9e052883 49# define snprintf _snprintf
50#endif
51
52#ifdef VMS
53# define unlink delete
54# define GZ_SUFFIX "-gz"
55#endif
56#ifdef RISCOS
57# define unlink remove
58# define GZ_SUFFIX "-gz"
59# define fileno(file) file->__file
60#endif
61#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
62# include <unix.h> /* for fileno */
63#endif
64
65#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
f535537f 66#ifndef _WIN32 /* unlink already in stdio.h for WIN32 */
648db22b 67 extern int unlink _Z_OF((const char *));
9e052883 68#endif
69#endif
70
71#if defined(UNDER_CE)
72# include <windows.h>
73# define perror(s) pwinerror(s)
74
75/* Map the Windows error number in ERROR to a locale-dependent error
76 message string and return a pointer to it. Typically, the values
77 for ERROR come from GetLastError.
78
79 The string pointed to shall not be modified by the application,
80 but may be overwritten by a subsequent call to strwinerror
81
82 The strwinerror function does not change the current setting
83 of GetLastError. */
84
f535537f 85static char *strwinerror(DWORD error)
9e052883 86{
87 static char buf[1024];
88
89 wchar_t *msgbuf;
90 DWORD lasterr = GetLastError();
91 DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
92 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
93 NULL,
94 error,
95 0, /* Default language */
96 (LPVOID)&msgbuf,
97 0,
98 NULL);
99 if (chars != 0) {
100 /* If there is an \r\n appended, zap it. */
101 if (chars >= 2
102 && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
103 chars -= 2;
104 msgbuf[chars] = 0;
105 }
106
107 if (chars > sizeof (buf) - 1) {
108 chars = sizeof (buf) - 1;
109 msgbuf[chars] = 0;
110 }
111
112 wcstombs(buf, msgbuf, chars + 1);
113 LocalFree(msgbuf);
114 }
115 else {
116 sprintf(buf, "unknown win32 error (%ld)", error);
117 }
118
119 SetLastError(lasterr);
120 return buf;
121}
122
f535537f 123static void pwinerror (const char *s)
9e052883 124{
125 if (s && *s)
126 fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
127 else
128 fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
129}
130
131#endif /* UNDER_CE */
132
133#ifndef GZ_SUFFIX
134# define GZ_SUFFIX ".gz"
135#endif
136#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
137
138#define BUFLEN 16384
139#define MAX_NAME_LEN 1024
140
141#ifdef MAXSEG_64K
142# define local static
143 /* Needed for systems with limitation on stack size. */
144#else
145# define local
146#endif
147
148#ifdef Z_SOLO
149/* for Z_SOLO, create simplified gz* functions using deflate and inflate */
150
151#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
152# include <unistd.h> /* for unlink() */
153#endif
154
648db22b 155void *myalloc _Z_OF((void *, unsigned, unsigned));
156void myfree _Z_OF((void *, void *));
9e052883 157
158void *myalloc(q, n, m)
159 void *q;
160 unsigned n, m;
161{
648db22b 162 q = Z_NULL;
9e052883 163 return calloc(n, m);
164}
165
166void myfree(q, p)
167 void *q, *p;
168{
648db22b 169 q = Z_NULL;
9e052883 170 free(p);
171}
172
173typedef struct gzFile_s {
174 FILE *file;
175 int write;
176 int err;
177 char *msg;
178 z_stream strm;
179} *gzFile;
180
648db22b 181gzFile gzopen _Z_OF((const char *, const char *));
182gzFile gzdopen _Z_OF((int, const char *));
183gzFile gz_open _Z_OF((const char *, int, const char *));
9e052883 184
185gzFile gzopen(path, mode)
186const char *path;
187const char *mode;
188{
189 return gz_open(path, -1, mode);
190}
191
192gzFile gzdopen(fd, mode)
193int fd;
194const char *mode;
195{
196 return gz_open(NULL, fd, mode);
197}
198
f535537f 199gzFile gz_open(const char *path, int fd, const char *mode) {
9e052883 200 gzFile gz;
201 int ret;
202
203 gz = malloc(sizeof(struct gzFile_s));
204 if (gz == NULL)
205 return NULL;
206 gz->write = strchr(mode, 'w') != NULL;
207 gz->strm.zalloc = myalloc;
208 gz->strm.zfree = myfree;
209 gz->strm.opaque = Z_NULL;
210 if (gz->write)
211 ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
212 else {
213 gz->strm.next_in = 0;
214 gz->strm.avail_in = Z_NULL;
215 ret = inflateInit2(&(gz->strm), 15 + 16);
216 }
217 if (ret != Z_OK) {
218 free(gz);
219 return NULL;
220 }
221 gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
222 fopen(path, gz->write ? "wb" : "rb");
223 if (gz->file == NULL) {
224 gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
225 free(gz);
226 return NULL;
227 }
228 gz->err = 0;
229 gz->msg = "";
230 return gz;
231}
232
648db22b 233int gzwrite _Z_OF((gzFile, const void *, unsigned));
9e052883 234
f535537f 235int gzwrite(gzFile gz, const void *buf, unsigned len) {
9e052883 236 z_stream *strm;
237 unsigned char out[BUFLEN];
238
239 if (gz == NULL || !gz->write)
240 return 0;
241 strm = &(gz->strm);
242 strm->next_in = (void *)buf;
243 strm->avail_in = len;
244 do {
245 strm->next_out = out;
246 strm->avail_out = BUFLEN;
247 (void)deflate(strm, Z_NO_FLUSH);
248 fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
249 } while (strm->avail_out == 0);
250 return len;
251}
252
648db22b 253int gzread _Z_OF((gzFile, void *, unsigned));
9e052883 254
f535537f 255int gzread(gzFile gz, void *buf, unsigned len) {
9e052883 256 int ret;
257 unsigned got;
258 unsigned char in[1];
259 z_stream *strm;
260
261 if (gz == NULL || gz->write)
262 return 0;
263 if (gz->err)
264 return 0;
265 strm = &(gz->strm);
266 strm->next_out = (void *)buf;
267 strm->avail_out = len;
268 do {
269 got = fread(in, 1, 1, gz->file);
270 if (got == 0)
271 break;
272 strm->next_in = in;
273 strm->avail_in = 1;
274 ret = inflate(strm, Z_NO_FLUSH);
275 if (ret == Z_DATA_ERROR) {
276 gz->err = Z_DATA_ERROR;
277 gz->msg = strm->msg;
278 return 0;
279 }
280 if (ret == Z_STREAM_END)
281 inflateReset(strm);
282 } while (strm->avail_out);
283 return len - strm->avail_out;
284}
285
648db22b 286int gzclose _Z_OF((gzFile));
9e052883 287
f535537f 288int gzclose(gzFile gz) {
9e052883 289 z_stream *strm;
290 unsigned char out[BUFLEN];
291
292 if (gz == NULL)
293 return Z_STREAM_ERROR;
294 strm = &(gz->strm);
295 if (gz->write) {
296 strm->next_in = Z_NULL;
297 strm->avail_in = 0;
298 do {
299 strm->next_out = out;
300 strm->avail_out = BUFLEN;
301 (void)deflate(strm, Z_FINISH);
302 fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
303 } while (strm->avail_out == 0);
304 deflateEnd(strm);
305 }
306 else
307 inflateEnd(strm);
308 fclose(gz->file);
309 free(gz);
310 return Z_OK;
311}
312
648db22b 313const char *gzerror _Z_OF((gzFile, int *));
9e052883 314
f535537f 315const char *gzerror(gzFile gz, int *err)
9e052883 316{
317 *err = gz->err;
318 return gz->msg;
319}
320
321#endif
322
648db22b 323char *prog;
9e052883 324
648db22b 325void error _Z_OF((const char *msg));
326void gz_compress _Z_OF((FILE *in, gzFile out));
9e052883 327#ifdef USE_MMAP
648db22b 328int gz_compress_mmap _Z_OF((FILE *in, gzFile out));
9e052883 329#endif
648db22b 330void gz_uncompress _Z_OF((gzFile in, FILE *out));
331void file_compress _Z_OF((char *file, char *mode));
332void file_uncompress _Z_OF((char *file));
333int main _Z_OF((int argc, char *argv[]));
9e052883 334
335/* ===========================================================================
336 * Display error message and exit
337 */
f535537f 338void error(const char *msg)
9e052883 339{
340 fprintf(stderr, "%s: %s\n", prog, msg);
341 exit(1);
342}
343
344/* ===========================================================================
345 * Compress input to output then close both files.
346 */
347
f535537f 348void gz_compress(FILE *in, gzFile out)
9e052883 349{
350 local char buf[BUFLEN];
351 int len;
352 int err;
353
354#ifdef USE_MMAP
355 /* Try first compressing with mmap. If mmap fails (minigzip used in a
356 * pipe), use the normal fread loop.
357 */
358 if (gz_compress_mmap(in, out) == Z_OK) return;
359#endif
360 for (;;) {
361 len = (int)fread(buf, 1, sizeof(buf), in);
362 if (ferror(in)) {
363 perror("fread");
364 exit(1);
365 }
366 if (len == 0) break;
367
368 if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
369 }
370 fclose(in);
371 if (gzclose(out) != Z_OK) error("failed gzclose");
372}
373
374#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
375
376/* Try compressing the input file at once using mmap. Return Z_OK if
377 * if success, Z_ERRNO otherwise.
378 */
f535537f 379int gz_compress_mmap(FILE *in, gzFile out) {
9e052883 380 int len;
381 int err;
382 int ifd = fileno(in);
383 caddr_t buf; /* mmap'ed buffer for the entire input file */
384 off_t buf_len; /* length of the input file */
385 struct stat sb;
386
387 /* Determine the size of the file, needed for mmap: */
388 if (fstat(ifd, &sb) < 0) return Z_ERRNO;
389 buf_len = sb.st_size;
390 if (buf_len <= 0) return Z_ERRNO;
391
392 /* Now do the actual mmap: */
393 buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
394 if (buf == (caddr_t)(-1)) return Z_ERRNO;
395
396 /* Compress the whole file at once: */
397 len = gzwrite(out, (char *)buf, (unsigned)buf_len);
398
399 if (len != (int)buf_len) error(gzerror(out, &err));
400
401 munmap(buf, buf_len);
402 fclose(in);
403 if (gzclose(out) != Z_OK) error("failed gzclose");
404 return Z_OK;
405}
406#endif /* USE_MMAP */
407
408/* ===========================================================================
409 * Uncompress input to output then close both files.
410 */
f535537f 411void gz_uncompress(gzFile in, FILE *out) {
9e052883 412 local char buf[BUFLEN];
413 int len;
414 int err;
415
416 for (;;) {
417 len = gzread(in, buf, sizeof(buf));
418 if (len < 0) error (gzerror(in, &err));
419 if (len == 0) break;
420
421 if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
422 error("failed fwrite");
423 }
424 }
425 if (fclose(out)) error("failed fclose");
426
427 if (gzclose(in) != Z_OK) error("failed gzclose");
428}
429
430
431/* ===========================================================================
432 * Compress the given file: create a corresponding .gz file and remove the
433 * original.
434 */
f535537f 435void file_compress(char *file, char *mode) {
9e052883 436 local char outfile[MAX_NAME_LEN];
437 FILE *in;
438 gzFile out;
439
440 if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
441 fprintf(stderr, "%s: filename too long\n", prog);
442 exit(1);
443 }
444
9e052883 445 strcpy(outfile, file);
446 strcat(outfile, GZ_SUFFIX);
9e052883 447
448 in = fopen(file, "rb");
449 if (in == NULL) {
450 perror(file);
451 exit(1);
452 }
453 out = gzopen(outfile, mode);
454 if (out == NULL) {
455 fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
456 exit(1);
457 }
458 gz_compress(in, out);
459
460 unlink(file);
461}
462
463
464/* ===========================================================================
465 * Uncompress the given file and remove the original.
466 */
f535537f 467void file_uncompress(char *file) {
9e052883 468 local char buf[MAX_NAME_LEN];
469 char *infile, *outfile;
470 FILE *out;
471 gzFile in;
648db22b 472 size_t len = strlen(file);
9e052883 473
474 if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
475 fprintf(stderr, "%s: filename too long\n", prog);
476 exit(1);
477 }
478
9e052883 479 strcpy(buf, file);
9e052883 480
481 if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
482 infile = file;
483 outfile = buf;
484 outfile[len-3] = '\0';
485 } else {
486 outfile = file;
487 infile = buf;
9e052883 488 strcat(infile, GZ_SUFFIX);
9e052883 489 }
490 in = gzopen(infile, "rb");
491 if (in == NULL) {
492 fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
493 exit(1);
494 }
495 out = fopen(outfile, "wb");
496 if (out == NULL) {
497 perror(file);
498 exit(1);
499 }
500
501 gz_uncompress(in, out);
502
503 unlink(infile);
504}
505
506
507/* ===========================================================================
508 * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
509 * -c : write to standard output
510 * -d : decompress
511 * -f : compress with Z_FILTERED
512 * -h : compress with Z_HUFFMAN_ONLY
513 * -r : compress with Z_RLE
514 * -1 to -9 : compression level
515 */
516
f535537f 517int main(int argc, char *argv[]) {
9e052883 518 int copyout = 0;
519 int uncompr = 0;
520 gzFile file;
521 char *bname, outmode[20];
522
9e052883 523 strcpy(outmode, "wb6 ");
9e052883 524
525 prog = argv[0];
526 bname = strrchr(argv[0], '/');
527 if (bname)
528 bname++;
529 else
530 bname = argv[0];
531 argc--, argv++;
532
533 if (!strcmp(bname, "gunzip"))
534 uncompr = 1;
535 else if (!strcmp(bname, "zcat"))
536 copyout = uncompr = 1;
537
538 while (argc > 0) {
539 if (strcmp(*argv, "-c") == 0)
540 copyout = 1;
541 else if (strcmp(*argv, "-d") == 0)
542 uncompr = 1;
543 else if (strcmp(*argv, "-f") == 0)
544 outmode[3] = 'f';
545 else if (strcmp(*argv, "-h") == 0)
546 outmode[3] = 'h';
547 else if (strcmp(*argv, "-r") == 0)
548 outmode[3] = 'R';
549 else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
550 (*argv)[2] == 0)
551 outmode[2] = (*argv)[1];
552 else
553 break;
554 argc--, argv++;
555 }
556 if (outmode[3] == ' ')
557 outmode[3] = 0;
558 if (argc == 0) {
559 SET_BINARY_MODE(stdin);
560 SET_BINARY_MODE(stdout);
561 if (uncompr) {
562 file = gzdopen(fileno(stdin), "rb");
563 if (file == NULL) error("can't gzdopen stdin");
564 gz_uncompress(file, stdout);
565 } else {
566 file = gzdopen(fileno(stdout), outmode);
567 if (file == NULL) error("can't gzdopen stdout");
568 gz_compress(stdin, file);
569 }
570 } else {
571 if (copyout) {
572 SET_BINARY_MODE(stdout);
573 }
574 do {
575 if (uncompr) {
576 if (copyout) {
577 file = gzopen(*argv, "rb");
578 if (file == NULL)
579 fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
580 else
581 gz_uncompress(file, stdout);
582 } else {
583 file_uncompress(*argv);
584 }
585 } else {
586 if (copyout) {
587 FILE * in = fopen(*argv, "rb");
588
589 if (in == NULL) {
590 perror(*argv);
591 } else {
592 file = gzdopen(fileno(stdout), outmode);
593 if (file == NULL) error("can't gzdopen stdout");
594
595 gz_compress(in, file);
596 }
597
598 } else {
599 file_compress(*argv, outmode);
600 }
601 }
602 } while (argv++, --argc);
603 }
604 return 0;
605}