mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-22 06:49:27 +02:00
* Speed rework, second iteration
git-svn-id: trunk@42884 -
This commit is contained in:
parent
9d969a5fb1
commit
42a9b6a681
@ -14,6 +14,7 @@
|
||||
**********************************************************************}
|
||||
{$mode objfpc}
|
||||
{$h+}
|
||||
{ $INLINE ON}
|
||||
|
||||
unit jsonscanner;
|
||||
|
||||
@ -67,25 +68,27 @@ Type
|
||||
FCurRow: Integer;
|
||||
FCurToken: TJSONToken;
|
||||
FCurTokenString: string;
|
||||
FCurLine: string;
|
||||
FCurLine: PChar;
|
||||
FTokenStr: PAnsiChar; // position inside FCurLine
|
||||
FEOL : PAnsiChar; // EOL
|
||||
FOptions : TJSONOptions;
|
||||
function GetCurColumn: Integer; inline;
|
||||
function GetCurLine: string;
|
||||
function GetO(AIndex: TJSONOption): Boolean;
|
||||
procedure SetO(AIndex: TJSONOption; AValue: Boolean);
|
||||
protected
|
||||
procedure Error(const Msg: string);overload;
|
||||
procedure Error(const Msg: string; Const Args: array of const);overload;
|
||||
function DoFetchToken: TJSONToken; inline;
|
||||
// function DoFetchToken: TJSONToken; inline;
|
||||
public
|
||||
constructor Create(Source : TStream; AUseUTF8 : Boolean = True); overload; deprecated 'use options form instead';
|
||||
constructor Create(Source: TStream; AOptions: TJSONOptions); overload;
|
||||
constructor Create(const aSource : RawByteString; AUseUTF8 : Boolean = True); overload; deprecated 'use options form instead';
|
||||
constructor Create(const aSource: RawByteString; AOptions: TJSONOptions); overload;
|
||||
|
||||
function FetchToken: TJSONToken;
|
||||
|
||||
|
||||
property CurLine: string read FCurLine;
|
||||
property CurLine: string read GetCurLine;
|
||||
property CurRow: Integer read FCurRow;
|
||||
property CurColumn: Integer read GetCurColumn;
|
||||
|
||||
@ -169,12 +172,12 @@ begin
|
||||
FOptions:=AOptions;
|
||||
end;
|
||||
|
||||
function TJSONScanner.FetchToken: TJSONToken;
|
||||
|
||||
function TJSONScanner.GetCurColumn: Integer;
|
||||
begin
|
||||
Result:=DoFetchToken;
|
||||
Result := FTokenStr - FCurLine;
|
||||
end;
|
||||
|
||||
|
||||
procedure TJSONScanner.Error(const Msg: string);
|
||||
begin
|
||||
raise EScannerError.Create(Msg);
|
||||
@ -185,22 +188,21 @@ begin
|
||||
raise EScannerError.CreateFmt(Msg, Args);
|
||||
end;
|
||||
|
||||
function TJSONScanner.DoFetchToken: TJSONToken;
|
||||
function TJSONScanner.FetchToken: TJSONToken;
|
||||
|
||||
|
||||
function FetchLine: Boolean;
|
||||
|
||||
var
|
||||
PEOL : PAnsiChar;
|
||||
Len : integer;
|
||||
|
||||
begin
|
||||
Result:=(FCurPos<>Nil) and (FCurPos^<>#0);
|
||||
if Result then
|
||||
begin
|
||||
FCurLine:=FCurPos;
|
||||
FTokenStr:=FCurPos;
|
||||
While Not (FCurPos^ in [#0,#10,#13]) do
|
||||
Inc(FCurPos);
|
||||
PEOL:=FCurPos;
|
||||
FEOL:=FCurPos;
|
||||
if (FCurPos^<>#0) then
|
||||
begin
|
||||
if (FCurPos^=#13) and (FCurPos[1]=#10) then
|
||||
@ -208,15 +210,12 @@ function TJSONScanner.DoFetchToken: TJSONToken;
|
||||
Inc(FCurPos); // To start of next line
|
||||
Inc(FCurRow); // Increase line index
|
||||
end;
|
||||
Len:=PEOL-FTokenStr;
|
||||
SetLength(FCurLine,Len);
|
||||
if Len>0 then
|
||||
Move(FTokenStr^,FCurLine[1],Len);
|
||||
FTokenStr:=PAnsiChar(FCurLine);
|
||||
// Len:=FEOL-FTokenStr;
|
||||
// FTokenStr:=PAnsiChar(FCurLine);
|
||||
end
|
||||
else
|
||||
begin
|
||||
FCurLine:='';
|
||||
FCurLine:=Nil;
|
||||
FTokenStr:=nil;
|
||||
end;
|
||||
end;
|
||||
@ -227,7 +226,7 @@ var
|
||||
I : Integer;
|
||||
OldLength, SectionLength, tstart,tcol, u1,u2: Integer;
|
||||
C , c2: char;
|
||||
S : String;
|
||||
S : String[4];
|
||||
IsStar,EOC: Boolean;
|
||||
|
||||
Procedure MaybeAppendUnicode;
|
||||
@ -251,7 +250,7 @@ var
|
||||
|
||||
|
||||
begin
|
||||
if FTokenStr = nil then
|
||||
if (FTokenStr = nil) or (FTokenStr=FEOL) then
|
||||
if not FetchLine then
|
||||
begin
|
||||
Result := tkEOF;
|
||||
@ -260,8 +259,7 @@ begin
|
||||
end;
|
||||
|
||||
FCurTokenString := '';
|
||||
|
||||
case FTokenStr[0] of
|
||||
case FTokenStr^ of
|
||||
#0: // Empty line
|
||||
begin
|
||||
FetchLine;
|
||||
@ -282,7 +280,7 @@ begin
|
||||
end;
|
||||
'"','''':
|
||||
begin
|
||||
C:=FTokenStr[0];
|
||||
C:=FTokenStr^;
|
||||
If (C='''') and (joStrict in Options) then
|
||||
Error(SErrInvalidCharacter, [CurRow,CurColumn,FTokenStr[0]]);
|
||||
Inc(FTokenStr);
|
||||
@ -290,15 +288,15 @@ begin
|
||||
OldLength := 0;
|
||||
FCurTokenString := '';
|
||||
u1:=0;
|
||||
while not (FTokenStr[0] in [#0,C]) do
|
||||
while not (FTokenStr^ in [#0,C]) do
|
||||
begin
|
||||
if (FTokenStr[0]='\') then
|
||||
if (FTokenStr^='\') then
|
||||
begin
|
||||
// Save length
|
||||
SectionLength := FTokenStr - TokenStart;
|
||||
Inc(FTokenStr);
|
||||
// Read escaped token
|
||||
Case FTokenStr[0] of
|
||||
Case FTokenStr^ of
|
||||
'"' : S:='"';
|
||||
'''' : S:='''';
|
||||
't' : S:=#9;
|
||||
@ -347,27 +345,28 @@ begin
|
||||
begin
|
||||
// If length=1, we know it was not \uXX, but u1 can be nonzero, and we must first append it.
|
||||
// example: \u00f8\"
|
||||
if I=1 then
|
||||
if (I=1) and (u1<>0) then
|
||||
MaybeAppendUnicode;
|
||||
SetLength(FCurTokenString, OldLength + SectionLength+Length(S));
|
||||
SetLength(FCurTokenString, OldLength + SectionLength+i);
|
||||
if SectionLength > 0 then
|
||||
Move(TokenStart^, FCurTokenString[OldLength + 1], SectionLength);
|
||||
if I>0 then
|
||||
Move(S[1],FCurTokenString[OldLength + SectionLength+1],i);
|
||||
Inc(OldLength, SectionLength+Length(S));
|
||||
Inc(OldLength, SectionLength+I);
|
||||
end;
|
||||
// Next char
|
||||
TokenStart := FTokenStr+1;
|
||||
end
|
||||
else
|
||||
else if u1<>0 then
|
||||
MaybeAppendUnicode;
|
||||
if FTokenStr[0] = #0 then
|
||||
if FTokenStr^ = #0 then
|
||||
Error(SErrOpenString,[FCurRow]);
|
||||
Inc(FTokenStr);
|
||||
end;
|
||||
if FTokenStr[0] = #0 then
|
||||
if FTokenStr^ = #0 then
|
||||
Error(SErrOpenString,[FCurRow]);
|
||||
MaybeAppendUnicode;
|
||||
if u1<>0 then
|
||||
MaybeAppendUnicode;
|
||||
SectionLength := FTokenStr - TokenStart;
|
||||
SetLength(FCurTokenString, OldLength + SectionLength);
|
||||
if SectionLength > 0 then
|
||||
@ -386,7 +385,7 @@ begin
|
||||
while true do
|
||||
begin
|
||||
Inc(FTokenStr);
|
||||
case FTokenStr[0] of
|
||||
case FTokenStr^ of
|
||||
'.':
|
||||
begin
|
||||
if FTokenStr[1] in ['0'..'9', 'e', 'E'] then
|
||||
@ -394,7 +393,7 @@ begin
|
||||
Inc(FTokenStr);
|
||||
repeat
|
||||
Inc(FTokenStr);
|
||||
until not (FTokenStr[0] in ['0'..'9', 'e', 'E','-','+']);
|
||||
until not (FTokenStr^ in ['0'..'9', 'e', 'E','-','+']);
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
@ -402,14 +401,14 @@ begin
|
||||
'e', 'E':
|
||||
begin
|
||||
Inc(FTokenStr);
|
||||
if FTokenStr[0] in ['-','+'] then
|
||||
if FTokenStr^ in ['-','+'] then
|
||||
Inc(FTokenStr);
|
||||
while FTokenStr[0] in ['0'..'9'] do
|
||||
while FTokenStr^ in ['0'..'9'] do
|
||||
Inc(FTokenStr);
|
||||
break;
|
||||
end;
|
||||
else
|
||||
if not (FTokenStr[0] in [#0,'}',']',',',#9,' ']) then
|
||||
if {(FTokenStr<>FEOL) and }not (FTokenStr^ in [#13,#10,#0,'}',']',',',#9,' ']) then
|
||||
Error(SErrInvalidCharacter, [CurRow,CurColumn,FTokenStr[0]]);
|
||||
break;
|
||||
end;
|
||||
@ -452,7 +451,7 @@ begin
|
||||
Error(SErrInvalidCharacter, [CurRow,CurCOlumn,FTokenStr[0]]);
|
||||
TokenStart:=FTokenStr;
|
||||
Inc(FTokenStr);
|
||||
Case FTokenStr[0] of
|
||||
Case FTokenStr^ of
|
||||
'/' : begin
|
||||
SectionLength := Length(FCurLine)- (FTokenStr - PChar(FCurLine));
|
||||
Inc(FTokenStr);
|
||||
@ -466,7 +465,7 @@ begin
|
||||
Inc(FTokenStr);
|
||||
TokenStart:=FTokenStr;
|
||||
Repeat
|
||||
if (FTokenStr[0]=#0) then
|
||||
if (FTokenStr^=#0) then
|
||||
begin
|
||||
SectionLength := (FTokenStr - TokenStart);
|
||||
S:='';
|
||||
@ -476,9 +475,9 @@ begin
|
||||
Error(SUnterminatedComment, [CurRow,CurCOlumn,FTokenStr[0]]);
|
||||
TokenStart:=FTokenStr;
|
||||
end;
|
||||
IsStar:=FTokenStr[0]='*';
|
||||
IsStar:=FTokenStr^='*';
|
||||
Inc(FTokenStr);
|
||||
EOC:=(isStar and (FTokenStr[0]='/'));
|
||||
EOC:=(isStar and (FTokenStr^='/'));
|
||||
Until EOC;
|
||||
if EOC then
|
||||
begin
|
||||
@ -501,7 +500,7 @@ begin
|
||||
TokenStart := FTokenStr;
|
||||
repeat
|
||||
Inc(FTokenStr);
|
||||
until not (FTokenStr[0] in ['A'..'Z', 'a'..'z', '0'..'9', '_']);
|
||||
until not (FTokenStr^ in ['A'..'Z', 'a'..'z', '0'..'9', '_']);
|
||||
SectionLength := FTokenStr - TokenStart;
|
||||
FCurTokenString:='';
|
||||
SetString(FCurTokenString, TokenStart, SectionLength);
|
||||
@ -520,13 +519,24 @@ begin
|
||||
else
|
||||
Error(SErrInvalidCharacter, [CurRow,CurColumn,FTokenStr[0]]);
|
||||
end;
|
||||
|
||||
FCurToken := Result;
|
||||
end;
|
||||
|
||||
function TJSONScanner.GetCurColumn: Integer;
|
||||
{function TJSONScanner.FetchToken: TJSONToken;
|
||||
|
||||
begin
|
||||
Result := FTokenStr - PChar(CurLine);
|
||||
Result:=DoFetchToken;
|
||||
end;}
|
||||
|
||||
function TJSONScanner.GetCurLine: string;
|
||||
begin
|
||||
Result:='';
|
||||
if FCurLine<>Nil then
|
||||
begin
|
||||
SetLength(Result,FEOL-FCurLine);
|
||||
if Length(Result)>0 then
|
||||
Move(FCurLine^,Result[1],Length(Result));
|
||||
end;
|
||||
end;
|
||||
|
||||
function TJSONScanner.GetO(AIndex: TJSONOption): Boolean;
|
||||
|
Loading…
Reference in New Issue
Block a user