-
Notifications
You must be signed in to change notification settings - Fork 5
/
jsonscannerhelper.pas
106 lines (91 loc) · 2.83 KB
/
jsonscannerhelper.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
unit jsonscannerhelper;
{$mode objfpc}{$H+}{$ModeSwitch typehelpers}{$ModeSwitch advancedrecords}
interface
uses
Classes, SysUtils,fastjsonscanner;
type
EJSONScannerHelperException = class(Exception);
TReadObject = function (var scanner: TJSONScanner; const typeId: string): TObject of object;
TJSONScannerHelper = record helper for TJSONScanner
procedure expectCurrentToken(token: TJSONToken);
function fetchNonWSToken: TJSONToken;
function fetchExpectedToken(token: TJSONToken): TJSONToken;
function fetchStringObjectPropertyValue: string;
function fetchSerializedTypedObject(callback: TReadObject): TObject; //['type', {obj}]
procedure skipObjectPropertyValue;
function CurTokenString: string;
procedure raiseUnexpectedError();
end;
implementation
uses math;
procedure TJSONScannerHelper.raiseUnexpectedError();
var
at: String;
begin
at := Copy(CurLine, CurColumn - 30, min(CurColumn - 1, 30) ) + '|' + Copy(CurLine, CurColumn, 30 ) ;
raise EJSONScannerHelperException.create('Konfigurationsdatei konnte nicht geladen werden. Unerwartetes Symbol hier: '+at);
end;
procedure TJSONScannerHelper.expectCurrentToken(token: TJSONToken);
begin
if CurToken <> token then
raiseUnexpectedError();
end;
function TJSONScannerHelper.fetchNonWSToken: TJSONToken;
begin
repeat
result := FetchToken;
until result <> tkWhitespace;
end;
function TJSONScannerHelper.fetchExpectedToken(token: TJSONToken): TJSONToken;
begin
result := fetchNonWSToken;
expectCurrentToken(token);
end;
function TJSONScannerHelper.fetchStringObjectPropertyValue: string;
begin
fetchNonWSToken; expectCurrentToken(tkColon);
fetchNonWSToken; expectCurrentToken(tkString);
result := CurTokenString;
fetchNonWSToken;
end;
function TJSONScannerHelper.fetchSerializedTypedObject(callback: TReadObject): TObject;
var additionalArray: boolean;
typeId: String;
begin
additionalArray := curtoken = tkSquaredBraceOpen;
if additionalArray then fetchNonWSToken;
expectCurrentToken(tkString);
typeId := CurTokenString;
fetchNonWSToken; expectCurrentToken(tkComma);
fetchNonWSToken;
result := callback(self, typeId);
if additionalArray then begin
fetchNonWSToken; expectCurrentToken(tkSquaredBraceClose);
end;
end;
procedure TJSONScannerHelper.skipObjectPropertyValue;
var nesting: sizeint;
begin
fetchExpectedToken(tkColon);
fetchNonWSToken;
case CurToken of
tkString: ;
tkSquaredBraceOpen: begin
nesting := 1;
while nesting > 0 do
case fetchNonWSToken of
tkSquaredBraceOpen: inc(nesting);
tkSquaredBraceClose: dec(nesting);
tkEOF: exit;
else ;
end;
end;
else expectCurrentToken(tkString);
end;
fetchNonWSToken;
end;
function TJSONScannerHelper.CurTokenString: string;
begin
result := decodeJSONString(CurTokenStart, CurTokenLength, jecEscapeNothing, nil);
end;
end.