filterkey.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // JSON filterkey example with SAX-style API.
  2. // This example parses JSON text from stdin with validation.
  3. // During parsing, specified key will be filtered using a SAX handler.
  4. // It re-output the JSON content to stdout without whitespace.
  5. #include <rtthread.h>
  6. #include "rapidjson/reader.h"
  7. #include "rapidjson/writer.h"
  8. #include "rapidjson/filereadstream.h"
  9. #include "rapidjson/filewritestream.h"
  10. #include "rapidjson/error/en.h"
  11. #include <stack>
  12. using namespace rapidjson;
  13. // This handler forwards event into an output handler, with filtering the descendent events of specified key.
  14. template <typename OutputHandler>
  15. class FilterKeyHandler {
  16. public:
  17. typedef char Ch;
  18. FilterKeyHandler(OutputHandler& outputHandler, const Ch* keyString, SizeType keyLength) :
  19. outputHandler_(outputHandler), keyString_(keyString), keyLength_(keyLength), filterValueDepth_(), filteredKeyCount_()
  20. {}
  21. bool Null() { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Null() && EndValue(); }
  22. bool Bool(bool b) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Bool(b) && EndValue(); }
  23. bool Int(int i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int(i) && EndValue(); }
  24. bool Uint(unsigned u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint(u) && EndValue(); }
  25. bool Int64(int64_t i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int64(i) && EndValue(); }
  26. bool Uint64(uint64_t u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint64(u) && EndValue(); }
  27. bool Double(double d) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Double(d) && EndValue(); }
  28. bool RawNumber(const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.RawNumber(str, len, copy) && EndValue(); }
  29. bool String (const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.String (str, len, copy) && EndValue(); }
  30. bool StartObject() {
  31. if (filterValueDepth_ > 0) {
  32. filterValueDepth_++;
  33. return true;
  34. }
  35. else {
  36. filteredKeyCount_.push(0);
  37. return outputHandler_.StartObject();
  38. }
  39. }
  40. bool Key(const Ch* str, SizeType len, bool copy) {
  41. if (filterValueDepth_ > 0)
  42. return true;
  43. else if (len == keyLength_ && std::memcmp(str, keyString_, len) == 0) {
  44. filterValueDepth_ = 1;
  45. return true;
  46. }
  47. else {
  48. ++filteredKeyCount_.top();
  49. return outputHandler_.Key(str, len, copy);
  50. }
  51. }
  52. bool EndObject(SizeType) {
  53. if (filterValueDepth_ > 0) {
  54. filterValueDepth_--;
  55. return EndValue();
  56. }
  57. else {
  58. // Use our own filtered memberCount
  59. SizeType memberCount = filteredKeyCount_.top();
  60. filteredKeyCount_.pop();
  61. return outputHandler_.EndObject(memberCount) && EndValue();
  62. }
  63. }
  64. bool StartArray() {
  65. if (filterValueDepth_ > 0) {
  66. filterValueDepth_++;
  67. return true;
  68. }
  69. else
  70. return outputHandler_.StartArray();
  71. }
  72. bool EndArray(SizeType elementCount) {
  73. if (filterValueDepth_ > 0) {
  74. filterValueDepth_--;
  75. return EndValue();
  76. }
  77. else
  78. return outputHandler_.EndArray(elementCount) && EndValue();
  79. }
  80. private:
  81. FilterKeyHandler(const FilterKeyHandler&);
  82. FilterKeyHandler& operator=(const FilterKeyHandler&);
  83. bool EndValue() {
  84. if (filterValueDepth_ == 1) // Just at the end of value after filtered key
  85. filterValueDepth_ = 0;
  86. return true;
  87. }
  88. OutputHandler& outputHandler_;
  89. const char* keyString_;
  90. const SizeType keyLength_;
  91. unsigned filterValueDepth_;
  92. std::stack<SizeType> filteredKeyCount_;
  93. };
  94. int filter_key(int argc, char* argv[]) {
  95. if (argc != 2) {
  96. fprintf(stderr, "filterkey key < input.json > output.json\n");
  97. return 1;
  98. }
  99. // Prepare JSON reader and input stream.
  100. Reader reader;
  101. char readBuffer[1024];
  102. FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
  103. // Prepare JSON writer and output stream.
  104. char writeBuffer[1024];
  105. FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
  106. Writer<FileWriteStream> writer(os);
  107. // Prepare Filter
  108. FilterKeyHandler<Writer<FileWriteStream> > filter(writer, argv[1], static_cast<SizeType>(strlen(argv[1])));
  109. // JSON reader parse from the input stream, filter handler filters the events, and forward to writer.
  110. // i.e. the events flow is: reader -> filter -> writer
  111. if (!reader.Parse(is, filter)) {
  112. fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
  113. return 1;
  114. }
  115. return 0;
  116. }
  117. MSH_CMD_EXPORT(filter_key, rapid json filter key example);