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