Skip to content

Commit 2dbf4b1

Browse files
committed
Perform CRC32 calculation in TLZMAEncoderStream
1 parent 7835c1a commit 2dbf4b1

File tree

2 files changed

+24
-13
lines changed

2 files changed

+24
-13
lines changed

System.Zip.LZMA.pas

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@ interface
66
System.SysUtils, System.Classes, System.Zip2, LzmaDec, LzmaEnc;
77

88
type
9+
PZipHeader = ^TZipHeader;
10+
911
TLZMAEncoderStream = class(TStream)
1012
private
1113
FStream: TStream;
1214
FEncoderHandle: TCLzmaEncHandle;
1315
FProgress: TZipProgressEvent;
14-
FZipHeader: TZipHeader;
16+
FZipHeader: PZipHeader;
1517
public
16-
constructor Create(const Stream: TStream; aZipHeader: TZipHeader; const
18+
constructor Create(const Stream: TStream; aZipHeader: PZipHeader; const
1719
aProgress: TZipProgressEvent); reintroduce;
1820
procedure AfterConstruction; override;
1921
procedure BeforeDestruction; override;
@@ -41,13 +43,14 @@ TLZMADecoderStream = class(TStream)
4143

4244
implementation
4345

44-
uses Winapi.Windows, LzmaTypes;
46+
uses System.ZLib, Winapi.Windows, LzmaTypes;
4547

4648
type
4749
PLzmaEncoderRead = ^TLzmaEncoderRead;
4850
TLzmaEncoderRead = record
4951
Proc: TInStreamReadProc;
5052
Stream: TStream;
53+
CRC32: UInt32;
5154
end;
5255

5356
PzmaEncoderWrite = ^TLzmaEncoderWrite;
@@ -70,6 +73,7 @@ function LzmaReadProc(p: PISeqInStream; buf: PByte; var size: SIZE_T): TSRes; cd
7073
try
7174
R := PLzmaEncoderRead(p);
7275
size := R.Stream.Read(buf^, size);
76+
R.CRC32 := crc32(R.CRC32, buf, size);
7377
Result := SZ_OK;
7478
except
7579
Result := SZ_ERROR_DATA;
@@ -132,7 +136,7 @@ procedure TLZMAEncoderStream.BeforeDestruction;
132136
end;
133137

134138
constructor TLZMAEncoderStream.Create(const Stream: TStream; aZipHeader:
135-
TZipHeader; const aProgress: TZipProgressEvent);
139+
PZipHeader; const aProgress: TZipProgressEvent);
136140
begin
137141
inherited Create;
138142
FStream := Stream;
@@ -156,16 +160,18 @@ function TLZMAEncoderStream.Write(const Buffer; Count: Longint): Longint;
156160
A.Init;
157161
R.Proc := LzmaReadProc;
158162
R.Stream := TStream(Buffer);
163+
R.CRC32 := 0;
159164

160165
W.Proc := LzmaWriteProc;
161166
W.Stream := FStream;
162167

163168
P.Proc := LzmaProgressProc;
164-
P.ZipHeader := FZipHeader;
169+
P.ZipHeader := FZipHeader^;
165170
P.UncompressedSize := R.Stream.Size;
166171
P.Progress := FProgress;
167172

168173
CheckLzma(LzmaEnc_Encode(FEncoderHandle, @W, @R, @P, A, A));
174+
FZipHeader.CRC32 := R.CRC32;
169175
Result := Count;
170176
end;
171177

@@ -250,7 +256,7 @@ procedure RegisterLZMA;
250256
TZipFile.RegisterCompressionHandler(zcLZMA,
251257
function(InStream: TStream; const ZipFile: TZipFile; const Item: TZipHeader): TStream
252258
begin
253-
Result := TLZMAEncoderStream.Create(InStream, Item, ZipFile.OnProgress);
259+
Result := TLZMAEncoderStream.Create(InStream, @Item, ZipFile.OnProgress);
254260
end,
255261
function(InStream: TStream; const ZipFile: TZipFile; const Item: TZipHeader): TStream
256262
begin

System.Zip2.pas

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,13 +1752,18 @@ procedure TZipFile.Add(Data: TStream; LocalHeader: TZipHeader; CentralHeader: PZ
17521752
if LCompressStream is TZCompressionStream then
17531753
(LCompressStream as TZCompressionStream).OnProgress := DoZLibProgress;
17541754
try
1755-
SetLength(LBuffer, $4000);
1756-
// Calculate Uncompressed data's CRC while copying Data
1757-
while Data.Position < LDataEnd do
1758-
begin
1759-
LReaded := Data.Read(LBuffer, Length(LBuffer));
1760-
LCompressStream.Write(LBuffer, LReaded);
1761-
LocalHeader.CRC32 := crc32(LocalHeader.CRC32, @LBuffer[0], LReaded);
1755+
if TZipCompression(LocalHeader.CompressionMethod) = zcLZMA then begin
1756+
LCompressStream.Write(Data, 0);
1757+
// LocalHeader.CRC32 is calculated in LCompressStream.Write
1758+
end else begin
1759+
SetLength(LBuffer, $4000);
1760+
// Calculate Uncompressed data's CRC while copying Data
1761+
while Data.Position < LDataEnd do
1762+
begin
1763+
LReaded := Data.Read(LBuffer, Length(LBuffer));
1764+
LCompressStream.Write(LBuffer, LReaded);
1765+
LocalHeader.CRC32 := crc32(LocalHeader.CRC32, @LBuffer[0], LReaded);
1766+
end;
17621767
end;
17631768
if Assigned(FOnProgress) then
17641769
FOnProgress(Self, FCurrentFile, FCurrentHeader, LCompressStream.Position);

0 commit comments

Comments
 (0)