TARAXA
Loading...
Searching...
No Matches
encoding_rlp.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <libdevcore/RLP.h>
4
5#include <optional>
6
7namespace taraxa::util {
8using dev::RLP;
9
12 RLP const& value;
14
16 RLPDecoderRef(RLP const& value, bool strict = false)
17 : RLPDecoderRef(value, strict ? RLP::VeryStrict : RLP::LaissezFaire) {}
18};
19
20template <typename... Params>
21void rlp_tuple(RLPEncoderRef encoding, Params const&... args);
22
23template <typename T>
24auto rlp(RLPEncoderRef encoding, T const& target) -> decltype(RLP().toInt<T>(), void()) {
25 encoding.append(target);
26}
27
28template <unsigned N>
29void rlp(RLPEncoderRef encoding, dev::FixedHash<N> const& target) {
30 encoding.append(target);
31}
32
33template <typename T>
34inline auto rlp(RLPEncoderRef encoding, T const& target) -> decltype(target.rlp(encoding), void()) {
35 target.rlp(encoding);
36}
37
38inline auto rlp(RLPEncoderRef encoding, std::string const& target) { encoding.append(target); }
39
40inline auto rlp(RLPEncoderRef encoding, dev::bytes const& target) { encoding.append(target); }
41
42template <typename Param>
43void rlp(RLPEncoderRef encoding, std::optional<Param> const& target) {
44 if (target) {
45 rlp(encoding, *target);
46 } else {
47 encoding.append(unsigned(0));
48 }
49}
50
51template <typename Param>
52void rlp(RLPEncoderRef encoding, std::shared_ptr<Param> const& target) {
53 if (target) {
54 rlp(encoding, *target);
55 } else {
56 encoding.append(unsigned(0));
57 }
58}
59
60template <typename T1, typename T2>
61void rlp(RLPEncoderRef encoding, std::pair<T1, T2> const& target) {
62 rlp_tuple(encoding, target.first, target.second);
63}
64
65template <typename Sequence>
66auto rlp(RLPEncoderRef encoding, Sequence const& target) -> decltype(target.size(), target.begin(), target.end(),
67 void()) {
68 encoding.appendList(target.size());
69 for (auto const& v : target) {
70 rlp(encoding, v);
71 }
72}
73
74template <typename Param, typename... Params>
75void __enc_rlp_tuple_body__(RLPEncoderRef encoding, Param const& target, Params const&... rest) {
76 rlp(encoding, target);
77 if constexpr (sizeof...(rest) != 0) {
78 __enc_rlp_tuple_body__(encoding, rest...);
79 }
80}
81
82template <typename... Params>
83void rlp_tuple(RLPEncoderRef encoding, Params const&... args) {
84 constexpr auto num_elements = sizeof...(args);
85 static_assert(0 < num_elements);
86 encoding.appendList(num_elements);
87 __enc_rlp_tuple_body__(encoding, args...);
88}
89
90template <typename... Params>
91void rlp_tuple(RLPDecoderRef encoding, Params&... args);
92
93template <typename T>
94auto rlp(RLPDecoderRef encoding, T& target) -> decltype(encoding.value.toInt<T>(), void()) {
95 target = encoding.value.toInt<T>(encoding.strictness);
96}
97
98template <unsigned N>
99void rlp(RLPDecoderRef encoding, dev::FixedHash<N>& target) {
100 target = encoding.value.toHash<dev::FixedHash<N>>(encoding.strictness);
101}
102
103inline auto rlp(RLPDecoderRef encoding, std::string& target) { target = encoding.value.toString(encoding.strictness); }
104
105inline auto rlp(RLPDecoderRef encoding, dev::bytes& target) { target = encoding.value.toBytes(encoding.strictness); }
106
107template <typename Param>
108void rlp(RLPDecoderRef encoding, std::optional<Param>& target) {
109 if (encoding.value.isNull() || encoding.value.isEmpty()) {
110 target = std::nullopt;
111 } else {
112 rlp(encoding, target.emplace());
113 }
114}
115
116template <typename Param>
117void rlp(RLPDecoderRef encoding, std::shared_ptr<Param>& target) {
118 if (encoding.value.isNull() || encoding.value.isEmpty()) {
119 target = nullptr;
120 } else {
121 target = std::make_shared<Param>();
122 rlp(encoding, *target);
123 }
124}
125
126template <typename Sequence>
127auto rlp(RLPDecoderRef encoding, Sequence& target) -> decltype(target.emplace_back(), void()) {
128 for (auto i : encoding.value) {
129 rlp(RLPDecoderRef(i, encoding.strictness), target.emplace_back());
130 }
131}
132inline void rlp(RLPDecoderRef encoding, bool& target) { target = encoding.value.toInt<uint8_t>(encoding.strictness); }
133
134template <typename T>
135inline auto rlp(RLPDecoderRef encoding, T& target) -> decltype(target.rlp(encoding), void()) {
136 target.rlp(encoding);
137}
138
139template <typename Map>
140auto rlp(RLPDecoderRef encoding, Map& target) -> decltype(target[target.begin()->first], void()) {
141 using key_type = std::remove_cv_t<decltype(target.begin()->first)>;
142 for (auto i : encoding.value) {
143 auto entry_i = i.begin();
144 key_type key;
145 rlp(RLPDecoderRef(*entry_i, encoding.strictness), key);
146 rlp(RLPDecoderRef(*(++entry_i), encoding.strictness), target[key]);
147 }
148}
149
150template <typename Param, typename... Params>
151void __dec_rlp_tuple_body__(RLP::iterator& i, RLP::iterator const& end, RLP::Strictness strictness, Param& target,
152 Params&... rest) {
153 if (i == end) {
154 return;
155 }
156
157 rlp(RLPDecoderRef(*i, strictness), target);
158
159 if constexpr (sizeof...(rest) > 0) {
160 __dec_rlp_tuple_body__(++i, end, strictness, rest...);
161 }
162}
163
166
167 InvalidEncodingSize(uint e, uint a) : expected(e), actual(a) {
168 RLPException() << dev::errinfo_comment("Invalid rlp list size") << dev::RequirementError(expected, actual);
169 }
170};
171
172template <typename... Params>
173void rlp_tuple(RLPDecoderRef encoding, Params&... args) {
174 constexpr auto num_elements = sizeof...(args);
175 static_assert(0 < num_elements);
176
177 if (encoding.value.itemCount() != num_elements) {
178 throw InvalidEncodingSize(num_elements, encoding.value.itemCount());
179 }
180
181 auto it_begin = encoding.value.begin();
182 __dec_rlp_tuple_body__(it_begin, encoding.value.end(), encoding.strictness, args...);
183}
184
185template <typename T>
187 T ret;
188 rlp(encoding, ret);
189 return ret;
190}
191
192template <typename T>
193dev::bytes const& rlp_enc(RLPEncoderRef encoder_to_reuse, T const& obj) {
194 encoder_to_reuse.clear();
195 rlp(encoder_to_reuse, obj);
196 return encoder_to_reuse.out();
197}
198
199template <typename T>
200dev::bytes rlp_enc(T const& obj) {
202 rlp(s, obj);
203 return std::move(s.invalidate());
204}
205
206} // namespace taraxa::util
207
208#define HAS_RLP_FIELDS \
209 void rlp(::taraxa::util::RLPDecoderRef encoding); \
210 void rlp(::taraxa::util::RLPEncoderRef encoding) const;
211
212#define RLP_FIELDS_DEFINE(_class_, ...) \
213 void _class_::rlp(::taraxa::util::RLPDecoderRef encoding) { ::taraxa::util::rlp_tuple(encoding, __VA_ARGS__); } \
214 void _class_::rlp(::taraxa::util::RLPEncoderRef encoding) const { ::taraxa::util::rlp_tuple(encoding, __VA_ARGS__); }
215
216#define RLP_FIELDS_DEFINE_INPLACE(...) \
217 void rlp(::taraxa::util::RLPDecoderRef encoding) { ::taraxa::util::rlp_tuple(encoding, __VA_ARGS__); } \
218 void rlp(::taraxa::util::RLPEncoderRef encoding) const { ::taraxa::util::rlp_tuple(encoding, __VA_ARGS__); }
Definition FixedHash.h:35
Iterator class for iterating through items of RLP list.
Definition RLP.h:148
Definition RLP.h:56
_N toHash(int _flags=Strict) const
Definition RLP.h:344
iterator begin() const
Iterator into beginning of sub-item list (valid only if we are a list).
Definition RLP.h:175
size_t itemCount() const
Definition RLP.h:106
iterator end() const
Iterator into end of sub-item list (valid only if we are a list).
Definition RLP.h:178
std::enable_if_t< is_integer< _T >(Signedness::any), _T > toInt(int _flags=Strict) const
Definition RLP.h:309
bool isNull() const
No value.
Definition RLP.h:91
int Strictness
Definition RLP.h:69
bool isEmpty() const
Contains a zero-length string or zero-length list.
Definition RLP.h:94
bytes toBytes(int _flags=LaissezFaire) const
Converts to bytearray.
Definition RLP.h:215
std::string toString(int _flags=LaissezFaire) const
Converts to string.
Definition RLP.h:235
Class for writing to an RLP bytestream.
Definition RLP.h:484
void clear()
Clear the output stream so far.
Definition RLP.h:608
std::enable_if_t< is_integer< N >(Signedness::signed_only), RLPStream & > append(N const &_i)
Definition RLP.h:498
bytes const & out() const
Read the byte stream.
Definition RLP.h:614
bytes && invalidate()
Invalidate the object and steal the output byte stream.
Definition RLP.h:620
RLPStream & appendList(size_t _items)
Appends a list.
Definition RLP.cpp:207
boost::tuple< errinfo_required, errinfo_got > RequirementError
Definition Exceptions.h:62
std::vector<::byte > bytes
Definition Common.h:46
boost::error_info< struct tag_comment, std::string > errinfo_comment
Definition Assertions.h:50
boost::multiprecision::number< boost::multiprecision::cpp_int_backend<> > bigint
Definition Common.h:92
Definition default_construct_copyable_movable.hpp:10
void rlp_tuple(RLPEncoderRef encoding, Params const &... args)
Definition encoding_rlp.hpp:83
dev::bytes const & rlp_enc(RLPEncoderRef encoder_to_reuse, T const &obj)
Definition encoding_rlp.hpp:193
T rlp_dec(RLPDecoderRef encoding)
Definition encoding_rlp.hpp:186
auto rlp(RLPEncoderRef encoding, T const &target) -> decltype(RLP().toInt< T >(), void())
Definition encoding_rlp.hpp:24
dev::RLPStream & RLPEncoderRef
Definition encoding_rlp.hpp:10
void __enc_rlp_tuple_body__(RLPEncoderRef encoding, Param const &target, Params const &... rest)
Definition encoding_rlp.hpp:75
void __dec_rlp_tuple_body__(RLP::iterator &i, RLP::iterator const &end, RLP::Strictness strictness, Param &target, Params &... rest)
Definition encoding_rlp.hpp:151
Base class for all RLP exceptions.
Definition Exceptions.h:29
Definition encoding_rlp.hpp:164
dev::bigint actual
Definition encoding_rlp.hpp:165
dev::bigint expected
Definition encoding_rlp.hpp:165
InvalidEncodingSize(uint e, uint a)
Definition encoding_rlp.hpp:167
Definition encoding_rlp.hpp:11
RLPDecoderRef(RLP const &value, bool strict=false)
Definition encoding_rlp.hpp:16
RLPDecoderRef(RLP const &value, RLP::Strictness strictness)
Definition encoding_rlp.hpp:15
RLP const & value
Definition encoding_rlp.hpp:12
RLP::Strictness strictness
Definition encoding_rlp.hpp:13