messagereader.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // Reading a message JSON with Reader (SAX-style API).
  2. // The JSON should be an object with key-string pairs.
  3. #include "rapidjson/reader.h"
  4. #include "rapidjson/error/en.h"
  5. #include <iostream>
  6. #include <string>
  7. #include <map>
  8. using namespace std;
  9. using namespace rapidjson;
  10. typedef map<string, string> MessageMap;
  11. #if defined(__GNUC__)
  12. RAPIDJSON_DIAG_PUSH
  13. RAPIDJSON_DIAG_OFF(effc++)
  14. #endif
  15. #ifdef __clang__
  16. RAPIDJSON_DIAG_PUSH
  17. RAPIDJSON_DIAG_OFF(switch-enum)
  18. #endif
  19. struct MessageHandler
  20. : public BaseReaderHandler<UTF8<>, MessageHandler> {
  21. MessageHandler() : messages_(), state_(kExpectObjectStart), name_() {}
  22. bool StartObject() {
  23. switch (state_) {
  24. case kExpectObjectStart:
  25. state_ = kExpectNameOrObjectEnd;
  26. return true;
  27. default:
  28. return false;
  29. }
  30. }
  31. bool String(const char* str, SizeType length, bool) {
  32. switch (state_) {
  33. case kExpectNameOrObjectEnd:
  34. name_ = string(str, length);
  35. state_ = kExpectValue;
  36. return true;
  37. case kExpectValue:
  38. messages_.insert(MessageMap::value_type(name_, string(str, length)));
  39. state_ = kExpectNameOrObjectEnd;
  40. return true;
  41. default:
  42. return false;
  43. }
  44. }
  45. bool EndObject(SizeType) { return state_ == kExpectNameOrObjectEnd; }
  46. bool Default() { return false; } // All other events are invalid.
  47. MessageMap messages_;
  48. enum State {
  49. kExpectObjectStart,
  50. kExpectNameOrObjectEnd,
  51. kExpectValue
  52. }state_;
  53. std::string name_;
  54. };
  55. #if defined(__GNUC__)
  56. RAPIDJSON_DIAG_POP
  57. #endif
  58. #ifdef __clang__
  59. RAPIDJSON_DIAG_POP
  60. #endif
  61. static void ParseMessages(const char* json, MessageMap& messages) {
  62. Reader reader;
  63. MessageHandler handler;
  64. StringStream ss(json);
  65. if (reader.Parse(ss, handler))
  66. messages.swap(handler.messages_); // Only change it if success.
  67. else {
  68. ParseErrorCode e = reader.GetParseErrorCode();
  69. size_t o = reader.GetErrorOffset();
  70. cout << "Error: " << GetParseError_En(e) << endl;;
  71. cout << " at offset " << o << " near '" << string(json).substr(o, 10) << "...'" << endl;
  72. }
  73. }
  74. int main() {
  75. MessageMap messages;
  76. const char* json1 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\" }";
  77. cout << json1 << endl;
  78. ParseMessages(json1, messages);
  79. for (MessageMap::const_iterator itr = messages.begin(); itr != messages.end(); ++itr)
  80. cout << itr->first << ": " << itr->second << endl;
  81. cout << endl << "Parse a JSON with invalid schema." << endl;
  82. const char* json2 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\", \"foo\" : {} }";
  83. cout << json2 << endl;
  84. ParseMessages(json2, messages);
  85. return 0;
  86. }