Browse Source

* Rework TStream.CopyFrom (see Mantis #17980):
a) Use significantly larger buffer (128k instead of 1k)
b) When Count=0, do not try to determine the source size. Just copy until the source can be read. This should improve performance with limited seek capability sources (e.g. a decompression stream will be decompressed once rather than twice).
c) Use ReadBuffer/WriteBuffer, so an exception is raised when something goes wrong. This conforms to Delphi behavior.

git-svn-id: trunk@16992 -

sergei 14 năm trước cách đây
mục cha
commit
41aeb9a22b
1 tập tin đã thay đổi với 35 bổ sung19 xóa
  1. 35 19
      rtl/objpas/classes/streams.inc

+ 35 - 19
rtl/objpas/classes/streams.inc

@@ -140,29 +140,45 @@ end;
   function TStream.CopyFrom(Source: TStream; Count: Int64): Int64;
 
     var
-       i : Int64;
-       buffer : array[0..1023] of byte;
+       Buffer: Pointer;
+       BufferSize, i: LongInt;
 
+    const
+       MaxSize = $20000;
     begin
-       CopyFrom:=0;
-       If (Count=0) then
-         begin
-         // This WILL fail for non-seekable streams...
-         Source.Position:=0;
-         Count:=Source.Size;
-         end;
-       while Count>0 do
-         begin
-         if (Count>sizeof(buffer)) then
-           i:=sizeof(Buffer)
+
+       Result:=0;
+       if Count=0 then
+         Source.Position:=0;   // This WILL fail for non-seekable streams...
+       BufferSize:=MaxSize;
+       if (Count>0) and (Count<BufferSize) then
+         BufferSize:=Count;    // do not allocate more than needed
+
+       GetMem(Buffer,BufferSize);
+       try
+         if Count=0 then
+         repeat
+           i:=Source.Read(buffer^,BufferSize);
+           if i>0 then
+             WriteBuffer(buffer^,i);
+           Inc(Result,i);
+         until i<BufferSize
          else
-           i:=Count;
-         i:=Source.Read(buffer,i);
-         i:=Write(buffer,i);
-         if i=0 then break;
-         dec(count,i);
-         CopyFrom:=CopyFrom+i;
+         while Count>0 do
+         begin
+           if Count>BufferSize then
+             i:=BufferSize
+           else
+             i:=Count;
+           Source.ReadBuffer(buffer^,i);
+           WriteBuffer(buffer^,i);
+           Dec(count,i);
+           Inc(Result,i);
          end;
+       finally
+         FreeMem(Buffer);
+       end;
+
     end;
 
   function TStream.ReadComponent(Instance: TComponent): TComponent;