rapidjson/example/messagereader/messagereader.cpp

106 lines
2.7 KiB
C++
Raw Normal View History

2014-07-13 01:17:38 +08:00
// 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_() {}
2014-07-13 01:17:38 +08:00
bool StartObject() {
switch (state_) {
case kExpectObjectStart:
state_ = kExpectNameOrObjectEnd;
return true;
default:
return false;
}
2014-07-13 01:17:38 +08:00
}
bool String(const char* str, SizeType length, bool) {
switch (state_) {
case kExpectNameOrObjectEnd:
2014-07-13 01:17:38 +08:00
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;
}
2014-07-13 01:17:38 +08:00
}
bool EndObject(SizeType) { return state_ == kExpectNameOrObjectEnd; }
bool Default() { return false; } // All other events are invalid.
2014-07-13 01:17:38 +08:00
MessageMap messages_;
2014-07-13 01:17:38 +08:00
enum State {
kExpectObjectStart,
kExpectNameOrObjectEnd,
2015-04-01 22:39:01 +02:00
kExpectValue
2014-07-13 01:17:38 +08:00
}state_;
std::string name_;
};
#if defined(__GNUC__)
RAPIDJSON_DIAG_POP
#endif
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
2015-12-18 18:34:04 +08:00
static void ParseMessages(const char* json, MessageMap& messages) {
2014-07-13 01:17:38 +08:00
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;
}
2014-07-13 01:17:38 +08:00
}
int main() {
MessageMap messages;
const char* json1 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\" }";
cout << json1 << endl;
2014-07-13 01:17:38 +08:00
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);
2014-07-13 01:17:38 +08:00
return 0;
}