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