19
19
//
20
20
// After calling EnterObject, you retrieve keys via NextObjectKey() and values via
21
21
// the normal getters. When NextObjectKey() returns null, you have exited the
22
- // object, or you can call ExitObject () to skip to the end of the object
22
+ // object, or you can call SkipObject () to skip to the end of the object
23
23
// immediately. If you fetch the entire object (i.e. NextObjectKey() returned null),
24
- // you should not call ExitObject ().
24
+ // you should not call SkipObject ().
25
25
//
26
26
// After calling EnterArray(), you must alternate between calling NextArrayValue()
27
27
// to see if the array has more data, and then retrieving values via the normal
28
- // getters. You can call ExitArray () to skip to the end of the array immediately.
28
+ // getters. You can call SkipArray () to skip to the end of the array immediately.
29
29
// If you fetch the entire array (i.e. NextArrayValue() returned null),
30
- // you should not call ExitArray ().
30
+ // you should not call SkipArray ().
31
31
//
32
32
// This parser uses in-situ strings, so the JSON buffer will be altered during the
33
33
// parse.
@@ -37,15 +37,15 @@ using namespace rapidjson;
37
37
38
38
class LookaheadParserHandler {
39
39
public:
40
- bool Null () { st_ = kHasValue ; v_.SetNull (); return true ; }
41
- bool Bool (bool b) { st_ = kHasValue ; v_.SetBool (b); return true ; }
42
- bool Int (int i) { st_ = kHasValue ; v_.SetInt (i); return true ; }
43
- bool Uint (unsigned u) { st_ = kHasValue ; v_.SetUint (u); return true ; }
44
- bool Int64 (int64_t i) { st_ = kHasValue ; v_.SetInt64 (i); return true ; }
45
- bool Uint64 (uint64_t u) { st_ = kHasValue ; v_.SetUint64 (u); return true ; }
46
- bool Double (double d) { st_ = kHasValue ; v_.SetDouble (d); return true ; }
40
+ bool Null () { st_ = kHasNull ; v_.SetNull (); return true ; }
41
+ bool Bool (bool b) { st_ = kHasBool ; v_.SetBool (b); return true ; }
42
+ bool Int (int i) { st_ = kHasNumber ; v_.SetInt (i); return true ; }
43
+ bool Uint (unsigned u) { st_ = kHasNumber ; v_.SetUint (u); return true ; }
44
+ bool Int64 (int64_t i) { st_ = kHasNumber ; v_.SetInt64 (i); return true ; }
45
+ bool Uint64 (uint64_t u) { st_ = kHasNumber ; v_.SetUint64 (u); return true ; }
46
+ bool Double (double d) { st_ = kHasNumber ; v_.SetDouble (d); return true ; }
47
47
bool RawNumber (const char *, SizeType, bool ) { return false ; }
48
- bool String (const char * str, SizeType length, bool ) { st_ = kHasValue ; v_.SetString (str, length); return true ; }
48
+ bool String (const char * str, SizeType length, bool ) { st_ = kHasString ; v_.SetString (str, length); return true ; }
49
49
bool StartObject () { st_ = kEnteringObject ; return true ; }
50
50
bool Key (const char * str, SizeType length, bool ) { st_ = kHasKey ; v_.SetString (str, length); return true ; }
51
51
bool EndObject (SizeType) { st_ = kExitingObject ; return true ; }
@@ -59,7 +59,10 @@ class LookaheadParserHandler {
59
59
protected:
60
60
enum LookaheadParsingState {
61
61
kError ,
62
- kHasValue ,
62
+ kHasNull ,
63
+ kHasBool ,
64
+ kHasNumber ,
65
+ kHasString ,
63
66
kHasKey ,
64
67
kEnteringObject ,
65
68
kExitingObject ,
@@ -93,10 +96,8 @@ class LookaheadParser : protected LookaheadParserHandler {
93
96
public:
94
97
LookaheadParser (char * str) : LookaheadParserHandler(str) {}
95
98
96
- void EnterObject ();
97
- void EnterArray ();
98
- void ExitObject ();
99
- void ExitArray ();
99
+ bool EnterObject ();
100
+ bool EnterArray ();
100
101
const char * NextObjectKey ();
101
102
bool NextArrayValue ();
102
103
int GetInt ();
@@ -105,70 +106,87 @@ class LookaheadParser : protected LookaheadParserHandler {
105
106
bool GetBool ();
106
107
void GetNull ();
107
108
109
+ void SkipObject ();
110
+ void SkipArray ();
108
111
void SkipValue ();
109
112
Value* PeekValue ();
110
113
int PeekType (); // returns a rapidjson::Type, or -1 for no value (at end of object/array)
111
114
112
115
bool IsValid () { return st_ != kError ; }
116
+
117
+ protected:
118
+ void SkipOut (int depth);
113
119
};
114
120
115
- void LookaheadParser::EnterObject () {
121
+ bool LookaheadParser::EnterObject () {
116
122
if (st_ != kEnteringObject ) {
117
123
st_ = kError ;
118
- return ;
124
+ return false ;
119
125
}
120
126
121
127
ParseNext ();
128
+ return true ;
122
129
}
123
130
124
- void LookaheadParser::EnterArray () {
131
+ bool LookaheadParser::EnterArray () {
125
132
if (st_ != kEnteringArray ) {
126
133
st_ = kError ;
127
- return ;
134
+ return false ;
128
135
}
129
136
130
137
ParseNext ();
131
- }
132
-
133
- void LookaheadParser::ExitObject () {
134
- while (NextObjectKey ()) {
135
- SkipValue ();
136
- }
137
- }
138
-
139
- void LookaheadParser::ExitArray () {
140
- while (NextArrayValue ()) {
141
- SkipValue ();
142
- }
138
+ return true ;
143
139
}
144
140
145
141
const char * LookaheadParser::NextObjectKey () {
146
- if (st_ == kExitingObject ) {
147
- ParseNext ();
148
- return 0 ;
149
- }
150
-
151
- if (st_ != kHasKey || !v_.IsString ()) {
152
- st_ = kError ;
153
- return 0 ;
142
+ switch (st_) {
143
+ case kHasKey : {
144
+ const char * result = v_.GetString ();
145
+ ParseNext ();
146
+ return result;
147
+ }
148
+
149
+ case kExitingObject :
150
+ ParseNext ();
151
+ return 0 ;
152
+
153
+ case kError :
154
+ case kHasNull :
155
+ case kHasBool :
156
+ case kHasNumber :
157
+ case kHasString :
158
+ case kEnteringObject :
159
+ case kEnteringArray :
160
+ case kExitingArray :
161
+ st_ = kError ;
162
+ return 0 ;
154
163
}
155
-
156
- const char * result = v_.GetString ();
157
- ParseNext ();
158
- return result;
159
164
}
160
165
161
166
bool LookaheadParser::NextArrayValue () {
162
- if (st_ == kExitingArray ) {
163
- ParseNext ();
164
- return false ;
167
+ switch (st_) {
168
+ case kExitingArray :
169
+ ParseNext ();
170
+ return false ;
171
+
172
+ case kError :
173
+ case kExitingObject :
174
+ case kHasKey :
175
+ st_ = kError ;
176
+ return false ;
177
+
178
+ case kHasNull :
179
+ case kHasBool :
180
+ case kHasNumber :
181
+ case kHasString :
182
+ case kEnteringObject :
183
+ case kEnteringArray :
184
+ return true ;
165
185
}
166
-
167
- return true ;
168
186
}
169
187
170
188
int LookaheadParser::GetInt () {
171
- if (st_ != kHasValue || !v_.IsInt ()) {
189
+ if (st_ != kHasNumber || !v_.IsInt ()) {
172
190
st_ = kError ;
173
191
return 0 ;
174
192
}
@@ -179,7 +197,7 @@ int LookaheadParser::GetInt() {
179
197
}
180
198
181
199
double LookaheadParser::GetDouble () {
182
- if (st_ != kHasValue || !v_.IsNumber ()) {
200
+ if (st_ != kHasNumber || !v_.IsNumber ()) {
183
201
st_ = kError ;
184
202
return 0 .;
185
203
}
@@ -190,7 +208,7 @@ double LookaheadParser::GetDouble() {
190
208
}
191
209
192
210
bool LookaheadParser::GetBool () {
193
- if (st_ != kHasValue || !v_. IsBool () ) {
211
+ if (st_ != kHasBool ) {
194
212
st_ = kError ;
195
213
return false ;
196
214
}
@@ -201,7 +219,7 @@ bool LookaheadParser::GetBool() {
201
219
}
202
220
203
221
void LookaheadParser::GetNull () {
204
- if (st_ != kHasValue || !v_. IsNull () ) {
222
+ if (st_ != kHasNull ) {
205
223
st_ = kError ;
206
224
return ;
207
225
}
@@ -210,7 +228,7 @@ void LookaheadParser::GetNull() {
210
228
}
211
229
212
230
const char * LookaheadParser::GetString () {
213
- if (st_ != kHasValue || !v_. IsString () ) {
231
+ if (st_ != kHasString ) {
214
232
st_ = kError ;
215
233
return 0 ;
216
234
}
@@ -220,8 +238,7 @@ const char* LookaheadParser::GetString() {
220
238
return result;
221
239
}
222
240
223
- void LookaheadParser::SkipValue () {
224
- int depth = 0 ;
241
+ void LookaheadParser::SkipOut (int depth) {
225
242
do {
226
243
switch (st_) {
227
244
case kEnteringArray :
@@ -237,17 +254,32 @@ void LookaheadParser::SkipValue() {
237
254
case kError :
238
255
return ;
239
256
240
- case kHasKey :
241
- case kHasValue :
257
+ case kHasNull :
258
+ case kHasBool :
259
+ case kHasNumber :
260
+ case kHasString :
261
+ case kHasKey :
242
262
break ;
243
263
}
244
264
ParseNext ();
245
265
}
246
266
while (depth > 0 );
247
267
}
248
268
269
+ void LookaheadParser::SkipValue () {
270
+ SkipOut (0 );
271
+ }
272
+
273
+ void LookaheadParser::SkipArray () {
274
+ SkipOut (1 );
275
+ }
276
+
277
+ void LookaheadParser::SkipObject () {
278
+ SkipOut (1 );
279
+ }
280
+
249
281
Value* LookaheadParser::PeekValue () {
250
- if (st_ == kHasValue || st_ = = kHasKey ) {
282
+ if (st_ >= kHasNull && st_ < = kHasKey ) {
251
283
return &v_;
252
284
}
253
285
@@ -256,7 +288,10 @@ Value* LookaheadParser::PeekValue() {
256
288
257
289
int LookaheadParser::PeekType () {
258
290
switch (st_) {
259
- case kHasValue :
291
+ case kHasNull :
292
+ case kHasBool :
293
+ case kHasNumber :
294
+ case kHasString :
260
295
case kHasKey :
261
296
return v_.GetType ();
262
297
@@ -269,7 +304,6 @@ int LookaheadParser::PeekType() {
269
304
case kExitingArray :
270
305
case kExitingObject :
271
306
case kError :
272
- default :
273
307
return -1 ;
274
308
}
275
309
}
@@ -325,7 +359,7 @@ int main() {
325
359
cout << r.GetString () << " " ;
326
360
}
327
361
else {
328
- r.ExitArray ();
362
+ r.SkipArray ();
329
363
break ;
330
364
}
331
365
}
0 commit comments