fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / rapidjson-1.1.0 / example / filterkeydom / filterkeydom.cpp
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"
10 #include "rapidjson/filereadstream.h"
11 #include "rapidjson/filewritestream.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
61     bool EndObject(SizeType) {
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:
93     FilterKeyHandler(const FilterKeyHandler&);
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>
111 class FilterKeyReader {
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:
131     FilterKeyReader(const FilterKeyReader&);
132     FilterKeyReader& operator=(const FilterKeyReader&);
133
134     InputStream& is_;
135     const char* keyString_;
136     const SizeType keyLength_;
137     ParseResult parseResult_;
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 }