|
@@ -574,7 +574,6 @@ Type
|
|
Procedure ReadZipDirectory;
|
|
Procedure ReadZipDirectory;
|
|
Procedure ReadZipHeader(Item : TFullZipFileEntry; out AMethod : Word);
|
|
Procedure ReadZipHeader(Item : TFullZipFileEntry; out AMethod : Word);
|
|
Procedure DoEndOfFile;
|
|
Procedure DoEndOfFile;
|
|
- Procedure UnZipOneFile(Item : TFullZipFileEntry); virtual;
|
|
|
|
Function OpenOutput(OutFileName : RawByteString; Out OutStream: TStream; Item : TFullZipFileEntry) : Boolean;
|
|
Function OpenOutput(OutFileName : RawByteString; Out OutStream: TStream; Item : TFullZipFileEntry) : Boolean;
|
|
Procedure SetBufSize(Value : LongWord);
|
|
Procedure SetBufSize(Value : LongWord);
|
|
Procedure SetFileName(Value : RawByteString);
|
|
Procedure SetFileName(Value : RawByteString);
|
|
@@ -583,6 +582,7 @@ Type
|
|
Public
|
|
Public
|
|
Constructor Create;
|
|
Constructor Create;
|
|
Destructor Destroy;override;
|
|
Destructor Destroy;override;
|
|
|
|
+ Procedure UnZipOneFile(Item : TFullZipFileEntry); virtual;
|
|
Procedure UnZipAllFiles; virtual;
|
|
Procedure UnZipAllFiles; virtual;
|
|
Procedure UnZipFile(const aExtractFileName: RawByteString);
|
|
Procedure UnZipFile(const aExtractFileName: RawByteString);
|
|
Procedure UnZipFile(const AZipFileName, aExtractFileName: RawByteString);
|
|
Procedure UnZipFile(const AZipFileName, aExtractFileName: RawByteString);
|
|
@@ -655,7 +655,7 @@ ResourceString
|
|
const
|
|
const
|
|
ZIPBITFLAG_ENCRYPTION = 1;
|
|
ZIPBITFLAG_ENCRYPTION = 1;
|
|
ZIPBITFLAG_SIZE_IN_DATADESC = 1 shl 3;
|
|
ZIPBITFLAG_SIZE_IN_DATADESC = 1 shl 3;
|
|
- ZIPBITFLAG_PATCH_SET = 1 shl 5;
|
|
|
|
|
|
+ ZIPBITFLAG_PATCH_SET = 1 shl 5;
|
|
|
|
|
|
{ ---------------------------------------------------------------------
|
|
{ ---------------------------------------------------------------------
|
|
Auxiliary
|
|
Auxiliary
|
|
@@ -1018,7 +1018,7 @@ begin
|
|
Count:=FInFile.Read(Buf^,FBufferSize);
|
|
Count:=FInFile.Read(Buf^,FBufferSize);
|
|
For I:=0 to Count-1 do
|
|
For I:=0 to Count-1 do
|
|
UpdC32(Buf[i]);
|
|
UpdC32(Buf[i]);
|
|
- // Writebuffer will loop
|
|
|
|
|
|
+ // Writebuffer will loop
|
|
C.WriteBuffer(Buf^,Count);
|
|
C.WriteBuffer(Buf^,Count);
|
|
inc(BytesNow,Count);
|
|
inc(BytesNow,Count);
|
|
if BytesNow>NextMark Then
|
|
if BytesNow>NextMark Then
|
|
@@ -1558,7 +1558,7 @@ Begin
|
|
{$ELSE}
|
|
{$ELSE}
|
|
F.Attributes := faArchive;
|
|
F.Attributes := faArchive;
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
- end;
|
|
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -2250,7 +2250,7 @@ Begin
|
|
for Windows compatibility: it allows both '/' and '\'
|
|
for Windows compatibility: it allows both '/' and '\'
|
|
as directory separator. We don't want that behavior
|
|
as directory separator. We don't want that behavior
|
|
here, since 'abc\' is a valid file name under Unix.
|
|
here, since 'abc\' is a valid file name under Unix.
|
|
-
|
|
|
|
|
|
+
|
|
The zip standard appnote.txt says zip files must have '/' as path
|
|
The zip standard appnote.txt says zip files must have '/' as path
|
|
separator, even on Windows: 4.4.17.1:
|
|
separator, even on Windows: 4.4.17.1:
|
|
"The path stored MUST not contain a drive or device letter, or a leading
|
|
"The path stored MUST not contain a drive or device letter, or a leading
|
|
@@ -2279,9 +2279,9 @@ Begin
|
|
ForceDirectories(Path);
|
|
ForceDirectories(Path);
|
|
AllowDirectorySeparators:=OldDirectorySeparators;
|
|
AllowDirectorySeparators:=OldDirectorySeparators;
|
|
OutStream:=TFileStream.Create(OutFileName,fmCreate);
|
|
OutStream:=TFileStream.Create(OutFileName,fmCreate);
|
|
-
|
|
|
|
|
|
+
|
|
end;
|
|
end;
|
|
-
|
|
|
|
|
|
+
|
|
AllowDirectorySeparators:=OldDirectorySeparators;
|
|
AllowDirectorySeparators:=OldDirectorySeparators;
|
|
Result:=True;
|
|
Result:=True;
|
|
If Assigned(FOnStartFile) then
|
|
If Assigned(FOnStartFile) then
|
|
@@ -2718,6 +2718,7 @@ Var
|
|
FOutStream: TStream;
|
|
FOutStream: TStream;
|
|
IsLink: Boolean;
|
|
IsLink: Boolean;
|
|
IsCustomStream: Boolean;
|
|
IsCustomStream: Boolean;
|
|
|
|
+ IsOpenedHere: Boolean;
|
|
U : UnicodeString;
|
|
U : UnicodeString;
|
|
|
|
|
|
Procedure SetAttributes;
|
|
Procedure SetAttributes;
|
|
@@ -2816,6 +2817,10 @@ Var
|
|
end;
|
|
end;
|
|
|
|
|
|
Begin
|
|
Begin
|
|
|
|
+ IsOpenedHere:=FZipStream = nil;
|
|
|
|
+ if IsOpenedHere then
|
|
|
|
+ OpenInput;
|
|
|
|
+
|
|
ReadZipHeader(Item, ZMethod);
|
|
ReadZipHeader(Item, ZMethod);
|
|
if (Item.BitFlags and ZIPBITFLAG_ENCRYPTION)<>0 then
|
|
if (Item.BitFlags and ZIPBITFLAG_ENCRYPTION)<>0 then
|
|
Raise EZipError.CreateFmt(SErrEncryptionNotSupported,[Item.ArchiveFileName]);
|
|
Raise EZipError.CreateFmt(SErrEncryptionNotSupported,[Item.ArchiveFileName]);
|
|
@@ -2873,6 +2878,9 @@ Begin
|
|
end;
|
|
end;
|
|
SetAttributes;
|
|
SetAttributes;
|
|
end;
|
|
end;
|
|
|
|
+
|
|
|
|
+ if IsOpenedHere then
|
|
|
|
+ CloseInput;
|
|
end;
|
|
end;
|
|
|
|
|
|
Function TUnZipper.IsMatch(I : TFullZipFileEntry) : Boolean;
|
|
Function TUnZipper.IsMatch(I : TFullZipFileEntry) : Boolean;
|
|
@@ -2887,16 +2895,22 @@ end;
|
|
Function TUnZipper.CalcTotalSize(AllFiles : Boolean) : Int64;
|
|
Function TUnZipper.CalcTotalSize(AllFiles : Boolean) : Int64;
|
|
|
|
|
|
Var
|
|
Var
|
|
- I : Integer;
|
|
|
|
|
|
+ I,cnt : Integer;
|
|
Item : TFullZipFileEntry;
|
|
Item : TFullZipFileEntry;
|
|
|
|
|
|
begin
|
|
begin
|
|
Result:=0;
|
|
Result:=0;
|
|
|
|
+ cnt:=FFiles.Count;
|
|
|
|
+ if cnt=0 then cnt:=FEntries.Count;
|
|
for i:=0 to FEntries.Count-1 do
|
|
for i:=0 to FEntries.Count-1 do
|
|
begin
|
|
begin
|
|
Item := FEntries[i];
|
|
Item := FEntries[i];
|
|
if AllFiles or IsMatch(Item) then
|
|
if AllFiles or IsMatch(Item) then
|
|
- Result := Result + TZipFileEntry(Item).Size;
|
|
|
|
|
|
+ begin
|
|
|
|
+ Result := Result + TZipFileEntry(Item).Size;
|
|
|
|
+ dec(cnt);
|
|
|
|
+ if cnt=0 then break;
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -2905,7 +2919,7 @@ procedure TUnZipper.UnZipAllFiles;
|
|
|
|
|
|
Var
|
|
Var
|
|
Item : TFullZipFileEntry;
|
|
Item : TFullZipFileEntry;
|
|
- I : integer; //Really QWord but limited to FEntries.Count
|
|
|
|
|
|
+ I, cnt : integer;
|
|
AllFiles : Boolean;
|
|
AllFiles : Boolean;
|
|
|
|
|
|
Begin
|
|
Begin
|
|
@@ -2915,16 +2929,23 @@ Begin
|
|
AllFiles:=(FFiles.Count=0);
|
|
AllFiles:=(FFiles.Count=0);
|
|
OpenInput;
|
|
OpenInput;
|
|
Try
|
|
Try
|
|
|
|
+ if FEntries.Count=0 then
|
|
ReadZipDirectory;
|
|
ReadZipDirectory;
|
|
FTotPos := 0;
|
|
FTotPos := 0;
|
|
if Assigned(FOnProgressEx) and not Terminated then
|
|
if Assigned(FOnProgressEx) and not Terminated then
|
|
FTotSize := CalcTotalSize(AllFiles);
|
|
FTotSize := CalcTotalSize(AllFiles);
|
|
i:=0;
|
|
i:=0;
|
|
|
|
+ cnt:=FFiles.Count;
|
|
|
|
+ if cnt=0 then cnt:=FEntries.Count;
|
|
While (I<FEntries.Count) and not Terminated do
|
|
While (I<FEntries.Count) and not Terminated do
|
|
begin
|
|
begin
|
|
Item:=FEntries[i];
|
|
Item:=FEntries[i];
|
|
if AllFiles or IsMatch(Item) then
|
|
if AllFiles or IsMatch(Item) then
|
|
|
|
+ begin
|
|
UnZipOneFile(Item);
|
|
UnZipOneFile(Item);
|
|
|
|
+ dec(cnt);
|
|
|
|
+ if cnt=0 then break;
|
|
|
|
+ end;
|
|
inc(I);
|
|
inc(I);
|
|
end;
|
|
end;
|
|
if Assigned(FOnProgressEx) and not Terminated then
|
|
if Assigned(FOnProgressEx) and not Terminated then
|
|
@@ -2938,6 +2959,49 @@ Begin
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
+procedure TUnZipper.UnZipFile(const AZipFileName, aExtractFileName: RawByteString);
|
|
|
|
+var
|
|
|
|
+ I : integer;
|
|
|
|
+begin
|
|
|
|
+ FileName:=AZipFileName;
|
|
|
|
+
|
|
|
|
+ FTerminated:=False;
|
|
|
|
+ FUnZipping:=True;
|
|
|
|
+ Try
|
|
|
|
+ OpenInput;
|
|
|
|
+ Try
|
|
|
|
+ if FEntries.Count=0 then
|
|
|
|
+ ReadZipDirectory;
|
|
|
|
+
|
|
|
|
+ i:=0;
|
|
|
|
+ if UseUTF8 then
|
|
|
|
+ begin
|
|
|
|
+ While I<FEntries.Count do
|
|
|
|
+ begin
|
|
|
|
+ if CompareText(FEntries[I].UTF8ArchiveFileName,aExtractFileName)=0 then break;
|
|
|
|
+ inc(I);
|
|
|
|
+ end;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ While I<FEntries.Count do
|
|
|
|
+ begin
|
|
|
|
+ if CompareText(FEntries[I].ArchiveFileName,aExtractFileName)=0 then break;
|
|
|
|
+ inc(I);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if I<FEntries.Count then
|
|
|
|
+ UnZipOneFile(FEntries[I]);
|
|
|
|
+
|
|
|
|
+ Finally
|
|
|
|
+ CloseInput;
|
|
|
|
+ end;
|
|
|
|
+ finally
|
|
|
|
+ FUnZipping:=False;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TUnZipper.SetBufSize(Value: LongWord);
|
|
procedure TUnZipper.SetBufSize(Value: LongWord);
|
|
|
|
|
|
begin
|
|
begin
|
|
@@ -2952,7 +3016,11 @@ procedure TUnZipper.SetFileName(Value: RawByteString);
|
|
begin
|
|
begin
|
|
If FUnZipping then
|
|
If FUnZipping then
|
|
Raise EZipError.Create(SErrFileChange);
|
|
Raise EZipError.Create(SErrFileChange);
|
|
- FFileName:=Value;
|
|
|
|
|
|
+ if CompareText(FFileName,Value)<>0 then
|
|
|
|
+ begin
|
|
|
|
+ FFileName:=Value;
|
|
|
|
+ FEntries.Clear;
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TUnZipper.SetOutputPath(Value: RawByteString);
|
|
procedure TUnZipper.SetOutputPath(Value: RawByteString);
|
|
@@ -2978,20 +3046,6 @@ begin
|
|
UnzipFile(FFileName, aExtractFileName);
|
|
UnzipFile(FFileName, aExtractFileName);
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TUnZipper.UnZipFile(const AZipFileName, aExtractFileName: RawByteString);
|
|
|
|
-var
|
|
|
|
- L: TStrings;
|
|
|
|
-begin
|
|
|
|
- FFileName := AZipFileName;
|
|
|
|
- L := TStringList.Create;
|
|
|
|
- try
|
|
|
|
- L.Add(aExtractFileName);
|
|
|
|
- UnzipFiles(L);
|
|
|
|
- finally
|
|
|
|
- L.Free;
|
|
|
|
- end;
|
|
|
|
-end;
|
|
|
|
-
|
|
|
|
procedure TUnZipper.UnZipFiles(const AZipFileName: RawByteString; FileList: TStrings);
|
|
procedure TUnZipper.UnZipFiles(const AZipFileName: RawByteString; FileList: TStrings);
|
|
|
|
|
|
begin
|
|
begin
|