filterkeydom.cpp
Go to the documentation of this file.
1 // JSON filterkey example which populates filtered SAX events into a Document.
2 
3 // This example parses JSON text from stdin with validation.
4 // During parsing, specified key will be filtered using a SAX handler.
5 // And finally the filtered events are used to populate a Document.
6 // As an example, the document is written to standard output.
7 
8 #include "rapidjson/document.h"
9 #include "rapidjson/writer.h"
12 #include "rapidjson/error/en.h"
13 #include <stack>
14 
15 using namespace rapidjson;
16 
17 // This handler forwards event into an output handler, with filtering the descendent events of specified key.
18 template <typename OutputHandler>
19 class FilterKeyHandler {
20 public:
21  typedef char Ch;
22 
23  FilterKeyHandler(OutputHandler& outputHandler, const Ch* keyString, SizeType keyLength) :
24  outputHandler_(outputHandler), keyString_(keyString), keyLength_(keyLength), filterValueDepth_(), filteredKeyCount_()
25  {}
26 
27  bool Null() { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Null() && EndValue(); }
28  bool Bool(bool b) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Bool(b) && EndValue(); }
29  bool Int(int i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int(i) && EndValue(); }
30  bool Uint(unsigned u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint(u) && EndValue(); }
31  bool Int64(int64_t i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int64(i) && EndValue(); }
32  bool Uint64(uint64_t u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint64(u) && EndValue(); }
33  bool Double(double d) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Double(d) && EndValue(); }
34  bool RawNumber(const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.RawNumber(str, len, copy) && EndValue(); }
35  bool String (const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.String (str, len, copy) && EndValue(); }
36 
37  bool StartObject() {
38  if (filterValueDepth_ > 0) {
39  filterValueDepth_++;
40  return true;
41  }
42  else {
43  filteredKeyCount_.push(0);
44  return outputHandler_.StartObject();
45  }
46  }
47 
48  bool Key(const Ch* str, SizeType len, bool copy) {
49  if (filterValueDepth_ > 0)
50  return true;
51  else if (len == keyLength_ && std::memcmp(str, keyString_, len) == 0) {
52  filterValueDepth_ = 1;
53  return true;
54  }
55  else {
56  ++filteredKeyCount_.top();
57  return outputHandler_.Key(str, len, copy);
58  }
59  }
60 
62  if (filterValueDepth_ > 0) {
63  filterValueDepth_--;
64  return EndValue();
65  }
66  else {
67  // Use our own filtered memberCount
68  SizeType memberCount = filteredKeyCount_.top();
69  filteredKeyCount_.pop();
70  return outputHandler_.EndObject(memberCount) && EndValue();
71  }
72  }
73 
74  bool StartArray() {
75  if (filterValueDepth_ > 0) {
76  filterValueDepth_++;
77  return true;
78  }
79  else
80  return outputHandler_.StartArray();
81  }
82 
83  bool EndArray(SizeType elementCount) {
84  if (filterValueDepth_ > 0) {
85  filterValueDepth_--;
86  return EndValue();
87  }
88  else
89  return outputHandler_.EndArray(elementCount) && EndValue();
90  }
91 
92 private:
94  FilterKeyHandler& operator=(const FilterKeyHandler&);
95 
96  bool EndValue() {
97  if (filterValueDepth_ == 1) // Just at the end of value after filtered key
98  filterValueDepth_ = 0;
99  return true;
100  }
101 
102  OutputHandler& outputHandler_;
103  const char* keyString_;
104  const SizeType keyLength_;
105  unsigned filterValueDepth_;
106  std::stack<SizeType> filteredKeyCount_;
107 };
108 
109 // Implements a generator for Document::Populate()
110 template <typename InputStream>
112 public:
113  typedef char Ch;
114 
115  FilterKeyReader(InputStream& is, const Ch* keyString, SizeType keyLength) :
116  is_(is), keyString_(keyString), keyLength_(keyLength), parseResult_()
117  {}
118 
119  // SAX event flow: reader -> filter -> handler
120  template <typename Handler>
121  bool operator()(Handler& handler) {
122  FilterKeyHandler<Handler> filter(handler, keyString_, keyLength_);
123  Reader reader;
124  parseResult_ = reader.Parse(is_, filter);
125  return parseResult_;
126  }
127 
128  const ParseResult& GetParseResult() const { return parseResult_; }
129 
130 private:
132  FilterKeyReader& operator=(const FilterKeyReader&);
133 
134  InputStream& is_;
135  const char* keyString_;
138 };
139 
140 int main(int argc, char* argv[]) {
141  if (argc != 2) {
142  fprintf(stderr, "filterkeydom key < input.json > output.json\n");
143  return 1;
144  }
145 
146  // Prepare input stream.
147  char readBuffer[65536];
148  FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
149 
150  // Prepare Filter
151  FilterKeyReader<FileReadStream> reader(is, argv[1], static_cast<SizeType>(strlen(argv[1])));
152 
153  // Populates the filtered events from reader
154  Document document;
155  document.Populate(reader);
156  ParseResult pr = reader.GetParseResult();
157  if (!pr) {
158  fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(pr.Offset()), GetParseError_En(pr.Code()));
159  return 1;
160  }
161 
162  // Prepare JSON writer and output stream.
163  char writeBuffer[65536];
164  FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
165  Writer<FileWriteStream> writer(os);
166 
167  // Write the document to standard output
168  document.Accept(writer);
169  return 0;
170 }
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition: reader.h:558
Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:389
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Definition: error.h:118
JSON writer.
Definition: fwd.h:95
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition: document.h:2210
bool String(const Ch *str, SizeType len, bool copy)
bool RawNumber(const Ch *str, SizeType len, bool copy)
Wrapper of C file stream for input using fread().
bool Bool(bool b)
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
const ParseResult & GetParseResult() const
bool Int64(int64_t i)
bool Key(const Ch *str, SizeType len, bool copy)
bool operator()(Handler &handler)
bool EndArray(SizeType elementCount)
bool Int(int i)
const char * keyString_
unsigned __int64 uint64_t
Definition: stdint.h:136
ParseErrorCode Code() const
Get the error code.
Definition: error.h:116
bool Uint64(uint64_t u)
bool Uint(unsigned u)
const SizeType keyLength_
main RapidJSON namespace
File byte stream for input using fread().
signed __int64 int64_t
Definition: stdint.h:135
bool Double(double d)
bool EndObject(SizeType)
RAPIDJSON_NAMESPACE_BEGIN const RAPIDJSON_ERROR_CHARTYPE * GetParseError_En(ParseErrorCode parseErrorCode)
Maps error code of parsing into error message.
Definition: en.h:36
ParseResult parseResult_
int main(int argc, char *argv[])
FilterKeyReader(InputStream &is, const Ch *keyString, SizeType keyLength)
InputStream & is_
FilterKeyHandler(OutputHandler &outputHandler, const Ch *keyString, SizeType keyLength)


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