git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / 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
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
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)
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
85static 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
124static 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
648db22b 157void *myalloc _Z_OF((void *, unsigned, unsigned));
158void myfree _Z_OF((void *, void *));
9e052883 159
160void *myalloc(q, n, m)
161 void *q;
162 unsigned n, m;
163{
648db22b 164 q = Z_NULL;
9e052883 165 return calloc(n, m);
166}
167
168void myfree(q, p)
169 void *q, *p;
170{
648db22b 171 q = Z_NULL;
9e052883 172 free(p);
173}
174
175typedef struct gzFile_s {
176 FILE *file;
177 int write;
178 int err;
179 char *msg;
180 z_stream strm;
181} *gzFile;
182
648db22b 183gzFile gzopen _Z_OF((const char *, const char *));
184gzFile gzdopen _Z_OF((int, const char *));
185gzFile gz_open _Z_OF((const char *, int, const char *));
9e052883 186
187gzFile gzopen(path, mode)
188const char *path;
189const char *mode;
190{
191 return gz_open(path, -1, mode);
192}
193
194gzFile gzdopen(fd, mode)
195int fd;
196const char *mode;
197{
198 return gz_open(NULL, fd, mode);
199}
200
201gzFile 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
648db22b 239int gzwrite _Z_OF((gzFile, const void *, unsigned));
9e052883 240
241int 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
648db22b 263int gzread _Z_OF((gzFile, void *, unsigned));
9e052883 264
265int 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
648db22b 300int gzclose _Z_OF((gzFile));
9e052883 301
302int 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
648db22b 329const char *gzerror _Z_OF((gzFile, int *));
9e052883 330
331const char *gzerror(gz, err)
332 gzFile gz;
333 int *err;
334{
335 *err = gz->err;
336 return gz->msg;
337}
338
339#endif
340
648db22b 341char *prog;
9e052883 342
648db22b 343void error _Z_OF((const char *msg));
344void gz_compress _Z_OF((FILE *in, gzFile out));
9e052883 345#ifdef USE_MMAP
648db22b 346int gz_compress_mmap _Z_OF((FILE *in, gzFile out));
9e052883 347#endif
648db22b 348void gz_uncompress _Z_OF((gzFile in, FILE *out));
349void file_compress _Z_OF((char *file, char *mode));
350void file_uncompress _Z_OF((char *file));
351int main _Z_OF((int argc, char *argv[]));
9e052883 352
353/* ===========================================================================
354 * Display error message and exit
355 */
356void 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
367void 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 */
400int 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 */
435void 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 */
462void 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
9e052883 475 strcpy(outfile, file);
476 strcat(outfile, GZ_SUFFIX);
9e052883 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 */
497void file_uncompress(file)
498 char *file;
499{
500 local char buf[MAX_NAME_LEN];
501 char *infile, *outfile;
502 FILE *out;
503 gzFile in;
648db22b 504 size_t len = strlen(file);
9e052883 505
506 if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
507 fprintf(stderr, "%s: filename too long\n", prog);
508 exit(1);
509 }
510
9e052883 511 strcpy(buf, file);
9e052883 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;
9e052883 520 strcat(infile, GZ_SUFFIX);
9e052883 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
549int 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
9e052883 558 strcpy(outmode, "wb6 ");
9e052883 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}