Browse Source

* new directory structur

git-svn-id: trunk@8933 -
peter 18 years ago
parent
commit
ea542d207e

+ 26 - 25
.gitattributes

@@ -4343,34 +4343,35 @@ packages/fpmkunit/fpmake.pp svneol=native#text/plain
 packages/fpmkunit/src/fpmkunit.pp svneol=native#text/plain
 packages/paszlib/Makefile svneol=native#text/plain
 packages/paszlib/Makefile.fpc svneol=native#text/plain
-packages/paszlib/adler.pas svneol=native#text/plain
-packages/paszlib/changes.txt svneol=native#text/plain
-packages/paszlib/demo/Makefile svneol=native#text/plain
-packages/paszlib/demo/Makefile.fpc svneol=native#text/plain
-packages/paszlib/demo/example.pas svneol=native#text/plain
-packages/paszlib/demo/minigzip.pas svneol=native#text/plain
-packages/paszlib/demo/miniunz.pas svneol=native#text/plain
-packages/paszlib/demo/minizip.pas svneol=native#text/plain
 packages/paszlib/fpmake.inc svneol=native#text/plain
 packages/paszlib/fpmake.pp svneol=native#text/plain
-packages/paszlib/gzio.pas svneol=native#text/plain
-packages/paszlib/infblock.pas svneol=native#text/plain
-packages/paszlib/infcodes.pas svneol=native#text/plain
-packages/paszlib/inffast.pas svneol=native#text/plain
-packages/paszlib/inftrees.pas svneol=native#text/plain
-packages/paszlib/infutil.pas svneol=native#text/plain
-packages/paszlib/paszlib.pas svneol=native#text/plain
 packages/paszlib/readme.txt svneol=native#text/plain
-packages/paszlib/trees.pas svneol=native#text/plain
-packages/paszlib/unzip.pas svneol=native#text/plain
-packages/paszlib/zbase.pas svneol=native#text/plain
-packages/paszlib/zcompres.pas svneol=native#text/plain
-packages/paszlib/zconf.inc svneol=native#text/plain
-packages/paszlib/zdeflate.pas svneol=native#text/plain
-packages/paszlib/zinflate.pas svneol=native#text/plain
-packages/paszlib/zip.pas svneol=native#text/plain
-packages/paszlib/ziputils.pas svneol=native#text/plain
-packages/paszlib/zuncompr.pas svneol=native#text/plain
+packages/paszlib/src/adler.pas svneol=native#text/plain
+packages/paszlib/src/gzio.pas svneol=native#text/plain
+packages/paszlib/src/infblock.pas svneol=native#text/plain
+packages/paszlib/src/infcodes.pas svneol=native#text/plain
+packages/paszlib/src/inffast.pas svneol=native#text/plain
+packages/paszlib/src/inftrees.pas svneol=native#text/plain
+packages/paszlib/src/infutil.pas svneol=native#text/plain
+packages/paszlib/src/paszlib.pas svneol=native#text/plain
+packages/paszlib/src/trees.pas svneol=native#text/plain
+packages/paszlib/src/unzip.pas svneol=native#text/plain
+packages/paszlib/src/zbase.pas svneol=native#text/plain
+packages/paszlib/src/zcompres.pas svneol=native#text/plain
+packages/paszlib/src/zconf.inc svneol=native#text/plain
+packages/paszlib/src/zdeflate.pas svneol=native#text/plain
+packages/paszlib/src/zinflate.pas svneol=native#text/plain
+packages/paszlib/src/zip.pas svneol=native#text/plain
+packages/paszlib/src/zipper.pp svneol=native#text/plain
+packages/paszlib/src/ziputils.pas svneol=native#text/plain
+packages/paszlib/src/zstream.pp svneol=native#text/plain
+packages/paszlib/src/zuncompr.pas svneol=native#text/plain
+packages/paszlib/tests/Makefile svneol=native#text/plain
+packages/paszlib/tests/Makefile.fpc svneol=native#text/plain
+packages/paszlib/tests/example.pas svneol=native#text/plain
+packages/paszlib/tests/minigzip.pas svneol=native#text/plain
+packages/paszlib/tests/miniunz.pas svneol=native#text/plain
+packages/paszlib/tests/minizip.pas svneol=native#text/plain
 rtl/COPYING -text
 rtl/COPYING.FPC -text
 rtl/Makefile svneol=native#text/plain

File diff suppressed because it is too large
+ 426 - 186
packages/paszlib/Makefile


+ 9 - 5
packages/paszlib/Makefile.fpc

@@ -6,18 +6,22 @@
 name=paszlib
 version=2.2.0
 
-[require]
-packages=hash
+#[require]
+#packages=hash
 
 [target]
-units=paszlib adler gzio infblock infcodes inffast inftrees infutil trees zcompres zdeflate zinflate zbase zuncompr zip ziputils unzip
-exampledirs=demo
+units=paszlib zip unzip zipper 
+implicitunits=adler gzio infblock infcodes inffast inftrees infutil trees zcompres zdeflate zinflate zbase zuncompr ziputils zstream
+exampledirs=tests
 
 [install]
 fpcpackage=y
 
+[compiler]
+sourcedir=src
+
 [default]
-fpcdir=../../..
+fpcdir=../..
 
 [rules]
 .NOTPARALLEL:

+ 0 - 12
packages/paszlib/changes.txt

@@ -1,12 +0,0 @@
-
-Changes to the last version of PASZLIB (http://www.tu-chemnitz.de/~nomssi)
-required for FPC-pascal:
-
-(Standard adding of @ for assignment of procedure variables)
-Zdeflate 532 and 536 added an @
-zinflate 259 263 294 added an @
-
-Warning only:
-inflatetrees  inflate_tree_fixed has two uint parameters in the interface, and
-        two uintf's in the implementation. Only a warning is issued btw, so
-        this is not critical.

+ 5 - 1
packages/paszlib/fpmake.inc

@@ -6,8 +6,12 @@
     {$ENDIF}
     Version:={$i %FPCVERSION%};
     T:=Targets.AddUnit('paszlib');
+    T:=Targets.AddUnit('zip');
+    T:=Targets.AddUnit('unzip');
+    T:=Targets.AddUnit('ziputils');
+    T:=Targets.AddUnit('zipper');
+    T:=Targets.AddUnit('zstream');
     T:=Targets.AddUnit('adler');
-    T:=Targets.AddUnit('crc');
     T:=Targets.AddUnit('gzio');
     T:=Targets.AddUnit('infblock');
     T:=Targets.AddUnit('infcodes');

+ 0 - 0
packages/paszlib/adler.pas → packages/paszlib/src/adler.pas


+ 0 - 0
packages/paszlib/gzio.pas → packages/paszlib/src/gzio.pas


+ 0 - 0
packages/paszlib/infblock.pas → packages/paszlib/src/infblock.pas


+ 0 - 0
packages/paszlib/infcodes.pas → packages/paszlib/src/infcodes.pas


+ 0 - 0
packages/paszlib/inffast.pas → packages/paszlib/src/inffast.pas


+ 0 - 0
packages/paszlib/inftrees.pas → packages/paszlib/src/inftrees.pas


+ 0 - 0
packages/paszlib/infutil.pas → packages/paszlib/src/infutil.pas


+ 0 - 0
packages/paszlib/paszlib.pas → packages/paszlib/src/paszlib.pas


+ 0 - 0
packages/paszlib/trees.pas → packages/paszlib/src/trees.pas


+ 0 - 0
packages/paszlib/unzip.pas → packages/paszlib/src/unzip.pas


+ 0 - 0
packages/paszlib/zbase.pas → packages/paszlib/src/zbase.pas


+ 0 - 0
packages/paszlib/zcompres.pas → packages/paszlib/src/zcompres.pas


+ 0 - 0
packages/paszlib/zconf.inc → packages/paszlib/src/zconf.inc


+ 0 - 0
packages/paszlib/zdeflate.pas → packages/paszlib/src/zdeflate.pas


+ 0 - 0
packages/paszlib/zinflate.pas → packages/paszlib/src/zinflate.pas


+ 0 - 0
packages/paszlib/zip.pas → packages/paszlib/src/zip.pas


+ 1470 - 0
packages/paszlib/src/zipper.pp

@@ -0,0 +1,1470 @@
+{
+    $Id: header,v 1.1 2000/07/13 06:33:45 michael Exp $
+    This file is part of the Free Component Library (FCL)
+    Copyright (c) 1999-2000 by the Free Pascal development team
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+{$mode objfpc}
+{$h+}
+unit zipper;
+
+Interface
+
+Uses
+   SysUtils,Classes,ZStream;
+
+
+Const
+  { Signatures }
+{$ifdef FPC_BIG_ENDIAN}
+  END_OF_CENTRAL_DIR_SIGNATURE  = $504B0506;
+  LOCAL_FILE_HEADER_SIGNATURE   = $504B0304;
+  CENTRAL_FILE_HEADER_SIGNATURE = $504B0102;
+{$else FPC_BIG_ENDIAN}
+  END_OF_CENTRAL_DIR_SIGNATURE  = $06054B50;
+  LOCAL_FILE_HEADER_SIGNATURE   = $04034B50;
+  CENTRAL_FILE_HEADER_SIGNATURE = $02014B50;
+{$endif FPC_BIG_ENDIAN}
+
+Type
+   Local_File_Header_Type = Packed Record
+     Signature              :  LongInt;
+     Extract_Version_Reqd   :  Word;
+     Bit_Flag               :  Word;
+     Compress_Method        :  Word;
+     Last_Mod_Time          :  Word;
+     Last_Mod_Date          :  Word;
+     Crc32                  :  LongWord;
+     Compressed_Size        :  LongInt;
+     Uncompressed_Size      :  LongInt;
+     Filename_Length        :  Word;
+     Extra_Field_Length     :  Word;
+   end;
+
+  { Define the Central Directory record types }
+
+  Central_File_Header_Type = Packed Record
+    Signature            :  LongInt;
+    MadeBy_Version       :  Word;
+    Extract_Version_Reqd :  Word;
+    Bit_Flag             :  Word;
+    Compress_Method      :  Word;
+    Last_Mod_Time        :  Word;
+    Last_Mod_Date        :  Word;
+    Crc32                :  LongWord;
+    Compressed_Size      :  LongInt;
+    Uncompressed_Size    :  LongInt;
+    Filename_Length      :  Word;
+    Extra_Field_Length   :  Word;
+    File_Comment_Length  :  Word;
+    Starting_Disk_Num    :  Word;
+    Internal_Attributes  :  Word;
+    External_Attributes  :  LongInt;
+    Local_Header_Offset  :  LongInt;
+  End;
+
+  End_of_Central_Dir_Type =  Packed Record
+    Signature               :  LongInt;
+    Disk_Number             :  Word;
+    Central_Dir_Start_Disk  :  Word;
+    Entries_This_Disk       :  Word;
+    Total_Entries           :  Word;
+    Central_Dir_Size        :  LongInt;
+    Start_Disk_Offset       :  LongInt;
+    ZipFile_Comment_Length  :  Word;
+  end;
+
+Const
+  Crc_32_Tab : Array[0..255] of LongWord = (
+    $00000000, $77073096, $ee0e612c, $990951ba, $076dc419, $706af48f, $e963a535, $9e6495a3,
+    $0edb8832, $79dcb8a4, $e0d5e91e, $97d2d988, $09b64c2b, $7eb17cbd, $e7b82d07, $90bf1d91,
+    $1db71064, $6ab020f2, $f3b97148, $84be41de, $1adad47d, $6ddde4eb, $f4d4b551, $83d385c7,
+    $136c9856, $646ba8c0, $fd62f97a, $8a65c9ec, $14015c4f, $63066cd9, $fa0f3d63, $8d080df5,
+    $3b6e20c8, $4c69105e, $d56041e4, $a2677172, $3c03e4d1, $4b04d447, $d20d85fd, $a50ab56b,
+    $35b5a8fa, $42b2986c, $dbbbc9d6, $acbcf940, $32d86ce3, $45df5c75, $dcd60dcf, $abd13d59,
+    $26d930ac, $51de003a, $c8d75180, $bfd06116, $21b4f4b5, $56b3c423, $cfba9599, $b8bda50f,
+    $2802b89e, $5f058808, $c60cd9b2, $b10be924, $2f6f7c87, $58684c11, $c1611dab, $b6662d3d,
+    $76dc4190, $01db7106, $98d220bc, $efd5102a, $71b18589, $06b6b51f, $9fbfe4a5, $e8b8d433,
+    $7807c9a2, $0f00f934, $9609a88e, $e10e9818, $7f6a0dbb, $086d3d2d, $91646c97, $e6635c01,
+    $6b6b51f4, $1c6c6162, $856530d8, $f262004e, $6c0695ed, $1b01a57b, $8208f4c1, $f50fc457,
+    $65b0d9c6, $12b7e950, $8bbeb8ea, $fcb9887c, $62dd1ddf, $15da2d49, $8cd37cf3, $fbd44c65,
+    $4db26158, $3ab551ce, $a3bc0074, $d4bb30e2, $4adfa541, $3dd895d7, $a4d1c46d, $d3d6f4fb,
+    $4369e96a, $346ed9fc, $ad678846, $da60b8d0, $44042d73, $33031de5, $aa0a4c5f, $dd0d7cc9,
+    $5005713c, $270241aa, $be0b1010, $c90c2086, $5768b525, $206f85b3, $b966d409, $ce61e49f,
+    $5edef90e, $29d9c998, $b0d09822, $c7d7a8b4, $59b33d17, $2eb40d81, $b7bd5c3b, $c0ba6cad,
+    $edb88320, $9abfb3b6, $03b6e20c, $74b1d29a, $ead54739, $9dd277af, $04db2615, $73dc1683,
+    $e3630b12, $94643b84, $0d6d6a3e, $7a6a5aa8, $e40ecf0b, $9309ff9d, $0a00ae27, $7d079eb1,
+    $f00f9344, $8708a3d2, $1e01f268, $6906c2fe, $f762575d, $806567cb, $196c3671, $6e6b06e7,
+    $fed41b76, $89d32be0, $10da7a5a, $67dd4acc, $f9b9df6f, $8ebeeff9, $17b7be43, $60b08ed5,
+    $d6d6a3e8, $a1d1937e, $38d8c2c4, $4fdff252, $d1bb67f1, $a6bc5767, $3fb506dd, $48b2364b,
+    $d80d2bda, $af0a1b4c, $36034af6, $41047a60, $df60efc3, $a867df55, $316e8eef, $4669be79,
+    $cb61b38c, $bc66831a, $256fd2a0, $5268e236, $cc0c7795, $bb0b4703, $220216b9, $5505262f,
+    $c5ba3bbe, $b2bd0b28, $2bb45a92, $5cb36a04, $c2d7ffa7, $b5d0cf31, $2cd99e8b, $5bdeae1d,
+    $9b64c2b0, $ec63f226, $756aa39c, $026d930a, $9c0906a9, $eb0e363f, $72076785, $05005713,
+    $95bf4a82, $e2b87a14, $7bb12bae, $0cb61b38, $92d28e9b, $e5d5be0d, $7cdcefb7, $0bdbdf21,
+    $86d3d2d4, $f1d4e242, $68ddb3f8, $1fda836e, $81be16cd, $f6b9265b, $6fb077e1, $18b74777,
+    $88085ae6, $ff0f6a70, $66063bca, $11010b5c, $8f659eff, $f862ae69, $616bffd3, $166ccf45,
+    $a00ae278, $d70dd2ee, $4e048354, $3903b3c2, $a7672661, $d06016f7, $4969474d, $3e6e77db,
+    $aed16a4a, $d9d65adc, $40df0b66, $37d83bf0, $a9bcae53, $debb9ec5, $47b2cf7f, $30b5ffe9,
+    $bdbdf21c, $cabac28a, $53b39330, $24b4a3a6, $bad03605, $cdd70693, $54de5729, $23d967bf,
+    $b3667a2e, $c4614ab8, $5d681b02, $2a6f2b94, $b40bbe37, $c30c8ea1, $5a05df1b, $2d02ef8d
+  );
+
+Type
+
+  TZipItem   = Class(TObject)
+    Path : String;
+    Name : String;
+    Size : LongInt;
+    DateTime : TDateTime;
+    HdrPos : Longint;
+  end;
+
+  TProgressEvent = Procedure(Sender : TObject; Const Pct : Double) of object;
+  TOnEndOfFileEvent = Procedure(Sender : TObject; Const Ratio : Double) of object;
+  TOnStartFileEvent = Procedure(Sender : TObject; Const AFileName : String) of object;
+
+Type
+
+  { TCompressor }
+  TCompressor = Class(TObject)
+  Protected
+    FInFile     : TStream;        { I/O file variables                         }
+    FOutFile    : TStream;
+    FCrc32Val   : LongWord;       { CRC calculation variable                   }
+    FBufferSize : LongWord;
+    FOnPercent  : Integer;
+    FOnProgress : TProgressEvent;
+    Procedure UpdC32(Octet: Byte);
+  Public
+    Constructor Create(AInFile, AOutFile : TStream; ABufSize : LongWord); virtual;
+    Procedure Compress; Virtual; Abstract;
+    Class Function ZipID : Word; virtual; Abstract;
+    Property BufferSize : LongWord read FBufferSize;
+    Property OnPercent : Integer Read FOnPercent Write FOnPercent;
+    Property OnProgress : TProgressEvent Read FOnProgress Write FOnProgress;
+    Property Crc32Val : LongWord Read FCrc32Val Write FCrc32Val;
+  end;
+
+  { TDeCompressor }
+  TDeCompressor = Class(TObject)
+  Protected
+    FInFile     : TStream;        { I/O file variables                         }
+    FOutFile    : TStream;
+    FCrc32Val   : LongWord;       { CRC calculation variable                   }
+    FBufferSize : LongWord;
+    FOnPercent  : Integer;
+    FOnProgress : TProgressEvent;
+    Procedure UpdC32(Octet: Byte);
+  Public
+    Constructor Create(AInFile, AOutFile : TStream; ABufSize : LongWord); virtual;
+    Procedure DeCompress; Virtual; Abstract;
+    Class Function ZipID : Word; virtual; Abstract;
+    Property BufferSize : LongWord read FBufferSize;
+    Property OnPercent : Integer Read FOnPercent Write FOnPercent;
+    Property OnProgress : TProgressEvent Read FOnProgress Write FOnProgress;
+    Property Crc32Val : LongWord Read FCrc32Val Write FCrc32Val;
+  end;
+
+  { TShrinker }
+
+Const
+   TABLESIZE   =   8191;
+   FIRSTENTRY  =    257;
+
+Type
+  CodeRec =  Packed Record
+    Child   : Smallint;
+    Sibling : Smallint;
+    Suffix  : Byte;
+  end;
+  CodeArray   =  Array[0..TABLESIZE] of CodeRec;
+  TablePtr    =  ^CodeArray;
+
+  FreeListPtr    =  ^FreeListArray;
+  FreeListArray  =  Array[FIRSTENTRY..TABLESIZE] of Word;
+
+  BufPtr      =  PByte;
+
+  TShrinker = Class(TCompressor)
+  Private
+    FBufSize    : LongWord;
+    MaxInBufIdx :  LongWord;      { Count of valid chars in input buffer       }
+    InputEof    :  Boolean;       { End of file indicator                      }
+    CodeTable   :  TablePtr;      { Points to code table for LZW compression   }
+    FreeList    :  FreeListPtr;   { Table of free code table entries           }
+    NextFree    :  Word;          { Index into free list table                 }
+
+    ClearList   :  Array[0..1023] of Byte;  { Bit mapped structure used in     }
+                                            {    during adaptive resets        }
+    CodeSize    :  Byte;     { Size of codes (in bits) currently being written }
+    MaxCode     :  Word;   { Largest code that can be written in CodeSize bits }
+    InBufIdx,                     { Points to next char in buffer to be read   }
+    OutBufIdx   :  LongWord;      { Points to next free space in output buffer }
+    InBuf,                        { I/O buffers                                }
+    OutBuf      :  BufPtr;
+    FirstCh     :  Boolean;  { Flag indicating the START of a shrink operation }
+    TableFull   :  Boolean;  { Flag indicating a full symbol table             }
+    SaveByte    :  Byte;     { Output code buffer                              }
+    BitsUsed    :  Byte;     { Index into output code buffer                   }
+    BytesIn     :  LongInt;  { Count of input file bytes processed             }
+    BytesOut    :  LongInt;  { Count of output bytes                           }
+    FOnBytes    : Longint;
+    Procedure FillInputBuffer;
+    Procedure WriteOutputBuffer;
+    Procedure FlushOutput;
+    Procedure PutChar(B : Byte);
+    procedure PutCode(Code : Smallint);
+    Procedure InitializeCodeTable;
+    Procedure Prune(Parent : Word);
+    Procedure Clear_Table;
+    Procedure Table_Add(Prefix : Word; Suffix : Byte);
+    function  Table_Lookup(TargetPrefix : Smallint;
+                           TargetSuffix : Byte;
+                           Out FoundAt  : Smallint) : Boolean;
+    Procedure Shrink(Suffix : Smallint);
+    Procedure ProcessLine(Const Source : String);
+    Procedure DoOnProgress(Const Pct : Double); Virtual;
+  Public
+    Constructor Create(AInFile, AOutFile : TStream; ABufSize : LongWord); override;
+    Destructor Destroy; override;
+    Procedure Compress; override;
+    Class Function ZipID : Word; override;
+  end;
+
+  { TDeflater }
+
+  TDeflater = Class(TCompressor)
+  private
+    FCompressionLevel: TCompressionlevel;
+  Public
+    Constructor Create(AInFile, AOutFile : TStream; ABufSize : LongWord);override;
+    Procedure Compress; override;
+    Class Function ZipID : Word; override;
+    Property CompressionLevel : TCompressionlevel Read FCompressionLevel Write FCompressionLevel;
+  end;
+
+  { TInflater }
+
+  TInflater = Class(TDeCompressor)
+  Public
+    Constructor Create(AInFile, AOutFile : TStream; ABufSize : LongWord);override;
+    Procedure DeCompress; override;
+    Class Function ZipID : Word; override;
+  end;
+
+  { TZipper }
+
+  TZipper = Class(TObject)
+  Private
+    FZipping    : Boolean;
+    FBufSize    : LongWord;
+    FFileName   :  String;         { Name of resulting Zip file                 }
+    FFiles      : TStrings;
+    FInMemSize  : Integer;
+    FOutFile    : TFileStream;
+    FInFile     : TFileStream;     { I/O file variables                         }
+    LocalHdr    : Local_File_Header_Type;
+    CentralHdr  : Central_File_Header_Type;
+    EndHdr      : End_of_Central_Dir_Type;
+    FOnPercent  : LongInt;
+    FOnProgress : TProgressEvent;
+    FOnEndOfFile : TOnEndOfFileEvent;
+    FOnStartFile : TOnStartFileEvent;
+  Protected
+    Procedure OpenOutput;
+    Procedure CloseOutput;
+    Procedure CloseInput;
+    Procedure StartZipFile(Item : TZipItem);
+    Function  UpdateZipHeader(Item : TZipItem; FZip : TStream; ACRC : LongWord;AMethod : Word) : Boolean;
+    Procedure BuildZipDirectory;
+    Procedure DoEndOfFile;
+    Procedure ZipOneFile(Item : TZipItem); virtual;
+    Function  OpenInput(InFileName : String) : Boolean;
+    Procedure GetFileInfo;
+    Procedure SetBufSize(Value : LongWord);
+    Procedure SetFileName(Value : String);
+    Function CreateCompressor(Item : TZipItem; AinFile,AZipStream : TStream) : TCompressor; virtual;
+  Public
+    Constructor Create;
+    Destructor Destroy;override;
+    Procedure ZipAllFiles; virtual;
+    Procedure ZipFiles(AFileName : String; FileList : TStrings);
+    Procedure Clear;
+  Public
+    Property BufferSize : LongWord Read FBufSize Write SetBufSize;
+    Property OnPercent : Integer Read FOnPercent Write FOnPercent;
+    Property OnProgress : TProgressEvent Read FOnProgress Write FOnProgress;
+    Property OnStartFile : TOnStartFileEvent Read FOnStartFile Write FOnStartFile;
+    Property OnEndFile : TOnEndOfFileEvent Read FOnEndOfFile Write FOnEndOfFile;
+    Property FileName : String Read FFileName Write SetFileName;
+    Property Files : TStrings Read FFiles;
+    Property InMemSize : Integer Read FInMemSize Write FInMemSize;
+  end;
+
+  { TYbZipper }
+
+  { TUnZipper }
+
+  TUnZipper = Class(TObject)
+  Private
+    FUnZipping  : Boolean;
+    FBufSize    : LongWord;
+    FFileName   :  String;         { Name of resulting Zip file                 }
+    FOutputPath : String;
+    FFiles      : TStrings;
+    FZipEntries : TFPList;  { don't use TFPObjectList, becuase of Contnrs dependency }
+    FOutFile    : TFileStream;
+    FZipFile     : TFileStream;     { I/O file variables                         }
+    LocalHdr    : Local_File_Header_Type;
+    CentralHdr  : Central_File_Header_Type;
+    EndHdr      : End_of_Central_Dir_Type;
+
+    FOnPercent  : LongInt;
+    FOnProgress : TProgressEvent;
+    FOnEndOfFile : TOnEndOfFileEvent;
+    FOnStartFile : TOnStartFileEvent;
+  Protected
+    Procedure OpenInput;
+    Procedure CloseOutput;
+    Procedure CloseInput;
+    Procedure ReadZipHeader(Item : TZipItem; out ACRC : LongWord;out AMethod : Word);
+    Procedure ReadZipDirectory;
+    Procedure DoEndOfFile;
+    Procedure UnZipOneFile(Item : TZipItem); virtual;
+    Function  OpenOutput(OutFileName : String) : Boolean;
+    Procedure SetBufSize(Value : LongWord);
+    Procedure SetFileName(Value : String);
+    Procedure SetOutputPath(Value:String);
+    Function CreateDeCompressor(Item : TZipItem; AMethod : Word;AZipFile,AOutFile : TStream) : TDeCompressor; virtual;
+  Public
+    Constructor Create;
+    Destructor Destroy;override;
+    Procedure UnZipAllFiles; virtual;
+    Procedure UnZipFiles(AFileName : String; FileList : TStrings);
+    Procedure UnZipAllFiles(AFileName : String);
+    Procedure Clear;
+  Public
+    Property BufferSize : LongWord Read FBufSize Write SetBufSize;
+    Property OnPercent : Integer Read FOnPercent Write FOnPercent;
+    Property OnProgress : TProgressEvent Read FOnProgress Write FOnProgress;
+    Property OnStartFile : TOnStartFileEvent Read FOnStartFile Write FOnStartFile;
+    Property OnEndFile : TOnEndOfFileEvent Read FOnEndOfFile Write FOnEndOfFile;
+    Property FileName : String Read FFileName Write SetFileName;
+    Property OutputPath : String Read FOutputPath Write SetOutputPath;
+    Property Files : TStrings Read FFiles;
+  end;
+
+  EZipError = Class(Exception);
+
+Implementation
+
+ResourceString
+  SErrBufsizeChange = 'Changing buffer size is not allowed while (un)zipping';
+  SErrFileChange = 'Changing output file name is not allowed while (un)zipping';
+  SErrInvalidCRC = 'Invalid CRC checksum while unzipping %s';
+  SErrCorruptZIP = 'Corrupt ZIP file %s';
+  SErrUnsupportedCompressionFormat = 'Unsupported compression format %d';
+
+{ ---------------------------------------------------------------------
+    Auxiliary
+  ---------------------------------------------------------------------}
+
+Procedure DateTimeToZipDateTime(DT : TDateTime; out ZD,ZT : Word);
+
+Var
+  Y,M,D,H,N,S,MS : Word;
+
+begin
+  DecodeDate(DT,Y,M,D);
+  DecodeTime(DT,H,N,S,MS);
+  Y:=Y-1980;
+  ZD:=d+(32*M)+(512*Y);
+  ZT:=(S div 2)+(32*N)+(2048*h);
+end;
+
+Procedure ZipDateTimeToDateTime(ZD,ZT : Word;out DT : TDateTime);
+
+Var
+  Y,M,D,H,N,S,MS : Word;
+
+begin
+  MS:=0;
+  S:=(ZT and 31) shl 1;
+  N:=(ZT shr 5) and 63;
+  H:=(ZT shr 12) and 31;
+  D:=ZD and 31;
+  M:=(ZD shr 5) and 15;
+  Y:=((ZD shr 9) and 127)+1980;
+  DT:=ComposeDateTime(EncodeDate(Y,M,D),EncodeTime(H,N,S,MS));
+end;
+
+{ ---------------------------------------------------------------------
+    TDeCompressor
+  ---------------------------------------------------------------------}
+
+
+Procedure TDeCompressor.UpdC32(Octet: Byte);
+
+Begin
+  FCrc32Val := Crc_32_Tab[Byte(FCrc32Val XOR LongInt(Octet))] XOR ((FCrc32Val SHR 8) AND $00FFFFFF);
+end;
+
+constructor TDeCompressor.Create(AInFile, AOutFile: TStream; ABufSize: LongWord);
+begin
+  FinFile:=AInFile;
+  FoutFile:=AOutFile;
+  FBufferSize:=ABufSize;
+  CRC32Val:=$FFFFFFFF;
+end;
+
+
+{ ---------------------------------------------------------------------
+    TCompressor
+  ---------------------------------------------------------------------}
+
+
+Procedure TCompressor.UpdC32(Octet: Byte);
+
+Begin
+  FCrc32Val := Crc_32_Tab[Byte(FCrc32Val XOR LongInt(Octet))] XOR ((FCrc32Val SHR 8) AND $00FFFFFF);
+end;
+
+constructor TCompressor.Create(AInFile, AOutFile: TStream; ABufSize: LongWord);
+begin
+  FinFile:=AInFile;
+  FoutFile:=AOutFile;
+  FBufferSize:=ABufSize;
+  CRC32Val:=$FFFFFFFF;
+end;
+
+
+{ ---------------------------------------------------------------------
+    TDeflater
+  ---------------------------------------------------------------------}
+
+constructor TDeflater.Create(AInFile, AOutFile: TStream; ABufSize: LongWord);
+begin
+  Inherited;
+  FCompressionLevel:=clDefault;
+end;
+
+
+procedure TDeflater.Compress;
+
+Var
+  Buf : PByte;
+  I,Count,NewCount : Integer;
+  C : TCompressionStream;
+
+begin
+  CRC32Val:=$FFFFFFFF;
+  Buf:=GetMem(FBufferSize);
+  Try
+    C:=TCompressionStream.Create(FCompressionLevel,FOutFile,True);
+    Try
+      Repeat
+        Count:=FInFile.Read(Buf^,FBufferSize);
+        For I:=0 to Count-1 do
+          UpdC32(Buf[i]);
+        NewCount:=Count;
+        While (NewCount>0) do
+          NewCount:=NewCount-C.Write(Buf^,NewCount);
+      Until (Count=0);
+    Finally
+      C.Free;
+    end;
+  Finally
+    FreeMem(Buf);
+  end;
+  Crc32Val:=NOT Crc32Val;
+end;
+
+class function TDeflater.ZipID: Word;
+begin
+  Result:=8;
+end;
+
+{ ---------------------------------------------------------------------
+    TInflater
+  ---------------------------------------------------------------------}
+
+constructor TInflater.Create(AInFile, AOutFile: TStream; ABufSize: LongWord);
+begin
+  Inherited;
+end;
+
+
+procedure TInflater.DeCompress;
+
+Var
+  Buf : PByte;
+  I,Count : Integer;
+  C : TDeCompressionStream;
+
+begin
+  CRC32Val:=$FFFFFFFF;
+  Buf:=GetMem(FBufferSize);
+  Try
+    C:=TDeCompressionStream.Create(FInFile,True);
+    Try
+      Repeat
+        Count:=C.Read(Buf^,FBufferSize);
+        For I:=0 to Count-1 do
+          UpdC32(Buf[i]);
+        FOutFile.Write(Buf^,Count);
+      Until (Count=0);
+    Finally
+      C.Free;
+    end;
+  Finally
+    FreeMem(Buf);
+  end;
+  Crc32Val:=NOT Crc32Val;
+end;
+
+class function TInflater.ZipID: Word;
+begin
+  Result:=8;
+end;
+
+
+{ ---------------------------------------------------------------------
+    TShrinker
+  ---------------------------------------------------------------------}
+
+Const
+   DefaultInMemSize = 256*1024; { Files larger than 256k are processed on disk   }
+   DefaultBufSize =  16384;     { Use 16K file buffers                             }
+   MINBITS     =      9;        { Starting code size of 9 bits                     }
+   MAXBITS     =     13;        { Maximum code size of 13 bits                     }
+   SPECIAL     =    256;        { Special function code                            }
+   INCSIZE     =      1;        { Code indicating a jump in code size              }
+   CLEARCODE   =      2;        { Code indicating code table has been cleared      }
+   STDATTR     =    $23;        { Standard file attribute for DOS Find First/Next  }
+
+constructor TShrinker.Create(AInFile, AOutFile : TStream; ABufSize : LongWord);
+begin
+  Inherited;
+  FBufSize:=ABufSize;
+  InBuf:=GetMem(FBUFSIZE);
+  OutBuf:=GetMem(FBUFSIZE);
+  CodeTable:=GetMem(SizeOf(CodeTable^));
+  FreeList:=GetMem(SizeOf(FreeList^));
+end;
+
+destructor TShrinker.Destroy;
+begin
+  FreeMem(CodeTable);
+  FreeMem(FreeList);
+  FreeMem(InBuf);
+  FreeMem(OutBuf);
+  inherited Destroy;
+end;
+
+Procedure TShrinker.Compress;
+
+Var
+   OneString : String;
+   Remaining : Word;
+
+begin
+  BytesIn := 1;
+  BytesOut := 1;
+  InitializeCodeTable;
+  FillInputBuffer;
+  FirstCh:= TRUE;
+  Crc32Val:=$FFFFFFFF;
+  FOnBytes:=Round((FInFile.Size * FOnPercent) / 100);
+  While NOT InputEof do
+    begin
+    Remaining:=Succ(MaxInBufIdx - InBufIdx);
+    If Remaining>255 then
+      Remaining:=255;
+    If Remaining=0 then
+      FillInputBuffer
+    else
+      begin
+      SetLength(OneString,Remaining);
+      Move(InBuf[InBufIdx], OneString[1], Remaining);
+      Inc(InBufIdx, Remaining);
+      ProcessLine(OneString);
+      end;
+    end;
+   Crc32Val := NOT Crc32Val;
+   ProcessLine('');
+end;
+
+class function TShrinker.ZipID: Word;
+begin
+  Result:=1;
+end;
+
+
+Procedure TShrinker.DoOnProgress(Const Pct: Double);
+
+begin
+  If Assigned(FOnProgress) then
+    FOnProgress(Self,Pct);
+end;
+
+
+Procedure TShrinker.FillInputBuffer;
+
+Begin
+   MaxInbufIDx:=FInfile.Read(InBuf[0], FBufSize);
+   If MaxInbufIDx=0 then
+      InputEof := TRUE
+   else
+      InputEOF := FALSE;
+   InBufIdx := 0;
+end;
+
+
+Procedure TShrinker.WriteOutputBuffer;
+Begin
+  FOutFile.WriteBuffer(OutBuf[0], OutBufIdx);
+  OutBufIdx := 0;
+end;
+
+
+Procedure TShrinker.PutChar(B : Byte);
+
+Begin
+  OutBuf[OutBufIdx] := B;
+  Inc(OutBufIdx);
+  If OutBufIdx>=FBufSize then
+    WriteOutputBuffer;
+  Inc(BytesOut);
+end;
+
+Procedure TShrinker.FlushOutput;
+Begin
+  If OutBufIdx>0 then
+    WriteOutputBuffer;
+End;
+
+
+procedure TShrinker.PutCode(Code : Smallint);
+
+var
+  ACode : LongInt;
+  XSize : Smallint;
+
+begin
+  if (Code=-1) then
+    begin
+    if BitsUsed>0 then
+      PutChar(SaveByte);
+    end
+  else
+    begin
+    ACode := Longint(Code);
+    XSize := CodeSize+BitsUsed;
+    ACode := (ACode shl BitsUsed) or SaveByte;
+    while (XSize div 8) > 0 do
+      begin
+      PutChar(Lo(ACode));
+      ACode := ACode shr 8;
+      Dec(XSize,8);
+      end;
+    BitsUsed := XSize;
+    SaveByte := Lo(ACode);
+    end;
+end;
+
+
+Procedure TShrinker.InitializeCodeTable;
+
+Var
+   I  :  Word;
+Begin
+   For I := 0 to TableSize do
+     begin
+     With CodeTable^[I] do
+       begin
+       Child := -1;
+       Sibling := -1;
+       If (I<=255) then
+         Suffix := I;
+       end;
+     If (I>=257) then
+       FreeList^[I] := I;
+     end;
+   NextFree  := FIRSTENTRY;
+   TableFull := FALSE;
+end;
+
+
+Procedure TShrinker.Prune(Parent : Word);
+
+Var
+   CurrChild   : Smallint;
+   NextSibling : Smallint;
+Begin
+  CurrChild := CodeTable^[Parent].Child;
+  { Find first Child that has descendants .. clear any that don't }
+  While (CurrChild <> -1) AND (CodeTable^[CurrChild].Child = -1) do
+    begin
+    CodeTable^[Parent].Child := CodeTable^[CurrChild].Sibling;
+    CodeTable^[CurrChild].Sibling := -1;
+     { Turn on ClearList bit to indicate a cleared entry }
+    ClearList[CurrChild DIV 8] := (ClearList[CurrChild DIV 8] OR (1 SHL (CurrChild MOD 8)));
+    CurrChild := CodeTable^[Parent].Child;
+    end;
+  If CurrChild <> -1 then
+    begin   { If there are any children left ...}
+    Prune(CurrChild);
+    NextSibling := CodeTable^[CurrChild].Sibling;
+    While NextSibling <> -1 do
+      begin
+      If CodeTable^[NextSibling].Child = -1 then
+        begin
+        CodeTable^[CurrChild].Sibling := CodeTable^[NextSibling].Sibling;
+        CodeTable^[NextSibling].Sibling := -1;
+        { Turn on ClearList bit to indicate a cleared entry }
+        ClearList[NextSibling DIV 8] := (ClearList[NextSibling DIV 8] OR (1 SHL (NextSibling MOD 8)));
+        NextSibling := CodeTable^[CurrChild].Sibling;
+        end
+      else
+        begin
+        CurrChild := NextSibling;
+        Prune(CurrChild);
+        NextSibling := CodeTable^[CurrChild].Sibling;
+        end;
+      end;
+    end;
+end;
+
+
+Procedure TShrinker.Clear_Table;
+Var
+   Node : Word;
+Begin
+   FillChar(ClearList, SizeOf(ClearList), $00);
+   For Node := 0 to 255 do
+     Prune(Node);
+   NextFree := Succ(TABLESIZE);
+   For Node := TABLESIZE downto FIRSTENTRY do
+     begin
+     If (ClearList[Node DIV 8] AND (1 SHL (Node MOD 8))) <> 0 then
+       begin
+       Dec(NextFree);
+       FreeList^[NextFree] := Node;
+       end;
+     end;
+   If NextFree <= TABLESIZE then
+     TableFull := FALSE;
+end;
+
+
+Procedure TShrinker.Table_Add(Prefix : Word; Suffix : Byte);
+Var
+   FreeNode : Word;
+Begin
+  If NextFree <= TABLESIZE then
+    begin
+    FreeNode := FreeList^[NextFree];
+    Inc(NextFree);
+    CodeTable^[FreeNode].Child := -1;
+    CodeTable^[FreeNode].Sibling := -1;
+    CodeTable^[FreeNode].Suffix := Suffix;
+    If CodeTable^[Prefix].Child  = -1 then
+      CodeTable^[Prefix].Child := FreeNode
+    else
+      begin
+      Prefix := CodeTable^[Prefix].Child;
+      While CodeTable^[Prefix].Sibling <> -1 do
+        Prefix := CodeTable^[Prefix].Sibling;
+      CodeTable^[Prefix].Sibling := FreeNode;
+      end;
+    end;
+  if NextFree > TABLESIZE then
+    TableFull := TRUE;
+end;
+
+function TShrinker.Table_Lookup(    TargetPrefix : Smallint;
+                          TargetSuffix : Byte;
+                      Out FoundAt      : Smallint   ) : Boolean;
+
+var TempPrefix : Smallint;
+
+begin
+  TempPrefix := TargetPrefix;
+  Table_lookup := False;
+  if CodeTable^[TempPrefix].Child <> -1 then
+    begin
+    TempPrefix := CodeTable^[TempPrefix].Child;
+    repeat
+      if CodeTable^[TempPrefix].Suffix = TargetSuffix then
+        begin
+        Table_lookup := True;
+        break;
+        end;
+      if CodeTable^[TempPrefix].Sibling = -1 then
+        break;
+      TempPrefix := CodeTable^[TempPrefix].Sibling;
+    until False;
+  end;
+  if Table_Lookup then
+    FoundAt := TempPrefix
+  else
+    FoundAt := -1;
+end;
+
+Procedure TShrinker.Shrink(Suffix : Smallint);
+
+Const
+  LastCode : Smallint = 0;
+
+Var
+  WhereFound : Smallint;
+
+Begin
+  If FirstCh then
+    begin
+    SaveByte := $00;
+    BitsUsed := 0;
+    CodeSize := MINBITS;
+    MaxCode  := (1 SHL CodeSize) - 1;
+    LastCode := Suffix;
+    FirstCh  := FALSE;
+    end
+  else
+    begin
+    If Suffix <> -1 then
+      begin
+      If TableFull then
+        begin
+        Putcode(LastCode);
+        PutCode(SPECIAL);
+        Putcode(CLEARCODE);
+        Clear_Table;
+        Table_Add(LastCode, Suffix);
+        LastCode := Suffix;
+        end
+      else
+        begin
+        If Table_Lookup(LastCode, Suffix, WhereFound) then
+          begin
+          LastCode  := WhereFound;
+          end
+        else
+          begin
+          PutCode(LastCode);
+          Table_Add(LastCode, Suffix);
+          LastCode := Suffix;
+          If (FreeList^[NextFree] > MaxCode) and (CodeSize < MaxBits) then
+            begin
+            PutCode(SPECIAL);
+            PutCode(INCSIZE);
+            Inc(CodeSize);
+            MaxCode := (1 SHL CodeSize) -1;
+            end;
+          end;
+        end;
+      end
+    else
+      begin
+      PutCode(LastCode);
+      PutCode(-1);
+      FlushOutput;
+      end;
+    end;
+end;
+
+Procedure TShrinker.ProcessLine(Const Source : String);
+
+Var
+  I : Word;
+
+Begin
+  If Source = '' then
+    Shrink(-1)
+  else
+    For I := 1 to Length(Source) do
+      begin
+      Inc(BytesIn);
+      If (Pred(BytesIn) MOD FOnBytes) = 0 then
+        DoOnProgress(100 * ( BytesIn / FInFile.Size));
+      UpdC32(Ord(Source[I]));
+      Shrink(Ord(Source[I]));
+      end;
+end;
+
+{ ---------------------------------------------------------------------
+    TZipper
+  ---------------------------------------------------------------------}
+
+
+Procedure TZipper.GetFileInfo;
+
+Var
+   Info : TSearchRec;
+   I       : Longint;
+   NewNode : TZipItem;
+
+
+Begin
+   For I := 0 to FFiles.Count-1 do
+    begin
+     If FindFirst(FFiles[I], STDATTR, Info)=0 then
+       try
+         NewNode:=TZipItem.Create;
+         NewNode.Path := ExtractFilePath(FFiles[i]);
+         NewNode.Name := Info.Name;
+         NewNode.Size := Info.Size;
+         NewNode.DateTime:=FileDateToDateTime(Info.Time);
+         FFiles.Objects[i]:=NewNode;
+       finally
+         FindClose(Info);
+       end;
+     end;  
+end;
+
+Procedure TZipper.OpenOutput;
+
+Begin
+  FOutFile:=TFileStream.Create(FFileName,fmCreate);
+End;
+
+
+Function TZipper.OpenInput(InFileName : String) : Boolean;
+
+Begin
+  FInFile:=TFileStream.Create(InFileName,fmOpenRead);
+  Result:=True;
+  If Assigned(FOnStartFile) then
+    FOnStartFile(Self,InFileName);
+End;
+
+
+Procedure TZipper.CloseOutput;
+
+Begin
+  FreeAndNil(FOutFile);
+end;
+
+
+Procedure TZipper.CloseInput;
+
+Begin
+  FreeAndNil(FInFile);
+end;
+
+
+Procedure TZipper.StartZipFile(Item : TZipItem);
+
+Begin
+  FillChar(LocalHdr,SizeOf(LocalHdr),0);
+  With LocalHdr do
+    begin
+    Signature := LOCAL_FILE_HEADER_SIGNATURE;
+    Extract_Version_Reqd := 10;
+    Bit_Flag := 0;
+    Compress_Method := 1;
+    DateTimeToZipDateTime(Item.DateTime,Last_Mod_Date,Last_Mod_Time);
+    Crc32 := 0;
+    Compressed_Size := 0;
+    Uncompressed_Size := Item.Size;
+    FileName_Length := 0;
+    Extra_Field_Length := 0;
+  end ;
+End;
+
+
+Function TZipper.UpdateZipHeader(Item : TZipItem; FZip : TStream; ACRC : LongWord; AMethod : Word) : Boolean;
+var
+  ZFileName  : ShortString;
+Begin
+  ZFileName:=Item.Path+Item.Name;
+  With LocalHdr do
+    begin
+    FileName_Length := Length(ZFileName);
+    Compressed_Size := FZip.Size;
+    Crc32 := ACRC;
+    Compress_method:=AMethod;
+    Result:=Not (Compressed_Size >= Uncompressed_Size);
+    If Not Result then
+      begin                     { No...                          }
+      Compress_Method := 0;                  { ...change stowage type      }
+      Compressed_Size := Uncompressed_Size;  { ...update compressed size   }
+      end;
+    end;
+  FOutFile.WriteBuffer(LocalHdr,SizeOf(LocalHdr));
+  FOutFile.WriteBuffer(ZFileName[1],Length(ZFileName));
+End;
+
+
+Procedure TZipper.BuildZipDirectory;
+
+Var
+   SavePos   : LongInt;
+   HdrPos    : LongInt;
+   CenDirPos : LongInt;
+   Entries   : Word;
+   ZFileName  : ShortString;
+
+Begin
+   Entries := 0;
+   CenDirPos := FOutFile.Position;
+   FOutFile.Seek(0,soFrombeginning);             { Rewind output file }
+   HdrPos := FOutFile.Position;
+   FOutFile.ReadBuffer(LocalHdr, SizeOf(LocalHdr));
+   Repeat
+     SetLength(ZFileName,LocalHdr.FileName_Length);
+     FOutFile.ReadBuffer(ZFileName[1], LocalHdr.FileName_Length);
+     SavePos := FOutFile.Position;
+     FillChar(CentralHdr,SizeOf(CentralHdr),0);
+     With CentralHdr do
+       begin
+       Signature := CENTRAL_FILE_HEADER_SIGNATURE;
+       MadeBy_Version := LocalHdr.Extract_Version_Reqd;
+       Move(LocalHdr.Extract_Version_Reqd, Extract_Version_Reqd, 26);
+       Last_Mod_Time:=localHdr.Last_Mod_Time;
+       Last_Mod_Date:=localHdr.Last_Mod_Date;
+       File_Comment_Length := 0;
+       Starting_Disk_Num := 0;
+       Internal_Attributes := 0;
+       External_Attributes := faARCHIVE;
+       Local_Header_Offset := HdrPos;
+       end;
+     FOutFile.Seek(0,soFromEnd);
+     FOutFile.WriteBuffer(CentralHdr,SizeOf(CentralHdr));
+     FOutFile.WriteBuffer(ZFileName[1],Length(ZFileName));
+     Inc(Entries);
+     FOutFile.Seek(SavePos + LocalHdr.Compressed_Size,soFromBeginning);
+     HdrPos:=FOutFile.Position;
+     FOutFile.ReadBuffer(LocalHdr, SizeOf(LocalHdr));
+   Until LocalHdr.Signature = CENTRAL_FILE_HEADER_SIGNATURE;
+   FOutFile.Seek(0,soFromEnd);
+   FillChar(EndHdr,SizeOf(EndHdr),0);
+   With EndHdr do
+     begin
+     Signature := END_OF_CENTRAL_DIR_SIGNATURE;
+     Disk_Number := 0;
+     Central_Dir_Start_Disk := 0;
+     Entries_This_Disk := Entries;
+     Total_Entries := Entries;
+     Central_Dir_Size := FOutFile.Size-CenDirPos;
+     Start_Disk_Offset := CenDirPos;
+     ZipFile_Comment_Length := 0;
+     FOutFile.WriteBuffer(EndHdr, SizeOf(EndHdr));
+     end;
+end;
+
+Function TZipper.CreateCompressor(Item : TZipItem; AInFile,AZipStream : TStream) : TCompressor;
+
+begin
+  Result:=TDeflater.Create(AinFile,AZipStream,FBufSize);
+end;
+
+Procedure TZipper.ZipOneFile(Item : TZipItem);
+
+Var
+  CRC : LongWord;
+  ZMethod : Word;
+  ZipStream : TStream;
+  TmpFileName : String;
+
+Begin
+  OpenInput(Item.Path+Item.Name);
+  Try
+    StartZipFile(Item);
+    If (FInfile.Size<=FInMemSize) then
+      ZipStream:=TMemoryStream.Create
+    else
+      begin
+      TmpFileName:=ChangeFileExt(FFileName,'.tmp');
+      ZipStream:=TFileStream.Create(TmpFileName,fmCreate);
+      end;
+    Try
+      With CreateCompressor(Item, FinFile,ZipStream) do
+        Try
+          OnProgress:=Self.OnProgress;
+          OnPercent:=Self.OnPercent;
+          Compress;
+          CRC:=Crc32Val;
+          ZMethod:=ZipID;
+        Finally
+          Free;
+        end;
+      If UpdateZipHeader(Item,ZipStream,CRC,ZMethod) then
+        // Compressed file smaller than original file.
+        FOutFile.CopyFrom(ZipStream,0)
+      else
+        begin
+        // Original file smaller than compressed file.
+        FInfile.Seek(0,soFromBeginning);
+        FOutFile.CopyFrom(FInFile,0);
+        end;
+    finally
+      ZipStream.Free;
+      If (TmpFileName<>'') then
+        DeleteFile(TmpFileName);
+    end;
+  Finally
+    CloseInput;
+  end;
+end;
+
+Procedure TZipper.ZipAllFiles;
+Var
+   Item : TZipItem;
+   I : Integer;
+   filecnt : integer;
+Begin
+  if FFiles.Count=0 then
+    exit;
+  FZipping:=True;
+  Try
+    GetFileInfo;
+    OpenOutput;
+    Try
+      filecnt:=0;
+      For I:=0 to FFiles.Count-1 do
+        begin
+          Item:=FFiles.Objects[i] as TZipItem;
+	  if assigned(Item) then
+	    begin
+              ZipOneFile(Item);
+	      inc(filecnt);
+	    end;  
+        end;
+      if filecnt>0 then	
+        BuildZipDirectory;
+    finally
+      CloseOutput;
+    end;
+  finally
+    FZipping:=False;
+  end;
+end;
+
+
+Procedure TZipper.SetBufSize(Value : LongWord);
+
+begin
+  If FZipping then
+    Raise EZipError.Create(SErrBufsizeChange);
+  If Value>=DefaultBufSize then
+    FBufSize:=Value;
+end;
+
+Procedure TZipper.SetFileName(Value : String);
+
+begin
+  If FZipping then
+    Raise EZipError.Create(SErrFileChange);
+  FFileName:=Value;
+end;
+
+Procedure TZipper.ZipFiles(AFileName : String; FileList : TStrings);
+
+begin
+  FFiles.Assign(FileList);
+  FFileName:=AFileName;
+  ZipAllFiles;
+end;
+
+Procedure TZipper.DoEndOfFile;
+
+Var
+  ComprPct : Double;
+
+begin
+  If (LocalHdr.Uncompressed_Size>0) then
+    ComprPct := (100.0 * (LocalHdr.Uncompressed_Size - LocalHdr.Compressed_Size)) / LocalHdr.Uncompressed_Size
+  else
+    ComprPct := 0;
+  If Assigned(FOnEndOfFile) then
+    FOnEndOfFile(Self,ComprPct);
+end;
+
+Constructor TZipper.Create;
+
+begin
+  FBufSize:=DefaultBufSize;
+  FInMemSize:=DefaultInMemSize;
+  FFiles:=TStringList.Create;
+  TStringlist(FFiles).Sorted:=True;
+  FOnPercent:=1;
+end;
+
+Procedure TZipper.Clear;
+
+Var
+  I : Integer;
+
+begin
+  For I:=0 to FFiles.Count-1 do
+    FFiles.Objects[i].Free;
+  FFiles.Clear;
+end;
+
+Destructor TZipper.Destroy;
+
+begin
+  Clear;
+  FreeAndNil(FFiles);
+  Inherited;
+end;
+
+
+{ ---------------------------------------------------------------------
+    TUnZipper
+  ---------------------------------------------------------------------}
+
+Procedure TUnZipper.OpenInput;
+
+Begin
+  FZipFile:=TFileStream.Create(FFileName,fmOpenRead);
+End;
+
+
+Function TUnZipper.OpenOutput(OutFileName : String) : Boolean;
+
+Begin
+  FOutFile:=TFileStream.Create(OutFileName,fmCreate);
+  Result:=True;
+  If Assigned(FOnStartFile) then
+    FOnStartFile(Self,OutFileName);
+End;
+
+
+Procedure TUnZipper.CloseOutput;
+
+Begin
+  FreeAndNil(FOutFile);
+end;
+
+
+Procedure TUnZipper.CloseInput;
+
+Begin
+  FreeAndNil(FZipFile);
+end;
+
+
+Procedure TUnZipper.ReadZipHeader(Item : TZipItem; out ACRC : LongWord; out AMethod : Word);
+
+Begin
+  FZipFile.Seek(Item.HdrPos,soFromBeginning);
+  FZipFile.ReadBuffer(LocalHdr,SizeOf(LocalHdr));
+  With LocalHdr do
+    begin
+      SetLength(Item.Name,Filename_Length);
+      FZipFile.ReadBuffer(Item.Name[1],Filename_Length);
+      FZipFile.Seek(Extra_Field_Length,soCurrent);
+      Item.Size:=Uncompressed_Size;
+      ZipDateTimeToDateTime(Last_Mod_Date,Last_Mod_Time,Item.DateTime);
+      ACrc:=Crc32;
+      AMethod:=Compress_method;
+    end;
+End;
+
+
+Procedure TUnZipper.ReadZipDirectory;
+
+Var
+   i,
+   EndHdrPos,
+   CenDirPos : LongInt;
+   NewNode   : TZipItem;
+Begin
+   EndHdrPos:=FZipFile.Size-SizeOf(EndHdr);
+   if EndHdrPos < 0 then
+     raise EZipError.CreateFmt(SErrCorruptZIP,[FZipFile.FileName]);
+   FZipFile.Seek(EndHdrPos,soFromBeginning);
+   FZipFile.ReadBuffer(EndHdr, SizeOf(EndHdr));
+   With EndHdr do
+     begin
+       if Signature <> END_OF_CENTRAL_DIR_SIGNATURE then
+         raise EZipError.CreateFmt(SErrCorruptZIP,[FZipFile.FileName]);
+       CenDirPos:=Start_Disk_Offset;
+     end;
+   FZipFile.Seek(CenDirPos,soFrombeginning);
+   for i:=0 to EndHdr.Entries_This_Disk-1 do
+     begin
+       FZipFile.ReadBuffer(CentralHdr, SizeOf(CentralHdr));
+       With CentralHdr do
+         begin
+           if Signature<>CENTRAL_FILE_HEADER_SIGNATURE then
+             raise EZipError.CreateFmt(SErrCorruptZIP,[FZipFile.FileName]);
+           NewNode:=TZipItem.Create;
+           NewNode.HdrPos := Local_Header_Offset;
+           SetLength(NewNode.Name,Filename_Length);
+           FZipFile.ReadBuffer(NewNode.Name[1],Filename_Length);
+           FZipFile.Seek(Extra_Field_Length+File_Comment_Length,soCurrent);
+           FZipEntries.Add(NewNode);
+         end;
+     end;
+end;
+
+Function TUnZipper.CreateDeCompressor(Item : TZipItem; AMethod : Word;AZipFile,AOutFile : TStream) : TDeCompressor;
+begin
+  case AMethod of
+    8 :
+      Result:=TInflater.Create(AZipFile,AOutFile,FBufSize);
+  else
+    raise EZipError.CreateFmt(SErrUnsupportedCompressionFormat,[AMethod]);
+  end;
+end;
+
+Procedure TUnZipper.UnZipOneFile(Item : TZipItem);
+
+Var
+  Count : Longint;
+  CRC : LongWord;
+  ZMethod : Word;
+  OutputFileName : string;
+Begin
+  Try
+    ReadZipHeader(Item,CRC,ZMethod);
+    OutputFileName:=Item.Name;
+    if FOutputPath<>'' then
+      OutputFileName:=IncludeTrailingPathDelimiter(FOutputPath)+OutputFileName;
+    OpenOutput(OutputFileName);  
+    if ZMethod=0 then
+      begin
+        Count:=FOutFile.CopyFrom(FZipFile,LocalHdr.Compressed_Size);
+{$warning TODO: Implement CRC Check}
+      end
+    else
+      With CreateDecompressor(Item, ZMethod, FZipFile, FOutFile) do
+        Try
+          OnProgress:=Self.OnProgress;
+          OnPercent:=Self.OnPercent;
+          DeCompress;
+          if CRC<>Crc32Val then
+            raise EZipError.CreateFmt(SErrInvalidCRC,[Item.Name]);
+        Finally
+          Free;
+        end;
+  Finally
+    CloseOutput;
+  end;
+end;
+
+
+Procedure TUnZipper.UnZipAllFiles;
+Var
+   Item : TZipItem;
+   I : Integer;
+
+Begin
+  FUnZipping:=True;
+  Try
+    OpenInput;
+    Try
+      ReadZipDirectory;
+      For I:=0 to FZipEntries.Count-1 do
+        begin
+          Item:=TZipItem(FZipEntries[i]);
+	  if (FFiles=nil) or
+	     (FFiles.IndexOf(Item.Name)<>-1) then
+            UnZipOneFile(Item);
+        end;
+    Finally
+       CloseInput;
+    end;
+  finally
+    FUnZipping:=False;
+  end;
+end;
+
+
+Procedure TUnZipper.SetBufSize(Value : LongWord);
+
+begin
+  If FUnZipping then
+    Raise EZipError.Create(SErrBufsizeChange);
+  If Value>=DefaultBufSize then
+    FBufSize:=Value;
+end;
+
+Procedure TUnZipper.SetFileName(Value : String);
+
+begin
+  If FUnZipping then
+    Raise EZipError.Create(SErrFileChange);
+  FFileName:=Value;
+end;
+
+Procedure TUnZipper.SetOutputPath(Value:String);
+begin
+  If FUnZipping then
+    Raise EZipError.Create(SErrFileChange);
+  FOutputPath:=Value;
+end;
+
+Procedure TUnZipper.UnZipFiles(AFileName : String; FileList : TStrings);
+
+begin
+  FFiles.Assign(FileList);
+  FFileName:=AFileName;
+  UnZipAllFiles;
+end;
+
+Procedure TUnZipper.UnZipAllFiles(AFileName : String);
+
+begin
+  FFileName:=AFileName;
+  UnZipAllFiles;
+end;
+
+Procedure TUnZipper.DoEndOfFile;
+
+Var
+  ComprPct : Double;
+
+begin
+  If (LocalHdr.Uncompressed_Size>0) then
+    ComprPct := (100.0 * (LocalHdr.Uncompressed_Size - LocalHdr.Compressed_Size)) / LocalHdr.Uncompressed_Size
+  else
+    ComprPct := 0;
+  If Assigned(FOnEndOfFile) then
+    FOnEndOfFile(Self,ComprPct);
+end;
+
+Constructor TUnZipper.Create;
+
+begin
+  FBufSize:=DefaultBufSize;
+  FFiles:=TStringList.Create;
+  FZipEntries:=TFPList.Create;
+  TStringlist(FFiles).Sorted:=True;
+  FOnPercent:=1;
+end;
+
+Procedure TUnZipper.Clear;
+
+Var
+  I : Integer;
+
+begin
+  For I:=0 to FFiles.Count-1 do
+    FFiles.Objects[i].Free;
+  FFiles.Clear;
+  For I:=0 to FZipEntries.Count-1 do
+    TZipItem(FZipEntries[i]).Free;
+  FZipEntries.Clear;
+end;
+
+Destructor TUnZipper.Destroy;
+
+begin
+  Clear;
+  FreeAndNil(FFiles);
+  FreeAndNil(FZipEntries);
+  Inherited;
+end;
+
+End.

+ 0 - 0
packages/paszlib/ziputils.pas → packages/paszlib/src/ziputils.pas


+ 440 - 0
packages/paszlib/src/zstream.pp

@@ -0,0 +1,440 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2000 by the Free Pascal development team
+
+    Implementation of compression streams.
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+{$mode objfpc}
+
+unit zstream;
+
+
+{ ---------------------------------------------------------------------
+  For linux and freebsd it's also possible to use ZLib instead
+  of paszlib. You need to undefine 'usepaszlib'.
+  ---------------------------------------------------------------------}
+
+{$define usepaszlib}
+
+
+interface
+
+uses
+  Sysutils, Classes
+{$ifdef usepaszlib}
+  ,paszlib,zbase
+{$else}
+  ,zlib
+{$endif}
+  ;
+
+{$H+}
+
+type
+  // Error reporting.
+  EZlibError = class(EStreamError);
+  ECompressionError = class(EZlibError);
+  EDecompressionError = class(EZlibError);
+
+  TCustomZlibStream = class(TOwnerStream)
+  private
+    FStrmPos: Integer;
+    FOnProgress: TNotifyEvent;
+    FZRec: TZStream;
+    FBuffer: array [Word] of Byte;
+  protected
+    procedure Progress(Sender: TObject); dynamic;
+    property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
+  public
+    constructor Create(Strm: TStream);
+  end;
+
+  TCompressionLevel = (clNone, clFastest, clDefault, clMax);
+
+  TCompressionStream = class(TCustomZlibStream)
+  private
+    function GetCompressionRate: extended;
+    function CompressionCheck(code: Integer): Integer;
+    procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
+                          var OutBuf: Pointer; var OutBytes: Integer);
+  public
+    constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream; ASkipHeader : Boolean = False);
+    destructor Destroy; override;
+    function Read(var Buffer; Count: Longint): Longint; override;
+    function Write(const Buffer; Count: Longint): Longint; override;
+    function Seek(Offset: Longint; Origin: Word): Longint; override;
+    property CompressionRate: extended read GetCompressionRate;
+    property OnProgress;
+  end;
+
+  TDecompressionStream = class(TCustomZlibStream)
+  private
+    function DecompressionCheck(code: Integer): Integer;
+    procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
+    OutEstimate: Integer; var OutBuf: Pointer; var OutBytes: Integer);
+  public
+    constructor Create(ASource: TStream; ASkipHeader : Boolean = False);
+    destructor Destroy; override;
+    function Read(var Buffer; Count: Longint): Longint; override;
+    function Write(const Buffer; Count: Longint): Longint; override;
+    function Seek(Offset: Longint; Origin: Word): Longint; override;
+    property OnProgress;
+  end;
+
+  TGZOpenMode = (gzOpenRead,gzOpenWrite);
+
+  TGZFileStream = Class(TStream)
+    Private
+    FOpenMode : TGZOpenmode;
+    FFIle : gzfile;
+    Public
+    Constructor Create(FileName: String;FileMode: TGZOpenMode);
+    Destructor Destroy;override;
+    Function Read(Var Buffer; Count : longint): longint;override;
+    function Write(const Buffer; Count: Longint): Longint; override;
+    function Seek(Offset: Longint; Origin: Word): Longint; override;
+    end;
+
+
+implementation
+
+Const
+  ErrorStrings : array [0..6] of string =
+    ('Unknown error %d','Z_ERRNO','Z_STREAM_ERROR',
+     'Z_DATA_ERROR','Z_MEM_ERROR','Z_BUF_ERROR','Z_VERSION_ERROR');
+  SCouldntOpenFile = 'Couldn''t open file : %s';
+  SReadOnlyStream = 'Decompression streams are read-only';
+  SWriteOnlyStream = 'Compression streams are write-only';
+  SSeekError = 'Compression stream seek error';
+  SInvalidSeek = 'Invalid Compression seek operation';
+
+procedure TCompressionStream.CompressBuf(const InBuf: Pointer; InBytes: Integer;
+                      var OutBuf: Pointer; var OutBytes: Integer);
+var
+  strm: TZStream;
+  P: Pointer;
+begin
+  FillChar(strm, sizeof(strm), 0);
+  OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
+  OutBuf:=GetMem(OutBytes);
+  try
+    strm.next_in := InBuf;
+    strm.avail_in := InBytes;
+    strm.next_out := OutBuf;
+    strm.avail_out := OutBytes;
+    CompressionCheck(deflateInit(strm, Z_BEST_COMPRESSION));
+    try
+      while CompressionCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do
+      begin
+        P := OutBuf;
+        Inc(OutBytes, 256);
+        ReallocMem(OutBuf,OutBytes);
+        strm.next_out := PByte(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
+        strm.avail_out := 256;
+      end;
+    finally
+      CompressionCheck(deflateEnd(strm));
+    end;
+    ReallocMem(OutBuf,strm.total_out);
+    OutBytes := strm.total_out;
+  except
+    FreeMem(OutBuf);
+    raise;
+  end;
+end;
+
+
+procedure TDecompressionStream.DecompressBuf(const InBuf: Pointer; InBytes: Integer;
+       OutEstimate: Integer; var OutBuf: Pointer; var OutBytes: Integer);
+var
+  strm: TZStream;
+  P: Pointer;
+  BufInc: Integer;
+Type
+  PByte = ^Byte;
+begin
+  FillChar(strm, sizeof(strm), 0);
+  BufInc := (InBytes + 255) and not 255;
+  if OutEstimate = 0 then
+    OutBytes := BufInc
+  else
+    OutBytes := OutEstimate;
+  OutBuf:=GetMem(OutBytes);
+  try
+    strm.next_in := InBuf;
+    strm.avail_in := InBytes;
+    strm.next_out := OutBuf;
+    strm.avail_out := OutBytes;
+    DecompressionCheck(inflateInit(strm));
+    try
+      while DecompressionCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END do
+      begin
+        P := OutBuf;
+        Inc(OutBytes, BufInc);
+        ReallocMem(OutBuf, OutBytes);
+        strm.next_out := PByte(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
+        strm.avail_out := BufInc;
+      end;
+    finally
+      DecompressionCheck(inflateEnd(strm));
+    end;
+    ReallocMem(OutBuf, strm.total_out);
+    OutBytes := strm.total_out;
+  except
+    FreeMem(OutBuf);
+    raise;
+  end;
+end;
+
+
+// TCustomZlibStream
+
+constructor TCustomZLibStream.Create(Strm: TStream);
+begin
+  inherited Create(Strm);
+  FStrmPos := Strm.Position;
+end;
+
+procedure TCustomZLibStream.Progress(Sender: TObject);
+begin
+  if Assigned(FOnProgress) then FOnProgress(Sender);
+end;
+
+
+// TCompressionStream
+
+constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel;
+  Dest: TStream; ASkipHeader : Boolean = False);
+const
+  Levels: array [TCompressionLevel] of ShortInt =
+    (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);
+begin
+  inherited Create(Dest);
+  FZRec.next_out := @FBuffer[0];
+  FZRec.avail_out := sizeof(FBuffer);
+  If ASkipHeader then
+    CompressionCheck(deflateInit2(FZRec, Levels[CompressionLevel],Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0))
+  else
+    CompressionCheck(deflateInit(FZRec, Levels[CompressionLevel]));
+end;
+
+destructor TCompressionStream.Destroy;
+begin
+  FZRec.next_in := nil;
+  FZRec.avail_in := 0;
+  try
+    if Source.Position <> FStrmPos then Source.Position := FStrmPos;
+    while (CompressionCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END)
+      and (FZRec.avail_out = 0) do
+    begin
+      Source.WriteBuffer(FBuffer, sizeof(FBuffer));
+      FZRec.next_out := @FBuffer[0];
+      FZRec.avail_out := sizeof(FBuffer);
+    end;
+    if FZRec.avail_out < sizeof(FBuffer) then
+      Source.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out);
+  finally
+    deflateEnd(FZRec);
+  end;
+  inherited Destroy;
+end;
+
+function TCompressionStream.CompressionCheck(code: Integer): Integer;
+begin
+  Result := code;
+  if (code < 0) then
+    if code < -6 then
+      raise ECompressionError.CreateFmt(Errorstrings[0],[Code])
+    else
+      raise ECompressionError.Create(ErrorStrings[Abs(Code)]);
+end;
+
+
+function TCompressionStream.Read(var Buffer; Count: Longint): Longint;
+begin
+  raise ECompressionError.Create('Invalid stream operation');
+  result:=0;
+end;
+
+function TCompressionStream.Write(const Buffer; Count: Longint): Longint;
+begin
+  FZRec.next_in := @Buffer;
+  FZRec.avail_in := Count;
+  if Source.Position <> FStrmPos then Source.Position := FStrmPos;
+  while (FZRec.avail_in > 0) do
+  begin
+    CompressionCheck(deflate(FZRec, 0));
+    if FZRec.avail_out = 0 then
+    begin
+      Source.WriteBuffer(FBuffer, sizeof(FBuffer));
+      FZRec.next_out := @FBuffer[0];
+      FZRec.avail_out := sizeof(FBuffer);
+      FStrmPos := Source.Position;
+      Progress(Self);
+    end;
+  end;
+  Result := Count;
+end;
+
+function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
+begin
+  if (Offset = 0) and (Origin = soFromCurrent) then
+    Result := FZRec.total_in
+  else
+    raise ECompressionError.Create(SInvalidSeek);
+end;
+
+function TCompressionStream.GetCompressionRate: extended;
+begin
+  Result:=0.0;
+{  With FZrec do
+    if total_in = 0 then
+      GetCompressionRate:=0.0
+    else
+      GetCompressionRate:=1.0E2*(1.0E0-(total_out/total_in));
+}
+end;
+
+
+// TDecompressionStream
+
+constructor TDecompressionStream.Create(ASource: TStream; ASkipHeader : Boolean = False);
+begin
+  inherited Create(ASource);
+  FZRec.next_in := @FBuffer[0];
+  If ASkipHeader then
+    DeCompressionCheck(inflateInit2(FZRec,-MAX_WBITS))
+  else
+    DeCompressionCheck(inflateInit(FZRec));
+end;
+
+destructor TDecompressionStream.Destroy;
+begin
+  if FZRec.avail_in <> 0 then
+    Source.Seek(-FZRec.avail_in, soFromCurrent);
+  inflateEnd(FZRec);
+  inherited Destroy;
+end;
+
+function TDecompressionStream.DecompressionCheck(code: Integer): Integer;
+begin
+  Result := code;
+  If Code<0 then
+    if code < -6 then
+      raise EDecompressionError.CreateFmt(Errorstrings[0],[Code])
+    else
+      raise EDecompressionError.Create(ErrorStrings[Abs(Code)]);
+end;
+
+function TDecompressionStream.Read(var Buffer; Count: Longint): Longint;
+begin
+  FZRec.next_out := @Buffer;
+  FZRec.avail_out := Count;
+  if Source.Position <> FStrmPos then Source.Position := FStrmPos;
+  while (FZRec.avail_out > 0) do
+  begin
+    if FZRec.avail_in = 0 then
+    begin
+      FZRec.avail_in := Source.Read(FBuffer, sizeof(FBuffer));
+      if FZRec.avail_in = 0 then
+        begin
+          Result := Count - FZRec.avail_out;
+          Exit;
+        end;
+      FZRec.next_in := @FBuffer[0];
+      FStrmPos := Source.Position;
+      Progress(Self);
+    end;
+    if DeCompressionCheck(inflate(FZRec, 0)) = Z_STREAM_END then
+        begin
+          Result := Count - FZRec.avail_out;
+          Exit;
+        end;
+  end;
+  Result := Count;
+end;
+
+function TDecompressionStream.Write(const Buffer; Count: Longint): Longint;
+begin
+  raise EDecompressionError.Create('Invalid stream operation');
+  result:=0;
+end;
+
+function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
+var
+  I: Integer;
+  Buf: array [0..4095] of Char;
+begin
+  if (Offset = 0) and (Origin = soFromBeginning) then
+  begin
+    DecompressionCheck(inflateReset(FZRec));
+    FZRec.next_in := @FBuffer[0];
+    FZRec.avail_in := 0;
+    Source.Position := 0;
+    FStrmPos := 0;
+  end
+  else if ( (Offset >= 0) and (Origin = soFromCurrent)) or
+          ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then
+  begin
+    if Origin = soFromBeginning then Dec(Offset, FZRec.total_out);
+    if Offset > 0 then
+    begin
+      for I := 1 to Offset div sizeof(Buf) do
+        ReadBuffer(Buf, sizeof(Buf));
+      ReadBuffer(Buf, Offset mod sizeof(Buf));
+    end;
+  end
+  else
+    raise EDecompressionError.Create(SInvalidSeek);
+  Result := FZRec.total_out;
+end;
+
+// TGZFileStream
+
+Constructor TGZFileStream.Create(FileName: String;FileMode: TGZOpenMode);
+
+Const OpenStrings : array[TGZOpenMode] of pchar = ('rb','wb');
+
+begin
+   FOpenMode:=FileMode;
+   FFile:=gzopen (PChar(FileName),Openstrings[FileMode]);
+   If FFile=Nil then
+     Raise ezlibError.CreateFmt (SCouldntOpenFIle,[FileName]);
+end;
+
+Destructor TGZFileStream.Destroy;
+begin
+  gzclose(FFile);
+  Inherited Destroy;
+end;
+
+Function TGZFileStream.Read(Var Buffer; Count : longint): longint;
+begin
+  If FOpenMode=gzOpenWrite then
+    Raise ezliberror.create(SWriteOnlyStream);
+  Result:=gzRead(FFile,@Buffer,Count);
+end;
+
+function TGZFileStream.Write(const Buffer; Count: Longint): Longint;
+begin
+  If FOpenMode=gzOpenRead then
+    Raise EzlibError.Create(SReadonlyStream);
+  Result:=gzWrite(FFile,@Buffer,Count);
+end;
+
+function TGZFileStream.Seek(Offset: Longint; Origin: Word): Longint;
+begin
+  Result:=gzseek(FFile,Offset,Origin);
+  If Result=-1 then
+    Raise eZlibError.Create(SSeekError);
+end;
+
+end.

+ 0 - 0
packages/paszlib/zuncompr.pas → packages/paszlib/src/zuncompr.pas


+ 66 - 134
packages/paszlib/demo/Makefile → packages/paszlib/tests/Makefile

@@ -1,11 +1,12 @@
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2007/08/22]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2007/10/25]
 #
 default: all
 MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded
 BSDs = freebsd netbsd openbsd darwin
 UNIXs = linux $(BSDs) solaris qnx
 LIMIT83fs = go32v2 os2 emx watcom
+OSNeedsComspecToRunBatch = go32v2 watcom
 FORCE:
 .PHONY: FORCE
 override PATH:=$(patsubst %/,%,$(subst \,/,$(PATH)))
@@ -56,6 +57,11 @@ else
 SRCBATCHEXT=.bat
 endif
 endif
+ifdef COMSPEC
+ifneq ($(findstring $(OS_SOURCE),$(OSNeedsComspecToRunBatch)),)
+RUNBATCH=$(COMSPEC) /C
+endif
+endif
 ifdef inUnix
 PATHSEP=/
 else
@@ -92,7 +98,7 @@ endif
 endif
 export ECHO
 endif
-override DEFAULT_FPCDIR=../../../..
+override DEFAULT_FPCDIR=../../..
 ifndef FPC
 ifdef PP
 FPC=$(PP)
@@ -102,7 +108,7 @@ ifndef FPC
 FPCPROG:=$(strip $(wildcard $(addsuffix /fpc$(SRCEXEEXT),$(SEARCHPATH))))
 ifneq ($(FPCPROG),)
 FPCPROG:=$(firstword $(FPCPROG))
-FPC:=$(shell $(FPCPROG) -PB)
+FPC:=$(shell $(FPCPROG) -P$(CPU_TARGET) -PB)
 ifneq ($(findstring Error,$(FPC)),)
 override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
 endif
@@ -231,160 +237,160 @@ UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
 endif
 PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_PROGRAMS+=minigzip example minizip  miniunz
+override TARGET_PROGRAMS+=minigzip example minizip miniunz
 endif
 override INSTALL_FPCPACKAGE=y
 ifdef REQUIRE_UNITSDIR
@@ -1137,262 +1143,210 @@ endif
 override REQUIRE_PACKAGES=rtl paszlib
 ifeq ($(FULL_TARGET),i386-linux)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-os2)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-beos)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-emx)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),arm-gba)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_PASZLIB=1
 endif
 ifdef REQUIRE_PACKAGES_RTL
@@ -1421,32 +1375,6 @@ ifdef UNITDIR_RTL
 override COMPILER_UNITDIR+=$(UNITDIR_RTL)
 endif
 endif
-ifdef REQUIRE_PACKAGES_HASH
-PACKAGEDIR_HASH:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /hash/Makefile.fpc,$(PACKAGESDIR))))))
-ifneq ($(PACKAGEDIR_HASH),)
-ifneq ($(wildcard $(PACKAGEDIR_HASH)/units/$(TARGETSUFFIX)),)
-UNITDIR_HASH=$(PACKAGEDIR_HASH)/units/$(TARGETSUFFIX)
-else
-UNITDIR_HASH=$(PACKAGEDIR_HASH)
-endif
-ifdef CHECKDEPEND
-$(PACKAGEDIR_HASH)/$(FPCMADE):
-	$(MAKE) -C $(PACKAGEDIR_HASH) $(FPCMADE)
-override ALLDEPENDENCIES+=$(PACKAGEDIR_HASH)/$(FPCMADE)
-endif
-else
-PACKAGEDIR_HASH=
-UNITDIR_HASH:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /hash/Package.fpc,$(UNITSDIR)))))
-ifneq ($(UNITDIR_HASH),)
-UNITDIR_HASH:=$(firstword $(UNITDIR_HASH))
-else
-UNITDIR_HASH=
-endif
-endif
-ifdef UNITDIR_HASH
-override COMPILER_UNITDIR+=$(UNITDIR_HASH)
-endif
-endif
 ifdef REQUIRE_PACKAGES_PASZLIB
 PACKAGEDIR_PASZLIB:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /paszlib/Makefile.fpc,$(PACKAGESDIR))))))
 ifneq ($(PACKAGEDIR_PASZLIB),)
@@ -1487,7 +1415,7 @@ override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
 endif
 ifndef CROSSBOOTSTRAP
 ifneq ($(BINUTILSPREFIX),)
-override FPCOPT+=-XP$(BINUTILSPREFIX) 
+override FPCOPT+=-XP$(BINUTILSPREFIX)
 endif
 ifneq ($(BINUTILSPREFIX),)
 override FPCOPT+=-Xr$(RLINKPATH)
@@ -1619,9 +1547,13 @@ ifeq (,$(findstring -s ,$(COMPILER)))
 EXECPPAS=
 else
 ifeq ($(FULL_SOURCE),$(FULL_TARGET))
+ifdef RUNBATCH
+EXECPPAS:=@$(RUNBATCH) $(PPAS)
+else
 EXECPPAS:=@$(PPAS)
 endif
 endif
+endif
 .PHONY: fpc_exes
 ifndef CROSSINSTALL
 ifneq ($(TARGET_PROGRAMS),)

+ 2 - 2
packages/paszlib/demo/Makefile.fpc → packages/paszlib/tests/Makefile.fpc

@@ -3,7 +3,7 @@
 #
 
 [target]
-programs=minigzip example minizip  miniunz
+programs=minigzip example minizip miniunz
 
 [require]
 packages=paszlib
@@ -12,5 +12,5 @@ packages=paszlib
 fpcpackage=y
 
 [default]
-fpcdir=../../../..
+fpcdir=../../..
 

+ 0 - 0
packages/paszlib/demo/example.pas → packages/paszlib/tests/example.pas


+ 0 - 0
packages/paszlib/demo/minigzip.pas → packages/paszlib/tests/minigzip.pas


+ 0 - 0
packages/paszlib/demo/miniunz.pas → packages/paszlib/tests/miniunz.pas


+ 0 - 0
packages/paszlib/demo/minizip.pas → packages/paszlib/tests/minizip.pas


Some files were not shown because too many files changed in this diff