ADD: Zip plugin - read/write uncompressed size (.zst)

This commit is contained in:
Alexander Koblov 2019-12-23 17:43:01 +00:00
commit fc4424eab6
3 changed files with 34 additions and 7 deletions

View file

@ -10,8 +10,8 @@
</General>
<VersionInfo>
<UseVersionInfo Value="True"/>
<MinorVersionNr Value="1"/>
<StringTable FileDescription="ZIP WCX plugin for Double Commander" LegalCopyright="Copyright (C) 2006-2017 Alexander Koblov"/>
<MinorVersionNr Value="2"/>
<StringTable FileDescription="ZIP WCX plugin for Double Commander" LegalCopyright="Copyright (C) 2006-2019 Alexander Koblov"/>
</VersionInfo>
<BuildModes Count="2">
<Item1 Name="Release" Default="True"/>

View file

@ -41,6 +41,7 @@ uses
Classes, SysUtils, CTypes;
const
ZSTD_FRAMEHEADERSIZE_MAX = 18;
ZSTD_CONTENTSIZE_UNKNOWN = UInt64(-1);
ZSTD_CONTENTSIZE_ERROR = UInt64(-2);
@ -98,6 +99,8 @@ type
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
end;
function ZSTD_FileSize(const InStream: TStream): UInt64;
implementation
uses
@ -195,6 +198,24 @@ begin
raise EZstdError.Create(ZSTD_getErrorName(code))
end;
function ZSTD_FileSize(const InStream: TStream): UInt64;
var
APosition: Int64;
ABuffer: array[1..ZSTD_FRAMEHEADERSIZE_MAX] of Byte;
begin
Initialize;
APosition:= InStream.Position;
InStream.Seek(0, soBeginning);
InStream.Read(ABuffer[1], ZSTD_FRAMEHEADERSIZE_MAX);
InStream.Seek(APosition, soBeginning);
Result:= ZSTD_getFrameContentSize(@ABuffer[1], ZSTD_FRAMEHEADERSIZE_MAX);
if (Result = ZSTD_CONTENTSIZE_UNKNOWN) or (Result = ZSTD_CONTENTSIZE_ERROR) then
Result:= 0;
end;
{ TZstdDecompressionStream }
constructor TZstdDecompressionStream.Create(InStream: TStream);

View file

@ -108,7 +108,7 @@ function VerifyZstd(Strm : TStream) : TAbArchiveType;
implementation
uses
StrUtils, SysUtils,
SysUtils,
AbZstd, AbExcept, AbVMStrm, AbBitBkt, DCOSUtils, DCClassesUtf8;
{ ****************** Helper functions Not from Classes Above ***************** }
@ -275,9 +275,9 @@ end;
{ -------------------------------------------------------------------------- }
procedure TAbZstdArchive.LoadArchive;
var
Item: TAbZstdItem;
Abort: Boolean;
ItemName: string;
Item: TAbZstdItem;
Abort: Boolean = False;
begin
if FZstdStream.Size = 0 then
Exit;
@ -292,6 +292,7 @@ begin
SwapToZstd;
Item := TAbZstdItem.Create;
Item.Action := aaNone;
Item.UncompressedSize := ZSTD_FileSize(FZstdStream);
{ Filename isn't stored, so constuct one based on the archive name }
ItemName := ExtractFileName(ArchiveName);
if ItemName = '' then
@ -327,7 +328,7 @@ begin
FZstdStream := TFileStreamEx.Create(TempFileName, fmCreate or fmShareDenyWrite);
end;
FTarStream.Position := 0;
CompStream := TZSTDCompressionStream.Create(FZstdStream, 5);
CompStream := TZSTDCompressionStream.Create(FZstdStream, 5, FTarStream.Size);
try
CompStream.CopyFrom(FTarStream, 0);
finally
@ -358,7 +359,12 @@ begin
aaDelete: ; {doing nothing omits file from new stream}
aaAdd, aaFreshen, aaReplace, aaStreamAdd: begin
FZstdStream.Size := 0;
CompStream := TZSTDCompressionStream.Create(FZstdStream, 5);
if CurItem.Action = aaStreamAdd then
CurItem.UncompressedSize := InStream.Size
else begin
CurItem.UncompressedSize := mbFileSize(CurItem.DiskFileName);
end;
CompStream := TZSTDCompressionStream.Create(FZstdStream, 5, CurItem.UncompressedSize);
try
if CurItem.Action = aaStreamAdd then
CompStream.CopyFrom(InStream, 0){ Copy/compress entire Instream to FZstdStream }