~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/zlib/minigzip.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* minigzip.c -- simulate gzip using the zlib compression library
 
2
 * Copyright (C) 1995-2006, 2010 Jean-loup Gailly.
 
3
 * For conditions of distribution and use, see copyright notice in zlib.h
 
4
 */
 
5
 
 
6
/*
 
7
 * minigzip is a minimal implementation of the gzip utility. This is
 
8
 * only an example of using zlib and isn't meant to replace the
 
9
 * full-featured gzip. No attempt is made to deal with file systems
 
10
 * limiting names to 14 or 8+3 characters, etc... Error checking is
 
11
 * very limited. So use minigzip only for testing; use gzip for the
 
12
 * real thing. On MSDOS, use only on file names without extension
 
13
 * or in pipe mode.
 
14
 */
 
15
 
 
16
/* @(#) $Id$ */
 
17
 
 
18
#include "zlib.h"
 
19
#include <stdio.h>
 
20
 
 
21
#ifdef STDC
 
22
#  include <string.h>
 
23
#  include <stdlib.h>
 
24
#endif
 
25
 
 
26
#ifdef USE_MMAP
 
27
#  include <sys/types.h>
 
28
#  include <sys/mman.h>
 
29
#  include <sys/stat.h>
 
30
#endif
 
31
 
 
32
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
 
33
#  include <fcntl.h>
 
34
#  include <io.h>
 
35
#  ifdef UNDER_CE
 
36
#    include <stdlib.h>
 
37
#  endif
 
38
#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
 
39
#else
 
40
#  define SET_BINARY_MODE(file)
 
41
#endif
 
42
 
 
43
#ifdef VMS
 
44
#  define unlink delete
 
45
#  define GZ_SUFFIX "-gz"
 
46
#endif
 
47
#ifdef RISCOS
 
48
#  define unlink remove
 
49
#  define GZ_SUFFIX "-gz"
 
50
#  define fileno(file) file->__file
 
51
#endif
 
52
#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
 
53
#  include <unix.h> /* for fileno */
 
54
#endif
 
55
 
 
56
#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
 
57
#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
 
58
  extern int unlink OF((const char *));
 
59
#endif
 
60
#endif
 
61
 
 
62
#if defined(UNDER_CE)
 
63
#  include <windows.h>
 
64
#  define perror(s) pwinerror(s)
 
65
 
 
66
/* Map the Windows error number in ERROR to a locale-dependent error
 
67
   message string and return a pointer to it.  Typically, the values
 
68
   for ERROR come from GetLastError.
 
69
 
 
70
   The string pointed to shall not be modified by the application,
 
71
   but may be overwritten by a subsequent call to strwinerror
 
72
 
 
73
   The strwinerror function does not change the current setting
 
74
   of GetLastError.  */
 
75
 
 
76
static char *strwinerror (error)
 
77
     DWORD error;
 
78
{
 
79
    static char buf[1024];
 
80
 
 
81
    wchar_t *msgbuf;
 
82
    DWORD lasterr = GetLastError();
 
83
    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
 
84
        | FORMAT_MESSAGE_ALLOCATE_BUFFER,
 
85
        NULL,
 
86
        error,
 
87
        0, /* Default language */
 
88
        (LPVOID)&msgbuf,
 
89
        0,
 
90
        NULL);
 
91
    if (chars != 0) {
 
92
        /* If there is an \r\n appended, zap it.  */
 
93
        if (chars >= 2
 
94
            && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
 
95
            chars -= 2;
 
96
            msgbuf[chars] = 0;
 
97
        }
 
98
 
 
99
        if (chars > sizeof (buf) - 1) {
 
100
            chars = sizeof (buf) - 1;
 
101
            msgbuf[chars] = 0;
 
102
        }
 
103
 
 
104
        wcstombs(buf, msgbuf, chars + 1);
 
105
        LocalFree(msgbuf);
 
106
    }
 
107
    else {
 
108
        sprintf(buf, "unknown win32 error (%ld)", error);
 
109
    }
 
110
 
 
111
    SetLastError(lasterr);
 
112
    return buf;
 
113
}
 
114
 
 
115
static void pwinerror (s)
 
116
    const char *s;
 
117
{
 
118
    if (s && *s)
 
119
        fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
 
120
    else
 
121
        fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
 
122
}
 
123
 
 
124
#endif /* UNDER_CE */
 
125
 
 
126
#ifndef GZ_SUFFIX
 
127
#  define GZ_SUFFIX ".gz"
 
128
#endif
 
129
#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
 
130
 
 
131
#define BUFLEN      16384
 
132
#define MAX_NAME_LEN 1024
 
133
 
 
134
#ifdef MAXSEG_64K
 
135
#  define local static
 
136
   /* Needed for systems with limitation on stack size. */
 
137
#else
 
138
#  define local
 
139
#endif
 
140
 
 
141
char *prog;
 
142
 
 
143
void error            OF((const char *msg));
 
144
void gz_compress      OF((FILE   *in, gzFile out));
 
145
#ifdef USE_MMAP
 
146
int  gz_compress_mmap OF((FILE   *in, gzFile out));
 
147
#endif
 
148
void gz_uncompress    OF((gzFile in, FILE   *out));
 
149
void file_compress    OF((char  *file, char *mode));
 
150
void file_uncompress  OF((char  *file));
 
151
int  main             OF((int argc, char *argv[]));
 
152
 
 
153
/* ===========================================================================
 
154
 * Display error message and exit
 
155
 */
 
156
void error(msg)
 
157
    const char *msg;
 
158
{
 
159
    fprintf(stderr, "%s: %s\n", prog, msg);
 
160
    exit(1);
 
161
}
 
162
 
 
163
/* ===========================================================================
 
164
 * Compress input to output then close both files.
 
165
 */
 
166
 
 
167
void gz_compress(in, out)
 
168
    FILE   *in;
 
169
    gzFile out;
 
170
{
 
171
    local char buf[BUFLEN];
 
172
    int len;
 
173
    int err;
 
174
 
 
175
#ifdef USE_MMAP
 
176
    /* Try first compressing with mmap. If mmap fails (minigzip used in a
 
177
     * pipe), use the normal fread loop.
 
178
     */
 
179
    if (gz_compress_mmap(in, out) == Z_OK) return;
 
180
#endif
 
181
    for (;;) {
 
182
        len = (int)fread(buf, 1, sizeof(buf), in);
 
183
        if (ferror(in)) {
 
184
            perror("fread");
 
185
            exit(1);
 
186
        }
 
187
        if (len == 0) break;
 
188
 
 
189
        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
 
190
    }
 
191
    fclose(in);
 
192
    if (gzclose(out) != Z_OK) error("failed gzclose");
 
193
}
 
194
 
 
195
#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
 
196
 
 
197
/* Try compressing the input file at once using mmap. Return Z_OK if
 
198
 * if success, Z_ERRNO otherwise.
 
199
 */
 
200
int gz_compress_mmap(in, out)
 
201
    FILE   *in;
 
202
    gzFile out;
 
203
{
 
204
    int len;
 
205
    int err;
 
206
    int ifd = fileno(in);
 
207
    caddr_t buf;    /* mmap'ed buffer for the entire input file */
 
208
    off_t buf_len;  /* length of the input file */
 
209
    struct stat sb;
 
210
 
 
211
    /* Determine the size of the file, needed for mmap: */
 
212
    if (fstat(ifd, &sb) < 0) return Z_ERRNO;
 
213
    buf_len = sb.st_size;
 
214
    if (buf_len <= 0) return Z_ERRNO;
 
215
 
 
216
    /* Now do the actual mmap: */
 
217
    buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
 
218
    if (buf == (caddr_t)(-1)) return Z_ERRNO;
 
219
 
 
220
    /* Compress the whole file at once: */
 
221
    len = gzwrite(out, (char *)buf, (unsigned)buf_len);
 
222
 
 
223
    if (len != (int)buf_len) error(gzerror(out, &err));
 
224
 
 
225
    munmap(buf, buf_len);
 
226
    fclose(in);
 
227
    if (gzclose(out) != Z_OK) error("failed gzclose");
 
228
    return Z_OK;
 
229
}
 
230
#endif /* USE_MMAP */
 
231
 
 
232
/* ===========================================================================
 
233
 * Uncompress input to output then close both files.
 
234
 */
 
235
void gz_uncompress(in, out)
 
236
    gzFile in;
 
237
    FILE   *out;
 
238
{
 
239
    local char buf[BUFLEN];
 
240
    int len;
 
241
    int err;
 
242
 
 
243
    for (;;) {
 
244
        len = gzread(in, buf, sizeof(buf));
 
245
        if (len < 0) error (gzerror(in, &err));
 
246
        if (len == 0) break;
 
247
 
 
248
        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
 
249
            error("failed fwrite");
 
250
        }
 
251
    }
 
252
    if (fclose(out)) error("failed fclose");
 
253
 
 
254
    if (gzclose(in) != Z_OK) error("failed gzclose");
 
255
}
 
256
 
 
257
 
 
258
/* ===========================================================================
 
259
 * Compress the given file: create a corresponding .gz file and remove the
 
260
 * original.
 
261
 */
 
262
void file_compress(file, mode)
 
263
    char  *file;
 
264
    char  *mode;
 
265
{
 
266
    local char outfile[MAX_NAME_LEN];
 
267
    FILE  *in;
 
268
    gzFile out;
 
269
 
 
270
    if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
 
271
        fprintf(stderr, "%s: filename too long\n", prog);
 
272
        exit(1);
 
273
    }
 
274
 
 
275
    strcpy(outfile, file);
 
276
    strcat(outfile, GZ_SUFFIX);
 
277
 
 
278
    in = fopen(file, "rb");
 
279
    if (in == NULL) {
 
280
        perror(file);
 
281
        exit(1);
 
282
    }
 
283
    out = gzopen(outfile, mode);
 
284
    if (out == NULL) {
 
285
        fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
 
286
        exit(1);
 
287
    }
 
288
    gz_compress(in, out);
 
289
 
 
290
    unlink(file);
 
291
}
 
292
 
 
293
 
 
294
/* ===========================================================================
 
295
 * Uncompress the given file and remove the original.
 
296
 */
 
297
void file_uncompress(file)
 
298
    char  *file;
 
299
{
 
300
    local char buf[MAX_NAME_LEN];
 
301
    char *infile, *outfile;
 
302
    FILE  *out;
 
303
    gzFile in;
 
304
    size_t len = strlen(file);
 
305
 
 
306
    if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
 
307
        fprintf(stderr, "%s: filename too long\n", prog);
 
308
        exit(1);
 
309
    }
 
310
 
 
311
    strcpy(buf, file);
 
312
 
 
313
    if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
 
314
        infile = file;
 
315
        outfile = buf;
 
316
        outfile[len-3] = '\0';
 
317
    } else {
 
318
        outfile = file;
 
319
        infile = buf;
 
320
        strcat(infile, GZ_SUFFIX);
 
321
    }
 
322
    in = gzopen(infile, "rb");
 
323
    if (in == NULL) {
 
324
        fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
 
325
        exit(1);
 
326
    }
 
327
    out = fopen(outfile, "wb");
 
328
    if (out == NULL) {
 
329
        perror(file);
 
330
        exit(1);
 
331
    }
 
332
 
 
333
    gz_uncompress(in, out);
 
334
 
 
335
    unlink(infile);
 
336
}
 
337
 
 
338
 
 
339
/* ===========================================================================
 
340
 * Usage:  minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
 
341
 *   -c : write to standard output
 
342
 *   -d : decompress
 
343
 *   -f : compress with Z_FILTERED
 
344
 *   -h : compress with Z_HUFFMAN_ONLY
 
345
 *   -r : compress with Z_RLE
 
346
 *   -1 to -9 : compression level
 
347
 */
 
348
 
 
349
int main(argc, argv)
 
350
    int argc;
 
351
    char *argv[];
 
352
{
 
353
    int copyout = 0;
 
354
    int uncompr = 0;
 
355
    gzFile file;
 
356
    char *bname, outmode[20];
 
357
 
 
358
    strcpy(outmode, "wb6 ");
 
359
 
 
360
    prog = argv[0];
 
361
    bname = strrchr(argv[0], '/');
 
362
    if (bname)
 
363
      bname++;
 
364
    else
 
365
      bname = argv[0];
 
366
    argc--, argv++;
 
367
 
 
368
    if (!strcmp(bname, "gunzip"))
 
369
      uncompr = 1;
 
370
    else if (!strcmp(bname, "zcat"))
 
371
      copyout = uncompr = 1;
 
372
 
 
373
    while (argc > 0) {
 
374
      if (strcmp(*argv, "-c") == 0)
 
375
        copyout = 1;
 
376
      else if (strcmp(*argv, "-d") == 0)
 
377
        uncompr = 1;
 
378
      else if (strcmp(*argv, "-f") == 0)
 
379
        outmode[3] = 'f';
 
380
      else if (strcmp(*argv, "-h") == 0)
 
381
        outmode[3] = 'h';
 
382
      else if (strcmp(*argv, "-r") == 0)
 
383
        outmode[3] = 'R';
 
384
      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
 
385
               (*argv)[2] == 0)
 
386
        outmode[2] = (*argv)[1];
 
387
      else
 
388
        break;
 
389
      argc--, argv++;
 
390
    }
 
391
    if (outmode[3] == ' ')
 
392
        outmode[3] = 0;
 
393
    if (argc == 0) {
 
394
        SET_BINARY_MODE(stdin);
 
395
        SET_BINARY_MODE(stdout);
 
396
        if (uncompr) {
 
397
            file = gzdopen(fileno(stdin), "rb");
 
398
            if (file == NULL) error("can't gzdopen stdin");
 
399
            gz_uncompress(file, stdout);
 
400
        } else {
 
401
            file = gzdopen(fileno(stdout), outmode);
 
402
            if (file == NULL) error("can't gzdopen stdout");
 
403
            gz_compress(stdin, file);
 
404
        }
 
405
    } else {
 
406
        if (copyout) {
 
407
            SET_BINARY_MODE(stdout);
 
408
        }
 
409
        do {
 
410
            if (uncompr) {
 
411
                if (copyout) {
 
412
                    file = gzopen(*argv, "rb");
 
413
                    if (file == NULL)
 
414
                        fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
 
415
                    else
 
416
                        gz_uncompress(file, stdout);
 
417
                } else {
 
418
                    file_uncompress(*argv);
 
419
                }
 
420
            } else {
 
421
                if (copyout) {
 
422
                    FILE * in = fopen(*argv, "rb");
 
423
 
 
424
                    if (in == NULL) {
 
425
                        perror(*argv);
 
426
                    } else {
 
427
                        file = gzdopen(fileno(stdout), outmode);
 
428
                        if (file == NULL) error("can't gzdopen stdout");
 
429
 
 
430
                        gz_compress(in, file);
 
431
                    }
 
432
 
 
433
                } else {
 
434
                    file_compress(*argv, outmode);
 
435
                }
 
436
            }
 
437
        } while (argv++, --argc);
 
438
    }
 
439
    return 0;
 
440
}