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> { 22 MessageHandler() : messages_(), state_(kExpectObjectStart), name_() {} 23 24 bool StartObject() { 25 switch (state_) { 26 case kExpectObjectStart: 27 state_ = kExpectNameOrObjectEnd; 28 return true; 29 default: 30 return false; 31 } 32 } 33 34 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 49 bool EndObject(SizeType) { return state_ == kExpectNameOrObjectEnd; } 50 51 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 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 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