CoolProp  6.6.1dev
An open-source fluid property and humid air property database
rapidjson_include.h
Go to the documentation of this file.
1 #ifndef RAPIDJSON_COOLPROP_H
2 #define RAPIDJSON_COOLPROP_H
3 
4 // On PowerPC, we are going to use the stdint.h integer types and not let rapidjson use its own
5 #if defined(__powerpc__)
6 typedef unsigned int UINT32;
7 # include "stdint.h"
8 # define RAPIDJSON_NO_INT64DEFINE
9 #endif
10 
11 #include "Exceptions.h"
12 #include "CoolPropTools.h"
13 
14 #include "externals/rapidjson/include/rapidjson/rapidjson.h"
15 #include "externals/rapidjson/include/rapidjson/document.h"
16 #include "externals/rapidjson/include/rapidjson/filewritestream.h" // wrapper of C stream for prettywriter as output
17 #include "externals/rapidjson/include/rapidjson/prettywriter.h" // for stringify JSON
18 #include "externals/rapidjson/include/rapidjson/stringbuffer.h" // for string buffer
19 #include "externals/rapidjson/include/rapidjson/schema.h"
20 
21 #include <cassert>
22 
23 namespace cpjson {
24 
26 inline void JSON_string_to_rapidjson(const std::string& JSON_string, rapidjson::Document& doc) {
27  doc.Parse<0>(JSON_string.c_str());
28  if (doc.HasParseError()) {
29  throw CoolProp::ValueError("Unable to load JSON string");
30  }
31 }
32 
34 {
36 };
37 inline value_information get_information(rapidjson::Value& v) {
39  i.isnull = v.IsNull();
40  i.isfalse = v.IsFalse();
41  i.istrue = v.IsTrue();
42  i.isbool = v.IsBool();
43  i.isobject = v.IsObject();
44  i.isarray = v.IsArray();
45  i.isnumber = v.IsNumber();
46  i.isint = v.IsInt();
47  i.isuint = v.IsUint();
48  i.isint64 = v.IsInt64();
49  i.isuint64 = v.IsUint64();
50  i.isdouble = v.IsDouble();
51  i.isstring = v.IsString();
52  return i;
53 };
54 
55 inline std::string json2string(const rapidjson::Value& v) {
56  rapidjson::StringBuffer buffer;
57  rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
58 
59  v.Accept(writer);
60  return buffer.GetString();
61 }
63 inline int get_integer(const rapidjson::Value& v, std::string m) {
64  if (!v.HasMember(m.c_str())) {
65  throw CoolProp::ValueError(format("Does not have member [%s]", m.c_str()));
66  }
67  const rapidjson::Value& el = v[m.c_str()];
68  if (!el.IsInt()) {
69  throw CoolProp::ValueError(format("Member [%s] is not an integer", m.c_str()));
70  } else {
71  return el.GetInt();
72  }
73 };
75 inline double get_double(const rapidjson::Value& v, std::string m) {
76  if (!v.HasMember(m.c_str())) {
77  throw CoolProp::ValueError(format("Does not have member [%s]", m.c_str()));
78  }
79  const rapidjson::Value& el = v[m.c_str()];
80  if (!el.IsNumber()) {
81  throw CoolProp::ValueError(format("Member [%s] is not a number", m.c_str()));
82  } else {
83  return el.GetDouble();
84  }
85 };
87 inline bool get_bool(const rapidjson::Value& v, std::string m) {
88  if (!v.HasMember(m.c_str())) {
89  throw CoolProp::ValueError(format("Does not have member [%s]", m.c_str()));
90  }
91  const rapidjson::Value& el = v[m.c_str()];
92  if (!el.IsBool()) {
93  throw CoolProp::ValueError(format("Member [%s] is not a boolean", m.c_str()));
94  } else {
95  return el.GetBool();
96  }
97 };
99 inline std::string get_string(const rapidjson::Value& v, std::string m) {
100  if (!v.HasMember(m.c_str())) {
101  throw CoolProp::ValueError(format("Does not have member [%s]", m.c_str()));
102  }
103  const rapidjson::Value& el = v[m.c_str()];
104  if (!el.IsString()) {
105  throw CoolProp::ValueError(format("Member [%s] is not a string", m.c_str()));
106  } else {
107  return el.GetString();
108  }
109 };
110 
112 inline std::vector<double> get_double_array(const rapidjson::Value& v) {
113  std::vector<double> out;
114  if (!v.IsArray()) {
115  throw CoolProp::ValueError("input is not an array");
116  }
117  for (rapidjson::Value::ConstValueIterator itr = v.Begin(); itr != v.End(); ++itr) {
118  if (!itr->IsNumber()) {
119  throw CoolProp::ValueError("input is not a number");
120  }
121  out.push_back(itr->GetDouble());
122  }
123  return out;
124 };
125 
127 inline std::vector<double> get_double_array(const rapidjson::Value& v, std::string m) {
128  if (!v.HasMember(m.c_str())) {
129  throw CoolProp::ValueError(format("Does not have member [%s]", m.c_str()));
130  } else {
131  return get_double_array(v[m.c_str()]);
132  }
133 };
134 
136 inline std::vector<CoolPropDbl> get_long_double_array(const rapidjson::Value& v) {
137  std::vector<CoolPropDbl> out;
138  if (!v.IsArray()) {
139  throw CoolProp::ValueError("input is not an array");
140  }
141  for (rapidjson::Value::ConstValueIterator itr = v.Begin(); itr != v.End(); ++itr) {
142  if (!itr->IsNumber()) {
143  throw CoolProp::ValueError("input is not a number");
144  }
145  out.push_back(itr->GetDouble());
146  }
147  return out;
148 };
149 
151 inline std::vector<std::vector<double>> get_double_array2D(const rapidjson::Value& v) {
152  std::vector<std::vector<double>> out;
153  std::vector<double> tmp;
154  if (!v.IsArray()) {
155  throw CoolProp::ValueError("input is not an array");
156  }
157  for (rapidjson::Value::ConstValueIterator itr = v.Begin(); itr != v.End(); ++itr) {
158  // This is here for debugging purposes
159  // cpjson::value_information vi = cpjson::get_information((*itr));
160  if (!(itr->IsArray())) {
161  throw CoolProp::ValueError(format("input \"%s\" is not a 2D array", cpjson::json2string(v).c_str()));
162  }
163  tmp.clear();
164  for (rapidjson::Value::ConstValueIterator i = itr->Begin(); i != itr->End(); ++i) {
165  if (!i->IsNumber()) {
166  throw CoolProp::ValueError("input is not a number");
167  }
168  tmp.push_back(i->GetDouble());
169  }
170  out.push_back(tmp);
171  }
172  return out;
173 };
174 
176 inline std::vector<std::vector<CoolPropDbl>> get_long_double_array2D(const rapidjson::Value& v) {
177  std::vector<std::vector<CoolPropDbl>> out;
178  std::vector<CoolPropDbl> tmp;
179  if (!v.IsArray()) {
180  throw CoolProp::ValueError("input is not an array");
181  }
182  for (rapidjson::Value::ConstValueIterator itr = v.Begin(); itr != v.End(); ++itr) {
183  if (!itr->IsArray()) {
184  throw CoolProp::ValueError("input is not a 2D array");
185  }
186  tmp.clear();
187  for (rapidjson::Value::ConstValueIterator i = itr->Begin(); i != itr->End(); ++i) {
188  if (!i->IsNumber()) {
189  throw CoolProp::ValueError("input is not a number");
190  }
191  tmp.push_back(i->GetDouble());
192  }
193  out.push_back(tmp);
194  }
195  return out;
196 };
197 
199 inline std::vector<CoolPropDbl> get_long_double_array(const rapidjson::Value& v, std::string name) {
200  std::vector<CoolPropDbl> out;
201  if (!v.HasMember(name.c_str())) {
202  throw CoolProp::ValueError(format("Does not have member [%s]", name.c_str()));
203  }
204  if (!v[name.c_str()].IsArray()) {
205  throw CoolProp::ValueError("input is not an array");
206  }
207  for (rapidjson::Value::ConstValueIterator itr = v[name.c_str()].Begin(); itr != v[name.c_str()].End(); ++itr) {
208  if (!itr->IsNumber()) {
209  throw CoolProp::ValueError("input is not a number");
210  }
211  out.push_back(itr->GetDouble());
212  }
213  return out;
214 };
215 
217 inline std::vector<std::string> get_string_array(const rapidjson::Value& v) {
218  std::vector<std::string> out;
219  if (!v.IsArray()) {
220  throw CoolProp::ValueError("input is not an array");
221  }
222  for (rapidjson::Value::ConstValueIterator itr = v.Begin(); itr != v.End(); ++itr) {
223  out.push_back(itr->GetString());
224  }
225  return out;
226 };
227 
229 inline std::vector<std::string> get_string_array(const rapidjson::Value& v, std::string m) {
230  if (!v.HasMember(m.c_str())) {
231  throw CoolProp::ValueError(format("Does not have member [%s]", m.c_str()));
232  } else {
233  return get_string_array(v[m.c_str()]);
234  }
235 };
236 
238 template <typename T>
239 inline std::string to_string(const T& v) {
240  rapidjson::StringBuffer buffer;
241  rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
242  v.Accept(writer);
243  return buffer.GetString();
244 };
245 
247 inline void set_double_array2D(const char* key, const std::vector<std::vector<double>>& vec, rapidjson::Value& value, rapidjson::Document& doc) {
248  rapidjson::Value _i(rapidjson::kArrayType);
249  for (unsigned int i = 0; i < vec.size(); ++i) {
250  rapidjson::Value _j(rapidjson::kArrayType);
251  for (unsigned int j = 0; j < vec[i].size(); ++j) {
252  rapidjson::Value v(rapidjson::kNumberType);
253  v.SetDouble(vec[i][j]);
254  _j.PushBack(v, doc.GetAllocator());
255  }
256  _i.PushBack(_j, doc.GetAllocator());
257  }
258  value.AddMember(rapidjson::Value(key, doc.GetAllocator()).Move(), _i, doc.GetAllocator());
259 };
260 
262 inline void set_string(const std::string& key, const std::string& s, rapidjson::Value& value, rapidjson::Document& doc) {
263  value.AddMember(rapidjson::Value(key.c_str(), doc.GetAllocator()).Move(), rapidjson::Value(s.c_str(), doc.GetAllocator()).Move(),
264  doc.GetAllocator());
265 };
266 
268 inline void set_string_array(const char* key, const std::vector<std::string>& vec, rapidjson::Value& value, rapidjson::Document& doc) {
269  rapidjson::Value _v(rapidjson::kArrayType);
270  for (unsigned int i = 0; i < vec.size(); ++i) {
271  _v.PushBack(rapidjson::Value(vec[i].c_str(), doc.GetAllocator()).Move(), doc.GetAllocator());
272  }
273  value.AddMember(rapidjson::Value(key, doc.GetAllocator()).Move(), _v, doc.GetAllocator());
274 };
275 
277 inline void set_int_array(const char* key, const std::vector<int>& vec, rapidjson::Value& value, rapidjson::Document& doc) {
278  rapidjson::Value _v(rapidjson::kArrayType);
279  for (unsigned int i = 0; i < vec.size(); ++i) {
280  _v.PushBack(vec[i], doc.GetAllocator());
281  }
282  value.AddMember(rapidjson::Value(key, doc.GetAllocator()).Move(), _v, doc.GetAllocator());
283 };
284 
286 inline void set_double_array(const char* key, const std::vector<double>& vec, rapidjson::Value& value, rapidjson::Document& doc) {
287  rapidjson::Value _v(rapidjson::kArrayType);
288  for (unsigned int i = 0; i < vec.size(); ++i) {
289  _v.PushBack(vec[i], doc.GetAllocator());
290  }
291  value.AddMember(rapidjson::Value(key, doc.GetAllocator()).Move(), _v, doc.GetAllocator());
292 };
293 
295 inline void set_long_double_array(const char* const key, const std::vector<CoolPropDbl>& vec, rapidjson::Value& value, rapidjson::Document& doc) {
296  rapidjson::Value _v(rapidjson::kArrayType);
297  for (unsigned int i = 0; i < vec.size(); ++i) {
298  _v.PushBack(static_cast<double>(vec[i]), doc.GetAllocator());
299  }
300  value.AddMember(rapidjson::Value(key, doc.GetAllocator()).Move(), _v, doc.GetAllocator());
301 };
302 
304 {
309 };
313 inline schema_validation_code validate_schema(const std::string& schemaJson, const std::string& inputJson, std::string& errstr) {
314  rapidjson::Document sd;
315  sd.Parse(schemaJson.c_str());
316  if (sd.HasParseError()) {
317  errstr = format("Invalid schema: %s\n", schemaJson.c_str());
318  return SCHEMA_INVALID_JSON;
319  }
320  rapidjson::SchemaDocument schema(sd); // Compile a Document to SchemaDocument
321 
322  rapidjson::Document d;
323  d.Parse(inputJson.c_str());
324  if (d.HasParseError()) {
325  errstr = format("Invalid input json: %s\n", inputJson.c_str());
326  return INPUT_INVALID_JSON;
327  }
328 
329  rapidjson::SchemaValidator validator(schema);
330  if (!d.Accept(validator)) {
331  // Input JSON is invalid according to the schema
332  // Output diagnostic information
333  errstr = to_string(validator.GetError());
334  return SCHEMA_NOT_VALIDATED;
335  }
336  return SCHEMA_VALIDATION_OK;
337 }
338 
339 } // namespace cpjson
340 #endif