filterkey.cpp
Go to the documentation of this file.
1 // JSON filterkey example with SAX-style API.
2 
3 // This example parses JSON text from stdin with validation.
4 // During parsing, specified key will be filtered using a SAX handler.
5 // It re-output the JSON content to stdout without whitespace.
6 
7 #include "rapidjson/reader.h"
8 #include "rapidjson/writer.h"
11 #include "rapidjson/error/en.h"
12 #include <stack>
13 
14 using namespace rapidjson;
15 
16 // This handler forwards event into an output handler, with filtering the descendent events of specified key.
17 template <typename OutputHandler>
19 public:
20  typedef char Ch;
21 
22  FilterKeyHandler(OutputHandler& outputHandler, const Ch* keyString, SizeType keyLength) :
23  outputHandler_(outputHandler), keyString_(keyString), keyLength_(keyLength), filterValueDepth_(), filteredKeyCount_()
24  {}
25 
26  bool Null() { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Null() && EndValue(); }
27  bool Bool(bool b) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Bool(b) && EndValue(); }
28  bool Int(int i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int(i) && EndValue(); }
29  bool Uint(unsigned u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint(u) && EndValue(); }
30  bool Int64(int64_t i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int64(i) && EndValue(); }
31  bool Uint64(uint64_t u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint64(u) && EndValue(); }
32  bool Double(double d) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Double(d) && EndValue(); }
33  bool RawNumber(const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.RawNumber(str, len, copy) && EndValue(); }
34  bool String (const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.String (str, len, copy) && EndValue(); }
35 
36  bool StartObject() {
37  if (filterValueDepth_ > 0) {
38  filterValueDepth_++;
39  return true;
40  }
41  else {
42  filteredKeyCount_.push(0);
43  return outputHandler_.StartObject();
44  }
45  }
46 
47  bool Key(const Ch* str, SizeType len, bool copy) {
48  if (filterValueDepth_ > 0)
49  return true;
50  else if (len == keyLength_ && std::memcmp(str, keyString_, len) == 0) {
51  filterValueDepth_ = 1;
52  return true;
53  }
54  else {
55  ++filteredKeyCount_.top();
56  return outputHandler_.Key(str, len, copy);
57  }
58  }
59 
61  if (filterValueDepth_ > 0) {
62  filterValueDepth_--;
63  return EndValue();
64  }
65  else {
66  // Use our own filtered memberCount
67  SizeType memberCount = filteredKeyCount_.top();
68  filteredKeyCount_.pop();
69  return outputHandler_.EndObject(memberCount) && EndValue();
70  }
71  }
72 
73  bool StartArray() {
74  if (filterValueDepth_ > 0) {
75  filterValueDepth_++;
76  return true;
77  }
78  else
79  return outputHandler_.StartArray();
80  }
81 
82  bool EndArray(SizeType elementCount) {
83  if (filterValueDepth_ > 0) {
84  filterValueDepth_--;
85  return EndValue();
86  }
87  else
88  return outputHandler_.EndArray(elementCount) && EndValue();
89  }
90 
91 private:
93  FilterKeyHandler& operator=(const FilterKeyHandler&);
94 
95  bool EndValue() {
96  if (filterValueDepth_ == 1) // Just at the end of value after filtered key
97  filterValueDepth_ = 0;
98  return true;
99  }
100 
101  OutputHandler& outputHandler_;
102  const char* keyString_;
105  std::stack<SizeType> filteredKeyCount_;
106 };
107 
108 int main(int argc, char* argv[]) {
109  if (argc != 2) {
110  fprintf(stderr, "filterkey key < input.json > output.json\n");
111  return 1;
112  }
113 
114  // Prepare JSON reader and input stream.
115  Reader reader;
116  char readBuffer[65536];
117  FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
118 
119  // Prepare JSON writer and output stream.
120  char writeBuffer[65536];
121  FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
122  Writer<FileWriteStream> writer(os);
123 
124  // Prepare Filter
125  FilterKeyHandler<Writer<FileWriteStream> > filter(writer, argv[1], static_cast<SizeType>(strlen(argv[1])));
126 
127  // JSON reader parse from the input stream, filter handler filters the events, and forward to writer.
128  // i.e. the events flow is: reader -> filter -> writer
129  if (!reader.Parse(is, filter)) {
130  fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
131  return 1;
132  }
133 
134  return 0;
135 }
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition: reader.h:558
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:389
std::stack< SizeType > filteredKeyCount_
Definition: filterkey.cpp:105
JSON writer.
Definition: fwd.h:95
ParseErrorCode GetParseErrorCode() const
Get the ParseErrorCode of last parsing.
Definition: reader.h:684
bool String(const Ch *str, SizeType len, bool copy)
Definition: filterkey.cpp:34
bool RawNumber(const Ch *str, SizeType len, bool copy)
Definition: filterkey.cpp:33
Wrapper of C file stream for input using fread().
bool Bool(bool b)
Definition: filterkey.cpp:27
int main(int argc, char *argv[])
Definition: filterkey.cpp:108
bool Int64(int64_t i)
Definition: filterkey.cpp:30
bool Key(const Ch *str, SizeType len, bool copy)
Definition: filterkey.cpp:47
bool EndArray(SizeType elementCount)
Definition: filterkey.cpp:82
bool Int(int i)
Definition: filterkey.cpp:28
const SizeType keyLength_
Definition: filterkey.cpp:103
unsigned __int64 uint64_t
Definition: stdint.h:136
bool Uint64(uint64_t u)
Definition: filterkey.cpp:31
bool Uint(unsigned u)
Definition: filterkey.cpp:29
main RapidJSON namespace
const char * keyString_
Definition: filterkey.cpp:102
File byte stream for input using fread().
signed __int64 int64_t
Definition: stdint.h:135
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: reader.h:687
bool Double(double d)
Definition: filterkey.cpp:32
unsigned filterValueDepth_
Definition: filterkey.cpp:104
bool StartObject()
Definition: filterkey.cpp:36
OutputHandler & outputHandler_
Definition: filterkey.cpp:101
bool EndObject(SizeType)
Definition: filterkey.cpp:60
RAPIDJSON_NAMESPACE_BEGIN const RAPIDJSON_ERROR_CHARTYPE * GetParseError_En(ParseErrorCode parseErrorCode)
Maps error code of parsing into error message.
Definition: en.h:36
FilterKeyHandler(OutputHandler &outputHandler, const Ch *keyString, SizeType keyLength)
Definition: filterkey.cpp:22


choreo_rapidjson
Author(s):
autogenerated on Thu Jul 18 2019 03:59:09