Electroneum
Toggle main menu visibility
Loading...
Searching...
No Matches
lookaheadparser.cpp
Go to the documentation of this file.
1
#include "
rapidjson/reader.h
"
2
#include "
rapidjson/document.h
"
3
#include <iostream>
4
5
RAPIDJSON_DIAG_PUSH
6
#ifdef __GNUC__
7
RAPIDJSON_DIAG_OFF(effc++)
8
#endif
9
10
// This example demonstrates JSON token-by-token parsing with an API that is
11
// more direct; you don't need to design your logic around a handler object and
12
// callbacks. Instead, you retrieve values from the JSON stream by calling
13
// GetInt(), GetDouble(), GetString() and GetBool(), traverse into structures
14
// by calling EnterObject() and EnterArray(), and skip over unwanted data by
15
// calling SkipValue(). When you know your JSON's structure, this can be quite
16
// convenient.
17
//
18
// If you aren't sure of what's next in the JSON data, you can use PeekType() and
19
// PeekValue() to look ahead to the next object before reading it.
20
//
21
// If you call the wrong retrieval method--e.g. GetInt when the next JSON token is
22
// not an int, EnterObject or EnterArray when there isn't actually an object or array
23
// to read--the stream parsing will end immediately and no more data will be delivered.
24
//
25
// After calling EnterObject, you retrieve keys via NextObjectKey() and values via
26
// the normal getters. When NextObjectKey() returns null, you have exited the
27
// object, or you can call SkipObject() to skip to the end of the object
28
// immediately. If you fetch the entire object (i.e. NextObjectKey() returned null),
29
// you should not call SkipObject().
30
//
31
// After calling EnterArray(), you must alternate between calling NextArrayValue()
32
// to see if the array has more data, and then retrieving values via the normal
33
// getters. You can call SkipArray() to skip to the end of the array immediately.
34
// If you fetch the entire array (i.e. NextArrayValue() returned null),
35
// you should not call SkipArray().
36
//
37
// This parser uses in-situ strings, so the JSON buffer will be altered during the
38
// parse.
39
40
using namespace
rapidjson
;
41
42
43
class
LookaheadParserHandler
{
44
public
:
45
bool
Null
() {
st_
=
kHasNull
;
v_
.SetNull();
return
true
; }
46
bool
Bool
(
bool
b) {
st_
=
kHasBool
;
v_
.SetBool(b);
return
true
; }
47
bool
Int
(
int
i) {
st_
=
kHasNumber
;
v_
.SetInt(i);
return
true
; }
48
bool
Uint
(
unsigned
u) {
st_
=
kHasNumber
;
v_
.SetUint(u);
return
true
; }
49
bool
Int64
(
int64_t
i) {
st_
=
kHasNumber
;
v_
.SetInt64(i);
return
true
; }
50
bool
Uint64
(
uint64_t
u) {
st_
=
kHasNumber
;
v_
.SetUint64(u);
return
true
; }
51
bool
Double
(
double
d) {
st_
=
kHasNumber
;
v_
.SetDouble(d);
return
true
; }
52
bool
RawNumber
(
const
char
*,
SizeType
,
bool
) {
return
false
; }
53
bool
String
(
const
char
* str,
SizeType
length,
bool
) {
st_
=
kHasString
;
v_
.SetString(str, length);
return
true
; }
54
bool
StartObject
() {
st_
=
kEnteringObject
;
return
true
; }
55
bool
Key
(
const
char
* str,
SizeType
length,
bool
) {
st_
=
kHasKey
;
v_
.SetString(str, length);
return
true
; }
56
bool
EndObject
(
SizeType
) {
st_
=
kExitingObject
;
return
true
; }
57
bool
StartArray
() {
st_
=
kEnteringArray
;
return
true
; }
58
bool
EndArray
(
SizeType
) {
st_
=
kExitingArray
;
return
true
; }
59
60
protected
:
61
LookaheadParserHandler
(
char
* str);
62
void
ParseNext
();
63
64
protected
:
65
enum
LookaheadParsingState
{
66
kInit
,
67
kError
,
68
kHasNull
,
69
kHasBool
,
70
kHasNumber
,
71
kHasString
,
72
kHasKey
,
73
kEnteringObject
,
74
kExitingObject
,
75
kEnteringArray
,
76
kExitingArray
77
};
78
79
Value
v_
;
80
LookaheadParsingState
st_
;
81
Reader
r_
;
82
InsituStringStream
ss_
;
83
84
static
const
int
parseFlags
=
kParseDefaultFlags
|
kParseInsituFlag
;
85
};
86
87
LookaheadParserHandler::LookaheadParserHandler
(
char
* str) :
v_
(),
st_
(
kInit
),
r_
(),
ss_
(str) {
88
r_
.IterativeParseInit();
89
ParseNext
();
90
}
91
92
void
LookaheadParserHandler::ParseNext
() {
93
if
(
r_
.HasParseError()) {
94
st_
=
kError
;
95
return
;
96
}
97
98
r_
.IterativeParseNext<
parseFlags
>(
ss_
, *
this
);
99
}
100
101
class
LookaheadParser
:
protected
LookaheadParserHandler
{
102
public
:
103
LookaheadParser
(
char
* str) :
LookaheadParserHandler
(str) {}
104
105
bool
EnterObject
();
106
bool
EnterArray
();
107
const
char
*
NextObjectKey
();
108
bool
NextArrayValue
();
109
int
GetInt
();
110
double
GetDouble
();
111
const
char
*
GetString
();
112
bool
GetBool
();
113
void
GetNull
();
114
115
void
SkipObject
();
116
void
SkipArray
();
117
void
SkipValue
();
118
Value
*
PeekValue
();
119
int
PeekType
();
// returns a rapidjson::Type, or -1 for no value (at end of object/array)
120
121
bool
IsValid
() {
return
st_
!=
kError
; }
122
123
protected
:
124
void
SkipOut
(
int
depth);
125
};
126
127
bool
LookaheadParser::EnterObject
() {
128
if
(
st_
!=
kEnteringObject
) {
129
st_
=
kError
;
130
return
false
;
131
}
132
133
ParseNext
();
134
return
true
;
135
}
136
137
bool
LookaheadParser::EnterArray
() {
138
if
(
st_
!=
kEnteringArray
) {
139
st_
=
kError
;
140
return
false
;
141
}
142
143
ParseNext
();
144
return
true
;
145
}
146
147
const
char
*
LookaheadParser::NextObjectKey
() {
148
if
(
st_
==
kHasKey
) {
149
const
char
* result =
v_
.GetString();
150
ParseNext
();
151
return
result;
152
}
153
154
if
(
st_
!=
kExitingObject
) {
155
st_
=
kError
;
156
return
0;
157
}
158
159
ParseNext
();
160
return
0;
161
}
162
163
bool
LookaheadParser::NextArrayValue
() {
164
if
(
st_
==
kExitingArray
) {
165
ParseNext
();
166
return
false
;
167
}
168
169
if
(
st_
==
kError
||
st_
==
kExitingObject
||
st_
==
kHasKey
) {
170
st_
=
kError
;
171
return
false
;
172
}
173
174
return
true
;
175
}
176
177
int
LookaheadParser::GetInt
() {
178
if
(
st_
!=
kHasNumber
|| !
v_
.IsInt()) {
179
st_
=
kError
;
180
return
0;
181
}
182
183
int
result =
v_
.GetInt();
184
ParseNext
();
185
return
result;
186
}
187
188
double
LookaheadParser::GetDouble
() {
189
if
(
st_
!=
kHasNumber
) {
190
st_
=
kError
;
191
return
0.;
192
}
193
194
double
result =
v_
.GetDouble();
195
ParseNext
();
196
return
result;
197
}
198
199
bool
LookaheadParser::GetBool
() {
200
if
(
st_
!=
kHasBool
) {
201
st_
=
kError
;
202
return
false
;
203
}
204
205
bool
result =
v_
.GetBool();
206
ParseNext
();
207
return
result;
208
}
209
210
void
LookaheadParser::GetNull
() {
211
if
(
st_
!=
kHasNull
) {
212
st_
=
kError
;
213
return
;
214
}
215
216
ParseNext
();
217
}
218
219
const
char
*
LookaheadParser::GetString
() {
220
if
(
st_
!=
kHasString
) {
221
st_
=
kError
;
222
return
0;
223
}
224
225
const
char
* result =
v_
.GetString();
226
ParseNext
();
227
return
result;
228
}
229
230
void
LookaheadParser::SkipOut
(
int
depth) {
231
do
{
232
if
(
st_
==
kEnteringArray
||
st_
==
kEnteringObject
) {
233
++depth;
234
}
235
else
if
(
st_
==
kExitingArray
||
st_
==
kExitingObject
) {
236
--depth;
237
}
238
else
if
(
st_
==
kError
) {
239
return
;
240
}
241
242
ParseNext
();
243
}
244
while
(depth > 0);
245
}
246
247
void
LookaheadParser::SkipValue
() {
248
SkipOut
(0);
249
}
250
251
void
LookaheadParser::SkipArray
() {
252
SkipOut
(1);
253
}
254
255
void
LookaheadParser::SkipObject
() {
256
SkipOut
(1);
257
}
258
259
Value
*
LookaheadParser::PeekValue
() {
260
if
(
st_
>=
kHasNull
&&
st_
<=
kHasKey
) {
261
return
&
v_
;
262
}
263
264
return
0;
265
}
266
267
int
LookaheadParser::PeekType
() {
268
if
(
st_
>=
kHasNull
&&
st_
<=
kHasKey
) {
269
return
v_
.GetType();
270
}
271
272
if
(
st_
==
kEnteringArray
) {
273
return
kArrayType
;
274
}
275
276
if
(
st_
==
kEnteringObject
) {
277
return
kObjectType
;
278
}
279
280
return
-1;
281
}
282
283
//-------------------------------------------------------------------------
284
285
int
main
() {
286
using namespace
std
;
287
288
char
json
[] =
" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null,"
289
"\"i\":123, \"pi\": 3.1416, \"a\":[-1, 2, 3, 4, \"array\", []], \"skipArrays\":[1, 2, [[[3]]]], "
290
"\"skipObject\":{ \"i\":0, \"t\":true, \"n\":null, \"d\":123.45 }, "
291
"\"skipNested\":[[[[{\"\":0}, {\"\":[-9.87]}]]], [], []], "
292
"\"skipString\":\"zzz\", \"reachedEnd\":null, \"t\":true }"
;
293
294
LookaheadParser
r(
json
);
295
296
RAPIDJSON_ASSERT
(r.
PeekType
() ==
kObjectType
);
297
298
r.
EnterObject
();
299
while
(
const
char
*
key
= r.
NextObjectKey
()) {
300
if
(0 == strcmp(
key
,
"hello"
)) {
301
RAPIDJSON_ASSERT
(r.
PeekType
() ==
kStringType
);
302
cout <<
key
<<
":"
<< r.
GetString
() << endl;
303
}
304
else
if
(0 == strcmp(
key
,
"t"
) || 0 == strcmp(
key
,
"f"
)) {
305
RAPIDJSON_ASSERT
(r.
PeekType
() ==
kTrueType
|| r.
PeekType
() ==
kFalseType
);
306
cout <<
key
<<
":"
<< r.
GetBool
() << endl;
307
continue
;
308
}
309
else
if
(0 == strcmp(
key
,
"n"
)) {
310
RAPIDJSON_ASSERT
(r.
PeekType
() ==
kNullType
);
311
r.
GetNull
();
312
cout <<
key
<< endl;
313
continue
;
314
}
315
else
if
(0 == strcmp(
key
,
"pi"
)) {
316
RAPIDJSON_ASSERT
(r.
PeekType
() ==
kNumberType
);
317
cout <<
key
<<
":"
<< r.
GetDouble
() << endl;
318
continue
;
319
}
320
else
if
(0 == strcmp(
key
,
"a"
)) {
321
RAPIDJSON_ASSERT
(r.
PeekType
() ==
kArrayType
);
322
323
r.
EnterArray
();
324
325
cout <<
key
<<
":[ "
;
326
while
(r.
NextArrayValue
()) {
327
if
(r.
PeekType
() ==
kNumberType
) {
328
cout << r.
GetDouble
() <<
" "
;
329
}
330
else
if
(r.
PeekType
() ==
kStringType
) {
331
cout << r.
GetString
() <<
" "
;
332
}
333
else
{
334
r.
SkipArray
();
335
break
;
336
}
337
}
338
339
cout <<
"]"
<< endl;
340
}
341
else
{
342
cout <<
key
<<
":skipped"
<< endl;
343
r.
SkipValue
();
344
}
345
}
346
347
return
0;
348
}
349
350
RAPIDJSON_DIAG_POP
LookaheadParserHandler::StartObject
bool StartObject()
Definition
lookaheadparser.cpp:54
LookaheadParserHandler::ss_
InsituStringStream ss_
Definition
lookaheadparser.cpp:82
LookaheadParserHandler::RawNumber
bool RawNumber(const char *, SizeType, bool)
Definition
lookaheadparser.cpp:52
LookaheadParserHandler::st_
LookaheadParsingState st_
Definition
lookaheadparser.cpp:80
LookaheadParserHandler::v_
Value v_
Definition
lookaheadparser.cpp:79
LookaheadParserHandler::parseFlags
static const int parseFlags
Definition
lookaheadparser.cpp:84
LookaheadParserHandler::Int64
bool Int64(int64_t i)
Definition
lookaheadparser.cpp:49
LookaheadParserHandler::EndObject
bool EndObject(SizeType)
Definition
lookaheadparser.cpp:56
LookaheadParserHandler::Int
bool Int(int i)
Definition
lookaheadparser.cpp:47
LookaheadParserHandler::ParseNext
void ParseNext()
Definition
lookaheadparser.cpp:92
LookaheadParserHandler::StartArray
bool StartArray()
Definition
lookaheadparser.cpp:57
LookaheadParserHandler::EndArray
bool EndArray(SizeType)
Definition
lookaheadparser.cpp:58
LookaheadParserHandler::Null
bool Null()
Definition
lookaheadparser.cpp:45
LookaheadParserHandler::Uint
bool Uint(unsigned u)
Definition
lookaheadparser.cpp:48
LookaheadParserHandler::Key
bool Key(const char *str, SizeType length, bool)
Definition
lookaheadparser.cpp:55
LookaheadParserHandler::String
bool String(const char *str, SizeType length, bool)
Definition
lookaheadparser.cpp:53
LookaheadParserHandler::LookaheadParserHandler
LookaheadParserHandler(char *str)
Definition
lookaheadparser.cpp:87
LookaheadParserHandler::Bool
bool Bool(bool b)
Definition
lookaheadparser.cpp:46
LookaheadParserHandler::Uint64
bool Uint64(uint64_t u)
Definition
lookaheadparser.cpp:50
LookaheadParserHandler::LookaheadParsingState
LookaheadParsingState
Definition
lookaheadparser.cpp:65
LookaheadParserHandler::kHasNull
@ kHasNull
Definition
lookaheadparser.cpp:68
LookaheadParserHandler::kExitingArray
@ kExitingArray
Definition
lookaheadparser.cpp:76
LookaheadParserHandler::kHasNumber
@ kHasNumber
Definition
lookaheadparser.cpp:70
LookaheadParserHandler::kInit
@ kInit
Definition
lookaheadparser.cpp:66
LookaheadParserHandler::kExitingObject
@ kExitingObject
Definition
lookaheadparser.cpp:74
LookaheadParserHandler::kEnteringArray
@ kEnteringArray
Definition
lookaheadparser.cpp:75
LookaheadParserHandler::kError
@ kError
Definition
lookaheadparser.cpp:67
LookaheadParserHandler::kHasBool
@ kHasBool
Definition
lookaheadparser.cpp:69
LookaheadParserHandler::kHasString
@ kHasString
Definition
lookaheadparser.cpp:71
LookaheadParserHandler::kHasKey
@ kHasKey
Definition
lookaheadparser.cpp:72
LookaheadParserHandler::kEnteringObject
@ kEnteringObject
Definition
lookaheadparser.cpp:73
LookaheadParserHandler::Double
bool Double(double d)
Definition
lookaheadparser.cpp:51
LookaheadParserHandler::r_
Reader r_
Definition
lookaheadparser.cpp:81
LookaheadParser
Definition
lookaheadparser.cpp:101
LookaheadParser::NextArrayValue
bool NextArrayValue()
Definition
lookaheadparser.cpp:163
LookaheadParser::LookaheadParser
LookaheadParser(char *str)
Definition
lookaheadparser.cpp:103
LookaheadParser::GetString
const char * GetString()
Definition
lookaheadparser.cpp:219
LookaheadParser::SkipObject
void SkipObject()
Definition
lookaheadparser.cpp:255
LookaheadParser::PeekValue
Value * PeekValue()
Definition
lookaheadparser.cpp:259
LookaheadParser::GetNull
void GetNull()
Definition
lookaheadparser.cpp:210
LookaheadParser::PeekType
int PeekType()
Definition
lookaheadparser.cpp:267
LookaheadParser::GetInt
int GetInt()
Definition
lookaheadparser.cpp:177
LookaheadParser::IsValid
bool IsValid()
Definition
lookaheadparser.cpp:121
LookaheadParser::SkipValue
void SkipValue()
Definition
lookaheadparser.cpp:247
LookaheadParser::EnterArray
bool EnterArray()
Definition
lookaheadparser.cpp:137
LookaheadParser::NextObjectKey
const char * NextObjectKey()
Definition
lookaheadparser.cpp:147
LookaheadParser::SkipArray
void SkipArray()
Definition
lookaheadparser.cpp:251
LookaheadParser::GetDouble
double GetDouble()
Definition
lookaheadparser.cpp:188
LookaheadParser::SkipOut
void SkipOut(int depth)
Definition
lookaheadparser.cpp:230
LookaheadParser::EnterObject
bool EnterObject()
Definition
lookaheadparser.cpp:127
LookaheadParser::GetBool
bool GetBool()
Definition
lookaheadparser.cpp:199
document.h
Value
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition
document.h:2116
InsituStringStream
GenericInsituStringStream< UTF8< char > > InsituStringStream
Definition
fwd.h:54
Reader
GenericReader< UTF8< char >, UTF8< char >, CrtAllocator > Reader
Definition
fwd.h:90
RAPIDJSON_ASSERT
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition
rapidjson.h:411
key
const char * key
Definition
hmac_keccak.cpp:39
main
int main()
Definition
lookaheadparser.cpp:285
rapidjson
main RapidJSON namespace
std
STL namespace.
kFalseType
@ kFalseType
false
Definition
rapidjson.h:622
kObjectType
@ kObjectType
object
Definition
rapidjson.h:624
kTrueType
@ kTrueType
true
Definition
rapidjson.h:623
kStringType
@ kStringType
string
Definition
rapidjson.h:626
kNullType
@ kNullType
null
Definition
rapidjson.h:621
kArrayType
@ kArrayType
array
Definition
rapidjson.h:625
kNumberType
@ kNumberType
number
Definition
rapidjson.h:627
SizeType
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.).
Definition
rapidjson.h:389
reader.h
kParseInsituFlag
@ kParseInsituFlag
In-situ(destructive) parsing.
Definition
reader.h:147
kParseDefaultFlags
@ kParseDefaultFlags
Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS.
Definition
reader.h:156
int64_t
signed __int64 int64_t
Definition
stdint.h:135
uint64_t
unsigned __int64 uint64_t
Definition
stdint.h:136
json
rapidjson::Document json
Definition
transport.cpp:49
external
rapidjson
example
lookaheadparser
lookaheadparser.cpp
Generated on
for Electroneum by
1.17.0