]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rapidjson/example/filterkey/filterkey.cpp
1 // JSON filterkey example with SAX-style API.
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.
7 #include "rapidjson/reader.h"
8 #include "rapidjson/writer.h"
9 #include "rapidjson/filereadstream.h"
10 #include "rapidjson/filewritestream.h"
11 #include "rapidjson/error/en.h"
14 using namespace rapidjson
;
16 // This handler forwards event into an output handler, with filtering the descendent events of specified key.
17 template <typename OutputHandler
>
18 class FilterKeyHandler
{
22 FilterKeyHandler(OutputHandler
& outputHandler
, const Ch
* keyString
, SizeType keyLength
) :
23 outputHandler_(outputHandler
), keyString_(keyString
), keyLength_(keyLength
), filterValueDepth_(), filteredKeyCount_()
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(); }
37 if (filterValueDepth_
> 0) {
42 filteredKeyCount_
.push(0);
43 return outputHandler_
.StartObject();
47 bool Key(const Ch
* str
, SizeType len
, bool copy
) {
48 if (filterValueDepth_
> 0)
50 else if (len
== keyLength_
&& std::memcmp(str
, keyString_
, len
) == 0) {
51 filterValueDepth_
= 1;
55 ++filteredKeyCount_
.top();
56 return outputHandler_
.Key(str
, len
, copy
);
60 bool EndObject(SizeType
) {
61 if (filterValueDepth_
> 0) {
66 // Use our own filtered memberCount
67 SizeType memberCount
= filteredKeyCount_
.top();
68 filteredKeyCount_
.pop();
69 return outputHandler_
.EndObject(memberCount
) && EndValue();
74 if (filterValueDepth_
> 0) {
79 return outputHandler_
.StartArray();
82 bool EndArray(SizeType elementCount
) {
83 if (filterValueDepth_
> 0) {
88 return outputHandler_
.EndArray(elementCount
) && EndValue();
92 FilterKeyHandler(const FilterKeyHandler
&);
93 FilterKeyHandler
& operator=(const FilterKeyHandler
&);
96 if (filterValueDepth_
== 1) // Just at the end of value after filtered key
97 filterValueDepth_
= 0;
101 OutputHandler
& outputHandler_
;
102 const char* keyString_
;
103 const SizeType keyLength_
;
104 unsigned filterValueDepth_
;
105 std::stack
<SizeType
> filteredKeyCount_
;
108 int main(int argc
, char* argv
[]) {
110 fprintf(stderr
, "filterkey key < input.json > output.json\n");
114 // Prepare JSON reader and input stream.
116 char readBuffer
[65536];
117 FileReadStream
is(stdin
, readBuffer
, sizeof(readBuffer
));
119 // Prepare JSON writer and output stream.
120 char writeBuffer
[65536];
121 FileWriteStream
os(stdout
, writeBuffer
, sizeof(writeBuffer
));
122 Writer
<FileWriteStream
> writer(os
);
125 FilterKeyHandler
<Writer
<FileWriteStream
> > filter(writer
, argv
[1], static_cast<SizeType
>(strlen(argv
[1])));
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()));