📄 zlibex.pas
字号:
* fileName = filename *
* comment = comment *
* dateTime = date/time *
* *
* return *
* uncompressed data string *
*****************************************************************************}
function ZDecompressStrG(const s: String; var fileName, comment: String;
var dateTime: TDateTime): String; overload;
function ZDecompressStrG(const s: String): String; overload;
{** stream routines *********************************************************}
procedure ZCompressStream(inStream, outStream: TStream;
level: TZCompressionLevel = zcDefault);
procedure ZCompressStream2(inStream, outStream: TStream;
level: TZCompressionLevel; windowBits, memLevel: Integer;
strategy: TZStrategy);
procedure ZCompressStreamWeb(inStream, outStream: TStream);
procedure ZCompressStreamG(inStream, outStream: TStream; const fileName,
comment: String; dateTime: TDateTime);
procedure ZDecompressStream(inStream, outStream: TStream);
procedure ZDecompressStream2(inStream, outStream: TStream;
windowBits: Integer);
{** checksum routines *******************************************************}
function ZAdler32(adler: Longint; const buffer; size: Integer): Longint;
function ZCrc32(crc: Longint; const buffer; size: Integer): Longint;
{****************************************************************************}
type
EZLibErrorClass = class of EZlibError;
EZLibError = class(Exception)
private
FErrorCode: Integer;
public
constructor Create(code: Integer; const dummy: String = ''); overload;
property ErrorCode: Integer read FErrorCode write FErrorCode;
end;
EZCompressionError = class(EZLibError);
EZDecompressionError = class(EZLibError);
implementation
{** link zlib code **********************************************************}
{$L deflate.obj}
{$L inflate.obj}
{$L inftrees.obj}
{$L infback.obj}
{$L inffast.obj}
{$L trees.obj}
{$L compress.obj}
{$L adler32.obj}
{$L crc32.obj}
{*****************************************************************************
* note: do not reorder the above -- doing so will result in external *
* functions being undefined *
*****************************************************************************}
{** gzip ********************************************************************}
type
PGZHeader = ^TGZHeader;
TGZHeader = packed record
Id1 : Byte;
Id2 : Byte;
Method : Byte;
Flags : Byte;
Time : Cardinal;
ExtraFlags: Byte;
OS : Byte;
end;
PGZTrailer = ^TGZTrailer;
TGZTrailer = packed record
Crc : Cardinal;
Size: Cardinal;
end;
const
GZ_ASCII_TEXT = $01;
GZ_HEADER_CRC = $02;
GZ_EXTRA_FIELD = $04;
GZ_FILENAME = $08;
GZ_COMMENT = $10;
GZ_RESERVED = $E0;
GZ_EXTRA_DEFAULT = 0;
GZ_EXTRA_MAX = 2;
GZ_EXTRA_FASTEST = 4;
const
{** flush constants *******************************************************}
Z_NO_FLUSH = 0;
Z_PARTIAL_FLUSH = 1;
Z_SYNC_FLUSH = 2;
Z_FULL_FLUSH = 3;
Z_FINISH = 4;
Z_BLOCK = 5;
{** return codes **********************************************************}
Z_OK = 0;
Z_STREAM_END = 1;
Z_NEED_DICT = 2;
Z_ERRNO = (-1);
Z_STREAM_ERROR = (-2);
Z_DATA_ERROR = (-3);
Z_MEM_ERROR = (-4);
Z_BUF_ERROR = (-5);
Z_VERSION_ERROR = (-6);
{** compression levels ****************************************************}
Z_NO_COMPRESSION = 0;
Z_BEST_SPEED = 1;
Z_BEST_COMPRESSION = 9;
Z_DEFAULT_COMPRESSION = (-1);
{** compression strategies ************************************************}
Z_FILTERED = 1;
Z_HUFFMAN_ONLY = 2;
Z_RLE = 3;
Z_FIXED = 4;
Z_DEFAULT_STRATEGY = 0;
{** data types ************************************************************}
Z_BINARY = 0;
Z_ASCII = 1;
Z_TEXT = Z_ASCII;
Z_UNKNOWN = 2;
{** return code messages **************************************************}
_z_errmsg: array[0..9] of PChar = (
'need dictionary', // Z_NEED_DICT (2)
'stream end', // Z_STREAM_END (1)
'ok', // Z_OK (0)
'file error', // Z_ERRNO (-1)
'stream error', // Z_STREAM_ERROR (-2)
'data error', // Z_DATA_ERROR (-3)
'insufficient memory', // Z_MEM_ERROR (-4)
'buffer error', // Z_BUF_ERROR (-5)
'incompatible version', // Z_VERSION_ERROR (-6)
''
);
ZLevels: Array [TZCompressionLevel] of Shortint = (
Z_NO_COMPRESSION, // zcNone
Z_BEST_SPEED, // zcFastest
Z_DEFAULT_COMPRESSION, // zcDefault
Z_BEST_COMPRESSION, // zcMax
1, // zcLevel1
2, // zcLevel2
3, // zcLevel3
4, // zcLevel4
5, // zcLevel5
6, // zcLevel6
7, // zcLevel7
8, // zcLevel8
9 // zcLevel9
);
ZStrategies: Array [TZStrategy] of Shortint = (
Z_DEFAULT_STRATEGY, // zsDefault
Z_FILTERED, // zsFiltered
Z_HUFFMAN_ONLY, // zsHuffman
Z_RLE, // zsRLE
Z_FIXED // zsFixed
);
SZInvalid = 'Invalid ZStream operation!';
{$IFNDEF Version6Plus}
PWord = ^Word;
{$ENDIF}
{** deflate routines ********************************************************}
function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
recsize: Integer): Integer;
external;
function deflateInit2_(var strm: TZStreamRec; level, method, windowBits,
memLevel, strategy: Integer; version: PChar; recsize: Integer): Integer;
external;
function deflate(var strm: TZStreamRec; flush: Integer): Integer;
external;
function deflateEnd(var strm: TZStreamRec): Integer;
external;
{** inflate routines ********************************************************}
function inflateInit_(var strm: TZStreamRec; version: PChar;
recsize: Integer): Integer;
external;
function inflateInit2_(var strm: TZStreamRec; windowBits: Integer;
version: PChar; recsize: Integer): Integer;
external;
function inflate(var strm: TZStreamRec; flush: Integer): Integer;
external;
function inflateEnd(var strm: TZStreamRec): Integer;
external;
function inflateReset(var strm: TZStreamRec): Integer;
external;
{** checksum routines *******************************************************}
function adler32(adler: Longint; const buf; len: Integer): Longint;
external;
function crc32(crc: Longint; const buf; len: Integer): Longint;
external;
{** zlib function implementations *******************************************}
function zcalloc(opaque: Pointer; items, size: Integer): Pointer;
begin
GetMem(result,items * size);
end;
procedure zcfree(opaque, block: Pointer);
begin
FreeMem(block);
end;
{** c function implementations **********************************************}
procedure _memset(p: Pointer; b: Byte; count: Integer); cdecl;
begin
FillChar(p^,count,b);
end;
procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
begin
Move(source^,dest^,count);
end;
{** custom zlib routines ****************************************************}
function DeflateInit(var stream: TZStreamRec; level: Integer): Integer;
begin
result := deflateInit_(stream,level,ZLIB_VERSION,SizeOf(TZStreamRec));
end;
function DeflateInit2(var stream: TZStreamRec; level, method, windowBits,
memLevel, strategy: Integer): Integer;
begin
result := deflateInit2_(stream,level,method,windowBits,memLevel,strategy,
ZLIB_VERSION,SizeOf(TZStreamRec));
end;
function InflateInit(var stream: TZStreamRec): Integer;
begin
result := inflateInit_(stream,ZLIB_VERSION,SizeOf(TZStreamRec));
end;
function InflateInit2(var stream: TZStreamRec; windowBits: Integer): Integer;
begin
result := inflateInit2_(stream,windowBits,ZLIB_VERSION,SizeOf(TZStreamRec));
end;
{** DateTimeToUnix **********************************************************}
{$IFNDEF Version6Plus}
{ Days between TDateTime basis (12/31/1899) and Unix time_t basis (1/1/1970) }
const
UnixDateDelta = 25569;
function DateTimeToUnix(const AValue: TDateTime): Cardinal;
begin
Result := Round((AValue - UnixDateDelta) * SecsPerDay);
end;
function UnixToDateTime(const AValue: Cardinal): TDateTime;
begin
Result := AValue / SecsPerDay + UnixDateDelta;
end;
{$ENDIF}
{****************************************************************************}
function ZCompressCheck(code: Integer): Integer;
begin
result := code;
if code < 0 then
begin
raise EZCompressionError.Create(code);
end;
end;
function ZDecompressCheck(code: Integer): Integer;
begin
Result := code;
if code < 0 then
begin
raise EZDecompressionError.Create(code);
end;
end;
procedure ZInternalCompress(var zstream: TZStreamRec; const inBuffer: Pointer;
inSize: Integer; out outBuffer: Pointer; out outSize: Integer);
const
delta = 256;
begin
outSize := ((inSize + (inSize div 10) + 12) + 255) and not 255;
GetMem(outBuffer,outSize);
try
try
zstream.next_in := inBuffer;
zstream.avail_in := inSize;
zstream.next_out := outBuffer;
zstream.avail_out := outSize;
while ZCompressCheck(deflate(zstream,Z_FINISH)) <> Z_STREAM_END do
begin
Inc(outSize,delta);
ReallocMem(outBuffer,outSize);
zstream.next_out := PChar(Integer(outBuffer) + zstream.total_out);
zstream.avail_out := delta;
end;
finally
ZCompressCheck(deflateEnd(zstream));
end;
ReallocMem(outBuffer,zstream.total_out);
outSize := zstream.total_out;
except
FreeMem(outBuffer);
raise;
end;
end;
procedure ZInternalDecompress(zstream: TZStreamRec; const inBuffer: Pointer;
inSize: Integer; out outBuffer: Pointer; out outSize: Integer;
outEstimate: Integer);
var
delta: Integer;
begin
delta := (inSize + 255) and not 255;
if outEstimate = 0 then outSize := delta
else outSize := outEstimate;
GetMem(outBuffer,outSize);
try
try
zstream.next_in := inBuffer;
zstream.avail_in := inSize;
zstream.next_out := outBuffer;
zstream.avail_out := outSize;
while ZDecompressCheck(inflate(zstream,Z_NO_FLUSH)) <> Z_STREAM_END do
begin
Inc(outSize,delta);
ReallocMem(outBuffer,outSize);
zstream.next_out := PChar(Integer(outBuffer) + zstream.total_out);
zstream.avail_out := delta;
end;
finally
ZDecompressCheck(inflateEnd(zstream));
end;
ReallocMem(outBuffer,zstream.total_out);
outSize := zstream.total_out;
except
FreeMem(outBuffer);
raise;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -