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 // Enable std::string support in rapidjson
14 #define RAPIDJSON_HAS_STDSTRING 1
15 #include <rapidjson/document.h>
16 #include <rapidjson/prettywriter.h>
17 #include <rapidjson/stringbuffer.h>
18 
19 #include "common/bind.hpp"
20 #include "common/byteutils.hpp"
21 #include "common/obj_utils.hpp"
22 #include "model/block.hpp"
23 #include "model/common.hpp"
25 #include "model/signature.hpp"
26 
27 namespace iroha {
28  namespace model {
29  namespace converters {
34  template <typename V>
35  struct Convert {
42  template <typename T>
43  auto operator()(T &&x) const {
44  return boost::optional<V>(std::forward<T>(x));
45  }
46  };
47 
48  template <size_t size>
49  struct Convert<blob_t<size>> {
50  template <typename T>
51  auto operator()(T &&x) const {
52  return hexstringToArray<size>(std::forward<T>(x));
53  }
54  };
55 
64  template <typename T, typename D>
65  boost::optional<T> deserializeField(const D &document,
66  const std::string &field) {
67  if (document.HasMember(field.c_str())
68  and document[field.c_str()].template Is<T>()) {
69  return document[field.c_str()].template Get<T>();
70  }
71  return boost::none;
72  }
73 
78  template <typename D>
83  explicit FieldDeserializer(const D &document) : document(document) {}
84 
99  template <typename T,
100  typename V,
101  typename B,
102  typename Convert = Convert<V>>
103  auto deserialize(V B::*member,
104  const std::string &field,
105  Convert transform = Convert()) {
106  return [this, member, field, transform](auto block) {
107  return deserializeField<T>(document, field) | transform
108  | assignObjectField(block, member);
109  };
110  }
111 
120  template <typename V, typename B>
121  auto Uint(V B::*member, const std::string &field) {
122  return deserialize<uint32_t>(member, field);
123  }
124 
133  template <typename V, typename B>
134  auto Uint64(V B::*member, const std::string &field) {
135  return deserialize<uint64_t>(member, field);
136  }
137 
146  template <typename V, typename B>
147  auto Bool(V B::*member, const std::string &field) {
148  return deserialize<bool>(member, field);
149  }
150 
159  template <typename V, typename B>
160  auto String(V B::*member, const std::string &field) {
161  return deserialize<std::string>(member, field);
162  }
163 
169  auto String(const std::string &field) {
170  return deserializeField<std::string>(document, field);
171  }
172 
184  template <typename V, typename B, typename Convert = Convert<V>>
185  auto Array(V B::*member,
186  const std::string &field,
187  Convert transform = Convert()) {
188  return deserialize<rapidjson::Value::ConstArray>(
189  member, field, transform);
190  }
191 
200  template <typename V, typename B, typename Convert = Convert<V>>
201  auto Object(V B::*member,
202  const std::string &field,
203  Convert transform = Convert()) {
204  return deserialize<rapidjson::Value::ConstObject>(
205  member, field, transform);
206  }
207 
208  // document for deserialization
209  const D &document;
210  };
211 
218  template <typename D>
219  auto makeFieldDeserializer(const D &document) {
220  return FieldDeserializer<D>(document);
221  }
222 
223  template <>
224  struct Convert<Signature> {
225  template <typename T>
226  auto operator()(T &&x) const {
227  auto des = makeFieldDeserializer(std::forward<T>(x));
228  return boost::make_optional(Signature())
229  | des.String(&Signature::pubkey, "pubkey")
230  | des.String(&Signature::signature, "signature");
231  }
232  };
233 
234  template <>
235  struct Convert<Block::SignaturesType> {
236  template <typename T>
237  auto operator()(T &&x) const {
238  auto acc_signatures = [](auto init, auto &x) {
239  return init | [&x](auto signatures) {
240  return Convert<Signature>()(x) | [&signatures](auto signature) {
241  signatures.push_back(signature);
242  return boost::make_optional(std::move(signatures));
243  };
244  };
245  };
246  return std::accumulate(x.begin(),
247  x.end(),
248  boost::make_optional(Block::SignaturesType()),
249  acc_signatures);
250  }
251  };
252 
253  template <>
254  struct Convert<GetTransactions::TxHashCollectionType> {
255  template <typename T>
256  auto operator()(T &&x) const {
257  auto acc_hashes = [](auto init, auto &x) {
258  return init | [&x](auto tx_hashes)
259  -> boost::optional<
261  // If invalid type included, returns nullopt
262  if (not x.IsString()) {
263  return boost::none;
264  }
265  auto tx_hash_opt =
266  Convert<GetTransactions::TxHashType>()(x.GetString());
267  if (not tx_hash_opt) {
268  // If the the hash is wrong, just skip.
269  return boost::make_optional(std::move(tx_hashes));
270  }
271  return tx_hash_opt | [&tx_hashes](auto tx_hash) {
272  tx_hashes.push_back(tx_hash);
273  return boost::make_optional(std::move(tx_hashes));
274  };
275  };
276  };
277  return std::accumulate(
278  x.begin(),
279  x.end(),
280  boost::make_optional(GetTransactions::TxHashCollectionType()),
281  acc_hashes);
282  }
283  };
284 
291  rapidjson::Value serializeSignature(
292  const Signature &signature,
293  rapidjson::Document::AllocatorType &allocator);
294 
300  boost::optional<rapidjson::Document> stringToJson(
301  const std::string &string);
302 
308  std::string jsonToString(const rapidjson::Document &document);
309  } // namespace converters
310  } // namespace model
311 } // namespace iroha
312 
313 #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:201
auto Uint64(V B::*member, const std::string &field)
Definition: json_common.hpp:134
auto operator()(T &&x) const
Definition: json_common.hpp:237
auto String(const std::string &field)
Definition: json_common.hpp:169
std::string jsonToString(const Document &document)
Definition: json_common.cpp:35
auto Array(V B::*member, const std::string &field, Convert transform=Convert())
Definition: json_common.hpp:185
const D & document
Definition: json_common.hpp:209
auto deserialize(V B::*member, const std::string &field, Convert transform=Convert())
Definition: json_common.hpp:103
auto Bool(V B::*member, const std::string &field)
Definition: json_common.hpp:147
Definition: block_query.hpp:16
auto operator()(T &&x) const
Definition: json_common.hpp:51
FieldDeserializer(const D &document)
Definition: json_common.hpp:83
boost::optional< T > deserializeField(const D &document, const std::string &field)
Definition: json_common.hpp:65
std::vector< TxHashType > TxHashCollectionType
Definition: get_transactions.hpp:48
decltype(sigs) SignaturesType
Definition: block.hpp:39
auto operator()(T &&x) const
Definition: json_common.hpp:43
Definition: blob.hpp:49
Definition: get_transactions.hpp:46
Definition: json_common.hpp:35
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 operator()(T &&x) const
Definition: json_common.hpp:256
auto makeFieldDeserializer(const D &document)
Definition: json_common.hpp:219
sig_t signature
Definition: signature.hpp:22
boost::optional< Document > stringToJson(const std::string &string)
Definition: json_common.cpp:26
Definition: json_common.hpp:224
Definition: json_common.hpp:79
Definition: block.hpp:24
auto operator()(T &&x) const
Definition: json_common.hpp:226
auto String(V B::*member, const std::string &field)
Definition: json_common.hpp:160
auto Uint(V B::*member, const std::string &field)
Definition: json_common.hpp:121