diff options
| author | marco <marco@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2009-11-22 19:48:00 +0000 |
|---|---|---|
| committer | marco <marco@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2009-11-22 19:48:00 +0000 |
| commit | 0c974663852c74db2380e3c5636091f41fa8d6de (patch) | |
| tree | 0dfc680cc760b2ec3feea2c0f6d4a3f5cee730ce /packages/paszlib | |
| parent | b9e59f9ac65ad7fc0081c35edc7407346aebea8f (diff) | |
| download | fpc-0c974663852c74db2380e3c5636091f41fa8d6de.tar.gz | |
* TUnzipper now instrumentable with events to be usable with custom streams
Patch from Andrew, Mantis 15151
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@14256 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/paszlib')
| -rw-r--r-- | packages/paszlib/src/zipper.pp | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/packages/paszlib/src/zipper.pp b/packages/paszlib/src/zipper.pp index 5f1c9ca1eb..f2c83e5082 100644 --- a/packages/paszlib/src/zipper.pp +++ b/packages/paszlib/src/zipper.pp @@ -362,6 +362,7 @@ Type end; TOnCustomStreamEvent = Procedure(Sender : TObject; var AStream : TStream; AItem : TFullZipFileEntry) of object; + TCustomInputStreamEvent = Procedure(Sender: TObject; var AStream: TStream) of object; { TFullZipFileEntries } @@ -377,15 +378,17 @@ Type TUnZipper = Class(TObject) Private + FOnCloseInputStream: TCustomInputStreamEvent; FOnCreateStream: TOnCustomStreamEvent; FOnDoneStream: TOnCustomStreamEvent; + FOnOpenInputStream: TCustomInputStreamEvent; FUnZipping : Boolean; FBufSize : LongWord; FFileName : String; { Name of resulting Zip file } FOutputPath : String; FEntries : TFullZipFileEntries; FFiles : TStrings; - FZipFile : TFileStream; { I/O file variables } + FZipStream : TStream; { I/O file variables } LocalHdr : Local_File_Header_Type; CentralHdr : Central_File_Header_Type; EndHdr : End_of_Central_Dir_Type; @@ -418,6 +421,8 @@ Type Procedure Examine; Public 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 OnDoneStream : TOnCustomStreamEvent Read FOnDoneStream Write FOnDoneStream; Property OnPercent : Integer Read FOnPercent Write FOnPercent; @@ -444,6 +449,7 @@ ResourceString SErrMissingArchiveName = 'Missing archive filename in streamed entry %d'; SErrFileDoesNotExist = 'File "%s" does not exist.'; SErrNoFileName = 'No archive filename for examine operation.'; + SErrNoStream = 'No stream is opened.'; { --------------------------------------------------------------------- Auxiliary @@ -1498,7 +1504,10 @@ end; Procedure TUnZipper.OpenInput; Begin - FZipFile:=TFileStream.Create(FFileName,fmOpenRead); + if Assigned(FOnOpenInputStream) then + FOnOpenInputStream(Self, FZipStream); + if FZipStream = nil then + FZipStream:=TFileStream.Create(FFileName,fmOpenRead); End; @@ -1549,7 +1558,9 @@ end; Procedure TUnZipper.CloseInput; Begin - FreeAndNil(FZipFile); + if Assigned(FOnCloseInputStream) then + FOnCloseInputStream(Self, FZipStream); + FreeAndNil(FZipStream); end; @@ -1558,18 +1569,18 @@ Var S : String; D : TDateTime; 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} LocalHdr := SwapLFH(LocalHdr); {$ENDIF} With LocalHdr do begin SetLength(S,Filename_Length); - FZipFile.ReadBuffer(S[1],Filename_Length); + FZipStream.ReadBuffer(S[1],Filename_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.DiskFileName:=S; Item.Size:=Uncompressed_Size; @@ -1592,36 +1603,36 @@ Var D : TDateTime; S : String; Begin - EndHdrPos:=FZipFile.Size-SizeOf(EndHdr); + EndHdrPos:=FZipStream.Size-SizeOf(EndHdr); 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} EndHdr := SwapECD(EndHdr); {$ENDIF} With EndHdr do begin if Signature <> END_OF_CENTRAL_DIR_SIGNATURE then - raise EZipError.CreateFmt(SErrCorruptZIP,[FZipFile.FileName]); + raise EZipError.CreateFmt(SErrCorruptZIP,[FileName]); CenDirPos:=Start_Disk_Offset; end; - FZipFile.Seek(CenDirPos,soFrombeginning); + FZipStream.Seek(CenDirPos,soFrombeginning); FEntries.Clear; for i:=0 to EndHdr.Entries_This_Disk-1 do begin - FZipFile.ReadBuffer(CentralHdr, SizeOf(CentralHdr)); + FZipStream.ReadBuffer(CentralHdr, SizeOf(CentralHdr)); {$IFDEF FPC_BIG_ENDIAN} CentralHdr := SwapCFH(CentralHdr); {$ENDIF} With CentralHdr do begin if Signature<>CENTRAL_FILE_HEADER_SIGNATURE then - raise EZipError.CreateFmt(SErrCorruptZIP,[FZipFile.FileName]); + raise EZipError.CreateFmt(SErrCorruptZIP,[FileName]); NewNode:=FEntries.Add as TFullZipFileEntry; NewNode.HdrPos := Local_Header_Offset; SetLength(S,Filename_Length); - FZipFile.ReadBuffer(S[1],Filename_Length); + FZipStream.ReadBuffer(S[1],Filename_Length); NewNode.ArchiveFileName:=S; NewNode.Size:=Uncompressed_Size; NewNode.FCompressedSize:=Compressed_Size; @@ -1634,7 +1645,7 @@ Begin NewNode.Attributes := External_Attributes; ZipDateTimeToDateTime(Last_Mod_Date,Last_Mod_Time,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; @@ -1667,14 +1678,14 @@ Var begin if (LocalHdr.Compressed_Size<>0) then begin - Count:=Dest.CopyFrom(FZipFile,LocalHdr.Compressed_Size) + Count:=Dest.CopyFrom(FZipStream,LocalHdr.Compressed_Size) {$warning TODO: Implement CRC Check} end else Count:=0; end else - With CreateDecompressor(Item, ZMethod, FZipFile, Dest) do + With CreateDecompressor(Item, ZMethod, FZipStream, Dest) do Try OnProgress:=Self.OnProgress; OnPercent:=Self.OnPercent; @@ -1883,9 +1894,11 @@ end; procedure TUnZipper.Examine; begin - If (FFileName='') then + if (FOnOpenInputStream = nil) and (FFileName='') then Raise EZipError.Create(SErrNoFileName); OpenInput; + If (FZipStream=nil) then + Raise EZipError.Create(SErrNoStream); Try ReadZipDirectory; Finally |
