📄 zlibex.pas
字号:
end;
end;
procedure ZCompress(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer;
level: TZCompressionLevel);
var
zstream: TZStreamRec;
begin
FillChar(zstream,SizeOf(TZStreamRec),0);
ZCompressCheck(DeflateInit(zstream,ZLevels[level]));
ZInternalCompress(zstream,inBuffer,inSize,outBuffer,outSize);
end;
procedure ZCompress2(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer; level: TZCompressionLevel;
windowBits, memLevel: Integer; strategy: TZStrategy);
var
zstream: TZStreamRec;
begin
FillChar(zstream,SizeOf(TZStreamRec),0);
ZCompressCheck(DeflateInit2(zstream,ZLevels[level],Z_DEFLATED,windowBits,
memLevel,ZStrategies[strategy]));
ZInternalCompress(zstream,inBuffer,inSize,outBuffer,outSize);
end;
procedure ZDecompress(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer);
var
zstream: TZStreamRec;
begin
FillChar(zstream,SizeOf(TZStreamRec),0);
ZDecompressCheck(InflateInit(zstream));
ZInternalDecompress(zstream,inBuffer,inSize,outBuffer,outSize,outEstimate);
end;
procedure ZDecompress2(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer; windowBits: Integer;
outEstimate: Integer);
var
zstream: TZStreamRec;
begin
FillChar(zstream,SizeOf(TZStreamRec),0);
ZDecompressCheck(InflateInit2(zstream,windowBits));
ZInternalDecompress(zstream,inBuffer,inSize,outBuffer,outSize,outEstimate);
end;
{** string routines *********************************************************}
function ZCompressStr(const s: String; level: TZCompressionLevel): String;
var
buffer: Pointer;
size : Integer;
begin
ZCompress(PChar(s),Length(s),buffer,size,level);
SetLength(result,size);
Move(buffer^,result[1],size);
FreeMem(buffer);
end;
function ZCompressStrEx(const s: String; level: TZCompressionLevel): String;
var
buffer: Pointer;
size : Integer;
begin
ZCompress(PChar(s),Length(s),buffer,size,level);
SetLength(result,size + SizeOf(Integer));
Move(buffer^,result[5],size);
size := Length(s);
Move(size,result[1],SizeOf(Integer));
FreeMem(buffer);
end;
function ZCompressStr2(const s: String; level: TZCompressionLevel;
windowBits, memLevel: Integer; strategy: TZStrategy): String;
var
buffer: Pointer;
size : Integer;
begin
ZCompress2(PChar(s),Length(s),buffer,size,level,windowBits,memLevel,
strategy);
SetLength(result,size);
Move(buffer^,result[1],size);
FreeMem(buffer);
end;
function ZCompressStrWeb(const s: String): String;
begin
result := ZCompressStr2(s,zcFastest,-15,9,zsDefault);
end;
function ZCompressStrG(const s: String; const fileName, comment: String;
dateTime: TDateTime): String;
var
header : PGZHeader;
trailer: PGZTrailer;
len : Integer;
begin
SetLength(result,SizeOf(TGZHeader));
header := PGZHeader(@result[1]);
FillChar(header^,SizeOf(TGZHeader),0);
header^.Id1 := $1F;
header^.Id2 := $8B;
header^.Method := Z_DEFLATED;
if dateTime <> 0 then header^.Time := DateTimeToUnix(dateTime);
header^.ExtraFlags := GZ_EXTRA_DEFAULT;
header^.OS := 0;
header^.Flags := 0;
if Length(fileName) > 0 then
begin
header^.Flags := header^.Flags or GZ_FILENAME;
result := result + fileName + #$00;
end;
if Length(comment) > 0 then
begin
header^.Flags := header^.Flags or GZ_COMMENT;
result := result + comment + #$00;
end;
result := result + ZCompressStr2(s,zcDefault,-15,9,zsDefault);
len := Length(result);
SetLength(result,len + SizeOf(TGZTrailer));
trailer := PGZTrailer(@result[len + 1]);
FillChar(trailer^,SizeOf(TGZTrailer),0);
trailer^.Crc := crc32(0,s[1],Length(s));
trailer^.Size := Length(s);
end;
function ZDecompressStr(const s: String): String;
var
buffer: Pointer;
size : Integer;
begin
ZDecompress(PChar(s),Length(s),buffer,size);
SetLength(result,size);
Move(buffer^,result[1],size);
FreeMem(buffer);
end;
function ZDecompressStrEx(const s: String): String;
var
buffer : Pointer;
size : Integer;
data : String;
dataSize: Integer;
begin
Move(s[1],size,SizeOf(Integer));
dataSize := Length(s) - SizeOf(Integer);
SetLength(data,dataSize);
Move(s[5],data[1],dataSize);
ZDecompress(PChar(data),dataSize,buffer,size,size);
SetLength(result,size);
Move(buffer^,result[1],size);
FreeMem(buffer);
end;
function ZDecompressStr2(const s: String; windowBits: Integer): String;
var
buffer: Pointer;
size : Integer;
begin
ZDecompress2(PChar(s),Length(s),buffer,size,windowBits);
SetLength(result,size);
Move(buffer^,result[1],size);
FreeMem(buffer);
end;
function ZDecompressStrG(const s: String; var fileName, comment: String;
var dateTime: TDateTime): String;
var
header : PGZHeader;
trailer : PGZTrailer;
index : Integer;
maxIndex: Integer;
endIndex: Integer;
size : Integer;
begin
result := '';
if Length(s) < SizeOf(TGZHeader) then
begin
raise EZDecompressionError.Create(Z_DATA_ERROR);
end;
header := PGZHeader(@s[1]);
if (header^.Id1 <> $1F)
or (header^.Id2 <> $8B)
or (header^.Method <> Z_DEFLATED)
or ((header^.Flags and GZ_RESERVED) <> 0) then
begin
raise EZDecompressionError.Create(Z_DATA_ERROR);
end;
if header^.Time <> 0 then dateTime := UnixToDateTime(header^.Time)
else dateTime := 0;
maxIndex := Length(s) - SizeOf(TGZTrailer);
index := SizeOf(TGZHeader) + 1;
if (header^.Flags and GZ_EXTRA_FIELD) <> 0 then
begin
if index <= (maxIndex - 1) then
begin
size := PWord(@s[index])^;
Inc(index,2);
if (size >= 0) and ((index + size) <= maxIndex) then Inc(index,size)
else index := maxIndex + 1;
end
else index := maxIndex + 1;
end;
if (header^.Flags and GZ_FILENAME) <> 0 then
begin
endIndex := index;
while (endIndex <= maxIndex) and (s[endIndex] <> #$00) do Inc(endIndex);
SetLength(fileName,endIndex - index);
Move(s[index],fileName[1],endIndex - index);
index := endIndex;
if index <= maxIndex then Inc(index);
end
else fileName := '';
if (header^.Flags and GZ_COMMENT) <> 0 then
begin
endIndex := index;
while (endIndex <= maxIndex) and (s[endIndex] <> #$00) do Inc(endIndex);
SetLength(comment,endIndex - index);
Move(s[index],comment[1],endIndex - index);
index := endIndex;
if index <= maxIndex then Inc(index);
end
else comment := '';
if (header^.Flags and GZ_HEADER_CRC) <> 0 then
begin
if index <= (maxIndex - 1) then
begin
// todo: validate header crc
Inc(index,2);
end
else index := maxIndex + 1; // force eof
end;
if index > maxIndex then
begin
raise EZDecompressionError.Create(Z_DATA_ERROR);
end;
size := maxIndex - index + 1;
result := ZDecompressStr2(Copy(s,index,size),-15);
Inc(index,size);
trailer := PGZTrailer(@s[index]);
if (trailer^.Crc <> Cardinal(crc32(0,result[1],Length(result))))
or (trailer^.Size <> Cardinal(Length(result))) then
begin
raise EZDecompressionError.Create(Z_DATA_ERROR);
end;
end;
function ZDecompressStrG(const s: String): String;
var
fileName: String;
comment : String;
dateTime: TDateTime;
begin
result := ZDecompressStrG(s,fileName,comment,dateTime);
end;
{** stream routines *********************************************************}
procedure ZInternalCompressStream(zstream: TZStreamRec; inStream,
outStream: TStream);
const
bufferSize = 32768;
var
zresult : Integer;
inBuffer : Array [0..bufferSize-1] of Char;
outBuffer: Array [0..bufferSize-1] of Char;
outSize : Integer;
begin
zresult := Z_STREAM_END;
zstream.avail_in := inStream.Read(inBuffer,bufferSize);
while zstream.avail_in > 0 do
begin
zstream.next_in := inBuffer;
repeat
zstream.next_out := outBuffer;
zstream.avail_out := bufferSize;
zresult := ZCompressCheck(deflate(zstream,Z_NO_FLUSH));
outSize := bufferSize - zstream.avail_out;
outStream.Write(outBuffer,outSize);
until (zresult = Z_STREAM_END) or (zstream.avail_in = 0);
zstream.avail_in := inStream.Read(inBuffer,bufferSize);
end;
while zresult <> Z_STREAM_END do
begin
zstream.next_out := outBuffer;
zstream.avail_out := bufferSize;
zresult := ZCompressCheck(deflate(zstream,Z_FINISH));
outSize := bufferSize - zstream.avail_out;
outStream.Write(outBuffer,outSize);
end;
ZCompressCheck(deflateEnd(zstream));
end;
procedure ZInternalDecompressStream(zstream: TZStreamRec; inStream,
outStream: TStream);
const
bufferSize = 32768;
var
zresult : Integer;
inBuffer : Array [0..bufferSize-1] of Char;
outBuffer: Array [0..bufferSize-1] of Char;
outSize : Integer;
begin
zresult := Z_STREAM_END;
zstream.avail_in := inStream.Read(inBuffer,bufferSize);
while zstream.avail_in > 0 do
begin
zstream.next_in := inBuffer;
repeat
zstream.next_out := outBuffer;
zstream.avail_out := bufferSize;
zresult := ZDecompressCheck(inflate(zstream,Z_NO_FLUSH));
outSize := bufferSize - zstream.avail_out;
outStream.Write(outBuffer,outSize);
until (zresult = Z_STREAM_END) or (zstream.avail_in = 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -