function UnZlib(Compressed: String): String; //gzdecompress from PHP
const BuffSize = 4096;
var Z: TDecompressionStream;
Read: Integer;
Temp: String;
Str: TStringStream;
begin
Str := TStringStream.Create(Compressed);
Z := TDecompressionStream.Create(Str, False);
SetLength(Temp, BuffSize);
Result := '';
try
repeat
Read := Z.Read(Temp[1], BuffSize);
Result := Result + Copy(Temp, 1, Read);
until Read<BuffSize-1;
finally
Z.Free;
Str.Free;
end;
end;
function Zlib(UnCompressed: String): String; //gzcompress from PHP
const BuffSize = 4096;
var Z: TCompressionStream;
Read: Integer;
Temp: AnsiString;
Str: TStringStream;
Str2: TStringStream;
begin
Str := TStringStream.Create('');
Str2 := TStringStream.Create(UnCompressed);
Z := TCompressionStream.Create(clMax, Str, False);
SetLength(Temp, BuffSize);
Result := '';
try
repeat
Read := Str2.Read(Temp[1], BuffSize);
Z.Write(Temp[1], Read);
until Read = 0;
finally
Z.Free;
Str2.Free;
end;
Result := Str.DataString;
Str.Free;
end;
function GZip(const Uncompressed: AnsiString): AnsiString;
procedure AppendByte(var S: AnsiString; B: Byte);
var
L: Integer;
begin
L := Length(S);
SetLength(S, L + 1);
S[L + 1] := AnsiChar(B);
end;
procedure AppendUInt32LE(var S: AnsiString; Value: Cardinal);
begin
AppendByte(S, Byte(Value and $FF));
AppendByte(S, Byte((Value shr 8) and $FF));
AppendByte(S, Byte((Value shr 16) and $FF));
AppendByte(S, Byte((Value shr 24) and $FF));
end;
function CRC32Of(const S: AnsiString): Cardinal;
const
Polynomial = $EDB88320;
var
CRC: Cardinal;
I, J: Integer;
B: Byte;
begin
CRC := $FFFFFFFF;
for I := 1 to Length(S) do
begin
B := Byte(S[I]);
CRC := CRC xor B;
for J := 0 to 7 do
begin
if (CRC and 1) <> 0 then
CRC := (CRC shr 1) xor Polynomial
else
CRC := CRC shr 1;
end;
end;
Result := not CRC;
end;
var
Deflated: TStringStream;
Input: TStringStream;
Z: TCompressionStream;
CRC: Cardinal;
UnixTime: Cardinal;
begin
Deflated := TStringStream.Create('');
try
Input := TStringStream.Create(String(Uncompressed));
try
Z := TCompressionStream.Create(clMax, Deflated, True);
try
Z.CopyFrom(Input, 0);
finally
Z.Free;
end;
CRC := CRC32Of(Uncompressed);
UnixTime := DateTimeToUnix(Now);
Result := '';
// GZIP header (10 bytes)
AppendByte(Result, $1F); // ID1
AppendByte(Result, $8B); // ID2
AppendByte(Result, $08); //CM = deflate
AppendByte(Result, $00); // FLG = no extra fields
AppendUInt32LE(Result, UnixTime); // ModTime
AppendByte(Result, $02); // XFL = max compression
AppendByte(Result, $FF); // OS = unknown
Result := Result + AnsiString(Deflated.DataString);
// Gzip foot
AppendUInt32LE(Result, CRC); // CRC32 of unpacked data
AppendUInt32LE(Result, Cardinal(Length(Uncompressed))); // ISIZE mod 2^32
finally
Input.Free;
end;
finally
Deflated.Free;
end;
end;
function UnGzip(Compressed: String): String; //gzdecode from PHP
const BuffSize = 4096;
var Z: TDecompressionStream;
Read: Integer;
Temp: String;
Str: TStringStream;
ID: Word;
Method: Byte;
Head: Word;
Date: Cardinal;
Flag, OS: Byte;
Skip: Word;
Tmp: String;
Null: Integer;
begin
Str := TStringStream.Create(Compressed);
ID := Str.ReadWord;
Method := Str.ReadByte;
Head := Str.ReadByte;
Date := Str.ReadDWord;
Flag := Str.ReadByte;
OS := Str.ReadByte;
//FEXTRA
if ((Head shr 2) and 1 = 1) then begin
Skip := Str.ReadByte;
Str.Position := Str.Position + Skip;
end;
//FNAME
if ((Head shr 3) and 1 = 1) then begin
Tmp := Str.ReadString(256);
Null := Pos(chr(0), Tmp);
Str.Position := Str.Position - Length(Tmp) + Null;
end;
//FCOMMENT
if ((Head shr 4) and 1 = 1) then begin
Tmp := Str.ReadString(256);
Null := Pos(chr(0), Tmp);
Str.Position := Str.Position - Length(Tmp) + Null;
end;
//FHCRC
if ((Head shr 1) and 1 = 1) then begin
Str.Position := Str.Position + Skip;
end;
//https://datatracker.ietf.org/doc/html/rfc1952#page-5
Z := TDecompressionStream.Create(Str, True);
SetLength(Temp, BuffSize);
Result := '';
try
repeat
Read := Z.Read(Temp[1], BuffSize);
Result := Result + Copy(Temp, 1, Read);
until Read<BuffSize-1;
finally
Z.Free;
Str.Free;
end;
end;