Electroneum
json_object.h
Go to the documentation of this file.
1 // Copyright (c) 2016-2019, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #pragma once
30 
31 #include "string_tools.h"
32 #include "rapidjson/document.h"
36 #include "common/sfinae_helpers.h"
37 
38 #define OBJECT_HAS_MEMBER_OR_THROW(val, key) \
39  do \
40  { \
41  if (!val.HasMember(key)) \
42  { \
43  throw cryptonote::json::MISSING_KEY(key); \
44  } \
45  } while (0);
46 
47 #define INSERT_INTO_JSON_OBJECT(jsonVal, doc, key, source) \
48  rapidjson::Value key##Val; \
49  cryptonote::json::toJsonValue(doc, source, key##Val); \
50  jsonVal.AddMember(#key, key##Val, doc.GetAllocator());
51 
52 #define GET_FROM_JSON_OBJECT(source, dst, key) \
53  OBJECT_HAS_MEMBER_OR_THROW(source, #key) \
54  decltype(dst) dstVal##key; \
55  cryptonote::json::fromJsonValue(source[#key], dstVal##key); \
56  dst = dstVal##key;
57 
58 namespace cryptonote
59 {
60 
61 namespace json
62 {
63 
64 struct JSON_ERROR : public std::exception
65 {
66  protected:
67  JSON_ERROR() { }
68  std::string m;
69 
70  public:
71  virtual ~JSON_ERROR() { }
72 
73  const char* what() const throw()
74  {
75  return m.c_str();
76  }
77 };
78 
79 struct MISSING_KEY : public JSON_ERROR
80 {
81  MISSING_KEY(const char* key)
82  {
83  m = std::string("Key \"") + key + "\" missing from object.";
84  }
85 };
86 
87 struct WRONG_TYPE : public JSON_ERROR
88 {
89  WRONG_TYPE(const char* type)
90  {
91  m = std::string("Json value has incorrect type, expected: ") + type;
92  }
93 };
94 
95 struct BAD_INPUT : public JSON_ERROR
96 {
98  {
99  m = "An item failed to convert from json object to native object";
100  }
101 };
102 
103 struct PARSE_FAIL : public JSON_ERROR
104 {
106  {
107  m = "Failed to parse the json request";
108  }
109 };
110 
111 template<typename Type>
112 inline constexpr bool is_to_hex()
113 {
114  return std::is_pod<Type>() && !std::is_integral<Type>();
115 }
116 
117 
118 // POD to json value
119 template <class Type>
120 typename std::enable_if<is_to_hex<Type>()>::type toJsonValue(rapidjson::Document& doc, const Type& pod, rapidjson::Value& value)
121 {
122  value = rapidjson::Value(epee::string_tools::pod_to_hex(pod).c_str(), doc.GetAllocator());
123 }
124 
125 template <class Type>
126 typename std::enable_if<is_to_hex<Type>()>::type fromJsonValue(const rapidjson::Value& val, Type& t)
127 {
128  if (!val.IsString())
129  {
130  throw WRONG_TYPE("string");
131  }
132 
133  //TODO: handle failure to convert hex string to POD type
134  bool success = epee::string_tools::hex_to_pod(val.GetString(), t);
135 
136  if (!success)
137  {
138  throw BAD_INPUT();
139  }
140 }
141 
142 void toJsonValue(rapidjson::Document& doc, const std::string& i, rapidjson::Value& val);
143 void fromJsonValue(const rapidjson::Value& val, std::string& str);
144 
145 void toJsonValue(rapidjson::Document& doc, bool i, rapidjson::Value& val);
146 void fromJsonValue(const rapidjson::Value& val, bool& b);
147 
148 // integers overloads for toJsonValue are not needed for standard promotions
149 
150 void fromJsonValue(const rapidjson::Value& val, unsigned char& i);
151 
152 void fromJsonValue(const rapidjson::Value& val, signed char& i);
153 
154 void fromJsonValue(const rapidjson::Value& val, char& i);
155 
156 void fromJsonValue(const rapidjson::Value& val, unsigned short& i);
157 
158 void fromJsonValue(const rapidjson::Value& val, short& i);
159 
160 void toJsonValue(rapidjson::Document& doc, const unsigned i, rapidjson::Value& val);
161 void fromJsonValue(const rapidjson::Value& val, unsigned& i);
162 
163 void toJsonValue(rapidjson::Document& doc, const int, rapidjson::Value& val);
164 void fromJsonValue(const rapidjson::Value& val, int& i);
165 
166 
167 void toJsonValue(rapidjson::Document& doc, const unsigned long long i, rapidjson::Value& val);
168 void fromJsonValue(const rapidjson::Value& val, unsigned long long& i);
169 
170 void toJsonValue(rapidjson::Document& doc, const long long i, rapidjson::Value& val);
171 void fromJsonValue(const rapidjson::Value& val, long long& i);
172 
173 inline void toJsonValue(rapidjson::Document& doc, const unsigned long i, rapidjson::Value& val) {
174  toJsonValue(doc, static_cast<unsigned long long>(i), val);
175 }
176 void fromJsonValue(const rapidjson::Value& val, unsigned long& i);
177 
178 inline void toJsonValue(rapidjson::Document& doc, const long i, rapidjson::Value& val) {
179  toJsonValue(doc, static_cast<long long>(i), val);
180 }
181 void fromJsonValue(const rapidjson::Value& val, long& i);
182 
183 // end integers
184 
185 void toJsonValue(rapidjson::Document& doc, const cryptonote::transaction& tx, rapidjson::Value& val);
186 void fromJsonValue(const rapidjson::Value& val, cryptonote::transaction& tx);
187 
188 void toJsonValue(rapidjson::Document& doc, const cryptonote::block& b, rapidjson::Value& val);
189 void fromJsonValue(const rapidjson::Value& val, cryptonote::block& b);
190 
191 void toJsonValue(rapidjson::Document& doc, const cryptonote::txin_v& txin, rapidjson::Value& val);
192 void fromJsonValue(const rapidjson::Value& val, cryptonote::txin_v& txin);
193 
194 void toJsonValue(rapidjson::Document& doc, const cryptonote::txin_gen& txin, rapidjson::Value& val);
195 void fromJsonValue(const rapidjson::Value& val, cryptonote::txin_gen& txin);
196 
197 void toJsonValue(rapidjson::Document& doc, const cryptonote::txin_to_script& txin, rapidjson::Value& val);
198 void fromJsonValue(const rapidjson::Value& val, cryptonote::txin_to_script& txin);
199 
200 void toJsonValue(rapidjson::Document& doc, const cryptonote::txin_to_scripthash& txin, rapidjson::Value& val);
201 void fromJsonValue(const rapidjson::Value& val, cryptonote::txin_to_scripthash& txin);
202 
203 void toJsonValue(rapidjson::Document& doc, const cryptonote::txin_to_key& txin, rapidjson::Value& val);
204 void fromJsonValue(const rapidjson::Value& val, cryptonote::txin_to_key& txin);
205 
206 void toJsonValue(rapidjson::Document& doc, const cryptonote::txout_target_v& txout, rapidjson::Value& val);
207 void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_target_v& txout);
208 
209 void toJsonValue(rapidjson::Document& doc, const cryptonote::txout_to_script& txout, rapidjson::Value& val);
210 void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_to_script& txout);
211 
212 void toJsonValue(rapidjson::Document& doc, const cryptonote::txout_to_scripthash& txout, rapidjson::Value& val);
213 void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_to_scripthash& txout);
214 
215 void toJsonValue(rapidjson::Document& doc, const cryptonote::txout_to_key& txout, rapidjson::Value& val);
216 void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_to_key& txout);
217 
218 void toJsonValue(rapidjson::Document& doc, const cryptonote::tx_out& txout, rapidjson::Value& val);
219 void fromJsonValue(const rapidjson::Value& val, cryptonote::tx_out& txout);
220 
221 void toJsonValue(rapidjson::Document& doc, const cryptonote::connection_info& info, rapidjson::Value& val);
222 void fromJsonValue(const rapidjson::Value& val, cryptonote::connection_info& info);
223 
224 void toJsonValue(rapidjson::Document& doc, const cryptonote::block_complete_entry& blk, rapidjson::Value& val);
225 void fromJsonValue(const rapidjson::Value& val, cryptonote::block_complete_entry& blk);
226 
227 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::block_with_transactions& blk, rapidjson::Value& val);
228 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::block_with_transactions& blk);
229 
230 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::transaction_info& tx_info, rapidjson::Value& val);
231 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::transaction_info& tx_info);
232 
233 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::output_key_and_amount_index& out, rapidjson::Value& val);
234 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_key_and_amount_index& out);
235 
236 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::amount_with_random_outputs& out, rapidjson::Value& val);
237 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::amount_with_random_outputs& out);
238 
239 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::peer& peer, rapidjson::Value& val);
240 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::peer& peer);
241 
242 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::tx_in_pool& tx, rapidjson::Value& val);
243 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::tx_in_pool& tx);
244 
245 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::hard_fork_info& info, rapidjson::Value& val);
246 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::hard_fork_info& info);
247 
248 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::output_amount_count& out, rapidjson::Value& val);
249 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_amount_count& out);
250 
251 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::output_amount_and_index& out, rapidjson::Value& val);
252 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_amount_and_index& out);
253 
254 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::output_key_mask_unlocked& out, rapidjson::Value& val);
255 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_key_mask_unlocked& out);
256 
257 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::error& err, rapidjson::Value& val);
258 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::error& error);
259 
260 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::BlockHeaderResponse& response, rapidjson::Value& val);
261 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::BlockHeaderResponse& response);
262 
263 void toJsonValue(rapidjson::Document& doc, const rct::rctSig& i, rapidjson::Value& val);
264 void fromJsonValue(const rapidjson::Value& i, rct::rctSig& sig);
265 
266 void toJsonValue(rapidjson::Document& doc, const rct::ecdhTuple& tuple, rapidjson::Value& val);
267 void fromJsonValue(const rapidjson::Value& val, rct::ecdhTuple& tuple);
268 
269 void toJsonValue(rapidjson::Document& doc, const rct::rangeSig& sig, rapidjson::Value& val);
270 void fromJsonValue(const rapidjson::Value& val, rct::rangeSig& sig);
271 
272 void toJsonValue(rapidjson::Document& doc, const rct::Bulletproof& p, rapidjson::Value& val);
273 void fromJsonValue(const rapidjson::Value& val, rct::Bulletproof& p);
274 
275 void toJsonValue(rapidjson::Document& doc, const rct::boroSig& sig, rapidjson::Value& val);
276 void fromJsonValue(const rapidjson::Value& val, rct::boroSig& sig);
277 
278 void toJsonValue(rapidjson::Document& doc, const rct::mgSig& sig, rapidjson::Value& val);
279 void fromJsonValue(const rapidjson::Value& val, rct::mgSig& sig);
280 
281 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::DaemonInfo& info, rapidjson::Value& val);
282 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::DaemonInfo& info);
283 
284 void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::output_distribution& dist, rapidjson::Value& val);
285 void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_distribution& dist);
286 
287 template <typename Map>
288 typename std::enable_if<sfinae::is_map_like<Map>::value, void>::type toJsonValue(rapidjson::Document& doc, const Map& map, rapidjson::Value& val);
289 
290 template <typename Map>
291 typename std::enable_if<sfinae::is_map_like<Map>::value, void>::type fromJsonValue(const rapidjson::Value& val, Map& map);
292 
293 template <typename Vec>
294 typename std::enable_if<sfinae::is_vector_like<Vec>::value, void>::type toJsonValue(rapidjson::Document& doc, const Vec &vec, rapidjson::Value& val);
295 
296 template <typename Vec>
297 typename std::enable_if<sfinae::is_vector_like<Vec>::value, void>::type fromJsonValue(const rapidjson::Value& val, Vec& vec);
298 
299 
300 // ideally would like to have the below functions in the .cpp file, but
301 // unfortunately because of how templates work they have to be here.
302 
303 template <typename Map>
304 typename std::enable_if<sfinae::is_map_like<Map>::value, void>::type toJsonValue(rapidjson::Document& doc, const Map& map, rapidjson::Value& val)
305 {
306  val.SetObject();
307 
308  auto& al = doc.GetAllocator();
309 
310  for (const auto& i : map)
311  {
312  rapidjson::Value k;
313  rapidjson::Value m;
314  toJsonValue(doc, i.first, k);
315  toJsonValue(doc, i.second, m);
316  val.AddMember(k, m, al);
317  }
318 }
319 
320 template <typename Map>
321 typename std::enable_if<sfinae::is_map_like<Map>::value, void>::type fromJsonValue(const rapidjson::Value& val, Map& map)
322 {
323  if (!val.IsObject())
324  {
325  throw WRONG_TYPE("json object");
326  }
327 
328  auto itr = val.MemberBegin();
329 
330  while (itr != val.MemberEnd())
331  {
332  typename Map::key_type k;
333  typename Map::mapped_type m;
334  fromJsonValue(itr->name, k);
335  fromJsonValue(itr->value, m);
336  map.emplace(k, m);
337  ++itr;
338  }
339 }
340 
341 template <typename Vec>
342 typename std::enable_if<sfinae::is_vector_like<Vec>::value, void>::type toJsonValue(rapidjson::Document& doc, const Vec &vec, rapidjson::Value& val)
343 {
344  val.SetArray();
345 
346  for (const auto& t : vec)
347  {
348  rapidjson::Value v;
349  toJsonValue(doc, t, v);
350  val.PushBack(v, doc.GetAllocator());
351  }
352 }
353 
354 template <typename Vec>
355 typename std::enable_if<sfinae::is_vector_like<Vec>::value, void>::type fromJsonValue(const rapidjson::Value& val, Vec& vec)
356 {
357  if (!val.IsArray())
358  {
359  throw WRONG_TYPE("json array");
360  }
361 
362  for (rapidjson::SizeType i=0; i < val.Size(); i++)
363  {
364  typename Vec::value_type v;
365  fromJsonValue(val[i], v);
366  vec.push_back(v);
367  }
368 }
369 
370 } // namespace json
371 
372 } // namespace cryptonote
Definition: cryptonote_basic.h:205
expect< void > success() noexcept
Definition: expect.h:397
int b
Definition: base.py:1
void toJsonValue(rapidjson::Document &doc, const std::string &i, rapidjson::Value &val)
Definition: json_object.cpp:112
constexpr bool is_to_hex()
Definition: json_object.h:112
void fromJsonValue(const rapidjson::Value &val, std::string &str)
Definition: json_object.cpp:117
Holds cryptonote related classes and helpers.
Definition: db_bdb.cpp:226
boost::variant< txout_to_script, txout_to_scripthash, txout_to_key > txout_target_v
Definition: cryptonote_basic.h:140
boost::variant< txin_gen, txin_to_script, txin_to_scripthash, txin_to_key > txin_v
Definition: cryptonote_basic.h:138
error
Tracks LMDB error codes.
Definition: error.h:45
CXA_THROW_INFO_T * info
Definition: stack_trace.cpp:91
Definition: cryptonote_protocol_defs.h:118
Definition: cryptonote_basic.h:410
Definition: cryptonote_protocol_defs.h:49
Definition: json_object.h:96
BAD_INPUT()
Definition: json_object.h:97
Definition: json_object.h:65
std::string m
Definition: json_object.h:68
const char * what() const
Definition: json_object.h:73
virtual ~JSON_ERROR()
Definition: json_object.h:71
JSON_ERROR()
Definition: json_object.h:67
Definition: json_object.h:80
MISSING_KEY(const char *key)
Definition: json_object.h:81
Definition: json_object.h:104
PARSE_FAIL()
Definition: json_object.h:105
Definition: json_object.h:88
WRONG_TYPE(const char *type)
Definition: json_object.h:89
Definition: core_rpc_server_commands_defs.h:1197
Definition: message_data_structs.h:160
Definition: message_data_structs.h:175
Definition: message_data_structs.h:72
Definition: message_data_structs.h:47
Definition: message_data_structs.h:143
Definition: message_data_structs.h:130
Definition: message_data_structs.h:117
Definition: message_data_structs.h:109
Definition: message_data_structs.h:204
Definition: message_data_structs.h:64
Definition: message_data_structs.h:123
Definition: message_data_structs.h:78
Definition: message_data_structs.h:57
Definition: message_data_structs.h:88
Definition: core_rpc_server_commands_defs.h:1320
Definition: cryptonote_basic.h:144
Definition: cryptonote_basic.h:88
Definition: cryptonote_basic.h:125
Definition: cryptonote_basic.h:97
Definition: cryptonote_basic.h:110
Definition: cryptonote_basic.h:78
Definition: cryptonote_basic.h:62
Definition: cryptonote_basic.h:73
Definition: rctTypes.h:180
Definition: rctTypes.h:139
Definition: rctTypes.h:124
Definition: rctTypes.h:152
Definition: rctTypes.h:169
Definition: rctTypes.h:436
rapidjson::Document json
Definition: transport.cpp:49