]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rapidjson/example/filterkeydom/filterkeydom.cpp
1 // JSON filterkey example which populates filtered SAX events into a Document.
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.
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"
15 using namespace rapidjson
;
17 // This handler forwards event into an output handler, with filtering the descendent events of specified key.
18 template <typename OutputHandler
>
19 class FilterKeyHandler
{
23 FilterKeyHandler(OutputHandler
& outputHandler
, const Ch
* keyString
, SizeType keyLength
) :
24 outputHandler_(outputHandler
), keyString_(keyString
), keyLength_(keyLength
), filterValueDepth_(), filteredKeyCount_()
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(); }
38 if (filterValueDepth_
> 0) {
43 filteredKeyCount_
.push(0);
44 return outputHandler_
.StartObject();
48 bool Key(const Ch
* str
, SizeType len
, bool copy
) {
49 if (filterValueDepth_
> 0)
51 else if (len
== keyLength_
&& std::memcmp(str
, keyString_
, len
) == 0) {
52 filterValueDepth_
= 1;
56 ++filteredKeyCount_
.top();
57 return outputHandler_
.Key(str
, len
, copy
);
61 bool EndObject(SizeType
) {
62 if (filterValueDepth_
> 0) {
67 // Use our own filtered memberCount
68 SizeType memberCount
= filteredKeyCount_
.top();
69 filteredKeyCount_
.pop();
70 return outputHandler_
.EndObject(memberCount
) && EndValue();
75 if (filterValueDepth_
> 0) {
80 return outputHandler_
.StartArray();
83 bool EndArray(SizeType elementCount
) {
84 if (filterValueDepth_
> 0) {
89 return outputHandler_
.EndArray(elementCount
) && EndValue();
93 FilterKeyHandler(const FilterKeyHandler
&);
94 FilterKeyHandler
& operator=(const FilterKeyHandler
&);
97 if (filterValueDepth_
== 1) // Just at the end of value after filtered key
98 filterValueDepth_
= 0;
102 OutputHandler
& outputHandler_
;
103 const char* keyString_
;
104 const SizeType keyLength_
;
105 unsigned filterValueDepth_
;
106 std::stack
<SizeType
> filteredKeyCount_
;
109 // Implements a generator for Document::Populate()
110 template <typename InputStream
>
111 class FilterKeyReader
{
115 FilterKeyReader(InputStream
& is
, const Ch
* keyString
, SizeType keyLength
) :
116 is_(is
), keyString_(keyString
), keyLength_(keyLength
), parseResult_()
119 // SAX event flow: reader -> filter -> handler
120 template <typename Handler
>
121 bool operator()(Handler
& handler
) {
122 FilterKeyHandler
<Handler
> filter(handler
, keyString_
, keyLength_
);
124 parseResult_
= reader
.Parse(is_
, filter
);
128 const ParseResult
& GetParseResult() const { return parseResult_
; }
131 FilterKeyReader(const FilterKeyReader
&);
132 FilterKeyReader
& operator=(const FilterKeyReader
&);
135 const char* keyString_
;
136 const SizeType keyLength_
;
137 ParseResult parseResult_
;
140 int main(int argc
, char* argv
[]) {
142 fprintf(stderr
, "filterkeydom key < input.json > output.json\n");
146 // Prepare input stream.
147 char readBuffer
[65536];
148 FileReadStream
is(stdin
, readBuffer
, sizeof(readBuffer
));
151 FilterKeyReader
<FileReadStream
> reader(is
, argv
[1], static_cast<SizeType
>(strlen(argv
[1])));
153 // Populates the filtered events from reader
155 document
.Populate(reader
);
156 ParseResult pr
= reader
.GetParseResult();
158 fprintf(stderr
, "\nError(%u): %s\n", static_cast<unsigned>(pr
.Offset()), GetParseError_En(pr
.Code()));
162 // Prepare JSON writer and output stream.
163 char writeBuffer
[65536];
164 FileWriteStream
os(stdout
, writeBuffer
, sizeof(writeBuffer
));
165 Writer
<FileWriteStream
> writer(os
);
167 // Write the document to standard output
168 document
.Accept(writer
);