hyperledger/iroha
Iroha - A simple, decentralized ledger http://iroha.tech
json_common.hpp
Go to the documentation of this file.
1 
6 #ifndef IROHA_JSON_COMMON_HPP
7 #define IROHA_JSON_COMMON_HPP
8 
9 #include <numeric>
10 #include <string>
11 #include <unordered_map>
12 
13 #include <rapidjson/document.h>
14 #include <rapidjson/prettywriter.h>
15 #include <rapidjson/stringbuffer.h>
16 
17 #include "common/bind.hpp"
18 #include "common/byteutils.hpp"
19 #include "common/obj_utils.hpp"
20 #include "model/block.hpp"
21 #include "model/common.hpp"
23 #include "model/signature.hpp"
24 
25 namespace iroha {
26  namespace model {
27  namespace converters {
32  template <typename V>
33  struct Convert {
40  template <typename T>
41  auto operator()(T &&x) const {
42  return boost::optional<V>(std::forward<T>(x));
43  }
44  };
45 
46  template <size_t size>
47  struct Convert<blob_t<size>> {
48  template <typename T>
49  auto operator()(T &&x) const {
50  return hexstringToArray<size>(std::forward<T>(x));
51  }
52  };
53 
62  template <typename T, typename D>
63  boost::optional<T> deserializeField(const D &document,
64  const std::string &field) {
65  if (document.HasMember(field.c_str())
66  and document[field.c_str()].template Is<T>()) {
67  return document[field.c_str()].template Get<T>();
68  }
69  return boost::none;
70  }
71 
76  template <typename D>
81  explicit FieldDeserializer(const D &document) : document(document) {}
82 
97  template <typename T,
98  typename V,
99  typename B,
100  typename Convert = Convert<V>>
101  auto deserialize(V B::*member,
102  const std::string &field,
103  Convert transform = Convert()) {
104  return [this, member, field, transform](auto block) {
105  return deserializeField<T>(document, field) | transform
106  | assignObjectField(block, member);
107  };
108  }
109 
118  template <typename V, typename B>
119  auto Uint(V B::*member, const std::string &field) {
120  return deserialize<uint32_t>(member, field);
121  }
122 
131  template <typename V, typename B>
132  auto Uint64(V B::*member, const std::string &field) {
133  return deserialize<uint64_t>(member, field);
134  }
135 
144  template <typename V, typename B>
145  auto Bool(V B::*member, const std::string &field) {
146  return deserialize<bool>(member, field);
147  }
148 
157  template <typename V, typename B>
158  auto String(V B::*member, const std::string &field) {
159  return deserialize<std::string>(member, field);
160  }
161 
167  auto String(const std::string &field) {
168  return deserializeField<std::string>(document, field);
169  }
170 
182  template <typename V, typename B, typename Convert = Convert<V>>
183  auto Array(V B::*member,
184  const std::string &field,
185  Convert transform = Convert()) {
186  return deserialize<rapidjson::Value::ConstArray>(
187  member, field, transform);
188  }
189 
198  template <typename V, typename B, typename Convert = Convert<V>>
199  auto Object(V B::*member,
200  const std::string &field,
201  Convert transform = Convert()) {
202  return deserialize<rapidjson::Value::ConstObject>(
203  member, field, transform);
204  }
205 
206  // document for deserialization
207  const D &document;
208  };
209 
216  template <typename D>
217  auto makeFieldDeserializer(const D &document) {
218  return FieldDeserializer<D>(document);
219  }
220 
221  template <>
222  struct Convert<Signature> {
223  template <typename T>
224  auto operator()(T &&x) const {
225  auto des = makeFieldDeserializer(std::forward<T>(x));
226  return boost::make_optional(Signature())
227  | des.String(&Signature::pubkey, "pubkey")
228  | des.String(&Signature::signature, "signature");
229  }
230  };
231 
232  template <>
233  struct Convert<Block::SignaturesType> {
234  template <typename T>
235  auto operator()(T &&x) const {
236  auto acc_signatures = [](auto init, auto &x) {
237  return init | [&x](auto signatures) {
238  return Convert<Signature>()(x) | [&signatures](auto signature) {
239  signatures.push_back(signature);
240  return boost::make_optional(std::move(signatures));
241  };
242  };
243  };
244  return std::accumulate(x.begin(),
245  x.end(),
246  boost::make_optional(Block::SignaturesType()),
247  acc_signatures);
248  }
249  };
250 
251  template <>
252  struct Convert<GetTransactions::TxHashCollectionType> {
253  template <typename T>
254  auto operator()(T &&x) const {
255  auto acc_hashes = [](auto init, auto &x) {
256  return init | [&x](auto tx_hashes)
257  -> boost::optional<
259  // If invalid type included, returns nullopt
260  if (not x.IsString()) {
261  return boost::none;
262  }
263  auto tx_hash_opt =
264  Convert<GetTransactions::TxHashType>()(x.GetString());
265  if (not tx_hash_opt) {
266  // If the the hash is wrong, just skip.
267  return boost::make_optional(std::move(tx_hashes));
268  }
269  return tx_hash_opt | [&tx_hashes](auto tx_hash) {
270  tx_hashes.push_back(tx_hash);
271  return boost::make_optional(std::move(tx_hashes));
272  };
273  };
274  };
275  return std::accumulate(
276  x.begin(),
277  x.end(),
278  boost::make_optional(GetTransactions::TxHashCollectionType()),
279  acc_hashes);
280  }
281  };
282 
289  rapidjson::Value serializeSignature(
290  const Signature &signature,
291  rapidjson::Document::AllocatorType &allocator);
292 
298  boost::optional<rapidjson::Document> stringToJson(
299  const std::string &string);
300 
306  std::string jsonToString(const rapidjson::Document &document);
307  } // namespace converters
308  } // namespace model
309 } // namespace iroha
310 
311 #endif // IROHA_JSON_COMMON_HPP
Definition: signature.hpp:17
auto Object(V B::*member, const std::string &field, Convert transform=Convert())
Definition: json_common.hpp:199
auto Uint64(V B::*member, const std::string &field)
Definition: json_common.hpp:132
auto String(const std::string &field)
Definition: json_common.hpp:167
std::string jsonToString(const Document &document)
Definition: json_common.cpp:35
auto operator()(T &&x) const
Definition: json_common.hpp:254
auto Array(V B::*member, const std::string &field, Convert transform=Convert())
Definition: json_common.hpp:183
const D & document
Definition: json_common.hpp:207
auto deserialize(V B::*member, const std::string &field, Convert transform=Convert())
Definition: json_common.hpp:101
auto Bool(V B::*member, const std::string &field)
Definition: json_common.hpp:145
auto operator()(T &&x) const
Definition: json_common.hpp:224
auto operator()(T &&x) const
Definition: json_common.hpp:235
Definition: block_query.hpp:15
FieldDeserializer(const D &document)
Definition: json_common.hpp:81
boost::optional< T > deserializeField(const D &document, const std::string &field)
Definition: json_common.hpp:63
std::vector< TxHashType > TxHashCollectionType
Definition: get_transactions.hpp:48
decltype(sigs) SignaturesType
Definition: block.hpp:39
Definition: blob.hpp:31
Definition: get_transactions.hpp:46
Definition: json_common.hpp:33
Value serializeSignature(const Signature &signature, Document::AllocatorType &allocator)
Definition: json_common.cpp:13
auto assignObjectField(B object, V B::*member)
Definition: obj_utils.hpp:63
pubkey_t pubkey
Definition: signature.hpp:26
auto makeFieldDeserializer(const D &document)
Definition: json_common.hpp:217
sig_t signature
Definition: signature.hpp:22
boost::optional< Document > stringToJson(const std::string &string)
Definition: json_common.cpp:26
auto operator()(T &&x) const
Definition: json_common.hpp:41
Definition: json_common.hpp:222
Definition: json_common.hpp:77
Definition: block.hpp:24
auto operator()(T &&x) const
Definition: json_common.hpp:49
auto String(V B::*member, const std::string &field)
Definition: json_common.hpp:158
auto Uint(V B::*member, const std::string &field)
Definition: json_common.hpp:119