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 
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:
76  kExitingArray
77  };
78 
83 
84  static const int parseFlags = kParseDefaultFlags | kParseInsituFlag;
85 };
86 
87 LookaheadParserHandler::LookaheadParserHandler(char* str) : v_(), st_(kInit), r_(), ss_(str) {
89  ParseNext();
90 }
91 
93  if (r_.HasParseError()) {
94  st_ = kError;
95  return;
96  }
97 
99 }
100 
102 public:
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 
128  if (st_ != kEnteringObject) {
129  st_ = kError;
130  return false;
131  }
132 
133  ParseNext();
134  return true;
135 }
136 
138  if (st_ != kEnteringArray) {
139  st_ = kError;
140  return false;
141  }
142 
143  ParseNext();
144  return true;
145 }
146 
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 
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 
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 
189  if (st_ != kHasNumber) {
190  st_ = kError;
191  return 0.;
192  }
193 
194  double result = v_.GetDouble();
195  ParseNext();
196  return result;
197 }
198 
200  if (st_ != kHasBool) {
201  st_ = kError;
202  return false;
203  }
204 
205  bool result = v_.GetBool();
206  ParseNext();
207  return result;
208 }
209 
211  if (st_ != kHasNull) {
212  st_ = kError;
213  return;
214  }
215 
216  ParseNext();
217 }
218 
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 
248  SkipOut(0);
249 }
250 
252  SkipOut(1);
253 }
254 
256  SkipOut(1);
257 }
258 
260  if (st_ >= kHasNull && st_ <= kHasKey) {
261  return &v_;
262  }
263 
264  return 0;
265 }
266 
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 
297 
298  r.EnterObject();
299  while (const char* key = r.NextObjectKey()) {
300  if (0 == strcmp(key, "hello")) {
302  cout << key << ":" << r.GetString() << endl;
303  }
304  else if (0 == strcmp(key, "t") || 0 == strcmp(key, "f")) {
306  cout << key << ":" << r.GetBool() << endl;
307  continue;
308  }
309  else if (0 == strcmp(key, "n")) {
311  r.GetNull();
312  cout << key << endl;
313  continue;
314  }
315  else if (0 == strcmp(key, "pi")) {
317  cout << key << ":" << r.GetDouble() << endl;
318  continue;
319  }
320  else if (0 == strcmp(key, "a")) {
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
int main()
bool RawNumber(const char *, SizeType, bool)
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:389
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:411
object
Definition: rapidjson.h:620
array
Definition: rapidjson.h:621
void SkipOut(int depth)
false
Definition: rapidjson.h:618
bool String(const char *str, SizeType length, bool)
LookaheadParsingState st_
Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS. ...
Definition: reader.h:158
string
Definition: rapidjson.h:622
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: reader.h:681
static const char json[]
const char * NextObjectKey()
LookaheadParser(char *str)
unsigned __int64 uint64_t
Definition: stdint.h:136
bool IterativeParseNext(InputStream &is, Handler &handler)
Parse one token from JSON text.
Definition: reader.h:619
number
Definition: rapidjson.h:623
main RapidJSON namespace
InsituStringStream ss_
signed __int64 int64_t
Definition: stdint.h:135
true
Definition: rapidjson.h:619
const char * GetString()
void IterativeParseInit()
Initialize JSON text token-by-token parsing.
Definition: reader.h:606
static const int parseFlags
bool Key(const char *str, SizeType length, bool)
In-situ(destructive) parsing.
Definition: reader.h:149
bool Uint64(uint64_t u)
null
Definition: rapidjson.h:617


choreo_rapidjson
Author(s):
autogenerated on Thu Jul 18 2019 03:59:09