mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-30 01:39:28 +02:00
* Added fakeSeekForward for benefit of descendant streams.
* Override GetSize/Position for memory/stringstream for efficiency * Added InvalidSeek exception throwing. Should be overridden to throw custom exceptions. git-svn-id: trunk@18190 -
This commit is contained in:
parent
6992049034
commit
96e5333dc2
@ -145,6 +145,7 @@ type
|
|||||||
EParserError = class(Exception);
|
EParserError = class(Exception);
|
||||||
EOutOfResources = class(EOutOfMemory);
|
EOutOfResources = class(EOutOfMemory);
|
||||||
EInvalidOperation = class(Exception);
|
EInvalidOperation = class(Exception);
|
||||||
|
TExceptionClass = Class of Exception;
|
||||||
|
|
||||||
{ Forward class declarations }
|
{ Forward class declarations }
|
||||||
|
|
||||||
@ -767,15 +768,20 @@ type
|
|||||||
{ TStream abstract class }
|
{ TStream abstract class }
|
||||||
|
|
||||||
TStream = class(TObject)
|
TStream = class(TObject)
|
||||||
|
private
|
||||||
protected
|
protected
|
||||||
|
procedure InvalidSeek; virtual;
|
||||||
|
procedure Discard(const Count: Int64);
|
||||||
|
procedure DiscardLarge(Count: int64; const MaxBufferSize: Longint);
|
||||||
|
procedure FakeSeekForward(Offset: Int64; const Origin: TSeekOrigin; const Pos: Int64);
|
||||||
function GetPosition: Int64; virtual;
|
function GetPosition: Int64; virtual;
|
||||||
procedure SetPosition(const Pos: Int64); virtual;
|
procedure SetPosition(const Pos: Int64); virtual;
|
||||||
function GetSize: Int64; virtual;
|
function GetSize: Int64; virtual;
|
||||||
procedure SetSize64(const NewSize: Int64); virtual;
|
procedure SetSize64(const NewSize: Int64); virtual;
|
||||||
procedure SetSize(NewSize: Longint); virtual;overload;
|
procedure SetSize(NewSize: Longint); virtual;overload;
|
||||||
procedure SetSize(const NewSize: Int64); virtual;overload;
|
procedure SetSize(const NewSize: Int64); virtual;overload;
|
||||||
procedure ReadNotImplemented;
|
procedure ReadNotImplemented;
|
||||||
procedure WriteNotImplemented;
|
procedure WriteNotImplemented;
|
||||||
public
|
public
|
||||||
function Read(var Buffer; Count: Longint): Longint; virtual;
|
function Read(var Buffer; Count: Longint): Longint; virtual;
|
||||||
function Write(const Buffer; Count: Longint): Longint; virtual;
|
function Write(const Buffer; Count: Longint): Longint; virtual;
|
||||||
@ -873,9 +879,10 @@ type
|
|||||||
FMemory: Pointer;
|
FMemory: Pointer;
|
||||||
FSize, FPosition: PtrInt;
|
FSize, FPosition: PtrInt;
|
||||||
protected
|
protected
|
||||||
|
Function GetSize : Int64; Override;
|
||||||
|
function GetPosition: Int64; Override;
|
||||||
procedure SetPointer(Ptr: Pointer; ASize: PtrInt);
|
procedure SetPointer(Ptr: Pointer; ASize: PtrInt);
|
||||||
public
|
public
|
||||||
Function GetSize : Int64; Override;
|
|
||||||
function Read(var Buffer; Count: LongInt): LongInt; override;
|
function Read(var Buffer; Count: LongInt): LongInt; override;
|
||||||
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
|
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
|
||||||
procedure SaveToStream(Stream: TStream);
|
procedure SaveToStream(Stream: TStream);
|
||||||
@ -908,6 +915,8 @@ type
|
|||||||
FDataString: string;
|
FDataString: string;
|
||||||
FPosition: Integer;
|
FPosition: Integer;
|
||||||
protected
|
protected
|
||||||
|
Function GetSize : Int64; Override;
|
||||||
|
function GetPosition: Int64; Override;
|
||||||
procedure SetSize(NewSize: Longint); override;
|
procedure SetSize(NewSize: Longint); override;
|
||||||
public
|
public
|
||||||
constructor Create(const AString: string);
|
constructor Create(const AString: string);
|
||||||
|
@ -113,7 +113,66 @@ end;
|
|||||||
raise EStreamError.CreateFmt(SSeekNotImplemented,[ClassName]);
|
raise EStreamError.CreateFmt(SSeekNotImplemented,[ClassName]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TStream.Seek(const Offset: Int64; Origin: TSeekorigin): Int64;
|
procedure TStream.Discard(const Count: Int64);
|
||||||
|
|
||||||
|
const
|
||||||
|
CSmallSize =255;
|
||||||
|
CLargeMaxBuffer =32*1024; // 32 KiB
|
||||||
|
var
|
||||||
|
Buffer: array[1..CSmallSize] of Byte;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if Count=0 then
|
||||||
|
Exit;
|
||||||
|
if Count<=SizeOf(Buffer) then
|
||||||
|
ReadBuffer(Buffer,Count)
|
||||||
|
else
|
||||||
|
DiscardLarge(Count,CLargeMaxBuffer);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TStream.DiscardLarge(Count: int64; const MaxBufferSize: Longint);
|
||||||
|
|
||||||
|
var
|
||||||
|
Buffer: array of Byte;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if Count=0 then
|
||||||
|
Exit;
|
||||||
|
if Count>MaxBufferSize then
|
||||||
|
SetLength(Buffer,MaxBufferSize)
|
||||||
|
else
|
||||||
|
SetLength(Buffer,Count);
|
||||||
|
while (Count>=Length(Buffer)) do
|
||||||
|
begin
|
||||||
|
ReadBuffer(Buffer[0],Length(Buffer));
|
||||||
|
Dec(Count,Length(Buffer));
|
||||||
|
end;
|
||||||
|
if Count>0 then
|
||||||
|
ReadBuffer(Buffer[0],Count);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TStream.InvalidSeek;
|
||||||
|
|
||||||
|
begin
|
||||||
|
raise EStreamError.CreateFmt(SStreamInvalidSeek, [ClassName]) at get_caller_addr(get_frame);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TStream.FakeSeekForward(Offset: Int64; const Origin: TSeekOrigin; const Pos: Int64);
|
||||||
|
|
||||||
|
var
|
||||||
|
Buffer: Pointer;
|
||||||
|
BufferSize, i: LongInt;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if Origin=soBeginning then
|
||||||
|
Dec(Offset,Pos);
|
||||||
|
if (Offset<0) or (Origin=soEnd) then
|
||||||
|
InvalidSeek;
|
||||||
|
if Offset>0 then
|
||||||
|
Discard(Offset);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TStream.Seek(const Offset: Int64; Origin: TSeekorigin): Int64;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
// Backwards compatibility that calls the longint Seek
|
// Backwards compatibility that calls the longint Seek
|
||||||
@ -428,6 +487,7 @@ end;
|
|||||||
Constructor THandleStream.Create(AHandle: THandle);
|
Constructor THandleStream.Create(AHandle: THandle);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
Inherited Create;
|
||||||
FHandle:=AHandle;
|
FHandle:=AHandle;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -530,6 +590,11 @@ begin
|
|||||||
Result:=FSize;
|
Result:=FSize;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCustomMemoryStream.GetPosition: Int64;
|
||||||
|
begin
|
||||||
|
Result:=FPosition;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TCustomMemoryStream.Read(var Buffer; Count: LongInt): LongInt;
|
function TCustomMemoryStream.Read(var Buffer; Count: LongInt): LongInt;
|
||||||
|
|
||||||
@ -695,6 +760,16 @@ end;
|
|||||||
{* TStringStream *}
|
{* TStringStream *}
|
||||||
{****************************************************************************}
|
{****************************************************************************}
|
||||||
|
|
||||||
|
function TStringStream.GetSize: Int64;
|
||||||
|
begin
|
||||||
|
Result:=Length(FDataString);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TStringStream.GetPosition: Int64;
|
||||||
|
begin
|
||||||
|
Result:=FPosition;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TStringStream.SetSize(NewSize: Longint);
|
procedure TStringStream.SetSize(NewSize: Longint);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -740,10 +815,12 @@ begin
|
|||||||
Case Origin of
|
Case Origin of
|
||||||
soFromBeginning : FPosition:=Offset;
|
soFromBeginning : FPosition:=Offset;
|
||||||
soFromEnd : FPosition:=Length(FDataString)+Offset;
|
soFromEnd : FPosition:=Length(FDataString)+Offset;
|
||||||
soFromCurrent : FpoSition:=FPosition+Offset;
|
soFromCurrent : FPosition:=FPosition+Offset;
|
||||||
end;
|
end;
|
||||||
If FPosition>Length(FDataString) then FPosition:=Length(FDataString);
|
If FPosition>Length(FDataString) then
|
||||||
If FPosition<0 then FPosition:=0;
|
FPosition:=Length(FDataString)
|
||||||
|
else If FPosition<0 then
|
||||||
|
FPosition:=0;
|
||||||
Result:=FPosition;
|
Result:=FPosition;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user