summaryrefslogtreecommitdiffstats
path: root/src/rapidjson/example/filterkey/filterkey.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rapidjson/example/filterkey/filterkey.cpp')
-rw-r--r--src/rapidjson/example/filterkey/filterkey.cpp135
1 files changed, 135 insertions, 0 deletions
diff --git a/src/rapidjson/example/filterkey/filterkey.cpp b/src/rapidjson/example/filterkey/filterkey.cpp
new file mode 100644
index 000000000..c34a050dc
--- /dev/null
+++ b/src/rapidjson/example/filterkey/filterkey.cpp
@@ -0,0 +1,135 @@
+// JSON filterkey example with SAX-style API.
+
+// This example parses JSON text from stdin with validation.
+// During parsing, specified key will be filtered using a SAX handler.
+// It re-output the JSON content to stdout without whitespace.
+
+#include "rapidjson/reader.h"
+#include "rapidjson/writer.h"
+#include "rapidjson/filereadstream.h"
+#include "rapidjson/filewritestream.h"
+#include "rapidjson/error/en.h"
+#include <stack>
+
+using namespace rapidjson;
+
+// This handler forwards event into an output handler, with filtering the descendent events of specified key.
+template <typename OutputHandler>
+class FilterKeyHandler {
+public:
+ typedef char Ch;
+
+ FilterKeyHandler(OutputHandler& outputHandler, const Ch* keyString, SizeType keyLength) :
+ outputHandler_(outputHandler), keyString_(keyString), keyLength_(keyLength), filterValueDepth_(), filteredKeyCount_()
+ {}
+
+ bool Null() { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Null() && EndValue(); }
+ bool Bool(bool b) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Bool(b) && EndValue(); }
+ bool Int(int i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int(i) && EndValue(); }
+ bool Uint(unsigned u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint(u) && EndValue(); }
+ bool Int64(int64_t i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int64(i) && EndValue(); }
+ bool Uint64(uint64_t u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint64(u) && EndValue(); }
+ bool Double(double d) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Double(d) && EndValue(); }
+ bool RawNumber(const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.RawNumber(str, len, copy) && EndValue(); }
+ bool String (const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.String (str, len, copy) && EndValue(); }
+
+ bool StartObject() {
+ if (filterValueDepth_ > 0) {
+ filterValueDepth_++;
+ return true;
+ }
+ else {
+ filteredKeyCount_.push(0);
+ return outputHandler_.StartObject();
+ }
+ }
+
+ bool Key(const Ch* str, SizeType len, bool copy) {
+ if (filterValueDepth_ > 0)
+ return true;
+ else if (len == keyLength_ && std::memcmp(str, keyString_, len) == 0) {
+ filterValueDepth_ = 1;
+ return true;
+ }
+ else {
+ ++filteredKeyCount_.top();
+ return outputHandler_.Key(str, len, copy);
+ }
+ }
+
+ bool EndObject(SizeType) {
+ if (filterValueDepth_ > 0) {
+ filterValueDepth_--;
+ return EndValue();
+ }
+ else {
+ // Use our own filtered memberCount
+ SizeType memberCount = filteredKeyCount_.top();
+ filteredKeyCount_.pop();
+ return outputHandler_.EndObject(memberCount) && EndValue();
+ }
+ }
+
+ bool StartArray() {
+ if (filterValueDepth_ > 0) {
+ filterValueDepth_++;
+ return true;
+ }
+ else
+ return outputHandler_.StartArray();
+ }
+
+ bool EndArray(SizeType elementCount) {
+ if (filterValueDepth_ > 0) {
+ filterValueDepth_--;
+ return EndValue();
+ }
+ else
+ return outputHandler_.EndArray(elementCount) && EndValue();
+ }
+
+private:
+ FilterKeyHandler(const FilterKeyHandler&);
+ FilterKeyHandler& operator=(const FilterKeyHandler&);
+
+ bool EndValue() {
+ if (filterValueDepth_ == 1) // Just at the end of value after filtered key
+ filterValueDepth_ = 0;
+ return true;
+ }
+
+ OutputHandler& outputHandler_;
+ const char* keyString_;
+ const SizeType keyLength_;
+ unsigned filterValueDepth_;
+ std::stack<SizeType> filteredKeyCount_;
+};
+
+int main(int argc, char* argv[]) {
+ if (argc != 2) {
+ fprintf(stderr, "filterkey key < input.json > output.json\n");
+ return 1;
+ }
+
+ // Prepare JSON reader and input stream.
+ Reader reader;
+ char readBuffer[65536];
+ FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
+
+ // Prepare JSON writer and output stream.
+ char writeBuffer[65536];
+ FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
+ Writer<FileWriteStream> writer(os);
+
+ // Prepare Filter
+ FilterKeyHandler<Writer<FileWriteStream> > filter(writer, argv[1], static_cast<SizeType>(strlen(argv[1])));
+
+ // JSON reader parse from the input stream, filter handler filters the events, and forward to writer.
+ // i.e. the events flow is: reader -> filter -> writer
+ if (!reader.Parse(is, filter)) {
+ fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
+ return 1;
+ }
+
+ return 0;
+}