unit JazzZip;
{$I Jazz.inc}
interface
uses
Classes, SysUtils, ZLib;
type
TJzZipLevel = ZLib.TCompressionLevel;
IZip = interface(IInterface)
['{37930CD0-F127-4C03-BE46-B4731905B2DD}']
procedure Execute(const ZipLevel: TJzZipLevel = clMax);
end;
IJzUnzip = interface(IInterface)
['{D57C6894-BF3E-4AD6-8317-A7684F575878}']
procedure Execute;
end;
TJzZipClass = class of TJzZip;
TJzZip = class(TInterfacedObject, IZip)
private
FInput: TStream;
FOutput: TStream;
FSame: boolean;
FTempStream: TStream;
public
constructor Create(const Input: string; const Output: TStream); overload;
constructor Create(const Input, Output: TStream); overload;
destructor Destroy; override;
procedure Execute(const ZipLevel: TJzZipLevel = clMax); virtual;
end;
TJzUnzipClass = class of TJzUnzip;
TJzUnzip = class(TInterfacedObject, IJzUnzip)
private
FInput: TStream;
FOutput: TStream;
FOutputStr: PString;
FSame: boolean;
FTemp: TStream;
public
constructor Create(const Input: TStream; var Output: string); overload;
constructor Create(const Input, Output: TStream); overload;
destructor Destroy; override;
procedure Execute; virtual;
end;
TJzZLibZip = class(TJzZip)
public
procedure Execute(const ZipLevel: TJzZipLevel = clMax); override;
end;
TJzZLibUnzip = class(TJzUnzip)
public
procedure Execute; override;
end;
ECompression = class(Exception);
procedure ZipData(const Source: TStream; const Output: TStream = nil; ZipLevel: TJzZipLevel = clMax); overload;
procedure ZipData(const Source: string; const Output: TStream; ZipLevel: TJzZipLevel = clMax); overload;
procedure UnzipData(const Source: TStream; const Output: TStream = nil); overload;
procedure UnzipData(const Source: TStream; var Output: string); overload;
var
ZipClass: TJzZipClass = TJzZLibZip;
UnzipClass: TJzUnzipClass = TJzZLibUnzip;
implementation
const
SInvalidDestination = 'Output can''t be nil with source as string .';
procedure ZipData(const Source: TStream; const Output: TStream = nil; ZipLevel: TJzZipLevel = clMax);
var
LZip: IZip;
begin
LZip:= ZipClass.Create(Source, Output);
LZip.Execute(ZipLevel);
end;
procedure ZipData(const Source: string; const Output: TStream; ZipLevel: TJzZipLevel = clMax);
var
LZip: IZip;
begin
LZip:= ZipClass.Create(Source, Output);
LZip.Execute(ZipLevel);
end;
procedure UnzipData(const Source: TStream; const Output: TStream = nil);
var
LUnzip: IJzUnzip;
begin
LUnzip:= UnzipClass.Create(Source, Output);
LUnzip.Execute;
end;
procedure UnzipData(const Source: TStream; var Output: string); overload;
var
LUnzip: IJzUnzip;
begin
LUnzip:= UnzipClass.Create(Source, Output);
LUnzip.Execute;
end;
constructor TJzZip.Create(const Input: string; const Output: TStream);
begin
if Output = nil then
raise ECompression.Create(SInvalidDestination);
FTempStream:= TStringStream.Create(Input);
Create(FTempStream, Output);
end;
constructor TJzZip.Create(const Input, Output: TStream);
begin
inherited Create;
FInput:= Input;
FOutput:= Output;
FSame:= FOutput = nil;
if FSame then FOutput:= TMemoryStream.Create;
FInput.Position:= 0;
FOutput.Position:= 0;
end;
destructor TJzZip.Destroy;
begin
if FTempStream <> nil then FTempStream.Free;
if FSame then FOutput.Free;
inherited;
end;
procedure TJzZip.Execute(const ZipLevel: TJzZipLevel);
begin
if FSame then
begin
FOutput.Position:= 0;
FInput.Size:= 0;
FInput.CopyFrom(FOutput, FOutput.Size);
end;
end;
constructor TJzUnzip.Create(const Input: TStream; var Output: string);
begin
FTemp:= TStringStream.Create(Output);
FOutputStr:= @Output;
Create(Input, FTemp);
end;
constructor TJzUnzip.Create(const Input, Output: TStream);
begin
inherited Create;
FInput:= Input;
FOutput:= Output;
FSame:= FOutput = nil;
if FSame then FOutput:= TMemoryStream.Create;
FInput.Position:= 0;
end;
destructor TJzUnzip.Destroy;
begin
if FTemp <> nil then FTemp.Free;
if FSame then FOutput.Free;
inherited;
end;
procedure TJzUnzip.Execute;
begin
if FSame then
begin
FOutput.Position:= 0;
FInput.Size:= 0;
FInput.WriteBuffer(FOutput, FOutput.Size);
end;
if FOutputStr <> nil then
begin
FInput.Position:= 0;
FInput.ReadBuffer(FOutputStr, FInput.Size);
end;
end;
procedure TJzZLibZip.Execute(const ZipLevel: TJzZipLevel);
var
LComp: TCompressionStream;
begin
LComp:= TCompressionStream.Create(ZipLevel, FOutput);
LComp.CopyFrom(FInput, FInput.Size);
LComp.Free;
inherited Execute(ZipLevel);
end;
procedure TJzZLibUnzip.Execute;
var
LCount: Integer;
LDecomp: TDecompressionStream;
LBuffer: array[1..1024] of Byte;
begin
LDecomp:= TDecompressionStream.Create(FInput);
try
repeat
LCount:= LDecomp.Read(LBuffer, SizeOf(LBuffer));
if LCount > 0 then FOutput.Write(LBuffer, LCount);
until LCount < 1;
finally
LDecomp.Free;
end;
inherited Execute;
end;
end.