jsonx.cpp
Go to the documentation of this file.
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"
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 
88  return WriteEndElement("object");
89  }
90 
91  bool StartArray() {
92  return WriteStartElement("array");
93  }
94 
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_;
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 }
bool String(const char *str, SizeType length, bool)
Definition: jsonx.cpp:67
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition: reader.h:558
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:389
bool WriteEscapedAttributeValue(const char *s, size_t length)
Definition: jsonx.cpp:106
ParseErrorCode GetParseErrorCode() const
Get the ParseErrorCode of last parsing.
Definition: reader.h:684
bool Int(int i)
Definition: jsonx.cpp:35
Wrapper of C file stream for input using fread().
bool WriteEndElement(const char *type)
Definition: jsonx.cpp:162
bool WriteString(const char *s)
Definition: jsonx.cpp:100
bool WriteEscapedText(const char *s, size_t length)
Definition: jsonx.cpp:118
StringBuffer name_
Definition: jsonx.cpp:184
bool Double(double d)
Definition: jsonx.cpp:55
bool EndArray(SizeType)
Definition: jsonx.cpp:95
bool Uint64(uint64_t i)
Definition: jsonx.cpp:50
OutputStream & os_
Definition: jsonx.cpp:183
bool hasName_
Definition: jsonx.cpp:186
bool WriteNumberElement(const char *buffer, int length)
Definition: jsonx.cpp:175
unsigned __int64 uint64_t
Definition: stdint.h:136
bool Uint(unsigned i)
Definition: jsonx.cpp:40
bool Null()
Definition: jsonx.cpp:24
main RapidJSON namespace
int main(int, char *[])
Definition: jsonx.cpp:189
bool Bool(bool b)
Definition: jsonx.cpp:28
bool StartArray()
Definition: jsonx.cpp:91
bool WriteStartElement(const char *type, bool emptyElement=false)
Definition: jsonx.cpp:129
#define PRIu64
Definition: inttypes.h:142
File byte stream for input using fread().
bool StartObject()
Definition: jsonx.cpp:74
bool EndObject(SizeType)
Definition: jsonx.cpp:87
signed __int64 int64_t
Definition: stdint.h:135
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: reader.h:687
unsigned level_
Definition: jsonx.cpp:185
#define PRId64
Definition: inttypes.h:88
RAPIDJSON_NAMESPACE_BEGIN const RAPIDJSON_ERROR_CHARTYPE * GetParseError_En(ParseErrorCode parseErrorCode)
Maps error code of parsing into error message.
Definition: en.h:36
bool Key(const char *str, SizeType length, bool)
Definition: jsonx.cpp:78
JsonxWriter(OutputStream &os)
Definition: jsonx.cpp:21
bool RawNumber(const char *str, SizeType length, bool)
Definition: jsonx.cpp:60
bool Int64(int64_t i)
Definition: jsonx.cpp:45


choreo_rapidjson
Author(s):
autogenerated on Thu Jul 18 2019 03:59:09