* 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 -
This commit is contained in:
sergei 2011-02-24 03:25:40 +00:00
parent 41c946032e
commit 41aeb9a22b

View File

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