فهرست منبع

FIX: Zip - open small Gzip archive

Alexander Koblov 2 سال پیش
والد
کامیت
a193935b47
1فایلهای تغییر یافته به همراه30 افزوده شده و 3 حذف شده
  1. 30 3
      plugins/wcx/zip/src/fparchive/abzlibprc.pas

+ 30 - 3
plugins/wcx/zip/src/fparchive/abzlibprc.pas

@@ -27,6 +27,7 @@ type
   private
     FHash: UInt32;
   public
+    function CopyInto(ATarget: TStream; ACount: Int64): Int64;
     function Read(var Buffer; Count: LongInt): LongInt; override;
   end;
 
@@ -39,7 +40,7 @@ function Inflate(aSource : TStream; aDest : TStream;
 implementation
 
 uses
-  ZDeflate, ZBase, DCcrc32;
+  Math, ZDeflate, ZBase, DCcrc32;
 
 function Deflate(aSource : TStream; aDest : TStream;
                  aHelper : TAbDeflateHelper): longint;
@@ -85,11 +86,14 @@ begin
   AInflateStream:= TInflateStream.Create(aSource, True);
   try
     if aHelper.PartialSize > 0 then
-      ACount:= aHelper.PartialSize
+    begin
+      ACount:= aHelper.PartialSize;
+      aHelper.NormalSize:= AInflateStream.CopyInto(aDest, ACount);
+    end
     else begin
       ACount:= aHelper.NormalSize;
+      aHelper.NormalSize:= aDest.CopyFrom(AInflateStream, ACount);
     end;
-    aHelper.NormalSize:= aDest.CopyFrom(AInflateStream, ACount);
     aHelper.CompressedSize:= AInflateStream.compressed_read;
     Result:= LongInt(AInflateStream.FHash);
   finally
@@ -99,6 +103,29 @@ end;
 
 { TInflateStream }
 
+function TInflateStream.CopyInto(ATarget: TStream; ACount: Int64): Int64;
+var
+  ARead, ASize: Integer;
+  ABuffer: array of Byte;
+begin
+  Result:= 0;
+  ASize:= Min(ACount, $8000);
+  SetLength(ABuffer, ASize);
+  repeat
+    if ACount < ASize then
+    begin
+      ASize:= ACount;
+    end;
+    ARead:= Read(ABuffer[0], ASize);
+    if ARead > 0 then
+    begin
+      Dec(ACount, ARead);
+      Inc(Result, ARead);
+      ATarget.WriteBuffer(ABuffer[0], ARead);
+    end;
+  until (ARead < ASize) or (ACount = 0);
+end;
+
 function TInflateStream.Read(var Buffer; Count: LongInt): LongInt;
 begin
   Result:= inherited Read(Buffer, Count);