// Reading a message JSON with Reader (SAX-style API). // The JSON should be an object with key-string pairs. #include "rapidjson/reader.h" #include "rapidjson/error/en.h" #include #include #include using namespace std; using namespace rapidjson; typedef map MessageMap; #if defined(__GNUC__) RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_OFF(effc++) #endif #ifdef __clang__ RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_OFF(switch-enum) #endif struct MessageHandler : public BaseReaderHandler, MessageHandler> { MessageHandler() : messages_(), state_(kExpectObjectStart), name_() {} bool StartObject() { switch (state_) { case kExpectObjectStart: state_ = kExpectNameOrObjectEnd; return true; default: return false; } } bool String(const char* str, SizeType length, bool) { switch (state_) { case kExpectNameOrObjectEnd: name_ = string(str, length); state_ = kExpectValue; return true; case kExpectValue: messages_.insert(MessageMap::value_type(name_, string(str, length))); state_ = kExpectNameOrObjectEnd; return true; default: return false; } } bool EndObject(SizeType) { return state_ == kExpectNameOrObjectEnd; } bool Default() { return false; } // All other events are invalid. MessageMap messages_; enum State { kExpectObjectStart, kExpectNameOrObjectEnd, kExpectValue }state_; std::string name_; }; #if defined(__GNUC__) RAPIDJSON_DIAG_POP #endif #ifdef __clang__ RAPIDJSON_DIAG_POP #endif static void ParseMessages(const char* json, MessageMap& messages) { Reader reader; MessageHandler handler; StringStream ss(json); if (reader.Parse(ss, handler)) messages.swap(handler.messages_); // Only change it if success. else { ParseErrorCode e = reader.GetParseErrorCode(); size_t o = reader.GetErrorOffset(); cout << "Error: " << GetParseError_En(e) << endl;; cout << " at offset " << o << " near '" << string(json).substr(o, 10) << "...'" << endl; } } int main() { MessageMap messages; const char* json1 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\" }"; cout << json1 << endl; ParseMessages(json1, messages); for (MessageMap::const_iterator itr = messages.begin(); itr != messages.end(); ++itr) cout << itr->first << ": " << itr->second << endl; cout << endl << "Parse a JSON with invalid schema." << endl; const char* json2 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\", \"foo\" : {} }"; cout << json2 << endl; ParseMessages(json2, messages); return 0; }