|
@@ -362,6 +362,7 @@ Type
|
|
end;
|
|
end;
|
|
|
|
|
|
TOnCustomStreamEvent = Procedure(Sender : TObject; var AStream : TStream; AItem : TFullZipFileEntry) of object;
|
|
TOnCustomStreamEvent = Procedure(Sender : TObject; var AStream : TStream; AItem : TFullZipFileEntry) of object;
|
|
|
|
+ TCustomInputStreamEvent = Procedure(Sender: TObject; var AStream: TStream) of object;
|
|
|
|
|
|
{ TFullZipFileEntries }
|
|
{ TFullZipFileEntries }
|
|
|
|
|
|
@@ -377,15 +378,17 @@ Type
|
|
|
|
|
|
TUnZipper = Class(TObject)
|
|
TUnZipper = Class(TObject)
|
|
Private
|
|
Private
|
|
|
|
+ FOnCloseInputStream: TCustomInputStreamEvent;
|
|
FOnCreateStream: TOnCustomStreamEvent;
|
|
FOnCreateStream: TOnCustomStreamEvent;
|
|
FOnDoneStream: TOnCustomStreamEvent;
|
|
FOnDoneStream: TOnCustomStreamEvent;
|
|
|
|
+ FOnOpenInputStream: TCustomInputStreamEvent;
|
|
FUnZipping : Boolean;
|
|
FUnZipping : Boolean;
|
|
FBufSize : LongWord;
|
|
FBufSize : LongWord;
|
|
FFileName : String; { Name of resulting Zip file }
|
|
FFileName : String; { Name of resulting Zip file }
|
|
FOutputPath : String;
|
|
FOutputPath : String;
|
|
FEntries : TFullZipFileEntries;
|
|
FEntries : TFullZipFileEntries;
|
|
FFiles : TStrings;
|
|
FFiles : TStrings;
|
|
- FZipFile : TFileStream; { I/O file variables }
|
|
|
|
|
|
+ FZipStream : TStream; { I/O file variables }
|
|
LocalHdr : Local_File_Header_Type;
|
|
LocalHdr : Local_File_Header_Type;
|
|
CentralHdr : Central_File_Header_Type;
|
|
CentralHdr : Central_File_Header_Type;
|
|
EndHdr : End_of_Central_Dir_Type;
|
|
EndHdr : End_of_Central_Dir_Type;
|
|
@@ -418,6 +421,8 @@ Type
|
|
Procedure Examine;
|
|
Procedure Examine;
|
|
Public
|
|
Public
|
|
Property BufferSize : LongWord Read FBufSize Write SetBufSize;
|
|
Property BufferSize : LongWord Read FBufSize Write SetBufSize;
|
|
|
|
+ Property OnOpenInputStream: TCustomInputStreamEvent read FOnOpenInputStream write FOnOpenInputStream;
|
|
|
|
+ Property OnCloseInputStream: TCustomInputStreamEvent read FOnCloseInputStream write FOnCloseInputStream;
|
|
Property OnCreateStream : TOnCustomStreamEvent Read FOnCreateStream Write FOnCreateStream;
|
|
Property OnCreateStream : TOnCustomStreamEvent Read FOnCreateStream Write FOnCreateStream;
|
|
Property OnDoneStream : TOnCustomStreamEvent Read FOnDoneStream Write FOnDoneStream;
|
|
Property OnDoneStream : TOnCustomStreamEvent Read FOnDoneStream Write FOnDoneStream;
|
|
Property OnPercent : Integer Read FOnPercent Write FOnPercent;
|
|
Property OnPercent : Integer Read FOnPercent Write FOnPercent;
|
|
@@ -444,6 +449,7 @@ ResourceString
|
|
SErrMissingArchiveName = 'Missing archive filename in streamed entry %d';
|
|
SErrMissingArchiveName = 'Missing archive filename in streamed entry %d';
|
|
SErrFileDoesNotExist = 'File "%s" does not exist.';
|
|
SErrFileDoesNotExist = 'File "%s" does not exist.';
|
|
SErrNoFileName = 'No archive filename for examine operation.';
|
|
SErrNoFileName = 'No archive filename for examine operation.';
|
|
|
|
+ SErrNoStream = 'No stream is opened.';
|
|
|
|
|
|
{ ---------------------------------------------------------------------
|
|
{ ---------------------------------------------------------------------
|
|
Auxiliary
|
|
Auxiliary
|
|
@@ -1498,7 +1504,10 @@ end;
|
|
Procedure TUnZipper.OpenInput;
|
|
Procedure TUnZipper.OpenInput;
|
|
|
|
|
|
Begin
|
|
Begin
|
|
- FZipFile:=TFileStream.Create(FFileName,fmOpenRead);
|
|
|
|
|
|
+ if Assigned(FOnOpenInputStream) then
|
|
|
|
+ FOnOpenInputStream(Self, FZipStream);
|
|
|
|
+ if FZipStream = nil then
|
|
|
|
+ FZipStream:=TFileStream.Create(FFileName,fmOpenRead);
|
|
End;
|
|
End;
|
|
|
|
|
|
|
|
|
|
@@ -1549,7 +1558,9 @@ end;
|
|
Procedure TUnZipper.CloseInput;
|
|
Procedure TUnZipper.CloseInput;
|
|
|
|
|
|
Begin
|
|
Begin
|
|
- FreeAndNil(FZipFile);
|
|
|
|
|
|
+ if Assigned(FOnCloseInputStream) then
|
|
|
|
+ FOnCloseInputStream(Self, FZipStream);
|
|
|
|
+ FreeAndNil(FZipStream);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -1558,18 +1569,18 @@ Var
|
|
S : String;
|
|
S : String;
|
|
D : TDateTime;
|
|
D : TDateTime;
|
|
Begin
|
|
Begin
|
|
- FZipFile.Seek(Item.HdrPos,soFromBeginning);
|
|
|
|
- FZipFile.ReadBuffer(LocalHdr,SizeOf(LocalHdr));
|
|
|
|
|
|
+ FZipStream.Seek(Item.HdrPos,soFromBeginning);
|
|
|
|
+ FZipStream.ReadBuffer(LocalHdr,SizeOf(LocalHdr));
|
|
{$IFDEF FPC_BIG_ENDIAN}
|
|
{$IFDEF FPC_BIG_ENDIAN}
|
|
LocalHdr := SwapLFH(LocalHdr);
|
|
LocalHdr := SwapLFH(LocalHdr);
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
With LocalHdr do
|
|
With LocalHdr do
|
|
begin
|
|
begin
|
|
SetLength(S,Filename_Length);
|
|
SetLength(S,Filename_Length);
|
|
- FZipFile.ReadBuffer(S[1],Filename_Length);
|
|
|
|
|
|
+ FZipStream.ReadBuffer(S[1],Filename_Length);
|
|
//SetLength(E,Extra_Field_Length);
|
|
//SetLength(E,Extra_Field_Length);
|
|
- //FZipFile.ReadBuffer(E[1],Extra_Field_Length);
|
|
|
|
- FZipFile.Seek(Extra_Field_Length,soCurrent);
|
|
|
|
|
|
+ //FZipStream.ReadBuffer(E[1],Extra_Field_Length);
|
|
|
|
+ FZipStream.Seek(Extra_Field_Length,soCurrent);
|
|
Item.ArchiveFileName:=S;
|
|
Item.ArchiveFileName:=S;
|
|
Item.DiskFileName:=S;
|
|
Item.DiskFileName:=S;
|
|
Item.Size:=Uncompressed_Size;
|
|
Item.Size:=Uncompressed_Size;
|
|
@@ -1592,36 +1603,36 @@ Var
|
|
D : TDateTime;
|
|
D : TDateTime;
|
|
S : String;
|
|
S : String;
|
|
Begin
|
|
Begin
|
|
- EndHdrPos:=FZipFile.Size-SizeOf(EndHdr);
|
|
|
|
|
|
+ EndHdrPos:=FZipStream.Size-SizeOf(EndHdr);
|
|
if EndHdrPos < 0 then
|
|
if EndHdrPos < 0 then
|
|
- raise EZipError.CreateFmt(SErrCorruptZIP,[FZipFile.FileName]);
|
|
|
|
- FZipFile.Seek(EndHdrPos,soFromBeginning);
|
|
|
|
- FZipFile.ReadBuffer(EndHdr, SizeOf(EndHdr));
|
|
|
|
|
|
+ raise EZipError.CreateFmt(SErrCorruptZIP,[FileName]);
|
|
|
|
+ FZipStream.Seek(EndHdrPos,soFromBeginning);
|
|
|
|
+ FZipStream.ReadBuffer(EndHdr, SizeOf(EndHdr));
|
|
{$IFDEF FPC_BIG_ENDIAN}
|
|
{$IFDEF FPC_BIG_ENDIAN}
|
|
EndHdr := SwapECD(EndHdr);
|
|
EndHdr := SwapECD(EndHdr);
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
With EndHdr do
|
|
With EndHdr do
|
|
begin
|
|
begin
|
|
if Signature <> END_OF_CENTRAL_DIR_SIGNATURE then
|
|
if Signature <> END_OF_CENTRAL_DIR_SIGNATURE then
|
|
- raise EZipError.CreateFmt(SErrCorruptZIP,[FZipFile.FileName]);
|
|
|
|
|
|
+ raise EZipError.CreateFmt(SErrCorruptZIP,[FileName]);
|
|
CenDirPos:=Start_Disk_Offset;
|
|
CenDirPos:=Start_Disk_Offset;
|
|
end;
|
|
end;
|
|
- FZipFile.Seek(CenDirPos,soFrombeginning);
|
|
|
|
|
|
+ FZipStream.Seek(CenDirPos,soFrombeginning);
|
|
FEntries.Clear;
|
|
FEntries.Clear;
|
|
for i:=0 to EndHdr.Entries_This_Disk-1 do
|
|
for i:=0 to EndHdr.Entries_This_Disk-1 do
|
|
begin
|
|
begin
|
|
- FZipFile.ReadBuffer(CentralHdr, SizeOf(CentralHdr));
|
|
|
|
|
|
+ FZipStream.ReadBuffer(CentralHdr, SizeOf(CentralHdr));
|
|
{$IFDEF FPC_BIG_ENDIAN}
|
|
{$IFDEF FPC_BIG_ENDIAN}
|
|
CentralHdr := SwapCFH(CentralHdr);
|
|
CentralHdr := SwapCFH(CentralHdr);
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
With CentralHdr do
|
|
With CentralHdr do
|
|
begin
|
|
begin
|
|
if Signature<>CENTRAL_FILE_HEADER_SIGNATURE then
|
|
if Signature<>CENTRAL_FILE_HEADER_SIGNATURE then
|
|
- raise EZipError.CreateFmt(SErrCorruptZIP,[FZipFile.FileName]);
|
|
|
|
|
|
+ raise EZipError.CreateFmt(SErrCorruptZIP,[FileName]);
|
|
NewNode:=FEntries.Add as TFullZipFileEntry;
|
|
NewNode:=FEntries.Add as TFullZipFileEntry;
|
|
NewNode.HdrPos := Local_Header_Offset;
|
|
NewNode.HdrPos := Local_Header_Offset;
|
|
SetLength(S,Filename_Length);
|
|
SetLength(S,Filename_Length);
|
|
- FZipFile.ReadBuffer(S[1],Filename_Length);
|
|
|
|
|
|
+ FZipStream.ReadBuffer(S[1],Filename_Length);
|
|
NewNode.ArchiveFileName:=S;
|
|
NewNode.ArchiveFileName:=S;
|
|
NewNode.Size:=Uncompressed_Size;
|
|
NewNode.Size:=Uncompressed_Size;
|
|
NewNode.FCompressedSize:=Compressed_Size;
|
|
NewNode.FCompressedSize:=Compressed_Size;
|
|
@@ -1634,7 +1645,7 @@ Begin
|
|
NewNode.Attributes := External_Attributes;
|
|
NewNode.Attributes := External_Attributes;
|
|
ZipDateTimeToDateTime(Last_Mod_Date,Last_Mod_Time,D);
|
|
ZipDateTimeToDateTime(Last_Mod_Date,Last_Mod_Time,D);
|
|
NewNode.DateTime:=D;
|
|
NewNode.DateTime:=D;
|
|
- FZipFile.Seek(Extra_Field_Length+File_Comment_Length,soCurrent);
|
|
|
|
|
|
+ FZipStream.Seek(Extra_Field_Length+File_Comment_Length,soCurrent);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -1667,14 +1678,14 @@ Var
|
|
begin
|
|
begin
|
|
if (LocalHdr.Compressed_Size<>0) then
|
|
if (LocalHdr.Compressed_Size<>0) then
|
|
begin
|
|
begin
|
|
- Count:=Dest.CopyFrom(FZipFile,LocalHdr.Compressed_Size)
|
|
|
|
|
|
+ Count:=Dest.CopyFrom(FZipStream,LocalHdr.Compressed_Size)
|
|
{$warning TODO: Implement CRC Check}
|
|
{$warning TODO: Implement CRC Check}
|
|
end
|
|
end
|
|
else
|
|
else
|
|
Count:=0;
|
|
Count:=0;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
- With CreateDecompressor(Item, ZMethod, FZipFile, Dest) do
|
|
|
|
|
|
+ With CreateDecompressor(Item, ZMethod, FZipStream, Dest) do
|
|
Try
|
|
Try
|
|
OnProgress:=Self.OnProgress;
|
|
OnProgress:=Self.OnProgress;
|
|
OnPercent:=Self.OnPercent;
|
|
OnPercent:=Self.OnPercent;
|
|
@@ -1883,9 +1894,11 @@ end;
|
|
|
|
|
|
procedure TUnZipper.Examine;
|
|
procedure TUnZipper.Examine;
|
|
begin
|
|
begin
|
|
- If (FFileName='') then
|
|
|
|
|
|
+ if (FOnOpenInputStream = nil) and (FFileName='') then
|
|
Raise EZipError.Create(SErrNoFileName);
|
|
Raise EZipError.Create(SErrNoFileName);
|
|
OpenInput;
|
|
OpenInput;
|
|
|
|
+ If (FZipStream=nil) then
|
|
|
|
+ Raise EZipError.Create(SErrNoStream);
|
|
Try
|
|
Try
|
|
ReadZipDirectory;
|
|
ReadZipDirectory;
|
|
Finally
|
|
Finally
|