📄 myldbzlib.pas
字号:
unit MYLDBZlib;
{$I MYLDBVer.Inc}
{$I CompilerDefines.inc}
interface
uses Sysutils, Classes;
resourcestring
sTargetBufferTooSmall = 'ZLib error: target buffer may be too small';
sInvalidStreamOp = 'Invalid stream operation';
type
TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; register;
TFree = procedure (AppData, Block: Pointer); register;
// Internal structure. Ignore.
{ TZStreamRec = packed record
next_in: PChar; // next input byte
avail_in: Integer; // number of bytes available at next_in
total_in: Int64; // total nb of input bytes read so far
next_out: PChar; // next output byte should be put here
avail_out: Integer; // remaining free space at next_out
total_out: Int64; // total nb of bytes output so far
msg: PChar; // last error message, NULL if no error
internal: Pointer; // not visible by applications
zalloc: TAlloc; // used to allocate the internal state
zfree: TFree; // used to free the internal state
AppData: Pointer; // private data object passed to zalloc and zfree
data_type: Integer; // best guess about the data type: ascii or binary
adler: Integer; // adler32 value of the uncompressed data
reserved: Integer; // reserved for future use
end;
}
TZStreamRec = packed record
next_in: PChar; // next input byte
avail_in: Longint; // number of bytes available at next_in
total_in: Longint; // total nb of input bytes read so far
next_out: PChar; // next output byte should be put here
avail_out: Longint; // remaining free space at next_out
total_out: Longint; // total nb of bytes output so far
msg: PChar; // last error message, NULL if no error
state: Pointer; // not visible by applications
zalloc: TAlloc; // used to allocate the internal state
zfree: TFree; // used to free the internal state
opaque: Pointer; // private data object passed to zalloc and zfree
data_type: Integer; // best guess about the data type: ascii or binary
adler: Longint; // adler32 value of the uncompressed data
reserved: Longint; // reserved for future use
end;
{ CompressBuf compresses data, buffer to buffer, in one call.
In: InBuf = ptr to compressed data
InBytes = number of bytes in InBuf
Out: OutBuf = ptr to newly allocated buffer containing decompressed data
OutBytes = number of bytes in OutBuf }
procedure ZLIBCompressBuf(
const InBuf: Pointer; InBytes: Integer;
out OutBuf: Pointer; out OutBytes: Integer;
compMode: Byte = 1
);
{ DecompressBuf decompresses data, buffer to buffer, in one call.
In: InBuf = ptr to compressed data
InBytes = number of bytes in InBuf
OutEstimate = zero, or est. size of the decompressed data
Out: OutBuf = ptr to newly allocated buffer containing decompressed data
OutBytes = number of bytes in OutBuf }
procedure ZLIBDecompressBuf(const InBuf: Pointer; InBytes: Integer;
OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
const
zlib_version = '1.2.2';
type
EZlibError = class(Exception);
ECompressionError = class(EZlibError);
EDecompressionError = class(EZlibError);
{$IFNDEF BCB4}
function adler32(adler: Cardinal; buf: PChar; len: Integer): Cardinal;
{$ENDIF}
function CCheck(code: Integer): Integer;
function DCheck(code: Integer): Integer;
const
Z_NO_FLUSH = 0;
Z_PARTIAL_FLUSH = 1;
Z_SYNC_FLUSH = 2;
Z_FULL_FLUSH = 3;
Z_FINISH = 4;
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);
Z_NO_COMPRESSION = 0;
Z_BEST_SPEED = 1;
Z_BEST_COMPRESSION = 9;
Z_DEFAULT_COMPRESSION = (-1);
Z_FILTERED = 1;
Z_HUFFMAN_ONLY = 2;
Z_DEFAULT_STRATEGY = 0;
Z_BINARY = 0;
Z_ASCII = 1;
Z_UNKNOWN = 2;
Z_DEFLATED = 8;
implementation
const
Levels: array [0..3] of ShortInt =
(Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);
_z_errmsg: array[0..9] of PChar = (
'need dictionary', // Z_NEED_DICT (2)
'stream end', // Z_STREAM_END (1)
'', // 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)
''
);
{$L adler32.obj}
{$L deflate.obj}
{$L infback.obj}
{$L inffast.obj}
{$L inflate.obj}
{$L inftrees.obj}
{$L trees.obj}
{$L crc32.obj}
{$L compress.obj}
procedure _tr_init; external;
procedure _tr_tally; external;
procedure _tr_flush_block; external;
procedure _tr_align; external;
procedure _tr_stored_block; external;
{$IFDEF BD5}
function adler32; external;
{$ENDIF}
{$IFDEF BCB5}
function adler32; external;
{$ELSE}
{$IFDEF BD4}
procedure adler32; external;
{$ENDIF}
{$IFDEF BCB4}
procedure adler32; external;
{$ENDIF}
{$ENDIF}
{** deflate routines ********************************************************}
function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
recsize: Integer): Integer; external;
function DeflateInit2_(var strm: TZStreamRec; level: integer; method: integer; windowBits: integer;
memLevel: integer; 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;
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;
function zcAlloc(AppData: Pointer; Items, Size: Integer): Pointer; register;
begin
Result := AllocMem(Items * Size);
end;
procedure zcFree(AppData, Block: Pointer); register;
begin
FreeMem(Block);
end;
function CCheck(code: Integer): Integer;
begin
Result := code;
if code < 0 then
raise ECompressionError.Create('error'); //!!
end;
function DCheck(code: Integer): Integer;
begin
Result := code;
if code < 0 then
raise EDecompressionError.Create('error'); //!!
end;
procedure ZLIBCompressBuf(const InBuf: Pointer; InBytes: Integer;
out OutBuf: Pointer; out OutBytes: Integer;
compMode: Byte = 1
);
var
strm: TZStreamRec;
P: Pointer;
begin
FillChar(strm, sizeof(strm), 0);
strm.zalloc := zcAlloc;
strm.zfree := zcFree;
OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
// GetMem(OutBuf, OutBytes);
OutBuf := AllocMem(OutBytes);
try
strm.next_in := InBuf;
strm.avail_in := InBytes;
strm.next_out := OutBuf;
strm.avail_out := OutBytes;
CCheck(deflateInit_(strm, compMode, zlib_version, sizeof(strm)));
try
while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do
begin
P := OutBuf;
Inc(OutBytes, 256);
ReallocMem(OutBuf, OutBytes);
strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
strm.avail_out := 256;
end;
finally
CCheck(deflateEnd(strm));
end;
ReallocMem(OutBuf, strm.total_out);
OutBytes := strm.total_out;
except
FreeMem(OutBuf);
raise
end;
end;
procedure ZLIBDecompressBuf(const InBuf: Pointer; InBytes: Integer;
OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
label m_exit;
var
zstream: TZStreamRec;
delta : Integer;
x: Integer;
begin
FillChar(zstream,SizeOf(TZStreamRec),0);
delta := (InBytes + 255) and not 255;
if ((outEstimate <= 0) or (outEstimate > 10000)) then
outBytes := delta
else
outBytes := outEstimate;
GetMem(outBuf,outBytes);
// try
zstream.next_in := inBuf;
zstream.avail_in := InBytes;
zstream.next_out := outBuf;
zstream.avail_out := outBytes;
// DCheck(InflateInit_(zstream,zlib_version,sizeof(zstream)));
if (InflateInit_(zstream,zlib_version,sizeof(zstream)) < 0) then
goto m_exit;
// try
while (True) do
begin
// DCheck(inflate(zstream,Z_NO_FLUSH)) <> Z_STREAM_END
x := inflate(zstream,Z_NO_FLUSH);
if (x < 0) then
goto m_exit;
if (x = Z_STREAM_END) then
break;
Inc(outBytes,delta);
ReallocMem(outBuf,outBytes);
zstream.next_out := PChar(Integer(outBuf) + zstream.total_out);
zstream.avail_out := delta;
end; // while
// finally
// DCheck(inflateEnd(zstream));
if (inflateEnd(zstream) < 0) then
goto m_exit;
// end;
ReallocMem(outBuf,zstream.total_out);
outBytes := zstream.total_out;
Exit;
m_exit:
// error
// except
if (outBuf <> nil) then
FreeMem(outBuf);
outBuf := nil;
outBytes := 0;
// raise;
// end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -