Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
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
9#include "rapidjson/writer.h"
12#include "rapidjson/error/en.h"
13#include <stack>
14
15using namespace rapidjson;
16
17// This handler forwards event into an output handler, with filtering the descendent events of specified key.
18template <typename OutputHandler>
19class FilterKeyHandler {
20public:
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
92private:
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()
110template <typename InputStream>
112public:
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
130private:
132 FilterKeyReader& operator=(const FilterKeyReader&);
133
134 InputStream& is_;
135 const char* keyString_;
136 const SizeType keyLength_;
137 ParseResult parseResult_;
138};
139
140int 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));
166
167 // Write the document to standard output
168 document.Accept(writer);
169 return 0;
170}
File byte stream for input using fread().
Wrapper of C file stream for output using fwrite().
bool String(const Ch *str, SizeType len, bool copy)
bool EndObject(SizeType)
bool Bool(bool b)
bool Int64(int64_t i)
bool Uint64(uint64_t u)
bool Double(double d)
bool Key(const Ch *str, SizeType len, bool copy)
FilterKeyHandler(OutputHandler &outputHandler, const Ch *keyString, SizeType keyLength)
bool EndArray(SizeType elementCount)
bool RawNumber(const Ch *str, SizeType len, bool copy)
bool Uint(unsigned u)
const ParseResult & GetParseResult() const
FilterKeyReader(InputStream &is, const Ch *keyString, SizeType keyLength)
bool operator()(Handler &handler)
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition document.h:2239
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition reader.h:557
JSON writer.
Definition writer.h:89
Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...
os_t os
RAPIDJSON_NAMESPACE_BEGIN const RAPIDJSON_ERROR_CHARTYPE * GetParseError_En(ParseErrorCode parseErrorCode)
Maps error code of parsing into error message.
Definition en.h:36
char ** argv
main RapidJSON namespace
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition rapidjson.h:384
signed __int64 int64_t
Definition stdint.h:135
unsigned __int64 uint64_t
Definition stdint.h:136
Result of parsing (wraps ParseErrorCode)
Definition error.h:106
ParseErrorCode Code() const
Get the error code.
Definition error.h:116
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Definition error.h:118
CK_ULONG d
size_t len