minigzip.pas 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. program minigzip;
  2. {
  3. minigzip.c -- simulate gzip using the zlib compression library
  4. Copyright (C) 1995-1998 Jean-loup Gailly.
  5. minigzip is a minimal implementation of the gzip utility. This is
  6. only an example of using zlib and isn't meant to replace the
  7. full-featured gzip. No attempt is made to deal with file systems
  8. limiting names to 14 or 8+3 characters, etc... Error checking is
  9. very limited. So use minigzip only for testing; use gzip for the
  10. real thing. On MSDOS, use only on file names without extension
  11. or in pipe mode.
  12. Pascal tranlastion based on code contributed by Francisco Javier Crespo
  13. Copyright (C) 1998 by Jacques Nomssi Nzali
  14. For conditions of distribution and use, see copyright notice in readme.txt
  15. }
  16. uses
  17. gzio;
  18. const
  19. BUFLEN = 16384 ;
  20. GZ_SUFFIX = '.gz' ;
  21. {$DEFINE MAXSEF_64K}
  22. var
  23. buf : packed array [0..BUFLEN-1] of byte; { Global uses BSS instead of stack }
  24. prog : string;
  25. { ERROR =====================================================================
  26. Display error message and exit
  27. ============================================================================}
  28. procedure error (msg:string);
  29. begin
  30. writeln (prog,': ',msg);
  31. halt(1);
  32. end;
  33. { GZ_COMPRESS ===============================================================
  34. Compress input to output then close both files
  35. ============================================================================}
  36. procedure gz_compress (var infile:file; outfile:gzFile);
  37. var
  38. len : cardinal;
  39. ioerr : integer;
  40. err : integer;
  41. begin
  42. while true do begin
  43. {$push}{$I-}
  44. blockread (infile, buf, BUFLEN, len);
  45. {$pop}
  46. ioerr := IOResult;
  47. if (ioerr <> 0) then begin
  48. writeln ('read error: ',ioerr);
  49. halt(1);
  50. end;
  51. if (len = 0) then break;
  52. if (gzwrite (outfile, @buf, len) <> len)
  53. then error (gzerror (outfile, err));
  54. end; {WHILE}
  55. close (infile);
  56. if (gzclose (outfile) <> 0{Z_OK})
  57. then error ('gzclose error');
  58. end;
  59. { GZ_UNCOMPRESS =============================================================
  60. Uncompress input to output then close both files
  61. ============================================================================}
  62. procedure gz_uncompress (infile:gzFile; var outfile:file);
  63. var
  64. len : longint;
  65. written : cardinal;
  66. ioerr : integer;
  67. err : integer;
  68. begin
  69. while true do begin
  70. len := gzread (infile, @buf, BUFLEN);
  71. if (len < 0)
  72. then error (gzerror (infile, err));
  73. if (len = 0)
  74. then break;
  75. {$push}{$I-}
  76. blockwrite (outfile, buf, len, written);
  77. {$pop}
  78. if (written <> len)
  79. then error ('write error');
  80. end; {WHILE}
  81. {$push}{$I-}
  82. close (outfile);
  83. {$pop}
  84. ioerr := IOResult;
  85. if (ioerr <> 0) then begin
  86. writeln ('close error: ',ioerr);
  87. halt(1);
  88. end;
  89. if (gzclose (infile) <> 0{Z_OK})
  90. then error ('gzclose error');
  91. end;
  92. { FILE_COMPRESS =============================================================
  93. Compress the given file:
  94. create a corresponding .gz file and remove the original
  95. ============================================================================}
  96. procedure file_compress (filename:string; mode:string);
  97. var
  98. infile : file;
  99. outfile : gzFile;
  100. ioerr : integer;
  101. outname : string;
  102. begin
  103. Assign (infile, filename);
  104. {$push}{$I-}
  105. Reset (infile,1);
  106. {$pop}
  107. ioerr := IOResult;
  108. if (ioerr <> 0) then begin
  109. writeln ('open error: ',ioerr);
  110. halt(1);
  111. end;
  112. outname := filename + GZ_SUFFIX;
  113. outfile := gzopen (outname, mode);
  114. if (outfile = NIL) then begin
  115. writeln (prog,': can''t gzopen ',outname);
  116. halt(1);
  117. end;
  118. gz_compress(infile, outfile);
  119. erase (infile);
  120. end;
  121. { FILE_UNCOMPRESS ===========================================================
  122. Uncompress the given file and remove the original
  123. ============================================================================}
  124. procedure file_uncompress (filename:string);
  125. var
  126. inname : string;
  127. outname : string;
  128. infile : gzFile;
  129. outfile : file;
  130. ioerr : integer;
  131. len : integer;
  132. begin
  133. len := Length(filename);
  134. if (copy(filename,len-2,3) = GZ_SUFFIX) then begin
  135. inname := filename;
  136. outname := copy(filename,0,len-3);
  137. end
  138. else begin
  139. inname := filename + GZ_SUFFIX;
  140. outname := filename;
  141. end;
  142. infile := gzopen (inname, 'r');
  143. if (infile = NIL) then begin
  144. writeln (prog,': can''t gzopen ',inname);
  145. halt(1);
  146. end;
  147. Assign (outfile, outname);
  148. {$push}{$I-}
  149. Rewrite (outfile,1);
  150. {$pop}
  151. ioerr := IOResult;
  152. if (ioerr <> 0) then begin
  153. writeln ('open error: ',ioerr);
  154. halt(1);
  155. end;
  156. gz_uncompress (infile, outfile);
  157. { erase (infile); }
  158. end;
  159. { MINIGZIP =================================================================}
  160. var
  161. uncompr : boolean;
  162. outmode : string[20];
  163. i : integer;
  164. option : string;
  165. begin
  166. uncompr := false;
  167. outmode := 'w6 ';
  168. prog := ParamStr(0);
  169. if (ParamCount = 0) then begin
  170. writeln ('Error: STDIO/STDOUT not supported yet');
  171. writeln;
  172. writeln ('Usage: minigzip [-d] [-f] [-h] [-1 to -9] <file>');
  173. writeln (' -d : decompress');
  174. writeln (' -f : compress with Z_FILTERED');
  175. writeln (' -h : compress with Z_HUFFMAN_ONLY');
  176. writeln (' -1 to -9 : compression level');
  177. exit;
  178. end;
  179. for i:=1 to ParamCount do begin
  180. option := ParamStr(i);
  181. if (option = '-d') then uncompr := true;
  182. if (option = '-f') then outmode[3] := 'f';
  183. if (option = '-h') then outmode[3] := 'h';
  184. if (option[1] = '-') and (option[2] >= '1') and (option[2] <= '9')
  185. then outmode[2] := option[2];
  186. end;
  187. if (uncompr = true)
  188. then file_uncompress (ParamStr(ParamCount))
  189. else file_compress (ParamStr(ParamCount), outmode);
  190. end.