Electroneum
Loading...
Searching...
No Matches
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"
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
58namespace cryptonote
59{
60
61namespace json
62{
63
64struct JSON_ERROR : public std::exception
65{
66 protected:
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
79struct 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
87struct 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
95struct BAD_INPUT : public JSON_ERROR
96{
98 {
99 m = "An item failed to convert from json object to native object";
100 }
101};
102
103struct PARSE_FAIL : public JSON_ERROR
104{
106 {
107 m = "Failed to parse the json request";
108 }
109};
110
111template<typename Type>
112inline constexpr bool is_to_hex()
113{
114 return std::is_pod<Type>() && !std::is_integral<Type>();
115}
116
117
118// POD to json value
119template <class Type>
120typename 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
125template <class Type>
126typename 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
142void toJsonValue(rapidjson::Document& doc, const std::string& i, rapidjson::Value& val);
143void fromJsonValue(const rapidjson::Value& val, std::string& str);
144
145void toJsonValue(rapidjson::Document& doc, bool i, rapidjson::Value& val);
146void fromJsonValue(const rapidjson::Value& val, bool& b);
147
148// integers overloads for toJsonValue are not needed for standard promotions
149
150void fromJsonValue(const rapidjson::Value& val, unsigned char& i);
151
152void fromJsonValue(const rapidjson::Value& val, signed char& i);
153
154void fromJsonValue(const rapidjson::Value& val, char& i);
155
156void fromJsonValue(const rapidjson::Value& val, unsigned short& i);
157
158void fromJsonValue(const rapidjson::Value& val, short& i);
159
160void toJsonValue(rapidjson::Document& doc, const unsigned i, rapidjson::Value& val);
161void fromJsonValue(const rapidjson::Value& val, unsigned& i);
162
163void toJsonValue(rapidjson::Document& doc, const int, rapidjson::Value& val);
164void fromJsonValue(const rapidjson::Value& val, int& i);
165
166
167void toJsonValue(rapidjson::Document& doc, const unsigned long long i, rapidjson::Value& val);
168void fromJsonValue(const rapidjson::Value& val, unsigned long long& i);
169
170void toJsonValue(rapidjson::Document& doc, const long long i, rapidjson::Value& val);
171void fromJsonValue(const rapidjson::Value& val, long long& i);
172
173inline void toJsonValue(rapidjson::Document& doc, const unsigned long i, rapidjson::Value& val) {
174 toJsonValue(doc, static_cast<unsigned long long>(i), val);
175}
176void fromJsonValue(const rapidjson::Value& val, unsigned long& i);
177
178inline void toJsonValue(rapidjson::Document& doc, const long i, rapidjson::Value& val) {
179 toJsonValue(doc, static_cast<long long>(i), val);
180}
181void fromJsonValue(const rapidjson::Value& val, long& i);
182
183// end integers
184
185void toJsonValue(rapidjson::Document& doc, const cryptonote::transaction& tx, rapidjson::Value& val);
186void fromJsonValue(const rapidjson::Value& val, cryptonote::transaction& tx);
187
188void toJsonValue(rapidjson::Document& doc, const cryptonote::block& b, rapidjson::Value& val);
189void fromJsonValue(const rapidjson::Value& val, cryptonote::block& b);
190
191void toJsonValue(rapidjson::Document& doc, const cryptonote::txin_v& txin, rapidjson::Value& val);
192void fromJsonValue(const rapidjson::Value& val, cryptonote::txin_v& txin);
193
194void toJsonValue(rapidjson::Document& doc, const cryptonote::txin_gen& txin, rapidjson::Value& val);
195void fromJsonValue(const rapidjson::Value& val, cryptonote::txin_gen& txin);
196
197void toJsonValue(rapidjson::Document& doc, const cryptonote::txin_to_script& txin, rapidjson::Value& val);
198void fromJsonValue(const rapidjson::Value& val, cryptonote::txin_to_script& txin);
199
200void toJsonValue(rapidjson::Document& doc, const cryptonote::txin_to_scripthash& txin, rapidjson::Value& val);
201void fromJsonValue(const rapidjson::Value& val, cryptonote::txin_to_scripthash& txin);
202
203void toJsonValue(rapidjson::Document& doc, const cryptonote::txin_to_key& txin, rapidjson::Value& val);
204void fromJsonValue(const rapidjson::Value& val, cryptonote::txin_to_key& txin);
205
206void toJsonValue(rapidjson::Document& doc, const cryptonote::txin_to_key_public& txin, rapidjson::Value& val);
207void fromJsonValue(const rapidjson::Value& val, cryptonote::txin_to_key_public& txin);
208
209void toJsonValue(rapidjson::Document& doc, const cryptonote::txout_target_v& txout, rapidjson::Value& val);
210void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_target_v& txout);
211
212void toJsonValue(rapidjson::Document& doc, const cryptonote::txout_to_script& txout, rapidjson::Value& val);
213void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_to_script& txout);
214
215void toJsonValue(rapidjson::Document& doc, const cryptonote::txout_to_scripthash& txout, rapidjson::Value& val);
216void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_to_scripthash& txout);
217
218void toJsonValue(rapidjson::Document& doc, const cryptonote::txout_to_key& txout, rapidjson::Value& val);
219void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_to_key& txout);
220
221void toJsonValue(rapidjson::Document& doc, const cryptonote::txout_to_key_public& txout, rapidjson::Value& val);
222void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_to_key_public& txout);
223
224void toJsonValue(rapidjson::Document& doc, const cryptonote::tx_out& txout, rapidjson::Value& val);
225void fromJsonValue(const rapidjson::Value& val, cryptonote::tx_out& txout);
226
227void toJsonValue(rapidjson::Document& doc, const cryptonote::connection_info& info, rapidjson::Value& val);
228void fromJsonValue(const rapidjson::Value& val, cryptonote::connection_info& info);
229
230void toJsonValue(rapidjson::Document& doc, const cryptonote::block_complete_entry& blk, rapidjson::Value& val);
231void fromJsonValue(const rapidjson::Value& val, cryptonote::block_complete_entry& blk);
232
233void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::block_with_transactions& blk, rapidjson::Value& val);
234void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::block_with_transactions& blk);
235
236void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::transaction_info& tx_info, rapidjson::Value& val);
237void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::transaction_info& tx_info);
238
239void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::output_key_and_amount_index& out, rapidjson::Value& val);
240void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_key_and_amount_index& out);
241
242void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::amount_with_random_outputs& out, rapidjson::Value& val);
243void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::amount_with_random_outputs& out);
244
245void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::peer& peer, rapidjson::Value& val);
246void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::peer& peer);
247
248void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::tx_in_pool& tx, rapidjson::Value& val);
249void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::tx_in_pool& tx);
250
251void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::hard_fork_info& info, rapidjson::Value& val);
252void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::hard_fork_info& info);
253
254void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::output_amount_count& out, rapidjson::Value& val);
255void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_amount_count& out);
256
257void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::output_amount_and_index& out, rapidjson::Value& val);
258void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_amount_and_index& out);
259
260void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::output_key_mask_unlocked& out, rapidjson::Value& val);
261void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_key_mask_unlocked& out);
262
263void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::error& err, rapidjson::Value& val);
264void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::error& error);
265
266void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::BlockHeaderResponse& response, rapidjson::Value& val);
267void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::BlockHeaderResponse& response);
268
269void toJsonValue(rapidjson::Document& doc, const rct::rctSig& i, rapidjson::Value& val);
270void fromJsonValue(const rapidjson::Value& i, rct::rctSig& sig);
271
272void toJsonValue(rapidjson::Document& doc, const rct::ecdhTuple& tuple, rapidjson::Value& val);
273void fromJsonValue(const rapidjson::Value& val, rct::ecdhTuple& tuple);
274
275void toJsonValue(rapidjson::Document& doc, const rct::rangeSig& sig, rapidjson::Value& val);
276void fromJsonValue(const rapidjson::Value& val, rct::rangeSig& sig);
277
278void toJsonValue(rapidjson::Document& doc, const rct::Bulletproof& p, rapidjson::Value& val);
279void fromJsonValue(const rapidjson::Value& val, rct::Bulletproof& p);
280
281void toJsonValue(rapidjson::Document& doc, const rct::boroSig& sig, rapidjson::Value& val);
282void fromJsonValue(const rapidjson::Value& val, rct::boroSig& sig);
283
284void toJsonValue(rapidjson::Document& doc, const rct::mgSig& sig, rapidjson::Value& val);
285void fromJsonValue(const rapidjson::Value& val, rct::mgSig& sig);
286
287void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::DaemonInfo& info, rapidjson::Value& val);
288void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::DaemonInfo& info);
289
290void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::output_distribution& dist, rapidjson::Value& val);
291void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_distribution& dist);
292
293template <typename Map>
294typename std::enable_if<sfinae::is_map_like<Map>::value, void>::type toJsonValue(rapidjson::Document& doc, const Map& map, rapidjson::Value& val);
295
296template <typename Map>
297typename std::enable_if<sfinae::is_map_like<Map>::value, void>::type fromJsonValue(const rapidjson::Value& val, Map& map);
298
299template <typename Vec>
300typename std::enable_if<sfinae::is_vector_like<Vec>::value, void>::type toJsonValue(rapidjson::Document& doc, const Vec &vec, rapidjson::Value& val);
301
302template <typename Vec>
303typename std::enable_if<sfinae::is_vector_like<Vec>::value, void>::type fromJsonValue(const rapidjson::Value& val, Vec& vec);
304
305
306// ideally would like to have the below functions in the .cpp file, but
307// unfortunately because of how templates work they have to be here.
308
309template <typename Map>
310typename std::enable_if<sfinae::is_map_like<Map>::value, void>::type toJsonValue(rapidjson::Document& doc, const Map& map, rapidjson::Value& val)
311{
312 val.SetObject();
313
314 auto& al = doc.GetAllocator();
315
316 for (const auto& i : map)
317 {
318 rapidjson::Value k;
319 rapidjson::Value m;
320 toJsonValue(doc, i.first, k);
321 toJsonValue(doc, i.second, m);
322 val.AddMember(k, m, al);
323 }
324}
325
326template <typename Map>
327typename std::enable_if<sfinae::is_map_like<Map>::value, void>::type fromJsonValue(const rapidjson::Value& val, Map& map)
328{
329 if (!val.IsObject())
330 {
331 throw WRONG_TYPE("json object");
332 }
333
334 auto itr = val.MemberBegin();
335
336 while (itr != val.MemberEnd())
337 {
338 typename Map::key_type k;
339 typename Map::mapped_type m;
340 fromJsonValue(itr->name, k);
341 fromJsonValue(itr->value, m);
342 map.emplace(k, m);
343 ++itr;
344 }
345}
346
347template <typename Vec>
348typename std::enable_if<sfinae::is_vector_like<Vec>::value, void>::type toJsonValue(rapidjson::Document& doc, const Vec &vec, rapidjson::Value& val)
349{
350 val.SetArray();
351
352 for (const auto& t : vec)
353 {
354 rapidjson::Value v;
355 toJsonValue(doc, t, v);
356 val.PushBack(v, doc.GetAllocator());
357 }
358}
359
360template <typename Vec>
361typename std::enable_if<sfinae::is_vector_like<Vec>::value, void>::type fromJsonValue(const rapidjson::Value& val, Vec& vec)
362{
363 if (!val.IsArray())
364 {
365 throw WRONG_TYPE("json array");
366 }
367
368 for (rapidjson::SizeType i=0; i < val.Size(); i++)
369 {
370 typename Vec::value_type v;
371 fromJsonValue(val[i], v);
372 vec.push_back(v);
373 }
374}
375
376} // namespace json
377
378} // namespace cryptonote
const char * key
void toJsonValue(rapidjson::Document &doc, const std::string &i, rapidjson::Value &val)
constexpr bool is_to_hex()
void fromJsonValue(const rapidjson::Value &val, std::string &str)
Holds cryptonote related classes and helpers.
Definition ban.cpp:40
boost::variant< txin_gen, txin_to_script, txin_to_scripthash, txin_to_key, txin_to_key_public > txin_v
boost::variant< txout_to_script, txout_to_scripthash, txout_to_key, txout_to_key_public > txout_target_v
std::string pod_to_hex(const t_pod_type &s)
bool hex_to_pod(const std::string &hex_str, t_pod_type &s)
const GenericPointer< typename T::ValueType > T2 value
Definition pointer.h:1225
Type
Type of JSON value.
Definition rapidjson.h:620
CXA_THROW_INFO_T * info
const char * what() const
Definition json_object.h:73
MISSING_KEY(const char *key)
Definition json_object.h:81
WRONG_TYPE(const char *type)
Definition json_object.h:89
rapidjson::Document json
Definition transport.cpp:49