summaryrefslogtreecommitdiffstats
path: root/src/rapidjson/example/jsonx/jsonx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rapidjson/example/jsonx/jsonx.cpp')
-rw-r--r--src/rapidjson/example/jsonx/jsonx.cpp207
1 files changed, 207 insertions, 0 deletions
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;
+}