• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Reading a message JSON with Reader (SAX-style API).
2 // The JSON should be an object with key-string pairs.
3 
4 #include "rapidjson/reader.h"
5 #include "rapidjson/error/en.h"
6 #include <iostream>
7 #include <string>
8 #include <map>
9 
10 using namespace std;
11 using namespace rapidjson;
12 
13 typedef map<string, string> MessageMap;
14 
15 #if defined(__GNUC__)
16 RAPIDJSON_DIAG_PUSH
17 RAPIDJSON_DIAG_OFF(effc++)
18 #endif
19 
20 struct MessageHandler
21     : public BaseReaderHandler<UTF8<>, MessageHandler> {
MessageHandlerMessageHandler22     MessageHandler() : messages_(), state_(kExpectObjectStart), name_() {}
23 
StartObjectMessageHandler24     bool StartObject() {
25         switch (state_) {
26         case kExpectObjectStart:
27             state_ = kExpectNameOrObjectEnd;
28             return true;
29         default:
30             return false;
31         }
32     }
33 
StringMessageHandler34     bool String(const char* str, SizeType length, bool) {
35         switch (state_) {
36         case kExpectNameOrObjectEnd:
37             name_ = string(str, length);
38             state_ = kExpectValue;
39             return true;
40         case kExpectValue:
41             messages_.insert(MessageMap::value_type(name_, string(str, length)));
42             state_ = kExpectNameOrObjectEnd;
43             return true;
44         default:
45             return false;
46         }
47     }
48 
EndObjectMessageHandler49     bool EndObject(SizeType) { return state_ == kExpectNameOrObjectEnd; }
50 
DefaultMessageHandler51     bool Default() { return false; } // All other events are invalid.
52 
53     MessageMap messages_;
54     enum State {
55         kExpectObjectStart,
56         kExpectNameOrObjectEnd,
57         kExpectValue
58     }state_;
59     std::string name_;
60 };
61 
62 #if defined(__GNUC__)
63 RAPIDJSON_DIAG_POP
64 #endif
65 
ParseMessages(const char * json,MessageMap & messages)66 void ParseMessages(const char* json, MessageMap& messages) {
67     Reader reader;
68     MessageHandler handler;
69     StringStream ss(json);
70     if (reader.Parse(ss, handler))
71         messages.swap(handler.messages_);   // Only change it if success.
72     else {
73         ParseErrorCode e = reader.GetParseErrorCode();
74         size_t o = reader.GetErrorOffset();
75         cout << "Error: " << GetParseError_En(e) << endl;;
76         cout << " at offset " << o << " near '" << string(json).substr(o, 10) << "...'" << endl;
77     }
78 }
79 
main()80 int main() {
81     MessageMap messages;
82 
83     const char* json1 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\" }";
84     cout << json1 << endl;
85     ParseMessages(json1, messages);
86 
87     for (MessageMap::const_iterator itr = messages.begin(); itr != messages.end(); ++itr)
88         cout << itr->first << ": " << itr->second << endl;
89 
90     cout << endl << "Parse a JSON with invalid schema." << endl;
91     const char* json2 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\", \"foo\" : {} }";
92     cout << json2 << endl;
93     ParseMessages(json2, messages);
94 
95     return 0;
96 }
97