diff options
Diffstat (limited to 'src/rapidjson/example/messagereader/messagereader.cpp')
-rw-r--r-- | src/rapidjson/example/messagereader/messagereader.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/rapidjson/example/messagereader/messagereader.cpp b/src/rapidjson/example/messagereader/messagereader.cpp new file mode 100644 index 000000000..3399bc940 --- /dev/null +++ b/src/rapidjson/example/messagereader/messagereader.cpp @@ -0,0 +1,105 @@ +// 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; +} |