]>
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-2005 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 
  27 #  include <sys/types.h> 
  28 #  include <sys/mman.h> 
  29 #  include <sys/stat.h> 
  32 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) 
  35 #  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) 
  37 #  define SET_BINARY_MODE(file) 
  41 #  define unlink delete 
  42 #  define GZ_SUFFIX "-gz" 
  45 #  define unlink remove 
  46 #  define GZ_SUFFIX "-gz" 
  47 #  define fileno(file) file->__file 
  49 #if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os 
  50 #  include <unix.h> /* for fileno */ 
  53 #ifndef WIN32 /* unlink already in stdio.h for WIN32 */ 
  54   extern int unlink 
OF((const char *)); 
  58 #  define GZ_SUFFIX ".gz" 
  60 #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) 
  63 #define MAX_NAME_LEN 1024 
  67    /* Needed for systems with limitation on stack size. */ 
  74 void error            
OF((const char *msg
)); 
  75 void gz_compress      
OF((FILE   *in
, gzFile out
)); 
  77 int  gz_compress_mmap 
OF((FILE   *in
, gzFile out
)); 
  79 void gz_uncompress    
OF((gzFile in
, FILE   *out
)); 
  80 void file_compress    
OF((char  *file
, char *mode
)); 
  81 void file_uncompress  
OF((char  *file
)); 
  82 int  main             
OF((int argc
, char *argv
[])); 
  84 /* =========================================================================== 
  85  * Display error message and exit 
  90     fprintf(stderr
, "%s: %s\n", prog
, msg
); 
  94 /* =========================================================================== 
  95  * Compress input to output then close both files. 
  98 void gz_compress(in
, out
) 
 102     local 
char buf
[BUFLEN
]; 
 107     /* Try first compressing with mmap. If mmap fails (minigzip used in a 
 108      * pipe), use the normal fread loop. 
 110     if (gz_compress_mmap(in
, out
) == Z_OK
) return; 
 113         len 
= (int)fread(buf
, 1, sizeof(buf
), in
); 
 120         if (gzwrite(out
, buf
, (unsigned)len
) != len
) error(gzerror(out
, &err
)); 
 123     if (gzclose(out
) != Z_OK
) error("failed gzclose"); 
 126 #ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */ 
 128 /* Try compressing the input file at once using mmap. Return Z_OK if 
 129  * if success, Z_ERRNO otherwise. 
 131 int gz_compress_mmap(in
, out
) 
 137     int ifd 
= fileno(in
); 
 138     caddr_t buf
;    /* mmap'ed buffer for the entire input file */ 
 139     off_t buf_len
;  /* length of the input file */ 
 142     /* Determine the size of the file, needed for mmap: */ 
 143     if (fstat(ifd
, &sb
) < 0) return Z_ERRNO
; 
 144     buf_len 
= sb
.st_size
; 
 145     if (buf_len 
<= 0) return Z_ERRNO
; 
 147     /* Now do the actual mmap: */ 
 148     buf 
= mmap((caddr_t
) 0, buf_len
, PROT_READ
, MAP_SHARED
, ifd
, (off_t
)0); 
 149     if (buf 
== (caddr_t
)(-1)) return Z_ERRNO
; 
 151     /* Compress the whole file at once: */ 
 152     len 
= gzwrite(out
, (char *)buf
, (unsigned)buf_len
); 
 154     if (len 
!= (int)buf_len
) error(gzerror(out
, &err
)); 
 156     munmap(buf
, buf_len
); 
 158     if (gzclose(out
) != Z_OK
) error("failed gzclose"); 
 161 #endif /* USE_MMAP */ 
 163 /* =========================================================================== 
 164  * Uncompress input to output then close both files. 
 166 void gz_uncompress(in
, out
) 
 170     local 
char buf
[BUFLEN
]; 
 175         len 
= gzread(in
, buf
, sizeof(buf
)); 
 176         if (len 
< 0) error (gzerror(in
, &err
)); 
 179         if ((int)fwrite(buf
, 1, (unsigned)len
, out
) != len
) { 
 180             error("failed fwrite"); 
 183     if (fclose(out
)) error("failed fclose"); 
 185     if (gzclose(in
) != Z_OK
) error("failed gzclose"); 
 189 /* =========================================================================== 
 190  * Compress the given file: create a corresponding .gz file and remove the 
 193 void file_compress(file
, mode
) 
 197     local 
char outfile
[MAX_NAME_LEN
]; 
 201     strcpy(outfile
, file
); 
 202     strcat(outfile
, GZ_SUFFIX
); 
 204     in 
= fopen(file
, "rb"); 
 209     out 
= gzopen(outfile
, mode
); 
 211         fprintf(stderr
, "%s: can't gzopen %s\n", prog
, outfile
); 
 214     gz_compress(in
, out
); 
 220 /* =========================================================================== 
 221  * Uncompress the given file and remove the original. 
 223 void file_uncompress(file
) 
 226     local 
char buf
[MAX_NAME_LEN
]; 
 227     char *infile
, *outfile
; 
 230     uInt len 
= (uInt
)strlen(file
); 
 234     if (len 
> SUFFIX_LEN 
&& strcmp(file
+len
-SUFFIX_LEN
, GZ_SUFFIX
) == 0) { 
 237         outfile
[len
-3] = '\0'; 
 241         strcat(infile
, GZ_SUFFIX
); 
 243     in 
= gzopen(infile
, "rb"); 
 245         fprintf(stderr
, "%s: can't gzopen %s\n", prog
, infile
); 
 248     out 
= fopen(outfile
, "wb"); 
 254     gz_uncompress(in
, out
); 
 260 /* =========================================================================== 
 261  * Usage:  minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...] 
 263  *   -f : compress with Z_FILTERED 
 264  *   -h : compress with Z_HUFFMAN_ONLY 
 265  *   -r : compress with Z_RLE 
 266  *   -1 to -9 : compression level 
 277     strcpy(outmode
, "wb6 "); 
 283       if (strcmp(*argv
, "-d") == 0) 
 285       else if (strcmp(*argv
, "-f") == 0) 
 287       else if (strcmp(*argv
, "-h") == 0) 
 289       else if (strcmp(*argv
, "-r") == 0) 
 291       else if ((*argv
)[0] == '-' && (*argv
)[1] >= '1' && (*argv
)[1] <= '9' && 
 293         outmode
[2] = (*argv
)[1]; 
 298     if (outmode
[3] == ' ') 
 301         SET_BINARY_MODE(stdin
); 
 302         SET_BINARY_MODE(stdout
); 
 304             file 
= gzdopen(fileno(stdin
), "rb"); 
 305             if (file 
== NULL
) error("can't gzdopen stdin"); 
 306             gz_uncompress(file
, stdout
); 
 308             file 
= gzdopen(fileno(stdout
), outmode
); 
 309             if (file 
== NULL
) error("can't gzdopen stdout"); 
 310             gz_compress(stdin
, file
); 
 315                 file_uncompress(*argv
); 
 317                 file_compress(*argv
, outmode
); 
 319         } while (argv
++, --argc
);