ADD: Zip - show bzip2/zstd/xz compression/decompression progress

(cherry picked from commit c3f0f99774)
This commit is contained in:
Alexander Koblov 2022-06-21 21:35:33 +03:00
commit a10df2f68b
4 changed files with 156 additions and 29 deletions

View file

@ -119,7 +119,7 @@ uses
Windows, // Fix inline warnings
{$ENDIF}
StrUtils, SysUtils,
AbBzip2, AbExcept, AbVMStrm, AbBitBkt, DCOSUtils, DCClassesUtf8;
AbBzip2, AbExcept, AbVMStrm, AbBitBkt, AbProgress, DCOSUtils, DCClassesUtf8;
{ ****************** Helper functions Not from Classes Above ***************** }
function VerifyHeader(const Header : TAbBzip2Header) : Boolean;
@ -326,7 +326,7 @@ var
CurItem: TAbBzip2Item;
UpdateArchive: Boolean;
TempFileName: String;
InputFileStream: TStream;
InputFileStream: TAbProgressFileStream;
begin
if IsBzippedTar and TarAutoHandle then
begin
@ -338,7 +338,7 @@ begin
FreeAndNil(FBzip2Stream);
TempFileName := GetTempName(FArchiveName + ExtensionSeparator);
{ Create new archive with temporary name }
FBzip2Stream := TFileStreamEx.Create(TempFileName, fmCreate or fmShareDenyWrite);
FBzip2Stream := TAbProgressFileStream.Create(TempFileName, fmCreate or fmShareDenyWrite, OnProgress);
end;
FTarStream.Position := 0;
CompStream := TBZCompressionStream.Create(bs9, FBzip2Stream);
@ -377,7 +377,7 @@ begin
if CurItem.Action = aaStreamAdd then
CompStream.CopyFrom(InStream, 0){ Copy/compress entire Instream to FBzip2Stream }
else begin
InputFileStream := TFileStreamEx.Create(CurItem.DiskFileName, fmOpenRead or fmShareDenyWrite );
InputFileStream := TAbProgressFileStream.Create(CurItem.DiskFileName, fmOpenRead or fmShareDenyWrite, OnProgress);
try
CompStream.CopyFrom(InputFileStream, 0);{ Copy/compress entire Instream to FBzip2Stream }
finally
@ -408,23 +408,29 @@ const
BufSize = $F000;
var
DecompStream: TBZDecompressionStream;
ProxyStream: TAbProgressStream;
Buffer: PByte;
N: Integer;
begin
DecompStream := TBZDecompressionStream.Create(FBzip2Stream);
ProxyStream:= TAbProgressStream.Create(FBzip2Stream, OnProgress);
try
GetMem(Buffer, BufSize);
DecompStream := TBZDecompressionStream.Create(ProxyStream);
try
N := DecompStream.Read(Buffer^, BufSize);
while N > 0 do begin
aStream.WriteBuffer(Buffer^, N);
GetMem(Buffer, BufSize);
try
N := DecompStream.Read(Buffer^, BufSize);
while N > 0 do begin
aStream.WriteBuffer(Buffer^, N);
N := DecompStream.Read(Buffer^, BufSize);
end;
finally
FreeMem(Buffer, BufSize);
end;
finally
FreeMem(Buffer, BufSize);
DecompStream.Free;
end;
finally
DecompStream.Free;
ProxyStream.Free;
end;
end;
{ -------------------------------------------------------------------------- }

View file

@ -0,0 +1,109 @@
unit AbProgress;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, AbArcTyp, DCClassesUtf8;
type
{ TAbProgress }
TAbProgress = object
DoneSize: Int64;
FileSize: Int64;
OnProgress: TAbProgressEvent;
procedure DoProgress(Result: Integer);
end;
{ TAbProgressStream }
TAbProgressStream = class(TStream)
private
FSource: TStream;
FProgress: TAbProgress;
public
constructor Create(ASource : TStream; AEvent: TAbProgressEvent); reintroduce;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
end;
{ TAbProgressFileStream }
TAbProgressFileStream = class(TFileStreamEx)
private
FProgress: TAbProgress;
public
constructor Create(const AFileName: String; Mode: LongWord; AEvent: TAbProgressEvent); reintroduce;
function Read(var Buffer; Count: Longint): Longint; override;
end;
implementation
uses
AbExcept, DCOSUtils;
{ TAbProgress }
procedure TAbProgress.DoProgress(Result: Integer);
var
Percent: Byte;
Abort: Boolean = False;
begin
if (FileSize > 0) then
begin
DoneSize += Result;
Percent:= Byte(DoneSize * 100 div FileSize);
OnProgress(Percent, Abort);
if Abort then raise EAbUserAbort.Create;
end;
end;
{ TAbProgressStream }
constructor TAbProgressStream.Create(ASource: TStream; AEvent: TAbProgressEvent);
begin
FSource:= ASource;
FProgress.OnProgress:= AEvent;
FProgress.FileSize:= FSource.Size;
end;
function TAbProgressStream.Read(var Buffer; Count: Longint): Longint;
begin
Result:= FSource.Read(Buffer, Count);
if Assigned(FProgress.OnProgress) then FProgress.DoProgress(Result);
end;
function TAbProgressStream.Write(const Buffer; Count: Longint): Longint;
begin
Result:= FSource.Write(Buffer, Count);
end;
function TAbProgressStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
Result:= FSource.Seek(Offset, Origin);
end;
{ TAbProgressFileStream }
constructor TAbProgressFileStream.Create(const AFileName: String;
Mode: LongWord; AEvent: TAbProgressEvent);
begin
FProgress.OnProgress:= AEvent;
inherited Create(AFileName, Mode);
FProgress.FileSize:= FileGetSize(Handle);
end;
function TAbProgressFileStream.Read(var Buffer; Count: Longint): Longint;
begin
Result:= inherited Read(Buffer, Count);
if Assigned(FProgress.OnProgress) then FProgress.DoProgress(Result);
end;
end.

View file

@ -114,7 +114,7 @@ uses
Windows, // Fix inline warnings
{$ENDIF}
StrUtils, SysUtils,
AbXz, AbExcept, AbVMStrm, AbBitBkt, CRC, DCOSUtils, DCClassesUtf8;
AbXz, AbExcept, AbVMStrm, AbBitBkt, AbProgress, CRC, DCOSUtils, DCClassesUtf8;
{ ****************** Helper functions Not from Classes Above ***************** }
function VerifyHeader(const Header : TAbXzHeader) : Boolean;
@ -317,8 +317,8 @@ var
CurItem: TAbXzItem;
UpdateArchive: Boolean;
TempFileName: String;
InputFileStream: TStream;
LzmaCompression: TLzmaCompression;
InputFileStream: TAbProgressFileStream;
begin
if IsXzippedTar and TarAutoHandle then
begin
@ -330,7 +330,7 @@ begin
FreeAndNil(FXzStream);
TempFileName := GetTempName(FArchiveName + ExtensionSeparator);
{ Create new archive with temporary name }
FXzStream := TFileStreamEx.Create(TempFileName, fmCreate or fmShareDenyWrite);
FXzStream := TAbProgressFileStream.Create(TempFileName, fmCreate or fmShareDenyWrite, OnProgress);
end;
FTarStream.Position := 0;
LzmaCompression := TLzmaCompression.Create(FTarStream, FXzStream);
@ -374,7 +374,7 @@ begin
end;
end
else begin
InputFileStream := TFileStreamEx.Create(CurItem.DiskFileName, fmOpenRead or fmShareDenyWrite);
InputFileStream := TAbProgressFileStream.Create(CurItem.DiskFileName, fmOpenRead or fmShareDenyWrite, OnProgress);
try
LzmaCompression := TLzmaCompression.Create(InputFileStream, FXzStream);
try
@ -404,13 +404,19 @@ end;
{ -------------------------------------------------------------------------- }
procedure TAbXzArchive.DecompressToStream(aStream: TStream);
var
ProxyStream: TAbProgressStream;
LzmaDecompression: TLzmaDecompression;
begin
LzmaDecompression := TLzmaDecompression.Create(FXzStream, aStream);
ProxyStream:= TAbProgressStream.Create(FXzStream, OnProgress);
try
LzmaDecompression.Code
LzmaDecompression := TLzmaDecompression.Create(ProxyStream, aStream);
try
LzmaDecompression.Code
finally
LzmaDecompression.Free;
end;
finally
LzmaDecompression.Free;
ProxyStream.Free;
end;
end;
{ -------------------------------------------------------------------------- }

View file

@ -109,7 +109,7 @@ implementation
uses
SysUtils,
AbZstd, AbExcept, AbVMStrm, AbBitBkt, DCOSUtils, DCClassesUtf8;
AbZstd, AbExcept, AbVMStrm, AbBitBkt, AbProgress, DCOSUtils, DCClassesUtf8;
{ ****************** Helper functions Not from Classes Above ***************** }
function VerifyHeader(const Header : TAbZstdHeader) : Boolean;
@ -313,7 +313,7 @@ var
CurItem: TAbZstdItem;
UpdateArchive: Boolean;
TempFileName: String;
InputFileStream: TStream;
InputFileStream: TAbProgressFileStream;
begin
if IsZstdTar and TarAutoHandle then
begin
@ -325,7 +325,7 @@ begin
FreeAndNil(FZstdStream);
TempFileName := GetTempName(FArchiveName + ExtensionSeparator);
{ Create new archive with temporary name }
FZstdStream := TFileStreamEx.Create(TempFileName, fmCreate or fmShareDenyWrite);
FZstdStream := TAbProgressFileStream.Create(TempFileName, fmCreate or fmShareDenyWrite, OnProgress);
end;
FTarStream.Position := 0;
CompStream := TZSTDCompressionStream.Create(FZstdStream, 5, FTarStream.Size);
@ -369,7 +369,7 @@ begin
if CurItem.Action = aaStreamAdd then
CompStream.CopyFrom(InStream, 0){ Copy/compress entire Instream to FZstdStream }
else begin
InputFileStream := TFileStreamEx.Create(CurItem.DiskFileName, fmOpenRead or fmShareDenyWrite );
InputFileStream := TAbProgressFileStream.Create(CurItem.DiskFileName, fmOpenRead or fmShareDenyWrite, OnProgress);
try
CompStream.CopyFrom(InputFileStream, 0);{ Copy/compress entire Instream to FZstdStream }
finally
@ -400,23 +400,29 @@ const
BufSize = $F000;
var
DecompStream: TZSTDDecompressionStream;
ProxyStream: TAbProgressStream;
Buffer: PByte;
N: Integer;
begin
DecompStream := TZSTDDecompressionStream.Create(FZstdStream);
ProxyStream:= TAbProgressStream.Create(FZstdStream, OnProgress);
try
GetMem(Buffer, BufSize);
DecompStream := TZSTDDecompressionStream.Create(ProxyStream);
try
N := DecompStream.Read(Buffer^, BufSize);
while N > 0 do begin
aStream.WriteBuffer(Buffer^, N);
GetMem(Buffer, BufSize);
try
N := DecompStream.Read(Buffer^, BufSize);
while N > 0 do begin
aStream.WriteBuffer(Buffer^, N);
N := DecompStream.Read(Buffer^, BufSize);
end;
finally
FreeMem(Buffer, BufSize);
end;
finally
FreeMem(Buffer, BufSize);
DecompStream.Free;
end;
finally
DecompStream.Free;
ProxyStream.Free;
end;
end;
{ -------------------------------------------------------------------------- }