summaryrefslogtreecommitdiffstats
path: root/src/rapidjson/example
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/rapidjson/example/CMakeLists.txt42
-rw-r--r--src/rapidjson/example/capitalize/capitalize.cpp67
-rw-r--r--src/rapidjson/example/condense/condense.cpp32
-rw-r--r--src/rapidjson/example/filterkey/filterkey.cpp135
-rw-r--r--src/rapidjson/example/filterkeydom/filterkeydom.cpp170
-rw-r--r--src/rapidjson/example/jsonx/jsonx.cpp207
-rw-r--r--src/rapidjson/example/messagereader/messagereader.cpp105
-rw-r--r--src/rapidjson/example/parsebyparts/parsebyparts.cpp173
-rw-r--r--src/rapidjson/example/pretty/pretty.cpp30
-rw-r--r--src/rapidjson/example/prettyauto/prettyauto.cpp56
-rw-r--r--src/rapidjson/example/schemavalidator/schemavalidator.cpp72
-rw-r--r--src/rapidjson/example/serialize/serialize.cpp173
-rw-r--r--src/rapidjson/example/simpledom/simpledom.cpp29
-rw-r--r--src/rapidjson/example/simplereader/simplereader.cpp42
-rw-r--r--src/rapidjson/example/simplewriter/simplewriter.cpp36
-rw-r--r--src/rapidjson/example/tutorial/tutorial.cpp151
16 files changed, 1520 insertions, 0 deletions
diff --git a/src/rapidjson/example/CMakeLists.txt b/src/rapidjson/example/CMakeLists.txt
new file mode 100644
index 000000000..4d448ccc0
--- /dev/null
+++ b/src/rapidjson/example/CMakeLists.txt
@@ -0,0 +1,42 @@
+cmake_minimum_required(VERSION 2.8)
+
+if(POLICY CMP0054)
+ cmake_policy(SET CMP0054 NEW)
+endif()
+
+set(EXAMPLES
+ capitalize
+ condense
+ filterkey
+ filterkeydom
+ jsonx
+ messagereader
+ parsebyparts
+ pretty
+ prettyauto
+ schemavalidator
+ serialize
+ simpledom
+ simplereader
+ simplewriter
+ tutorial)
+
+include_directories("../include/")
+
+add_definitions(-D__STDC_FORMAT_MACROS)
+
+if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -Werror -Wall -Wextra -Weffc++ -Wswitch-default")
+elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough -Weverything")
+endif()
+
+foreach (example ${EXAMPLES})
+ add_executable(${example} ${example}/${example}.cpp)
+endforeach()
+
+if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ target_link_libraries(parsebyparts pthread)
+endif()
+
+add_custom_target(examples ALL DEPENDS ${EXAMPLES})
diff --git a/src/rapidjson/example/capitalize/capitalize.cpp b/src/rapidjson/example/capitalize/capitalize.cpp
new file mode 100644
index 000000000..7da37e9c5
--- /dev/null
+++ b/src/rapidjson/example/capitalize/capitalize.cpp
@@ -0,0 +1,67 @@
+// JSON condenser example
+
+// This example parses JSON from stdin with validation,
+// and re-output the JSON content to stdout with all string capitalized, and without whitespace.
+
+#include "rapidjson/reader.h"
+#include "rapidjson/writer.h"
+#include "rapidjson/filereadstream.h"
+#include "rapidjson/filewritestream.h"
+#include "rapidjson/error/en.h"
+#include <vector>
+#include <cctype>
+
+using namespace rapidjson;
+
+template<typename OutputHandler>
+struct CapitalizeFilter {
+ CapitalizeFilter(OutputHandler& out) : out_(out), buffer_() {}
+
+ bool Null() { return out_.Null(); }
+ bool Bool(bool b) { return out_.Bool(b); }
+ bool Int(int i) { return out_.Int(i); }
+ bool Uint(unsigned u) { return out_.Uint(u); }
+ bool Int64(int64_t i) { return out_.Int64(i); }
+ bool Uint64(uint64_t u) { return out_.Uint64(u); }
+ bool Double(double d) { return out_.Double(d); }
+ bool RawNumber(const char* str, SizeType length, bool copy) { return out_.RawNumber(str, length, copy); }
+ bool String(const char* str, SizeType length, bool) {
+ buffer_.clear();
+ for (SizeType i = 0; i < length; i++)
+ buffer_.push_back(static_cast<char>(std::toupper(str[i])));
+ return out_.String(&buffer_.front(), length, true); // true = output handler need to copy the string
+ }
+ bool StartObject() { return out_.StartObject(); }
+ bool Key(const char* str, SizeType length, bool copy) { return String(str, length, copy); }
+ bool EndObject(SizeType memberCount) { return out_.EndObject(memberCount); }
+ bool StartArray() { return out_.StartArray(); }
+ bool EndArray(SizeType elementCount) { return out_.EndArray(elementCount); }
+
+ OutputHandler& out_;
+ std::vector<char> buffer_;
+
+private:
+ CapitalizeFilter(const CapitalizeFilter&);
+ CapitalizeFilter& operator=(const CapitalizeFilter&);
+};
+
+int main(int, char*[]) {
+ // 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);
+
+ // JSON reader parse from the input stream and let writer generate the output.
+ CapitalizeFilter<Writer<FileWriteStream> > 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/src/rapidjson/example/condense/condense.cpp b/src/rapidjson/example/condense/condense.cpp
new file mode 100644
index 000000000..46dc35043
--- /dev/null
+++ b/src/rapidjson/example/condense/condense.cpp
@@ -0,0 +1,32 @@
+// JSON condenser example
+
+// This example parses JSON text from stdin with validation,
+// and 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"
+
+using namespace rapidjson;
+
+int main(int, char*[]) {
+ // 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);
+
+ // JSON reader parse from the input stream and let writer generate the output.
+ if (!reader.Parse(is, writer)) {
+ fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
+ return 1;
+ }
+
+ return 0;
+}
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;
+}
diff --git a/src/rapidjson/example/filterkeydom/filterkeydom.cpp b/src/rapidjson/example/filterkeydom/filterkeydom.cpp
new file mode 100644
index 000000000..732cc81f1
--- /dev/null
+++ b/src/rapidjson/example/filterkeydom/filterkeydom.cpp
@@ -0,0 +1,170 @@
+// 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>
+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_;
+};
+
+// 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), parseResult_()
+ {}
+
+ // SAX event flow: reader -> filter -> handler
+ template <typename Handler>
+ bool operator()(Handler& handler) {
+ FilterKeyHandler<Handler> filter(handler, keyString_, keyLength_);
+ Reader reader;
+ parseResult_ = reader.Parse(is_, filter);
+ return parseResult_;
+ }
+
+ const ParseResult& GetParseResult() const { return parseResult_; }
+
+private:
+ FilterKeyReader(const FilterKeyReader&);
+ FilterKeyReader& operator=(const FilterKeyReader&);
+
+ 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;
+}
diff --git a/src/rapidjson/example/jsonx/jsonx.cpp b/src/rapidjson/example/jsonx/jsonx.cpp
new file mode 100644
index 000000000..1346b578c
--- /dev/null
+++ b/src/rapidjson/example/jsonx/jsonx.cpp
@@ -0,0 +1,207 @@
+// JSON to JSONx conversion exmaple, using SAX API.
+// JSONx is an IBM standard format to represent JSON as XML.
+// https://www-01.ibm.com/support/knowledgecenter/SS9H2Y_7.1.0/com.ibm.dp.doc/json_jsonx.html
+// This example parses JSON text from stdin with validation,
+// and convert to JSONx format to stdout.
+// Need compile with -D__STDC_FORMAT_MACROS for defining PRId64 and PRIu64 macros.
+
+#include "rapidjson/reader.h"
+#include "rapidjson/stringbuffer.h"
+#include "rapidjson/filereadstream.h"
+#include "rapidjson/filewritestream.h"
+#include "rapidjson/error/en.h"
+#include <cstdio>
+
+using namespace rapidjson;
+
+// For simplicity, this example only read/write in UTF-8 encoding
+template <typename OutputStream>
+class JsonxWriter {
+public:
+ JsonxWriter(OutputStream& os) : os_(os), name_(), level_(0), hasName_(false) {
+ }
+
+ bool Null() {
+ return WriteStartElement("null", true);
+ }
+
+ bool Bool(bool b) {
+ return
+ WriteStartElement("boolean") &&
+ WriteString(b ? "true" : "false") &&
+ WriteEndElement("boolean");
+ }
+
+ bool Int(int i) {
+ char buffer[12];
+ return WriteNumberElement(buffer, sprintf(buffer, "%d", i));
+ }
+
+ bool Uint(unsigned i) {
+ char buffer[11];
+ return WriteNumberElement(buffer, sprintf(buffer, "%u", i));
+ }
+
+ bool Int64(int64_t i) {
+ char buffer[21];
+ return WriteNumberElement(buffer, sprintf(buffer, "%" PRId64, i));
+ }
+
+ bool Uint64(uint64_t i) {
+ char buffer[21];
+ return WriteNumberElement(buffer, sprintf(buffer, "%" PRIu64, i));
+ }
+
+ bool Double(double d) {
+ char buffer[30];
+ return WriteNumberElement(buffer, sprintf(buffer, "%.17g", d));
+ }
+
+ bool RawNumber(const char* str, SizeType length, bool) {
+ return
+ WriteStartElement("number") &&
+ WriteEscapedText(str, length) &&
+ WriteEndElement("number");
+ }
+
+ bool String(const char* str, SizeType length, bool) {
+ return
+ WriteStartElement("string") &&
+ WriteEscapedText(str, length) &&
+ WriteEndElement("string");
+ }
+
+ bool StartObject() {
+ return WriteStartElement("object");
+ }
+
+ bool Key(const char* str, SizeType length, bool) {
+ // backup key to name_
+ name_.Clear();
+ for (SizeType i = 0; i < length; i++)
+ name_.Put(str[i]);
+ hasName_ = true;
+ return true;
+ }
+
+ bool EndObject(SizeType) {
+ return WriteEndElement("object");
+ }
+
+ bool StartArray() {
+ return WriteStartElement("array");
+ }
+
+ bool EndArray(SizeType) {
+ return WriteEndElement("array");
+ }
+
+private:
+ bool WriteString(const char* s) {
+ while (*s)
+ os_.Put(*s++);
+ return true;
+ }
+
+ bool WriteEscapedAttributeValue(const char* s, size_t length) {
+ for (size_t i = 0; i < length; i++) {
+ switch (s[i]) {
+ case '&': WriteString("&amp;"); break;
+ case '<': WriteString("&lt;"); break;
+ case '"': WriteString("&quot;"); break;
+ default: os_.Put(s[i]); break;
+ }
+ }
+ return true;
+ }
+
+ bool WriteEscapedText(const char* s, size_t length) {
+ for (size_t i = 0; i < length; i++) {
+ switch (s[i]) {
+ case '&': WriteString("&amp;"); break;
+ case '<': WriteString("&lt;"); break;
+ default: os_.Put(s[i]); break;
+ }
+ }
+ return true;
+ }
+
+ bool WriteStartElement(const char* type, bool emptyElement = false) {
+ if (level_ == 0)
+ if (!WriteString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"))
+ return false;
+
+ if (!WriteString("<json:") || !WriteString(type))
+ return false;
+
+ // For root element, need to add declarations
+ if (level_ == 0) {
+ if (!WriteString(
+ " xsi:schemaLocation=\"http://www.datapower.com/schemas/json jsonx.xsd\""
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ " xmlns:json=\"http://www.ibm.com/xmlns/prod/2009/jsonx\""))
+ return false;
+ }
+
+ if (hasName_) {
+ hasName_ = false;
+ if (!WriteString(" name=\"") ||
+ !WriteEscapedAttributeValue(name_.GetString(), name_.GetSize()) ||
+ !WriteString("\""))
+ return false;
+ }
+
+ if (emptyElement)
+ return WriteString("/>");
+ else {
+ level_++;
+ return WriteString(">");
+ }
+ }
+
+ bool WriteEndElement(const char* type) {
+ if (!WriteString("</json:") ||
+ !WriteString(type) ||
+ !WriteString(">"))
+ return false;
+
+ // For the last end tag, flush the output stream.
+ if (--level_ == 0)
+ os_.Flush();
+
+ return true;
+ }
+
+ bool WriteNumberElement(const char* buffer, int length) {
+ if (!WriteStartElement("number"))
+ return false;
+ for (int j = 0; j < length; j++)
+ os_.Put(buffer[j]);
+ return WriteEndElement("number");
+ }
+
+ OutputStream& os_;
+ StringBuffer name_;
+ unsigned level_;
+ bool hasName_;
+};
+
+int main(int, char*[]) {
+ // 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));
+ JsonxWriter<FileWriteStream> writer(os);
+
+ // JSON reader parse from the input stream and let writer generate the output.
+ if (!reader.Parse(is, writer)) {
+ fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/src/rapidjson/example/messagereader/messagereader.cpp b/src/rapidjson/example/messagereader/messagereader.cpp
new file mode 100644
index 000000000..3399bc940
--- /dev/null
+++ b/src/rapidjson/example/messagereader/messagereader.cpp
@@ -0,0 +1,105 @@
+// Reading a message JSON with Reader (SAX-style API).
+// The JSON should be an object with key-string pairs.
+
+#include "rapidjson/reader.h"
+#include "rapidjson/error/en.h"
+#include <iostream>
+#include <string>
+#include <map>
+
+using namespace std;
+using namespace rapidjson;
+
+typedef map<string, string> MessageMap;
+
+#if defined(__GNUC__)
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(effc++)
+#endif
+
+#ifdef __clang__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(switch-enum)
+#endif
+
+struct MessageHandler
+ : public BaseReaderHandler<UTF8<>, MessageHandler> {
+ MessageHandler() : messages_(), state_(kExpectObjectStart), name_() {}
+
+ bool StartObject() {
+ switch (state_) {
+ case kExpectObjectStart:
+ state_ = kExpectNameOrObjectEnd;
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool String(const char* str, SizeType length, bool) {
+ switch (state_) {
+ case kExpectNameOrObjectEnd:
+ name_ = string(str, length);
+ state_ = kExpectValue;
+ return true;
+ case kExpectValue:
+ messages_.insert(MessageMap::value_type(name_, string(str, length)));
+ state_ = kExpectNameOrObjectEnd;
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool EndObject(SizeType) { return state_ == kExpectNameOrObjectEnd; }
+
+ bool Default() { return false; } // All other events are invalid.
+
+ MessageMap messages_;
+ enum State {
+ kExpectObjectStart,
+ kExpectNameOrObjectEnd,
+ kExpectValue
+ }state_;
+ std::string name_;
+};
+
+#if defined(__GNUC__)
+RAPIDJSON_DIAG_POP
+#endif
+
+#ifdef __clang__
+RAPIDJSON_DIAG_POP
+#endif
+
+static void ParseMessages(const char* json, MessageMap& messages) {
+ Reader reader;
+ MessageHandler handler;
+ StringStream ss(json);
+ if (reader.Parse(ss, handler))
+ messages.swap(handler.messages_); // Only change it if success.
+ else {
+ ParseErrorCode e = reader.GetParseErrorCode();
+ size_t o = reader.GetErrorOffset();
+ cout << "Error: " << GetParseError_En(e) << endl;;
+ cout << " at offset " << o << " near '" << string(json).substr(o, 10) << "...'" << endl;
+ }
+}
+
+int main() {
+ MessageMap messages;
+
+ const char* json1 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\" }";
+ cout << json1 << endl;
+ ParseMessages(json1, messages);
+
+ for (MessageMap::const_iterator itr = messages.begin(); itr != messages.end(); ++itr)
+ cout << itr->first << ": " << itr->second << endl;
+
+ cout << endl << "Parse a JSON with invalid schema." << endl;
+ const char* json2 = "{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\", \"foo\" : {} }";
+ cout << json2 << endl;
+ ParseMessages(json2, messages);
+
+ return 0;
+}
diff --git a/src/rapidjson/example/parsebyparts/parsebyparts.cpp b/src/rapidjson/example/parsebyparts/parsebyparts.cpp
new file mode 100644
index 000000000..57eed005d
--- /dev/null
+++ b/src/rapidjson/example/parsebyparts/parsebyparts.cpp
@@ -0,0 +1,173 @@
+// Example of parsing JSON to document by parts.
+
+// Using C++11 threads
+// Temporarily disable for clang (older version) due to incompatibility with libstdc++
+#if (__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1700)) && !defined(__clang__)
+
+#include "rapidjson/document.h"
+#include "rapidjson/error/en.h"
+#include "rapidjson/writer.h"
+#include "rapidjson/ostreamwrapper.h"
+#include <condition_variable>
+#include <iostream>
+#include <mutex>
+#include <thread>
+
+using namespace rapidjson;
+
+template<unsigned parseFlags = kParseDefaultFlags>
+class AsyncDocumentParser {
+public:
+ AsyncDocumentParser(Document& d)
+ : stream_(*this)
+ , d_(d)
+ , parseThread_(&AsyncDocumentParser::Parse, this)
+ , mutex_()
+ , notEmpty_()
+ , finish_()
+ , completed_()
+ {}
+
+ ~AsyncDocumentParser() {
+ if (!parseThread_.joinable())
+ return;
+
+ {
+ std::unique_lock<std::mutex> lock(mutex_);
+
+ // Wait until the buffer is read up (or parsing is completed)
+ while (!stream_.Empty() && !completed_)
+ finish_.wait(lock);
+
+ // Automatically append '\0' as the terminator in the stream.
+ static const char terminator[] = "";
+ stream_.src_ = terminator;
+ stream_.end_ = terminator + 1;
+ notEmpty_.notify_one(); // unblock the AsyncStringStream
+ }
+
+ parseThread_.join();
+ }
+
+ void ParsePart(const char* buffer, size_t length) {
+ std::unique_lock<std::mutex> lock(mutex_);
+
+ // Wait until the buffer is read up (or parsing is completed)
+ while (!stream_.Empty() && !completed_)
+ finish_.wait(lock);
+
+ // Stop further parsing if the parsing process is completed.
+ if (completed_)
+ return;
+
+ // Set the buffer to stream and unblock the AsyncStringStream
+ stream_.src_ = buffer;
+ stream_.end_ = buffer + length;
+ notEmpty_.notify_one();
+ }
+
+private:
+ void Parse() {
+ d_.ParseStream<parseFlags>(stream_);
+
+ // The stream may not be fully read, notify finish anyway to unblock ParsePart()
+ std::unique_lock<std::mutex> lock(mutex_);
+ completed_ = true; // Parsing process is completed
+ finish_.notify_one(); // Unblock ParsePart() or destructor if they are waiting.
+ }
+
+ struct AsyncStringStream {
+ typedef char Ch;
+
+ AsyncStringStream(AsyncDocumentParser& parser) : parser_(parser), src_(), end_(), count_() {}
+
+ char Peek() const {
+ std::unique_lock<std::mutex> lock(parser_.mutex_);
+
+ // If nothing in stream, block to wait.
+ while (Empty())
+ parser_.notEmpty_.wait(lock);
+
+ return *src_;
+ }
+
+ char Take() {
+ std::unique_lock<std::mutex> lock(parser_.mutex_);
+
+ // If nothing in stream, block to wait.
+ while (Empty())
+ parser_.notEmpty_.wait(lock);
+
+ count_++;
+ char c = *src_++;
+
+ // If all stream is read up, notify that the stream is finish.
+ if (Empty())
+ parser_.finish_.notify_one();
+
+ return c;
+ }
+
+ size_t Tell() const { return count_; }
+
+ // Not implemented
+ char* PutBegin() { return 0; }
+ void Put(char) {}
+ void Flush() {}
+ size_t PutEnd(char*) { return 0; }
+
+ bool Empty() const { return src_ == end_; }
+
+ AsyncDocumentParser& parser_;
+ const char* src_; //!< Current read position.
+ const char* end_; //!< End of buffer
+ size_t count_; //!< Number of characters taken so far.
+ };
+
+ AsyncStringStream stream_;
+ Document& d_;
+ std::thread parseThread_;
+ std::mutex mutex_;
+ std::condition_variable notEmpty_;
+ std::condition_variable finish_;
+ bool completed_;
+};
+
+int main() {
+ Document d;
+
+ {
+ AsyncDocumentParser<> parser(d);
+
+ const char json1[] = " { \"hello\" : \"world\", \"t\" : tr";
+ //const char json1[] = " { \"hello\" : \"world\", \"t\" : trX"; // Fot test parsing error
+ const char json2[] = "ue, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.14";
+ const char json3[] = "16, \"a\":[1, 2, 3, 4] } ";
+
+ parser.ParsePart(json1, sizeof(json1) - 1);
+ parser.ParsePart(json2, sizeof(json2) - 1);
+ parser.ParsePart(json3, sizeof(json3) - 1);
+ }
+
+ if (d.HasParseError()) {
+ std::cout << "Error at offset " << d.GetErrorOffset() << ": " << GetParseError_En(d.GetParseError()) << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ // Stringify the JSON to cout
+ OStreamWrapper os(std::cout);
+ Writer<OStreamWrapper> writer(os);
+ d.Accept(writer);
+ std::cout << std::endl;
+
+ return EXIT_SUCCESS;
+}
+
+#else // Not supporting C++11
+
+#include <iostream>
+int main() {
+ std::cout << "This example requires C++11 compiler" << std::endl;
+}
+
+#endif
diff --git a/src/rapidjson/example/pretty/pretty.cpp b/src/rapidjson/example/pretty/pretty.cpp
new file mode 100644
index 000000000..2feff5d02
--- /dev/null
+++ b/src/rapidjson/example/pretty/pretty.cpp
@@ -0,0 +1,30 @@
+// JSON pretty formatting example
+// This example can only handle UTF-8. For handling other encodings, see prettyauto example.
+
+#include "rapidjson/reader.h"
+#include "rapidjson/prettywriter.h"
+#include "rapidjson/filereadstream.h"
+#include "rapidjson/filewritestream.h"
+#include "rapidjson/error/en.h"
+
+using namespace rapidjson;
+
+int main(int, char*[]) {
+ // Prepare reader and input stream.
+ Reader reader;
+ char readBuffer[65536];
+ FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
+
+ // Prepare writer and output stream.
+ char writeBuffer[65536];
+ FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
+ PrettyWriter<FileWriteStream> writer(os);
+
+ // JSON reader parse from the input stream and let writer generate the output.
+ if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) {
+ fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/src/rapidjson/example/prettyauto/prettyauto.cpp b/src/rapidjson/example/prettyauto/prettyauto.cpp
new file mode 100644
index 000000000..1687bae55
--- /dev/null
+++ b/src/rapidjson/example/prettyauto/prettyauto.cpp
@@ -0,0 +1,56 @@
+// JSON pretty formatting example
+// This example can handle UTF-8/UTF-16LE/UTF-16BE/UTF-32LE/UTF-32BE.
+// The input firstly convert to UTF8, and then write to the original encoding with pretty formatting.
+
+#include "rapidjson/reader.h"
+#include "rapidjson/prettywriter.h"
+#include "rapidjson/filereadstream.h"
+#include "rapidjson/filewritestream.h"
+#include "rapidjson/encodedstream.h" // NEW
+#include "rapidjson/error/en.h"
+#ifdef _WIN32
+#include <fcntl.h>
+#include <io.h>
+#endif
+
+using namespace rapidjson;
+
+int main(int, char*[]) {
+#ifdef _WIN32
+ // Prevent Windows converting between CR+LF and LF
+ _setmode(_fileno(stdin), _O_BINARY); // NEW
+ _setmode(_fileno(stdout), _O_BINARY); // NEW
+#endif
+
+ // Prepare reader and input stream.
+ //Reader reader;
+ GenericReader<AutoUTF<unsigned>, UTF8<> > reader; // CHANGED
+ char readBuffer[65536];
+ FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
+ AutoUTFInputStream<unsigned, FileReadStream> eis(is); // NEW
+
+ // Prepare writer and output stream.
+ char writeBuffer[65536];
+ FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
+
+#if 1
+ // Use the same Encoding of the input. Also use BOM according to input.
+ typedef AutoUTFOutputStream<unsigned, FileWriteStream> OutputStream; // NEW
+ OutputStream eos(os, eis.GetType(), eis.HasBOM()); // NEW
+ PrettyWriter<OutputStream, UTF8<>, AutoUTF<unsigned> > writer(eos); // CHANGED
+#else
+ // You may also use static bound encoding type, such as output to UTF-16LE with BOM
+ typedef EncodedOutputStream<UTF16LE<>,FileWriteStream> OutputStream; // NEW
+ OutputStream eos(os, true); // NEW
+ PrettyWriter<OutputStream, UTF8<>, UTF16LE<> > writer(eos); // CHANGED
+#endif
+
+ // JSON reader parse from the input stream and let writer generate the output.
+ //if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) {
+ if (!reader.Parse<kParseValidateEncodingFlag>(eis, writer)) { // CHANGED
+ fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/src/rapidjson/example/schemavalidator/schemavalidator.cpp b/src/rapidjson/example/schemavalidator/schemavalidator.cpp
new file mode 100644
index 000000000..ce36ea95f
--- /dev/null
+++ b/src/rapidjson/example/schemavalidator/schemavalidator.cpp
@@ -0,0 +1,72 @@
+// Schema Validator example
+
+// The example validates JSON text from stdin with a JSON schema specified in the argument.
+
+#include "rapidjson/error/en.h"
+#include "rapidjson/filereadstream.h"
+#include "rapidjson/schema.h"
+#include "rapidjson/stringbuffer.h"
+
+using namespace rapidjson;
+
+int main(int argc, char *argv[]) {
+ if (argc != 2) {
+ fprintf(stderr, "Usage: schemavalidator schema.json < input.json\n");
+ return EXIT_FAILURE;
+ }
+
+ // Read a JSON schema from file into Document
+ Document d;
+ char buffer[4096];
+
+ {
+ FILE *fp = fopen(argv[1], "r");
+ if (!fp) {
+ printf("Schema file '%s' not found\n", argv[1]);
+ return -1;
+ }
+ FileReadStream fs(fp, buffer, sizeof(buffer));
+ d.ParseStream(fs);
+ if (d.HasParseError()) {
+ fprintf(stderr, "Schema file '%s' is not a valid JSON\n", argv[1]);
+ fprintf(stderr, "Error(offset %u): %s\n",
+ static_cast<unsigned>(d.GetErrorOffset()),
+ GetParseError_En(d.GetParseError()));
+ fclose(fp);
+ return EXIT_FAILURE;
+ }
+ fclose(fp);
+ }
+
+ // Then convert the Document into SchemaDocument
+ SchemaDocument sd(d);
+
+ // Use reader to parse the JSON in stdin, and forward SAX events to validator
+ SchemaValidator validator(sd);
+ Reader reader;
+ FileReadStream is(stdin, buffer, sizeof(buffer));
+ if (!reader.Parse(is, validator) && reader.GetParseErrorCode() != kParseErrorTermination) {
+ // Schema validator error would cause kParseErrorTermination, which will handle it in next step.
+ fprintf(stderr, "Input is not a valid JSON\n");
+ fprintf(stderr, "Error(offset %u): %s\n",
+ static_cast<unsigned>(reader.GetErrorOffset()),
+ GetParseError_En(reader.GetParseErrorCode()));
+ }
+
+ // Check the validation result
+ if (validator.IsValid()) {
+ printf("Input JSON is valid.\n");
+ return EXIT_SUCCESS;
+ }
+ else {
+ printf("Input JSON is invalid.\n");
+ StringBuffer sb;
+ validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
+ fprintf(stderr, "Invalid schema: %s\n", sb.GetString());
+ fprintf(stderr, "Invalid keyword: %s\n", validator.GetInvalidSchemaKeyword());
+ sb.Clear();
+ validator.GetInvalidDocumentPointer().StringifyUriFragment(sb);
+ fprintf(stderr, "Invalid document: %s\n", sb.GetString());
+ return EXIT_FAILURE;
+ }
+}
diff --git a/src/rapidjson/example/serialize/serialize.cpp b/src/rapidjson/example/serialize/serialize.cpp
new file mode 100644
index 000000000..12d87151e
--- /dev/null
+++ b/src/rapidjson/example/serialize/serialize.cpp
@@ -0,0 +1,173 @@
+// Serialize example
+// This example shows writing JSON string with writer directly.
+
+#include "rapidjson/prettywriter.h" // for stringify JSON
+#include <cstdio>
+#include <string>
+#include <vector>
+
+using namespace rapidjson;
+
+class Person {
+public:
+ Person(const std::string& name, unsigned age) : name_(name), age_(age) {}
+ Person(const Person& rhs) : name_(rhs.name_), age_(rhs.age_) {}
+ virtual ~Person();
+
+ Person& operator=(const Person& rhs) {
+ name_ = rhs.name_;
+ age_ = rhs.age_;
+ return *this;
+ }
+
+protected:
+ template <typename Writer>
+ void Serialize(Writer& writer) const {
+ // This base class just write out name-value pairs, without wrapping within an object.
+ writer.String("name");
+#if RAPIDJSON_HAS_STDSTRING
+ writer.String(name_);
+#else
+ writer.String(name_.c_str(), static_cast<SizeType>(name_.length())); // Supplying length of string is faster.
+#endif
+ writer.String("age");
+ writer.Uint(age_);
+ }
+
+private:
+ std::string name_;
+ unsigned age_;
+};
+
+Person::~Person() {
+}
+
+class Education {
+public:
+ Education(const std::string& school, double GPA) : school_(school), GPA_(GPA) {}
+ Education(const Education& rhs) : school_(rhs.school_), GPA_(rhs.GPA_) {}
+
+ template <typename Writer>
+ void Serialize(Writer& writer) const {
+ writer.StartObject();
+
+ writer.String("school");
+#if RAPIDJSON_HAS_STDSTRING
+ writer.String(school_);
+#else
+ writer.String(school_.c_str(), static_cast<SizeType>(school_.length()));
+#endif
+
+ writer.String("GPA");
+ writer.Double(GPA_);
+
+ writer.EndObject();
+ }
+
+private:
+ std::string school_;
+ double GPA_;
+};
+
+class Dependent : public Person {
+public:
+ Dependent(const std::string& name, unsigned age, Education* education = 0) : Person(name, age), education_(education) {}
+ Dependent(const Dependent& rhs) : Person(rhs), education_(0) { education_ = (rhs.education_ == 0) ? 0 : new Education(*rhs.education_); }
+ virtual ~Dependent();
+
+ Dependent& operator=(const Dependent& rhs) {
+ if (this == &rhs)
+ return *this;
+ delete education_;
+ education_ = (rhs.education_ == 0) ? 0 : new Education(*rhs.education_);
+ return *this;
+ }
+
+ template <typename Writer>
+ void Serialize(Writer& writer) const {
+ writer.StartObject();
+
+ Person::Serialize(writer);
+
+ writer.String("education");
+ if (education_)
+ education_->Serialize(writer);
+ else
+ writer.Null();
+
+ writer.EndObject();
+ }
+
+private:
+
+ Education *education_;
+};
+
+Dependent::~Dependent() {
+ delete education_;
+}
+
+class Employee : public Person {
+public:
+ Employee(const std::string& name, unsigned age, bool married) : Person(name, age), dependents_(), married_(married) {}
+ Employee(const Employee& rhs) : Person(rhs), dependents_(rhs.dependents_), married_(rhs.married_) {}
+ virtual ~Employee();
+
+ Employee& operator=(const Employee& rhs) {
+ static_cast<Person&>(*this) = rhs;
+ dependents_ = rhs.dependents_;
+ married_ = rhs.married_;
+ return *this;
+ }
+
+ void AddDependent(const Dependent& dependent) {
+ dependents_.push_back(dependent);
+ }
+
+ template <typename Writer>
+ void Serialize(Writer& writer) const {
+ writer.StartObject();
+
+ Person::Serialize(writer);
+
+ writer.String("married");
+ writer.Bool(married_);
+
+ writer.String(("dependents"));
+ writer.StartArray();
+ for (std::vector<Dependent>::const_iterator dependentItr = dependents_.begin(); dependentItr != dependents_.end(); ++dependentItr)
+ dependentItr->Serialize(writer);
+ writer.EndArray();
+
+ writer.EndObject();
+ }
+
+private:
+ std::vector<Dependent> dependents_;
+ bool married_;
+};
+
+Employee::~Employee() {
+}
+
+int main(int, char*[]) {
+ std::vector<Employee> employees;
+
+ employees.push_back(Employee("Milo YIP", 34, true));
+ employees.back().AddDependent(Dependent("Lua YIP", 3, new Education("Happy Kindergarten", 3.5)));
+ employees.back().AddDependent(Dependent("Mio YIP", 1));
+
+ employees.push_back(Employee("Percy TSE", 30, false));
+
+ StringBuffer sb;
+ PrettyWriter<StringBuffer> writer(sb);
+
+ writer.StartArray();
+ for (std::vector<Employee>::const_iterator employeeItr = employees.begin(); employeeItr != employees.end(); ++employeeItr)
+ employeeItr->Serialize(writer);
+ writer.EndArray();
+
+ puts(sb.GetString());
+
+ return 0;
+}
diff --git a/src/rapidjson/example/simpledom/simpledom.cpp b/src/rapidjson/example/simpledom/simpledom.cpp
new file mode 100644
index 000000000..80384199a
--- /dev/null
+++ b/src/rapidjson/example/simpledom/simpledom.cpp
@@ -0,0 +1,29 @@
+// JSON simple example
+// This example does not handle errors.
+
+#include "rapidjson/document.h"
+#include "rapidjson/writer.h"
+#include "rapidjson/stringbuffer.h"
+#include <iostream>
+
+using namespace rapidjson;
+
+int main() {
+ // 1. Parse a JSON string into DOM.
+ const char* json = "{\"project\":\"rapidjson\",\"stars\":10}";
+ Document d;
+ d.Parse(json);
+
+ // 2. Modify it by DOM.
+ Value& s = d["stars"];
+ s.SetInt(s.GetInt() + 1);
+
+ // 3. Stringify the DOM
+ StringBuffer buffer;
+ Writer<StringBuffer> writer(buffer);
+ d.Accept(writer);
+
+ // Output {"project":"rapidjson","stars":11}
+ std::cout << buffer.GetString() << std::endl;
+ return 0;
+}
diff --git a/src/rapidjson/example/simplereader/simplereader.cpp b/src/rapidjson/example/simplereader/simplereader.cpp
new file mode 100644
index 000000000..5aae8a1c0
--- /dev/null
+++ b/src/rapidjson/example/simplereader/simplereader.cpp
@@ -0,0 +1,42 @@
+#include "rapidjson/reader.h"
+#include <iostream>
+
+using namespace rapidjson;
+using namespace std;
+
+struct MyHandler {
+ bool Null() { cout << "Null()" << endl; return true; }
+ bool Bool(bool b) { cout << "Bool(" << boolalpha << b << ")" << endl; return true; }
+ bool Int(int i) { cout << "Int(" << i << ")" << endl; return true; }
+ bool Uint(unsigned u) { cout << "Uint(" << u << ")" << endl; return true; }
+ bool Int64(int64_t i) { cout << "Int64(" << i << ")" << endl; return true; }
+ bool Uint64(uint64_t u) { cout << "Uint64(" << u << ")" << endl; return true; }
+ bool Double(double d) { cout << "Double(" << d << ")" << endl; return true; }
+ bool RawNumber(const char* str, SizeType length, bool copy) {
+ cout << "Number(" << str << ", " << length << ", " << boolalpha << copy << ")" << endl;
+ return true;
+ }
+ bool String(const char* str, SizeType length, bool copy) {
+ cout << "String(" << str << ", " << length << ", " << boolalpha << copy << ")" << endl;
+ return true;
+ }
+ bool StartObject() { cout << "StartObject()" << endl; return true; }
+ bool Key(const char* str, SizeType length, bool copy) {
+ cout << "Key(" << str << ", " << length << ", " << boolalpha << copy << ")" << endl;
+ return true;
+ }
+ bool EndObject(SizeType memberCount) { cout << "EndObject(" << memberCount << ")" << endl; return true; }
+ bool StartArray() { cout << "StartArray()" << endl; return true; }
+ bool EndArray(SizeType elementCount) { cout << "EndArray(" << elementCount << ")" << endl; return true; }
+};
+
+int main() {
+ const char json[] = " { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ";
+
+ MyHandler handler;
+ Reader reader;
+ StringStream ss(json);
+ reader.Parse(ss, handler);
+
+ return 0;
+}
diff --git a/src/rapidjson/example/simplewriter/simplewriter.cpp b/src/rapidjson/example/simplewriter/simplewriter.cpp
new file mode 100644
index 000000000..8d1275c29
--- /dev/null
+++ b/src/rapidjson/example/simplewriter/simplewriter.cpp
@@ -0,0 +1,36 @@
+#include "rapidjson/writer.h"
+#include "rapidjson/stringbuffer.h"
+#include <iostream>
+
+using namespace rapidjson;
+using namespace std;
+
+int main() {
+ StringBuffer s;
+ Writer<StringBuffer> writer(s);
+
+ writer.StartObject(); // Between StartObject()/EndObject(),
+ writer.Key("hello"); // output a key,
+ writer.String("world"); // follow by a value.
+ writer.Key("t");
+ writer.Bool(true);
+ writer.Key("f");
+ writer.Bool(false);
+ writer.Key("n");
+ writer.Null();
+ writer.Key("i");
+ writer.Uint(123);
+ writer.Key("pi");
+ writer.Double(3.1416);
+ writer.Key("a");
+ writer.StartArray(); // Between StartArray()/EndArray(),
+ for (unsigned i = 0; i < 4; i++)
+ writer.Uint(i); // all values are elements of the array.
+ writer.EndArray();
+ writer.EndObject();
+
+ // {"hello":"world","t":true,"f":false,"n":null,"i":123,"pi":3.1416,"a":[0,1,2,3]}
+ cout << s.GetString() << endl;
+
+ return 0;
+}
diff --git a/src/rapidjson/example/tutorial/tutorial.cpp b/src/rapidjson/example/tutorial/tutorial.cpp
new file mode 100644
index 000000000..c8bfcc14c
--- /dev/null
+++ b/src/rapidjson/example/tutorial/tutorial.cpp
@@ -0,0 +1,151 @@
+// Hello World example
+// This example shows basic usage of DOM-style API.
+
+#include "rapidjson/document.h" // rapidjson's DOM-style API
+#include "rapidjson/prettywriter.h" // for stringify JSON
+#include <cstdio>
+
+using namespace rapidjson;
+using namespace std;
+
+int main(int, char*[]) {
+ ////////////////////////////////////////////////////////////////////////////
+ // 1. Parse a JSON text string to a document.
+
+ const char json[] = " { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ";
+ printf("Original JSON:\n %s\n", json);
+
+ Document document; // Default template parameter uses UTF8 and MemoryPoolAllocator.
+
+#if 0
+ // "normal" parsing, decode strings to new buffers. Can use other input stream via ParseStream().
+ if (document.Parse(json).HasParseError())
+ return 1;
+#else
+ // In-situ parsing, decode strings directly in the source string. Source must be string.
+ char buffer[sizeof(json)];
+ memcpy(buffer, json, sizeof(json));
+ if (document.ParseInsitu(buffer).HasParseError())
+ return 1;
+#endif
+
+ printf("\nParsing to document succeeded.\n");
+
+ ////////////////////////////////////////////////////////////////////////////
+ // 2. Access values in document.
+
+ printf("\nAccess values in document:\n");
+ assert(document.IsObject()); // Document is a JSON value represents the root of DOM. Root can be either an object or array.
+
+ assert(document.HasMember("hello"));
+ assert(document["hello"].IsString());
+ printf("hello = %s\n", document["hello"].GetString());
+
+ // Since version 0.2, you can use single lookup to check the existing of member and its value:
+ Value::MemberIterator hello = document.FindMember("hello");
+ assert(hello != document.MemberEnd());
+ assert(hello->value.IsString());
+ assert(strcmp("world", hello->value.GetString()) == 0);
+ (void)hello;
+
+ assert(document["t"].IsBool()); // JSON true/false are bool. Can also uses more specific function IsTrue().
+ printf("t = %s\n", document["t"].GetBool() ? "true" : "false");
+
+ assert(document["f"].IsBool());
+ printf("f = %s\n", document["f"].GetBool() ? "true" : "false");
+
+ printf("n = %s\n", document["n"].IsNull() ? "null" : "?");
+
+ assert(document["i"].IsNumber()); // Number is a JSON type, but C++ needs more specific type.
+ assert(document["i"].IsInt()); // In this case, IsUint()/IsInt64()/IsUInt64() also return true.
+ printf("i = %d\n", document["i"].GetInt()); // Alternative (int)document["i"]
+
+ assert(document["pi"].IsNumber());
+ assert(document["pi"].IsDouble());
+ printf("pi = %g\n", document["pi"].GetDouble());
+
+ {
+ const Value& a = document["a"]; // Using a reference for consecutive access is handy and faster.
+ assert(a.IsArray());
+ for (SizeType i = 0; i < a.Size(); i++) // rapidjson uses SizeType instead of size_t.
+ printf("a[%d] = %d\n", i, a[i].GetInt());
+
+ int y = a[0].GetInt();
+ (void)y;
+
+ // Iterating array with iterators
+ printf("a = ");
+ for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
+ printf("%d ", itr->GetInt());
+ printf("\n");
+ }
+
+ // Iterating object members
+ static const char* kTypeNames[] = { "Null", "False", "True", "Object", "Array", "String", "Number" };
+ for (Value::ConstMemberIterator itr = document.MemberBegin(); itr != document.MemberEnd(); ++itr)
+ printf("Type of member %s is %s\n", itr->name.GetString(), kTypeNames[itr->value.GetType()]);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // 3. Modify values in document.
+
+ // Change i to a bigger number
+ {
+ uint64_t f20 = 1; // compute factorial of 20
+ for (uint64_t j = 1; j <= 20; j++)
+ f20 *= j;
+ document["i"] = f20; // Alternate form: document["i"].SetUint64(f20)
+ assert(!document["i"].IsInt()); // No longer can be cast as int or uint.
+ }
+
+ // Adding values to array.
+ {
+ Value& a = document["a"]; // This time we uses non-const reference.
+ Document::AllocatorType& allocator = document.GetAllocator();
+ for (int i = 5; i <= 10; i++)
+ a.PushBack(i, allocator); // May look a bit strange, allocator is needed for potentially realloc. We normally uses the document's.
+
+ // Fluent API
+ a.PushBack("Lua", allocator).PushBack("Mio", allocator);
+ }
+
+ // Making string values.
+
+ // This version of SetString() just store the pointer to the string.
+ // So it is for literal and string that exists within value's life-cycle.
+ {
+ document["hello"] = "rapidjson"; // This will invoke strlen()
+ // Faster version:
+ // document["hello"].SetString("rapidjson", 9);
+ }
+
+ // This version of SetString() needs an allocator, which means it will allocate a new buffer and copy the the string into the buffer.
+ Value author;
+ {
+ char buffer2[10];
+ int len = sprintf(buffer2, "%s %s", "Milo", "Yip"); // synthetic example of dynamically created string.
+
+ author.SetString(buffer2, static_cast<SizeType>(len), document.GetAllocator());
+ // Shorter but slower version:
+ // document["hello"].SetString(buffer, document.GetAllocator());
+
+ // Constructor version:
+ // Value author(buffer, len, document.GetAllocator());
+ // Value author(buffer, document.GetAllocator());
+ memset(buffer2, 0, sizeof(buffer2)); // For demonstration purpose.
+ }
+ // Variable 'buffer' is unusable now but 'author' has already made a copy.
+ document.AddMember("author", author, document.GetAllocator());
+
+ assert(author.IsNull()); // Move semantic for assignment. After this variable is assigned as a member, the variable becomes null.
+
+ ////////////////////////////////////////////////////////////////////////////
+ // 4. Stringify JSON
+
+ printf("\nModified JSON with reformatting:\n");
+ StringBuffer sb;
+ PrettyWriter<StringBuffer> writer(sb);
+ document.Accept(writer); // Accept() traverses the DOM and generates Handler events.
+ puts(sb.GetString());
+
+ return 0;
+}