106 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// 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 <iostream>
 | 
						|
#include <string>
 | 
						|
#include <map>
 | 
						|
 | 
						|
using namespace std;
 | 
						|
using namespace rapidjson;
 | 
						|
 | 
						|
typedef map<string, string> 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<UTF8<>, 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;
 | 
						|
}
 |