messagereader.cpp 2.8 KB

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