]>
git.saurik.com Git - wxWidgets.git/blob - src/zlib/minigzip.c
   1 /* minigzip.c -- simulate gzip using the zlib compression library 
   2  * Copyright (C) 1995-2002 Jean-loup Gailly. 
   3  * For conditions of distribution and use, see copyright notice in zlib.h  
   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 
  19 #include "../zlib/zlib.h" 
  25    extern void exit  
OF((int)); 
  29 #  include <sys/types.h> 
  30 #  include <sys/mman.h> 
  31 #  include <sys/stat.h> 
  34 #if defined(MSDOS) || defined(OS2) || defined(WIN32) 
  37 #  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) 
  39 #  define SET_BINARY_MODE(file) 
  43 #  define unlink delete 
  44 #  define GZ_SUFFIX "-gz" 
  47 #  define unlink remove 
  48 #  define GZ_SUFFIX "-gz" 
  49 #  define fileno(file) file->__file 
  51 #if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os 
  52 #  include <unix.h> /* for fileno */ 
  55 #ifndef WIN32 /* unlink already in stdio.h for WIN32 */ 
  56   extern int unlink 
OF((const char *)); 
  60 #  define GZ_SUFFIX ".gz" 
  62 #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) 
  65 #define MAX_NAME_LEN 1024 
  69    /* Needed for systems with limitation on stack size. */ 
  76 void error            
OF((const char *msg
)); 
  77 void gz_compress      
OF((FILE   *in
, gzFile out
)); 
  79 int  gz_compress_mmap 
OF((FILE   *in
, gzFile out
)); 
  81 void gz_uncompress    
OF((gzFile in
, FILE   *out
)); 
  82 void file_compress    
OF((char  *file
, char *mode
)); 
  83 void file_uncompress  
OF((char  *file
)); 
  84 int  main             
OF((int argc
, char *argv
[])); 
  86 /* =========================================================================== 
  87  * Display error message and exit 
  92     fprintf(stderr
, "%s: %s\n", prog
, msg
); 
  96 /* =========================================================================== 
  97  * Compress input to output then close both files. 
 100 void gz_compress(in
, out
) 
 104     local 
char buf
[BUFLEN
]; 
 109     /* Try first compressing with mmap. If mmap fails (minigzip used in a 
 110      * pipe), use the normal fread loop. 
 112     if (gz_compress_mmap(in
, out
) == Z_OK
) return; 
 115         len 
= fread(buf
, 1, sizeof(buf
), in
); 
 122         if (gzwrite(out
, buf
, (unsigned)len
) != len
) error(gzerror(out
, &err
)); 
 125     if (gzclose(out
) != Z_OK
) error("failed gzclose"); 
 128 #ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */ 
 130 /* Try compressing the input file at once using mmap. Return Z_OK if 
 131  * if success, Z_ERRNO otherwise. 
 133 int gz_compress_mmap(in
, out
) 
 139     int ifd 
= fileno(in
); 
 140     caddr_t buf
;    /* mmap'ed buffer for the entire input file */ 
 141     off_t buf_len
;  /* length of the input file */ 
 144     /* Determine the size of the file, needed for mmap: */ 
 145     if (fstat(ifd
, &sb
) < 0) return Z_ERRNO
; 
 146     buf_len 
= sb
.st_size
; 
 147     if (buf_len 
<= 0) return Z_ERRNO
; 
 149     /* Now do the actual mmap: */ 
 150     buf 
= mmap((caddr_t
) 0, buf_len
, PROT_READ
, MAP_SHARED
, ifd
, (off_t
)0);  
 151     if (buf 
== (caddr_t
)(-1)) return Z_ERRNO
; 
 153     /* Compress the whole file at once: */ 
 154     len 
= gzwrite(out
, (char *)buf
, (unsigned)buf_len
); 
 156     if (len 
!= (int)buf_len
) error(gzerror(out
, &err
)); 
 158     munmap(buf
, buf_len
); 
 160     if (gzclose(out
) != Z_OK
) error("failed gzclose"); 
 163 #endif /* USE_MMAP */ 
 165 /* =========================================================================== 
 166  * Uncompress input to output then close both files. 
 168 void gz_uncompress(in
, out
) 
 172     local 
char buf
[BUFLEN
]; 
 177         len 
= gzread(in
, buf
, sizeof(buf
)); 
 178         if (len 
< 0) error (gzerror(in
, &err
)); 
 181         if ((int)fwrite(buf
, 1, (unsigned)len
, out
) != len
) { 
 182             error("failed fwrite"); 
 185     if (fclose(out
)) error("failed fclose"); 
 187     if (gzclose(in
) != Z_OK
) error("failed gzclose"); 
 191 /* =========================================================================== 
 192  * Compress the given file: create a corresponding .gz file and remove the 
 195 void file_compress(file
, mode
) 
 199     local 
char outfile
[MAX_NAME_LEN
]; 
 203     strcpy(outfile
, file
); 
 204     strcat(outfile
, GZ_SUFFIX
); 
 206     in 
= fopen(file
, "rb"); 
 211     out 
= gzopen(outfile
, mode
); 
 213         fprintf(stderr
, "%s: can't gzopen %s\n", prog
, outfile
); 
 216     gz_compress(in
, out
); 
 222 /* =========================================================================== 
 223  * Uncompress the given file and remove the original. 
 225 void file_uncompress(file
) 
 228     local 
char buf
[MAX_NAME_LEN
]; 
 229     char *infile
, *outfile
; 
 232     int len 
= strlen(file
); 
 236     if (len 
> SUFFIX_LEN 
&& strcmp(file
+len
-SUFFIX_LEN
, GZ_SUFFIX
) == 0) { 
 239         outfile
[len
-3] = '\0'; 
 243         strcat(infile
, GZ_SUFFIX
); 
 245     in 
= gzopen(infile
, "rb"); 
 247         fprintf(stderr
, "%s: can't gzopen %s\n", prog
, infile
); 
 250     out 
= fopen(outfile
, "wb"); 
 256     gz_uncompress(in
, out
); 
 262 /* =========================================================================== 
 263  * Usage:  minigzip [-d] [-f] [-h] [-1 to -9] [files...] 
 265  *   -f : compress with Z_FILTERED 
 266  *   -h : compress with Z_HUFFMAN_ONLY 
 267  *   -1 to -9 : compression level 
 278     strcpy(outmode
, "wb6 "); 
 284       if (strcmp(*argv
, "-d") == 0) 
 286       else if (strcmp(*argv
, "-f") == 0) 
 288       else if (strcmp(*argv
, "-h") == 0) 
 290       else if ((*argv
)[0] == '-' && (*argv
)[1] >= '1' && (*argv
)[1] <= '9' && 
 292         outmode
[2] = (*argv
)[1]; 
 298         SET_BINARY_MODE(stdin
); 
 299         SET_BINARY_MODE(stdout
); 
 301             file 
= gzdopen(fileno(stdin
), "rb"); 
 302             if (file 
== NULL
) error("can't gzdopen stdin"); 
 303             gz_uncompress(file
, stdout
); 
 305             file 
= gzdopen(fileno(stdout
), outmode
); 
 306             if (file 
== NULL
) error("can't gzdopen stdout"); 
 307             gz_compress(stdin
, file
); 
 312                 file_uncompress(*argv
); 
 314                 file_compress(*argv
, outmode
); 
 316         } while (argv
++, --argc
); 
 319     return 0; /* to avoid warning */