]> git.proxmox.com Git - ceph.git/blob - ceph/src/rapidjson/example/jsonx/jsonx.cpp
update sources to v12.1.0
[ceph.git] / ceph / src / rapidjson / example / jsonx / jsonx.cpp
1 // JSON to JSONx conversion exmaple, using SAX API.
2 // JSONx is an IBM standard format to represent JSON as XML.
3 // https://www-01.ibm.com/support/knowledgecenter/SS9H2Y_7.1.0/com.ibm.dp.doc/json_jsonx.html
4 // This example parses JSON text from stdin with validation,
5 // and convert to JSONx format to stdout.
6 // Need compile with -D__STDC_FORMAT_MACROS for defining PRId64 and PRIu64 macros.
7
8 #include "rapidjson/reader.h"
9 #include "rapidjson/stringbuffer.h"
10 #include "rapidjson/filereadstream.h"
11 #include "rapidjson/filewritestream.h"
12 #include "rapidjson/error/en.h"
13 #include <cstdio>
14
15 using namespace rapidjson;
16
17 // For simplicity, this example only read/write in UTF-8 encoding
18 template <typename OutputStream>
19 class JsonxWriter {
20 public:
21 JsonxWriter(OutputStream& os) : os_(os), name_(), level_(0), hasName_(false) {
22 }
23
24 bool Null() {
25 return WriteStartElement("null", true);
26 }
27
28 bool Bool(bool b) {
29 return
30 WriteStartElement("boolean") &&
31 WriteString(b ? "true" : "false") &&
32 WriteEndElement("boolean");
33 }
34
35 bool Int(int i) {
36 char buffer[12];
37 return WriteNumberElement(buffer, sprintf(buffer, "%d", i));
38 }
39
40 bool Uint(unsigned i) {
41 char buffer[11];
42 return WriteNumberElement(buffer, sprintf(buffer, "%u", i));
43 }
44
45 bool Int64(int64_t i) {
46 char buffer[21];
47 return WriteNumberElement(buffer, sprintf(buffer, "%" PRId64, i));
48 }
49
50 bool Uint64(uint64_t i) {
51 char buffer[21];
52 return WriteNumberElement(buffer, sprintf(buffer, "%" PRIu64, i));
53 }
54
55 bool Double(double d) {
56 char buffer[30];
57 return WriteNumberElement(buffer, sprintf(buffer, "%.17g", d));
58 }
59
60 bool RawNumber(const char* str, SizeType length, bool) {
61 return
62 WriteStartElement("number") &&
63 WriteEscapedText(str, length) &&
64 WriteEndElement("number");
65 }
66
67 bool String(const char* str, SizeType length, bool) {
68 return
69 WriteStartElement("string") &&
70 WriteEscapedText(str, length) &&
71 WriteEndElement("string");
72 }
73
74 bool StartObject() {
75 return WriteStartElement("object");
76 }
77
78 bool Key(const char* str, SizeType length, bool) {
79 // backup key to name_
80 name_.Clear();
81 for (SizeType i = 0; i < length; i++)
82 name_.Put(str[i]);
83 hasName_ = true;
84 return true;
85 }
86
87 bool EndObject(SizeType) {
88 return WriteEndElement("object");
89 }
90
91 bool StartArray() {
92 return WriteStartElement("array");
93 }
94
95 bool EndArray(SizeType) {
96 return WriteEndElement("array");
97 }
98
99 private:
100 bool WriteString(const char* s) {
101 while (*s)
102 os_.Put(*s++);
103 return true;
104 }
105
106 bool WriteEscapedAttributeValue(const char* s, size_t length) {
107 for (size_t i = 0; i < length; i++) {
108 switch (s[i]) {
109 case '&': WriteString("&amp;"); break;
110 case '<': WriteString("&lt;"); break;
111 case '"': WriteString("&quot;"); break;
112 default: os_.Put(s[i]); break;
113 }
114 }
115 return true;
116 }
117
118 bool WriteEscapedText(const char* s, size_t length) {
119 for (size_t i = 0; i < length; i++) {
120 switch (s[i]) {
121 case '&': WriteString("&amp;"); break;
122 case '<': WriteString("&lt;"); break;
123 default: os_.Put(s[i]); break;
124 }
125 }
126 return true;
127 }
128
129 bool WriteStartElement(const char* type, bool emptyElement = false) {
130 if (level_ == 0)
131 if (!WriteString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"))
132 return false;
133
134 if (!WriteString("<json:") || !WriteString(type))
135 return false;
136
137 // For root element, need to add declarations
138 if (level_ == 0) {
139 if (!WriteString(
140 " xsi:schemaLocation=\"http://www.datapower.com/schemas/json jsonx.xsd\""
141 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
142 " xmlns:json=\"http://www.ibm.com/xmlns/prod/2009/jsonx\""))
143 return false;
144 }
145
146 if (hasName_) {
147 hasName_ = false;
148 if (!WriteString(" name=\"") ||
149 !WriteEscapedAttributeValue(name_.GetString(), name_.GetSize()) ||
150 !WriteString("\""))
151 return false;
152 }
153
154 if (emptyElement)
155 return WriteString("/>");
156 else {
157 level_++;
158 return WriteString(">");
159 }
160 }
161
162 bool WriteEndElement(const char* type) {
163 if (!WriteString("</json:") ||
164 !WriteString(type) ||
165 !WriteString(">"))
166 return false;
167
168 // For the last end tag, flush the output stream.
169 if (--level_ == 0)
170 os_.Flush();
171
172 return true;
173 }
174
175 bool WriteNumberElement(const char* buffer, int length) {
176 if (!WriteStartElement("number"))
177 return false;
178 for (int j = 0; j < length; j++)
179 os_.Put(buffer[j]);
180 return WriteEndElement("number");
181 }
182
183 OutputStream& os_;
184 StringBuffer name_;
185 unsigned level_;
186 bool hasName_;
187 };
188
189 int main(int, char*[]) {
190 // Prepare JSON reader and input stream.
191 Reader reader;
192 char readBuffer[65536];
193 FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
194
195 // Prepare JSON writer and output stream.
196 char writeBuffer[65536];
197 FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
198 JsonxWriter<FileWriteStream> writer(os);
199
200 // JSON reader parse from the input stream and let writer generate the output.
201 if (!reader.Parse(is, writer)) {
202 fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
203 return 1;
204 }
205
206 return 0;
207 }