Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/miloyip/rapidjson.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilo Yip <miloyip@gmail.com>2016-04-23 11:02:40 +0300
committerMilo Yip <miloyip@gmail.com>2016-04-23 11:02:40 +0300
commit05b2ed7532bcaa17f0e2794a7fab67155d3e5cd3 (patch)
tree16a1f89bb79eb0a926147fd1f6f7846d3ca725ce /example
parent96ca84798fd546b0d1a22e24c5efde666a6c36c1 (diff)
Add filterkey and filterkeydom examples
Diffstat (limited to 'example')
-rw-r--r--example/CMakeLists.txt2
-rw-r--r--example/filterkey/filterkey.cpp130
-rw-r--r--example/filterkeydom/filterkeydom.cpp161
3 files changed, 293 insertions, 0 deletions
diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt
index fd0e6eb5..4d448ccc 100644
--- a/example/CMakeLists.txt
+++ b/example/CMakeLists.txt
@@ -7,6 +7,8 @@ endif()
set(EXAMPLES
capitalize
condense
+ filterkey
+ filterkeydom
jsonx
messagereader
parsebyparts
diff --git a/example/filterkey/filterkey.cpp b/example/filterkey/filterkey.cpp
new file mode 100644
index 00000000..14163625
--- /dev/null
+++ b/example/filterkey/filterkey.cpp
@@ -0,0 +1,130 @@
+// 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>
+struct FilterKeyHandler {
+ 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();
+ }
+
+ 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;
+}
diff --git a/example/filterkeydom/filterkeydom.cpp b/example/filterkeydom/filterkeydom.cpp
new file mode 100644
index 00000000..aba50bd0
--- /dev/null
+++ b/example/filterkeydom/filterkeydom.cpp
@@ -0,0 +1,161 @@
+// JSON filterkey example which populates filtered SAX events into a Document.
+
+// This example parses JSON text from stdin with validation.
+// During parsing, specified key will be filtered using a SAX handler.
+// And finally the filtered events are used to populate a Document.
+// As an example, the document is written to standard output.
+
+#include "rapidjson/document.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>
+struct FilterKeyHandler {
+ 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();
+ }
+
+ 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_;
+};
+
+// Implements a generator for Document::Populate()
+template <typename InputStream>
+class FilterKeyReader {
+public:
+ typedef char Ch;
+
+ FilterKeyReader(InputStream& is, const Ch* keyString, SizeType keyLength) :
+ is_(is), keyString_(keyString), keyLength_(keyLength)
+ {}
+
+ // SAX event flow: reader -> filter -> handler
+ template <typename Handler>
+ bool operator()(Handler& handler) {
+ FilterKeyHandler<Handler> filter(handler, keyString_, keyLength_);
+ Reader reader;
+ return parseResult_ = reader.Parse(is_, filter);
+ }
+
+ const ParseResult& GetParseResult() const { return parseResult_; }
+
+private:
+ InputStream& is_;
+ const char* keyString_;
+ const SizeType keyLength_;
+ ParseResult parseResult_;
+};
+
+int main(int argc, char* argv[]) {
+ if (argc != 2) {
+ fprintf(stderr, "filterkeydom key < input.json > output.json\n");
+ return 1;
+ }
+
+ // Prepare input stream.
+ char readBuffer[65536];
+ FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
+
+ // Prepare Filter
+ FilterKeyReader<FileReadStream> reader(is, argv[1], static_cast<SizeType>(strlen(argv[1])));
+
+ // Populates the filtered events from reader
+ Document document;
+ document.Populate(reader);
+ ParseResult pr = reader.GetParseResult();
+ if (!pr) {
+ fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(pr.Offset()), GetParseError_En(pr.Code()));
+ return 1;
+ }
+
+ // Prepare JSON writer and output stream.
+ char writeBuffer[65536];
+ FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
+ Writer<FileWriteStream> writer(os);
+
+ // Write the document to standard output
+ document.Accept(writer);
+ return 0;
+}