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 10using namespace std; 11using namespace rapidjson; 12 13typedef map<string, string> MessageMap; 14 15#if defined(__GNUC__) 16RAPIDJSON_DIAG_PUSH 17RAPIDJSON_DIAG_OFF(effc++) 18#endif 19 20struct 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__) 63RAPIDJSON_DIAG_POP 64#endif 65 66void 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 80int 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