IQRF Gateway Daemon
JsonUtils.h
Go to the documentation of this file.
1 /*
2  * Copyright 2016-2017 MICRORISC s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "IqrfLogging.h"
20 #include "rapidjson/rapidjson.h"
21 #include "rapidjson/document.h"
22 #include "rapidjson/istreamwrapper.h"
23 #include "rapidjson/stringbuffer.h"
24 #include "rapidjson/prettywriter.h"
25 #include <vector>
26 #include <utility>
27 #include <stdexcept>
28 
31 namespace jutils
32 {
40  inline void parseJsonFile(const std::string& fname, rapidjson::Document& json)
41  {
42  std::ifstream ifs(fname);
43  if (!ifs.is_open()) {
44  THROW_EX(std::logic_error, "Cannot open: " << PAR(fname));
45  }
46 
47  rapidjson::IStreamWrapper isw(ifs);
48  json.ParseStream(isw);
49 
50  if (json.HasParseError()) {
51  THROW_EX(std::logic_error, "Json parse error: " << NAME_PAR(emsg, json.GetParseError()) <<
52  NAME_PAR(eoffset, json.GetErrorOffset()));
53  }
54  }
55 
63  inline void parseIstream(std::istream& istr, rapidjson::Document& json)
64  {
65  rapidjson::IStreamWrapper isw(istr);
66  json.ParseStream(isw);
67 
68  if (json.HasParseError()) {
69  THROW_EX(std::logic_error, "Json parse error: " << NAME_PAR(emsg, json.GetParseError()) <<
70  NAME_PAR(eoffset, json.GetErrorOffset()));
71  }
72  }
73 
81  inline void parseString(const std::string& str, rapidjson::Document& json)
82  {
83  rapidjson::StringStream s(str.data());
84  rapidjson::Document doc;
85  json.ParseStream(s);
86 
87  if (json.HasParseError()) {
88  THROW_EX(std::logic_error, "Json parse error: " << NAME_PAR(emsg, json.GetParseError()) <<
89  NAME_PAR(eoffset, json.GetErrorOffset()));
90  }
91  }
92 
99  template<typename T>
100  inline void assertIs(const std::string& name, const rapidjson::Value& v) {
101  if (!v.Is<T>())
102  THROW_EX(std::logic_error, "Expected: " << typeid(T).name() << ", detected: " << PAR(name) << NAME_PAR(type, v.GetType()));
103  }
104 
113  template<>
114  inline void assertIs<std::string>(const std::string& name, const rapidjson::Value& v) {
115  if (!v.IsString())
116  THROW_EX(std::logic_error, "Expected: " << typeid(std::string).name() << ", detected: " << PAR(name) << NAME_PAR(type, v.GetType()));
117  }
118 
126  inline void assertIsObject(const std::string& name, const rapidjson::Value& v)
127  {
128  if (!v.IsObject())
129  THROW_EX(std::logic_error, "Expected: Json Object, detected: " << PAR(name) << NAME_PAR(type, v.GetType()));
130  }
131 
138  inline void assertIsArray(const std::string& name, const rapidjson::Value& v)
139  {
140  if (!v.IsArray())
141  THROW_EX(std::logic_error, "Expected: Json Array, detected: " << PAR(name) << NAME_PAR(type, v.GetType()));
142  }
143 
151  inline const rapidjson::Value::ConstMemberIterator getMember(const std::string& name, const rapidjson::Value& jsonValue)
152  {
153  const rapidjson::Value::ConstMemberIterator m = jsonValue.FindMember(name.c_str());
154  if (m == jsonValue.MemberEnd()) {
155  THROW_EX(std::logic_error, "Expected member: " << PAR(name));
156  }
157  return m;
158  }
159 
168  template<typename T>
169  inline T getMemberAs(const std::string& name, const rapidjson::Value& v) {
170  const auto m = getMember(name, v);
171  assertIs<T>(name, m->value);
172  return m->value.Get<T>();
173  }
174 
184  template<>
185  inline std::string getMemberAs<std::string>(const std::string& name, const rapidjson::Value& v) {
186  const auto m = getMember(name, v);
187  assertIs<std::string>(name, m->value);
188  return std::string(m->value.GetString());
189  }
190 
199  inline const rapidjson::Value& getMemberAsObject(const std::string& name, const rapidjson::Value& v)
200  {
201  const auto m = getMember(name, v);
202  assertIsObject(name, m->value);
203  return m->value;
204  }
205 
214  template<typename T>
215  inline std::vector<T> getMemberAsVector(const std::string& name, const rapidjson::Value& v)
216  {
217  std::vector<T> retval;
218  const auto m = getMember(name, v);
219  const rapidjson::Value& vct = m->value;
220  assertIsArray(name, vct);
221 
222  for (auto itr = vct.Begin(); itr != vct.End(); ++itr) {
223  assertIs<T>(name, *itr);
224  retval.push_back(itr->Get<T>());
225  }
226 
227  return retval;
228  }
229 
239  template<>
240  inline std::vector<std::string> getMemberAsVector<std::string>(const std::string& name, const rapidjson::Value& v)
241  {
242  std::vector<std::string> retval;
243  const auto m = getMember(name, v);
244  const rapidjson::Value& vct = m->value;
245  assertIsArray(name, vct);
246 
247  for (auto itr = vct.Begin(); itr != vct.End(); ++itr) {
248  assertIs<std::string>(name, *itr);
249  retval.push_back(std::string(itr->GetString()));
250  }
251 
252  return retval;
253  }
254 
264  template<typename T>
265  inline T getPossibleMemberAs(const std::string& name, const rapidjson::Value& v, T defaultVal) {
266  const auto m = v.FindMember(name.c_str());
267  if (m == v.MemberEnd()) {
268  return defaultVal;
269  }
270  assertIs<T>(name, m->value);
271  return m->value.Get<T>();
272  }
273 
284  template<>
285  inline std::string getPossibleMemberAs<std::string>(const std::string& name, const rapidjson::Value& v, std::string defaultVal) {
286  const auto m = v.FindMember(name.c_str());
287  if (m == v.MemberEnd()) {
288  return defaultVal;
289  }
290  assertIs<std::string>(name, m->value);
291  return std::string(m->value.GetString());
292  }
293 
303  template<typename T>
304  inline std::vector<T> getPossibleMemberAsVector(const std::string& name, const rapidjson::Value& v, std::vector<T> defaultVal = std::vector<T>())
305  {
306  const auto m = v.FindMember(name.c_str());
307  if (m == v.MemberEnd())
308  return defaultVal;
309 
310  const rapidjson::Value& vct = m->value;
311  assertIsArray(name, vct);
312  defaultVal.clear();
313 
314  for (auto itr = vct.Begin(); itr != vct.End(); ++itr) {
315  assertIs<T>(name, *itr);
316  defaultVal.push_back(itr->Get<T>());
317  }
318 
319  return defaultVal;
320  }
321 
331  template<typename T>
332  inline bool getMemberIfExistsAs(const std::string& name, const rapidjson::Value& v, T& member) {
333  const auto m = v.FindMember(name.c_str());
334  if (m == v.MemberEnd()) {
335  return false;
336  }
337  assertIs<T>(name, m->value);
338  member = m->value.Get<T>();
339  return true;
340  }
341 
352  template<>
353  inline bool getMemberIfExistsAs<std::string>(const std::string& name, const rapidjson::Value& v, std::string& member) {
354  const auto m = v.FindMember(name.c_str());
355  if (m == v.MemberEnd()) {
356  return false;
357  }
358  assertIs<std::string>(name, m->value);
359  member = m->value.GetString();
360  return true;
361  }
362 
363 } //jutils
void assertIsArray(const std::string &name, const rapidjson::Value &v)
Assert json value holds Json array.
Definition: JsonUtils.h:138
void parseString(const std::string &str, rapidjson::Document &json)
Parse string with Json content.
Definition: JsonUtils.h:81
const rapidjson::Value & getMemberAsObject(const std::string &name, const rapidjson::Value &v)
Get member with value of type Json object.
Definition: JsonUtils.h:199
const rapidjson::Value::ConstMemberIterator getMember(const std::string &name, const rapidjson::Value &jsonValue)
Get rapidjson member iterator.
Definition: JsonUtils.h:151
std::vector< T > getPossibleMemberAsVector(const std::string &name, const rapidjson::Value &v, std::vector< T > defaultVal=std::vector< T >())
Get possible member with std::vector of values of template type T.
Definition: JsonUtils.h:304
std::vector< T > getMemberAsVector(const std::string &name, const rapidjson::Value &v)
Get member with value std::vector of values of template type T.
Definition: JsonUtils.h:215
void assertIsObject(const std::string &name, const rapidjson::Value &v)
Assert json value holds Json object.
Definition: JsonUtils.h:126
str
Definition: build.py:27
type
Definition: build.py:27
T getMemberAs(const std::string &name, const rapidjson::Value &v)
Get member with value of type T.
Definition: JsonUtils.h:169
void parseIstream(std::istream &istr, rapidjson::Document &json)
Parse stream with Json content.
Definition: JsonUtils.h:63
void assertIs(const std::string &name, const rapidjson::Value &v)
Assert json value holds T type.
Definition: JsonUtils.h:100
Rapid Json values manipulation functions.
void parseJsonFile(const std::string &fname, rapidjson::Document &json)
Parse file with Json content.
Definition: JsonUtils.h:40
T getPossibleMemberAs(const std::string &name, const rapidjson::Value &v, T defaultVal)
Get possible member with value of type T.
Definition: JsonUtils.h:265
bool getMemberIfExistsAs(const std::string &name, const rapidjson::Value &v, T &member)
Get member value if exists of template type T.
Definition: JsonUtils.h:332