@eosrio/node-abieos 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/abieos.node +0 -0
- package/lib/abieos.d.ts +19 -0
- package/lib/abieos.d.ts.map +1 -0
- package/lib/abieos.js +100 -0
- package/lib/abieos.ts +107 -0
- package/package.json +13 -8
- package/.idea/modules.xml +0 -8
- package/.idea/node-abieos.iml +0 -12
- package/.idea/vcs.xml +0 -9
- package/.idea/workspace.xml +0 -66
- package/CMakeLists.txt +0 -35
- package/abieos.d.ts +0 -21
- package/abieos.js +0 -59
- package/eosio.json +0 -1596
- package/include/.clang-format +0 -76
- package/include/eosio/abi.hpp +0 -393
- package/include/eosio/asset.hpp +0 -458
- package/include/eosio/bytes.hpp +0 -27
- package/include/eosio/chain_conversions.hpp +0 -450
- package/include/eosio/chain_types.hpp +0 -14
- package/include/eosio/check.hpp +0 -178
- package/include/eosio/convert.hpp +0 -95
- package/include/eosio/crypto.hpp +0 -148
- package/include/eosio/eosio_outcome.hpp +0 -41
- package/include/eosio/fixed_bytes.hpp +0 -250
- package/include/eosio/float.hpp +0 -35
- package/include/eosio/for_each_field.hpp +0 -48
- package/include/eosio/fpconv.c +0 -336
- package/include/eosio/fpconv.h +0 -41
- package/include/eosio/fpconv.license +0 -23
- package/include/eosio/from_bin.hpp +0 -272
- package/include/eosio/from_json.hpp +0 -749
- package/include/eosio/from_string.hpp +0 -28
- package/include/eosio/map_macro.h +0 -64
- package/include/eosio/murmur.hpp +0 -55
- package/include/eosio/name.hpp +0 -178
- package/include/eosio/opaque.hpp +0 -184
- package/include/eosio/operators.hpp +0 -71
- package/include/eosio/powers.h +0 -76
- package/include/eosio/reflection.hpp +0 -61
- package/include/eosio/ship_protocol.hpp +0 -971
- package/include/eosio/stream.hpp +0 -235
- package/include/eosio/symbol.hpp +0 -300
- package/include/eosio/time.hpp +0 -264
- package/include/eosio/to_bin.hpp +0 -189
- package/include/eosio/to_json.hpp +0 -334
- package/include/eosio/to_key.hpp +0 -305
- package/include/eosio/types.hpp +0 -103
- package/include/eosio/varint.hpp +0 -452
- package/include/outcome-basic.hpp +0 -6836
- package/include/rapidjson/allocators.h +0 -284
- package/include/rapidjson/cursorstreamwrapper.h +0 -78
- package/include/rapidjson/document.h +0 -2646
- package/include/rapidjson/encodedstream.h +0 -299
- package/include/rapidjson/encodings.h +0 -716
- package/include/rapidjson/error/en.h +0 -74
- package/include/rapidjson/error/error.h +0 -161
- package/include/rapidjson/filereadstream.h +0 -99
- package/include/rapidjson/filewritestream.h +0 -104
- package/include/rapidjson/fwd.h +0 -151
- package/include/rapidjson/internal/biginteger.h +0 -290
- package/include/rapidjson/internal/diyfp.h +0 -271
- package/include/rapidjson/internal/dtoa.h +0 -245
- package/include/rapidjson/internal/ieee754.h +0 -78
- package/include/rapidjson/internal/itoa.h +0 -308
- package/include/rapidjson/internal/meta.h +0 -186
- package/include/rapidjson/internal/pow10.h +0 -55
- package/include/rapidjson/internal/regex.h +0 -732
- package/include/rapidjson/internal/stack.h +0 -231
- package/include/rapidjson/internal/strfunc.h +0 -69
- package/include/rapidjson/internal/strtod.h +0 -290
- package/include/rapidjson/internal/swap.h +0 -46
- package/include/rapidjson/istreamwrapper.h +0 -113
- package/include/rapidjson/memorybuffer.h +0 -70
- package/include/rapidjson/memorystream.h +0 -71
- package/include/rapidjson/msinttypes/inttypes.h +0 -316
- package/include/rapidjson/msinttypes/stdint.h +0 -300
- package/include/rapidjson/ostreamwrapper.h +0 -81
- package/include/rapidjson/pointer.h +0 -1357
- package/include/rapidjson/prettywriter.h +0 -277
- package/include/rapidjson/rapidjson.h +0 -654
- package/include/rapidjson/reader.h +0 -2230
- package/include/rapidjson/schema.h +0 -2494
- package/include/rapidjson/stream.h +0 -223
- package/include/rapidjson/stringbuffer.h +0 -121
- package/include/rapidjson/writer.h +0 -710
- package/src/abi.cpp +0 -274
- package/src/abieos.cpp +0 -334
- package/src/abieos.h +0 -91
- package/src/abieos.hpp +0 -1011
- package/src/abieos_exception.hpp +0 -89
- package/src/abieos_numeric.hpp +0 -94
- package/src/abieos_ripemd160.hpp +0 -417
- package/src/crypto.cpp +0 -215
- package/src/main.cpp +0 -242
- package/src/ship.abi.cpp +0 -695
- package/tools/CMakeLists.txt +0 -9
- package/tools/name.cpp +0 -86
package/src/abieos.hpp
DELETED
|
@@ -1,1011 +0,0 @@
|
|
|
1
|
-
// copyright defined in abieos/LICENSE.txt
|
|
2
|
-
|
|
3
|
-
#pragma once
|
|
4
|
-
|
|
5
|
-
#include <eosio/chain_conversions.hpp>
|
|
6
|
-
#include <eosio/from_bin.hpp>
|
|
7
|
-
#include <eosio/from_json.hpp>
|
|
8
|
-
#include <eosio/reflection.hpp>
|
|
9
|
-
#include <eosio/to_bin.hpp>
|
|
10
|
-
#include <eosio/to_json.hpp>
|
|
11
|
-
#include <eosio/abi.hpp>
|
|
12
|
-
#include <eosio/operators.hpp>
|
|
13
|
-
#include <eosio/bytes.hpp>
|
|
14
|
-
#include <eosio/crypto.hpp>
|
|
15
|
-
#include <eosio/symbol.hpp>
|
|
16
|
-
#include <eosio/asset.hpp>
|
|
17
|
-
#include <eosio/time.hpp>
|
|
18
|
-
#include <eosio/fixed_bytes.hpp>
|
|
19
|
-
#include <eosio/float.hpp>
|
|
20
|
-
#include <eosio/varint.hpp>
|
|
21
|
-
|
|
22
|
-
#ifdef __eosio_cdt__
|
|
23
|
-
#include <cwchar>
|
|
24
|
-
|
|
25
|
-
#pragma clang diagnostic push
|
|
26
|
-
#pragma clang diagnostic ignored "-W#warnings"
|
|
27
|
-
#endif
|
|
28
|
-
|
|
29
|
-
#include <ctime>
|
|
30
|
-
#include <map>
|
|
31
|
-
#include <optional>
|
|
32
|
-
#include <variant>
|
|
33
|
-
#include <vector>
|
|
34
|
-
|
|
35
|
-
#ifdef __eosio_cdt__
|
|
36
|
-
#pragma clang diagnostic pop
|
|
37
|
-
#endif
|
|
38
|
-
|
|
39
|
-
#include "abieos_numeric.hpp"
|
|
40
|
-
|
|
41
|
-
#include "rapidjson/reader.h"
|
|
42
|
-
#include "rapidjson/stringbuffer.h"
|
|
43
|
-
#include "rapidjson/writer.h"
|
|
44
|
-
|
|
45
|
-
namespace abieos {
|
|
46
|
-
|
|
47
|
-
using eosio::from_bin;
|
|
48
|
-
using eosio::to_bin;
|
|
49
|
-
|
|
50
|
-
inline constexpr bool trace_json_to_jvalue_event = false;
|
|
51
|
-
inline constexpr bool trace_json_to_jvalue = false;
|
|
52
|
-
inline constexpr bool trace_jvalue_to_bin = false;
|
|
53
|
-
inline constexpr bool trace_json_to_bin = false;
|
|
54
|
-
inline constexpr bool trace_json_to_bin_event = false;
|
|
55
|
-
inline constexpr bool trace_bin_to_json = false;
|
|
56
|
-
|
|
57
|
-
inline constexpr size_t max_stack_size = 128;
|
|
58
|
-
|
|
59
|
-
// Pseudo objects never exist, except in serialized form
|
|
60
|
-
struct pseudo_optional;
|
|
61
|
-
struct pseudo_extension;
|
|
62
|
-
struct pseudo_object;
|
|
63
|
-
struct pseudo_array;
|
|
64
|
-
struct pseudo_variant;
|
|
65
|
-
|
|
66
|
-
// !!!
|
|
67
|
-
template <typename SrcIt, typename DestIt>
|
|
68
|
-
void hex(SrcIt begin, SrcIt end, DestIt dest) {
|
|
69
|
-
static_assert(sizeof(*begin) == 1, "SrcIt should be an iterator to a byte");
|
|
70
|
-
auto nibble = [&dest](uint8_t i) {
|
|
71
|
-
if (i <= 9)
|
|
72
|
-
*dest++ = '0' + i;
|
|
73
|
-
else
|
|
74
|
-
*dest++ = 'A' + i - 10;
|
|
75
|
-
};
|
|
76
|
-
while (begin != end) {
|
|
77
|
-
nibble(((uint8_t)*begin) >> 4);
|
|
78
|
-
nibble(((uint8_t)*begin) & 0xf);
|
|
79
|
-
++begin;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// !!!
|
|
84
|
-
template <typename SrcIt>
|
|
85
|
-
std::string hex(SrcIt begin, SrcIt end) {
|
|
86
|
-
std::string s;
|
|
87
|
-
hex(begin, end, std::back_inserter(s));
|
|
88
|
-
return s;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// !!!
|
|
92
|
-
template <typename SrcIt, typename DestIt>
|
|
93
|
-
ABIEOS_NODISCARD bool unhex(std::string& error, SrcIt begin, SrcIt end, DestIt dest) {
|
|
94
|
-
auto get_digit = [&](uint8_t& nibble) {
|
|
95
|
-
if (*begin >= '0' && *begin <= '9')
|
|
96
|
-
nibble = *begin++ - '0';
|
|
97
|
-
else if (*begin >= 'a' && *begin <= 'f')
|
|
98
|
-
nibble = *begin++ - 'a' + 10;
|
|
99
|
-
else if (*begin >= 'A' && *begin <= 'F')
|
|
100
|
-
nibble = *begin++ - 'A' + 10;
|
|
101
|
-
else
|
|
102
|
-
return set_error(error, "expected hex string");
|
|
103
|
-
return true;
|
|
104
|
-
};
|
|
105
|
-
while (begin != end) {
|
|
106
|
-
uint8_t h, l;
|
|
107
|
-
if (!get_digit(h) || !get_digit(l))
|
|
108
|
-
return false;
|
|
109
|
-
*dest++ = (h << 4) | l;
|
|
110
|
-
}
|
|
111
|
-
return true;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
115
|
-
// stream events
|
|
116
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
117
|
-
|
|
118
|
-
enum class event_type {
|
|
119
|
-
received_null, // 0
|
|
120
|
-
received_bool, // 1
|
|
121
|
-
received_string, // 2
|
|
122
|
-
received_start_object, // 3
|
|
123
|
-
received_key, // 4
|
|
124
|
-
received_end_object, // 5
|
|
125
|
-
received_start_array, // 6
|
|
126
|
-
received_end_array, // 7
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
struct event_data {
|
|
130
|
-
bool value_bool = 0;
|
|
131
|
-
std::string value_string{};
|
|
132
|
-
std::string key{};
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
template <typename Derived>
|
|
136
|
-
struct json_reader_handler : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>, Derived> {
|
|
137
|
-
event_data received_data{};
|
|
138
|
-
bool started = false;
|
|
139
|
-
|
|
140
|
-
Derived& get_derived() { return *static_cast<Derived*>(this); }
|
|
141
|
-
|
|
142
|
-
bool get_start() {
|
|
143
|
-
if (started)
|
|
144
|
-
return false;
|
|
145
|
-
started = true;
|
|
146
|
-
return true;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
bool get_bool() const { return received_data.value_bool; }
|
|
150
|
-
|
|
151
|
-
const std::string& get_string() const { return received_data.value_string; }
|
|
152
|
-
|
|
153
|
-
bool Null() { return receive_event(get_derived(), event_type::received_null, get_start()); }
|
|
154
|
-
bool Bool(bool v) {
|
|
155
|
-
received_data.value_bool = v;
|
|
156
|
-
return receive_event(get_derived(), event_type::received_bool, get_start());
|
|
157
|
-
}
|
|
158
|
-
bool RawNumber(const char* v, rapidjson::SizeType length, bool copy) { return String(v, length, copy); }
|
|
159
|
-
bool Int(int v) { return false; }
|
|
160
|
-
bool Uint(unsigned v) { return false; }
|
|
161
|
-
bool Int64(int64_t v) { return false; }
|
|
162
|
-
bool Uint64(uint64_t v) { return false; }
|
|
163
|
-
bool Double(double v) { return false; }
|
|
164
|
-
bool String(const char* v, rapidjson::SizeType length, bool) {
|
|
165
|
-
received_data.value_string = {v, length};
|
|
166
|
-
return receive_event(get_derived(), event_type::received_string, get_start());
|
|
167
|
-
}
|
|
168
|
-
bool StartObject() { return receive_event(get_derived(), event_type::received_start_object, get_start()); }
|
|
169
|
-
bool Key(const char* v, rapidjson::SizeType length, bool) {
|
|
170
|
-
received_data.key = {v, length};
|
|
171
|
-
return receive_event(get_derived(), event_type::received_key, get_start());
|
|
172
|
-
}
|
|
173
|
-
bool EndObject(rapidjson::SizeType) {
|
|
174
|
-
return receive_event(get_derived(), event_type::received_end_object, get_start());
|
|
175
|
-
}
|
|
176
|
-
bool StartArray() { return receive_event(get_derived(), event_type::received_start_array, get_start()); }
|
|
177
|
-
bool EndArray(rapidjson::SizeType) {
|
|
178
|
-
return receive_event(get_derived(), event_type::received_end_array, get_start());
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
183
|
-
// json model
|
|
184
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
185
|
-
|
|
186
|
-
struct jvalue;
|
|
187
|
-
using jarray = std::vector<jvalue>;
|
|
188
|
-
using jobject = std::map<std::string, jvalue>;
|
|
189
|
-
|
|
190
|
-
struct jvalue {
|
|
191
|
-
std::variant<std::nullptr_t, bool, std::string, jobject, jarray> value;
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
195
|
-
// state and serializers
|
|
196
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
197
|
-
|
|
198
|
-
using eosio::abi_type;
|
|
199
|
-
|
|
200
|
-
struct size_insertion {
|
|
201
|
-
size_t position = 0;
|
|
202
|
-
uint32_t size = 0;
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
struct json_to_jvalue_stack_entry {
|
|
206
|
-
jvalue* value = nullptr;
|
|
207
|
-
std::string key = "";
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
struct jvalue_to_bin_stack_entry {
|
|
211
|
-
const abi_type* type = nullptr;
|
|
212
|
-
bool allow_extensions = false;
|
|
213
|
-
const jvalue* value = nullptr;
|
|
214
|
-
int position = -1;
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
struct json_to_bin_stack_entry {
|
|
218
|
-
const abi_type* type = nullptr;
|
|
219
|
-
bool allow_extensions = false;
|
|
220
|
-
int position = -1;
|
|
221
|
-
size_t size_insertion_index = 0;
|
|
222
|
-
size_t variant_type_index = 0;
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
struct bin_to_json_stack_entry {
|
|
226
|
-
const abi_type* type = nullptr;
|
|
227
|
-
bool allow_extensions = false;
|
|
228
|
-
int position = -1;
|
|
229
|
-
uint32_t array_size = 0;
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
struct json_to_jvalue_state : json_reader_handler<json_to_jvalue_state> {
|
|
233
|
-
std::string& error;
|
|
234
|
-
std::vector<json_to_jvalue_stack_entry> stack;
|
|
235
|
-
|
|
236
|
-
json_to_jvalue_state(std::string& error) : error{error} {}
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
struct jvalue_to_bin_state {
|
|
240
|
-
eosio::vector_stream writer;
|
|
241
|
-
const jvalue* received_value = nullptr;
|
|
242
|
-
std::vector<jvalue_to_bin_stack_entry> stack{};
|
|
243
|
-
bool skipped_extension = false;
|
|
244
|
-
|
|
245
|
-
bool get_bool() const {
|
|
246
|
-
auto* b = std::get_if<bool>(&received_value->value);
|
|
247
|
-
eosio::check(b, eosio::convert_json_error(eosio::from_json_error::expected_bool));
|
|
248
|
-
return *b;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
std::string_view get_string() const {
|
|
252
|
-
auto* s = std::get_if<std::string>(&received_value->value);
|
|
253
|
-
eosio::check(s, eosio::convert_json_error(eosio::from_json_error::expected_string));
|
|
254
|
-
return *s;
|
|
255
|
-
}
|
|
256
|
-
void get_null() {
|
|
257
|
-
eosio::check(std::holds_alternative<std::nullptr_t>(received_value->value),
|
|
258
|
-
eosio::convert_json_error(eosio::from_json_error::expected_null));
|
|
259
|
-
}
|
|
260
|
-
bool get_null_pred() {
|
|
261
|
-
return std::holds_alternative<std::nullptr_t>(received_value->value);
|
|
262
|
-
}
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
struct json_to_bin_state : eosio::json_token_stream {
|
|
266
|
-
using json_token_stream::json_token_stream;
|
|
267
|
-
eosio::vector_stream& writer;
|
|
268
|
-
std::vector<size_insertion> size_insertions{};
|
|
269
|
-
std::vector<json_to_bin_stack_entry> stack{};
|
|
270
|
-
bool skipped_extension = false;
|
|
271
|
-
|
|
272
|
-
explicit json_to_bin_state(char* in, eosio::vector_stream& out)
|
|
273
|
-
: eosio::json_token_stream(in), writer(out) {}
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
struct bin_to_json_state {
|
|
277
|
-
eosio::input_stream& bin;
|
|
278
|
-
eosio::vector_stream& writer;
|
|
279
|
-
std::vector<bin_to_json_stack_entry> stack{};
|
|
280
|
-
bool skipped_extension = false;
|
|
281
|
-
|
|
282
|
-
bin_to_json_state(eosio::input_stream& bin, eosio::vector_stream& writer)
|
|
283
|
-
: bin{bin}, writer{writer} {}
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
namespace eosio {
|
|
289
|
-
|
|
290
|
-
struct abi_serializer {
|
|
291
|
-
virtual void json_to_bin(::abieos::jvalue_to_bin_state& state, bool allow_extensions, const abi_type* type,
|
|
292
|
-
bool start) const = 0;
|
|
293
|
-
virtual void json_to_bin(::abieos::json_to_bin_state& state, bool allow_extensions, const abi_type* type,
|
|
294
|
-
bool start) const = 0;
|
|
295
|
-
virtual void bin_to_json(::abieos::bin_to_json_state& state, bool allow_extensions, const abi_type* type,
|
|
296
|
-
bool start) const = 0;
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
namespace abieos {
|
|
302
|
-
|
|
303
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
304
|
-
// serializer function prototypes
|
|
305
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
306
|
-
|
|
307
|
-
template <typename State>
|
|
308
|
-
void json_to_bin(pseudo_optional*, State& state, bool allow_extensions,
|
|
309
|
-
const abi_type* type, bool);
|
|
310
|
-
template <typename State>
|
|
311
|
-
void json_to_bin(pseudo_extension*, State& state, bool allow_extensions,
|
|
312
|
-
const abi_type* type, bool);
|
|
313
|
-
template <typename T, typename State>
|
|
314
|
-
void json_to_bin(T*, State& state, bool allow_extensions, const abi_type*,
|
|
315
|
-
bool start);
|
|
316
|
-
template <typename State>
|
|
317
|
-
void json_to_bin(std::string*, jvalue_to_bin_state& state, bool allow_extensions, const abi_type*,
|
|
318
|
-
bool start);
|
|
319
|
-
|
|
320
|
-
void json_to_bin(pseudo_object*, jvalue_to_bin_state& state, bool allow_extensions,
|
|
321
|
-
const abi_type* type, bool start);
|
|
322
|
-
void json_to_bin(pseudo_array*, jvalue_to_bin_state& state, bool allow_extensions,
|
|
323
|
-
const abi_type* type, bool start);
|
|
324
|
-
void json_to_bin(pseudo_variant*, jvalue_to_bin_state& state, bool allow_extensions,
|
|
325
|
-
const abi_type* type, bool start);
|
|
326
|
-
|
|
327
|
-
void json_to_bin(pseudo_object*, json_to_bin_state& state, bool allow_extensions, const abi_type* type,
|
|
328
|
-
bool start);
|
|
329
|
-
void json_to_bin(pseudo_array*, json_to_bin_state& state, bool allow_extensions, const abi_type* type,
|
|
330
|
-
bool start);
|
|
331
|
-
void json_to_bin(pseudo_variant*, json_to_bin_state& state, bool allow_extensions,
|
|
332
|
-
const abi_type* type, bool start);
|
|
333
|
-
|
|
334
|
-
void bin_to_json(pseudo_optional*, bin_to_json_state& state, bool allow_extensions,
|
|
335
|
-
const abi_type* type, bool start);
|
|
336
|
-
void bin_to_json(pseudo_extension*, bin_to_json_state& state, bool allow_extensions,
|
|
337
|
-
const abi_type* type, bool start);
|
|
338
|
-
void bin_to_json(pseudo_object*, bin_to_json_state& state, bool allow_extensions, const abi_type* type,
|
|
339
|
-
bool start);
|
|
340
|
-
void bin_to_json(pseudo_array*, bin_to_json_state& state, bool allow_extensions, const abi_type* type,
|
|
341
|
-
bool start);
|
|
342
|
-
void bin_to_json(pseudo_variant*, bin_to_json_state& state, bool allow_extensions,
|
|
343
|
-
const abi_type* type, bool start);
|
|
344
|
-
|
|
345
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
346
|
-
// serializable types
|
|
347
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
348
|
-
|
|
349
|
-
using eosio::bytes;
|
|
350
|
-
|
|
351
|
-
template <typename State>
|
|
352
|
-
void json_to_bin(bytes*, State& state, bool, const abi_type*, bool start) {
|
|
353
|
-
auto s = state.get_string();;
|
|
354
|
-
if (trace_json_to_bin)
|
|
355
|
-
printf("%*sbytes (%d hex digits)\n", int(state.stack.size() * 4), "", int(s.size()));
|
|
356
|
-
eosio::check( !(s.size() & 1), eosio::convert_json_error(eosio::from_json_error::expected_hex_string) );
|
|
357
|
-
eosio::varuint32_to_bin(s.size() / 2, state.writer);
|
|
358
|
-
// FIXME: Add a function to encode a hex string to a stream
|
|
359
|
-
eosio::check(eosio::unhex(std::back_inserter(state.writer.data), s.begin(), s.end()),
|
|
360
|
-
eosio::convert_json_error(eosio::from_json_error::expected_hex_string));
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
inline void bin_to_json(bytes*, bin_to_json_state& state, bool, const abi_type*, bool start) {
|
|
364
|
-
uint64_t size;
|
|
365
|
-
varuint64_from_bin(size, state.bin);
|
|
366
|
-
const char* data;
|
|
367
|
-
state.bin.read_reuse_storage(data, size);
|
|
368
|
-
return to_json_hex(data, size, state.writer);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
using eosio::float128;
|
|
372
|
-
using eosio::checksum160;
|
|
373
|
-
using eosio::checksum256;
|
|
374
|
-
using eosio::checksum512;
|
|
375
|
-
|
|
376
|
-
#ifndef ABIEOS_NO_INT128
|
|
377
|
-
using uint128 = unsigned __int128;
|
|
378
|
-
using int128 = __int128;
|
|
379
|
-
#endif
|
|
380
|
-
|
|
381
|
-
using eosio::public_key;
|
|
382
|
-
using eosio::private_key;
|
|
383
|
-
using eosio::signature;
|
|
384
|
-
using eosio::name;
|
|
385
|
-
|
|
386
|
-
using eosio::varuint32;
|
|
387
|
-
using eosio::varint32;
|
|
388
|
-
|
|
389
|
-
using eosio::time_point;
|
|
390
|
-
using eosio::time_point_sec;
|
|
391
|
-
using eosio::block_timestamp;
|
|
392
|
-
using eosio::symbol_code;
|
|
393
|
-
using eosio::symbol;
|
|
394
|
-
using eosio::asset;
|
|
395
|
-
using eosio::extended_asset;
|
|
396
|
-
|
|
397
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
398
|
-
// 128-bit support when native support is absent
|
|
399
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
400
|
-
|
|
401
|
-
#ifdef ABIEOS_NO_INT128
|
|
402
|
-
|
|
403
|
-
struct uint128 {
|
|
404
|
-
std::array<uint8_t, 16> data = {};
|
|
405
|
-
};
|
|
406
|
-
EOSIO_REFLECT(uint128, data)
|
|
407
|
-
|
|
408
|
-
struct int128 {
|
|
409
|
-
std::array<uint8_t, 16> data = {};
|
|
410
|
-
};
|
|
411
|
-
EOSIO_REFLECT(int128, data)
|
|
412
|
-
|
|
413
|
-
template <typename S>
|
|
414
|
-
void from_json(uint128& obj, S& stream) {
|
|
415
|
-
decimal_to_binary(obj.data, stream.get_string());
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
template <typename S>
|
|
419
|
-
void from_json(int128& obj, S& stream) {
|
|
420
|
-
auto s = stream.get_string();
|
|
421
|
-
if (s.size() && s[0] == '-') {
|
|
422
|
-
decimal_to_binary(obj.data, {s.data() + 1, s.size() - 1});
|
|
423
|
-
negate(obj.data);
|
|
424
|
-
eosio::check(is_negative(obj.data), eosio::convert_json_error(eosio::from_json_error::number_out_of_range));
|
|
425
|
-
} else {
|
|
426
|
-
decimal_to_binary(obj.data, s);
|
|
427
|
-
eosio::check(!is_negative(obj.data), eosio::convert_json_error(eosio::from_json_error::number_out_of_range));
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
template <typename S>
|
|
432
|
-
void to_json(const uint128& obj, S& stream) {
|
|
433
|
-
auto s = "\"" + binary_to_decimal(obj.data) + "\"";
|
|
434
|
-
stream.write(s.data(), s.size());
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
template <typename S>
|
|
438
|
-
void to_json(const int128& obj, S& stream) {
|
|
439
|
-
if (is_negative(obj.data)) {
|
|
440
|
-
auto n = obj;
|
|
441
|
-
negate(n.data);
|
|
442
|
-
auto s = "\"-" + binary_to_decimal(n.data) + "\"";
|
|
443
|
-
stream.write(s.data(), s.size());
|
|
444
|
-
} else {
|
|
445
|
-
auto s = "\"" + binary_to_decimal(obj.data) + "\"";
|
|
446
|
-
stream.write(s.data(), s.size());
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
#endif
|
|
451
|
-
|
|
452
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
453
|
-
// abi types
|
|
454
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
455
|
-
|
|
456
|
-
using extensions_type = std::vector<std::pair<uint16_t, bytes>>;
|
|
457
|
-
|
|
458
|
-
using eosio::abi_def;
|
|
459
|
-
|
|
460
|
-
ABIEOS_NODISCARD inline bool check_abi_version(const std::string& s, std::string& error) {
|
|
461
|
-
if (s.substr(0, 13) != "eosio::abi/1.")
|
|
462
|
-
return set_error(error, "unsupported abi version");
|
|
463
|
-
return true;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
467
|
-
// json_to_jvalue
|
|
468
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
469
|
-
|
|
470
|
-
ABIEOS_NODISCARD bool json_to_jobject(jvalue& value, json_to_jvalue_state& state, event_type event, bool start);
|
|
471
|
-
ABIEOS_NODISCARD bool json_to_jarray(jvalue& value, json_to_jvalue_state& state, event_type event, bool start);
|
|
472
|
-
|
|
473
|
-
ABIEOS_NODISCARD inline bool receive_event(struct json_to_jvalue_state& state, event_type event, bool start) {
|
|
474
|
-
if (state.stack.empty())
|
|
475
|
-
return set_error(state, "extra data");
|
|
476
|
-
if (state.stack.size() > max_stack_size)
|
|
477
|
-
return set_error(state, "recursion limit reached");
|
|
478
|
-
if (trace_json_to_jvalue_event)
|
|
479
|
-
printf("(event %d)\n", (int)event);
|
|
480
|
-
auto& v = *state.stack.back().value;
|
|
481
|
-
if (start) {
|
|
482
|
-
state.stack.pop_back();
|
|
483
|
-
if (event == event_type::received_null) {
|
|
484
|
-
v.value = nullptr;
|
|
485
|
-
} else if (event == event_type::received_bool) {
|
|
486
|
-
v.value = state.get_bool();
|
|
487
|
-
} else if (event == event_type::received_string) {
|
|
488
|
-
v.value = std::move(state.get_string());
|
|
489
|
-
} else if (event == event_type::received_start_object) {
|
|
490
|
-
v.value = jobject{};
|
|
491
|
-
return json_to_jobject(v, state, event, start);
|
|
492
|
-
} else if (event == event_type::received_start_array) {
|
|
493
|
-
v.value = jarray{};
|
|
494
|
-
return json_to_jarray(v, state, event, start);
|
|
495
|
-
} else {
|
|
496
|
-
return false;
|
|
497
|
-
}
|
|
498
|
-
} else {
|
|
499
|
-
if (std::holds_alternative<jobject>(v.value))
|
|
500
|
-
return json_to_jobject(v, state, event, start);
|
|
501
|
-
else if (std::holds_alternative<jarray>(v.value))
|
|
502
|
-
return json_to_jarray(v, state, event, start);
|
|
503
|
-
else
|
|
504
|
-
return set_error(state, "extra data");
|
|
505
|
-
}
|
|
506
|
-
return true;
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
template<typename F>
|
|
510
|
-
inline void json_to_jvalue(jvalue& value, std::string_view json, F&& f) {
|
|
511
|
-
std::string mutable_json{json};
|
|
512
|
-
mutable_json.push_back(0);
|
|
513
|
-
mutable_json.push_back(0);
|
|
514
|
-
mutable_json.push_back(0);
|
|
515
|
-
std::string error; // !!!
|
|
516
|
-
json_to_jvalue_state state{error};
|
|
517
|
-
state.stack.push_back({&value});
|
|
518
|
-
rapidjson::Reader reader;
|
|
519
|
-
rapidjson::InsituStringStream ss(mutable_json.data());
|
|
520
|
-
eosio::check(reader.Parse<rapidjson::kParseValidateEncodingFlag | rapidjson::kParseIterativeFlag |
|
|
521
|
-
rapidjson::kParseNumbersAsStringsFlag>(ss, state),
|
|
522
|
-
eosio::convert_json_error(eosio::from_json_error::unspecific_syntax_error));
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
ABIEOS_NODISCARD inline bool json_to_jobject(jvalue& value, json_to_jvalue_state& state, event_type event, bool start) {
|
|
526
|
-
if (start) {
|
|
527
|
-
if (event != event_type::received_start_object)
|
|
528
|
-
return set_error(state, "expected object");
|
|
529
|
-
if (trace_json_to_jvalue)
|
|
530
|
-
printf("%*s{\n", int(state.stack.size() * 4), "");
|
|
531
|
-
state.stack.push_back({&value});
|
|
532
|
-
return true;
|
|
533
|
-
} else if (event == event_type::received_end_object) {
|
|
534
|
-
if (trace_json_to_jvalue)
|
|
535
|
-
printf("%*s}\n", int((state.stack.size() - 1) * 4), "");
|
|
536
|
-
state.stack.pop_back();
|
|
537
|
-
return true;
|
|
538
|
-
}
|
|
539
|
-
auto& stack_entry = state.stack.back();
|
|
540
|
-
if (event == event_type::received_key) {
|
|
541
|
-
stack_entry.key = std::move(state.received_data.key);
|
|
542
|
-
return true;
|
|
543
|
-
} else {
|
|
544
|
-
if (trace_json_to_jvalue)
|
|
545
|
-
printf("%*sfield %s (event %d)\n", int(state.stack.size() * 4), "", stack_entry.key.c_str(), (int)event);
|
|
546
|
-
auto& x = std::get<jobject>(value.value)[stack_entry.key] = {};
|
|
547
|
-
state.stack.push_back({&x});
|
|
548
|
-
return receive_event(state, event, true);
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
ABIEOS_NODISCARD inline bool json_to_jarray(jvalue& value, json_to_jvalue_state& state, event_type event, bool start) {
|
|
553
|
-
if (start) {
|
|
554
|
-
if (event != event_type::received_start_array)
|
|
555
|
-
return set_error(state, "expected array");
|
|
556
|
-
if (trace_json_to_jvalue)
|
|
557
|
-
printf("%*s[\n", int(state.stack.size() * 4), "");
|
|
558
|
-
state.stack.push_back({&value});
|
|
559
|
-
return true;
|
|
560
|
-
} else if (event == event_type::received_end_array) {
|
|
561
|
-
if (trace_json_to_jvalue)
|
|
562
|
-
printf("%*s]\n", int((state.stack.size() - 1) * 4), "");
|
|
563
|
-
state.stack.pop_back();
|
|
564
|
-
return true;
|
|
565
|
-
}
|
|
566
|
-
auto& v = std::get<jarray>(value.value);
|
|
567
|
-
if (trace_json_to_jvalue)
|
|
568
|
-
printf("%*sitem %d (event %d)\n", int(state.stack.size() * 4), "", int(v.size()), (int)event);
|
|
569
|
-
v.emplace_back();
|
|
570
|
-
state.stack.push_back({&v.back()});
|
|
571
|
-
return receive_event(state, event, true);
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
575
|
-
// abi serializer implementations
|
|
576
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
577
|
-
|
|
578
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
579
|
-
// abi handling
|
|
580
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
581
|
-
|
|
582
|
-
using abi = eosio::abi;
|
|
583
|
-
|
|
584
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
585
|
-
// json_to_bin (jvalue)
|
|
586
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
587
|
-
|
|
588
|
-
template<typename F>
|
|
589
|
-
inline void json_to_bin(std::vector<char>& bin, const abi_type* type, const jvalue& value, F&& f) {
|
|
590
|
-
jvalue_to_bin_state state{{bin}, &value};
|
|
591
|
-
type->ser->json_to_bin(state, true, type, true);
|
|
592
|
-
while (!state.stack.empty()) {
|
|
593
|
-
f();
|
|
594
|
-
auto& entry = state.stack.back();
|
|
595
|
-
entry.type->ser->json_to_bin(state, entry.allow_extensions, entry.type, false);
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
template<typename State>
|
|
600
|
-
inline void json_to_bin(pseudo_optional*, State& state, bool allow_extensions,
|
|
601
|
-
const abi_type* type, bool) {
|
|
602
|
-
if (state.get_null_pred()) {
|
|
603
|
-
return state.writer.write(char(0));
|
|
604
|
-
}
|
|
605
|
-
state.writer.write(char(1));
|
|
606
|
-
const abi_type* t = type->optional_of();
|
|
607
|
-
return t->ser->json_to_bin(state, allow_extensions, t, true);
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
template<typename State>
|
|
611
|
-
inline void json_to_bin(pseudo_extension*, State& state, bool allow_extensions,
|
|
612
|
-
const abi_type* type, bool) {
|
|
613
|
-
const abi_type* t = type->extension_of();
|
|
614
|
-
return t->ser->json_to_bin(state, allow_extensions, t, true);
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
inline void json_to_bin(pseudo_object*, jvalue_to_bin_state& state, bool allow_extensions,
|
|
618
|
-
const abi_type* type, bool start) {
|
|
619
|
-
if (start) {
|
|
620
|
-
eosio::check(!(!state.received_value || !std::holds_alternative<jobject>(state.received_value->value)),
|
|
621
|
-
eosio::convert_json_error(eosio::from_json_error::expected_start_object));
|
|
622
|
-
if (trace_jvalue_to_bin)
|
|
623
|
-
printf("%*s{ %d fields, allow_ex=%d\n", int(state.stack.size() * 4), "", int(type->as_struct()->fields.size()),
|
|
624
|
-
allow_extensions);
|
|
625
|
-
state.stack.push_back({type, allow_extensions, state.received_value, -1});
|
|
626
|
-
}
|
|
627
|
-
auto& stack_entry = state.stack.back();
|
|
628
|
-
++stack_entry.position;
|
|
629
|
-
const std::vector<eosio::abi_field>& fields = stack_entry.type->as_struct()->fields;
|
|
630
|
-
if (stack_entry.position == (int)fields.size()) {
|
|
631
|
-
if (trace_jvalue_to_bin)
|
|
632
|
-
printf("%*s}\n", int((state.stack.size() - 1) * 4), "");
|
|
633
|
-
state.stack.pop_back();
|
|
634
|
-
return;
|
|
635
|
-
}
|
|
636
|
-
auto& field = fields[stack_entry.position];
|
|
637
|
-
auto& obj = std::get<jobject>(stack_entry.value->value);
|
|
638
|
-
auto it = obj.find(field.name);
|
|
639
|
-
if (trace_jvalue_to_bin)
|
|
640
|
-
printf("%*sfield %d/%d: %s\n", int(state.stack.size() * 4), "", int(stack_entry.position),
|
|
641
|
-
int(fields.size()), std::string{field.name}.c_str());
|
|
642
|
-
if (it == obj.end()) {
|
|
643
|
-
if (field.type->extension_of() && allow_extensions) {
|
|
644
|
-
state.skipped_extension = true;
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
|
-
stack_entry.position = -1;
|
|
648
|
-
eosio::check(false, eosio::convert_json_error(eosio::from_json_error::expected_field));
|
|
649
|
-
}
|
|
650
|
-
eosio::check(!state.skipped_extension,
|
|
651
|
-
eosio::convert_json_error(eosio::from_json_error::unexpected_field));
|
|
652
|
-
state.received_value = &it->second;
|
|
653
|
-
return field.type->ser->json_to_bin(state, allow_extensions && &field == &fields.back(),
|
|
654
|
-
field.type, true);
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
inline void json_to_bin(pseudo_array*, jvalue_to_bin_state& state, bool, const abi_type* type,
|
|
658
|
-
bool start) {
|
|
659
|
-
if (start) {
|
|
660
|
-
eosio::check(!(!state.received_value || !std::holds_alternative<jarray>(state.received_value->value)),
|
|
661
|
-
eosio::convert_json_error(eosio::from_json_error::expected_start_array));
|
|
662
|
-
if (trace_jvalue_to_bin)
|
|
663
|
-
printf("%*s[ %d elements\n", int(state.stack.size() * 4), "",
|
|
664
|
-
int(std::get<jarray>(state.received_value->value).size()));
|
|
665
|
-
eosio::varuint32_to_bin(std::get<jarray>(state.received_value->value).size(), state.writer);
|
|
666
|
-
state.stack.push_back({type, false, state.received_value, -1});
|
|
667
|
-
}
|
|
668
|
-
auto& stack_entry = state.stack.back();
|
|
669
|
-
auto& arr = std::get<jarray>(stack_entry.value->value);
|
|
670
|
-
++stack_entry.position;
|
|
671
|
-
if (stack_entry.position == (int)arr.size()) {
|
|
672
|
-
if (trace_jvalue_to_bin)
|
|
673
|
-
printf("%*s]\n", int((state.stack.size() - 1) * 4), "");
|
|
674
|
-
state.stack.pop_back();
|
|
675
|
-
return;
|
|
676
|
-
}
|
|
677
|
-
state.received_value = &arr[stack_entry.position];
|
|
678
|
-
if (trace_jvalue_to_bin)
|
|
679
|
-
printf("%*sitem\n", int(state.stack.size() * 4), "");
|
|
680
|
-
const abi_type * t = type->array_of();
|
|
681
|
-
return t->ser->json_to_bin(state, false, t, true);
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
inline void json_to_bin(pseudo_variant*, jvalue_to_bin_state& state, bool allow_extensions,
|
|
685
|
-
const abi_type* type, bool start) {
|
|
686
|
-
if (start) {
|
|
687
|
-
eosio::check(!(!state.received_value || !std::holds_alternative<jarray>(state.received_value->value)),
|
|
688
|
-
eosio::convert_json_error(eosio::from_json_error::expected_variant));
|
|
689
|
-
auto& arr = std::get<jarray>(state.received_value->value);
|
|
690
|
-
eosio::check(arr.size() == 2,
|
|
691
|
-
eosio::convert_json_error(eosio::from_json_error::expected_variant));
|
|
692
|
-
eosio::check(std::holds_alternative<std::string>(arr[0].value),
|
|
693
|
-
eosio::convert_json_error(eosio::from_json_error::expected_variant));
|
|
694
|
-
auto& typeName = std::get<std::string>(arr[0].value);
|
|
695
|
-
if (trace_jvalue_to_bin)
|
|
696
|
-
printf("%*s[ variant %s\n", int(state.stack.size() * 4), "", typeName.c_str());
|
|
697
|
-
state.stack.push_back({type, allow_extensions, state.received_value, 0});
|
|
698
|
-
return;
|
|
699
|
-
}
|
|
700
|
-
auto& stack_entry = state.stack.back();
|
|
701
|
-
auto& arr = std::get<jarray>(stack_entry.value->value);
|
|
702
|
-
if (stack_entry.position == 0) {
|
|
703
|
-
auto& typeName = std::get<std::string>(arr[0].value);
|
|
704
|
-
const std::vector<eosio::abi_field>& fields = *stack_entry.type->as_variant();
|
|
705
|
-
auto it = std::find_if(fields.begin(), fields.end(),
|
|
706
|
-
[&](auto& field) { return field.name == typeName; });
|
|
707
|
-
eosio::check(it != fields.end(),
|
|
708
|
-
eosio::convert_json_error(eosio::from_json_error::invalid_type_for_variant));
|
|
709
|
-
eosio::varuint32_to_bin(it - fields.begin(), state.writer);
|
|
710
|
-
state.received_value = &arr[++stack_entry.position];
|
|
711
|
-
return it->type->ser->json_to_bin(state, allow_extensions, it->type, true);
|
|
712
|
-
} else {
|
|
713
|
-
if (trace_jvalue_to_bin)
|
|
714
|
-
printf("%*s]\n", int((state.stack.size() - 1) * 4), "");
|
|
715
|
-
state.stack.pop_back();
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
template <typename T, typename State>
|
|
720
|
-
void json_to_bin(T*, State& state, bool, const abi_type*, bool start) {
|
|
721
|
-
using eosio::from_json;
|
|
722
|
-
T x;
|
|
723
|
-
from_json(x, state);
|
|
724
|
-
return to_bin(x, state.writer);
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
template <typename State>
|
|
728
|
-
inline void json_to_bin(std::string*, State& state, bool, const abi_type*,
|
|
729
|
-
bool start) {
|
|
730
|
-
auto s = state.get_string();
|
|
731
|
-
if (trace_jvalue_to_bin)
|
|
732
|
-
printf("%*sstring: %.*s\n", int(state.stack.size() * 4), "", (int)s.size(), s.data());
|
|
733
|
-
return to_bin(s, state.writer);
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
737
|
-
// json_to_bin
|
|
738
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
739
|
-
|
|
740
|
-
template<typename F>
|
|
741
|
-
inline void json_to_bin(std::vector<char>& bin, const abi_type* type, std::string_view json, F&& f) {
|
|
742
|
-
std::string mutable_json{json};
|
|
743
|
-
mutable_json.push_back(0);
|
|
744
|
-
mutable_json.push_back(0);
|
|
745
|
-
mutable_json.push_back(0);
|
|
746
|
-
std::vector<char> out_buf;
|
|
747
|
-
eosio::vector_stream out(out_buf);
|
|
748
|
-
json_to_bin_state state(mutable_json.data(), out);
|
|
749
|
-
|
|
750
|
-
type->ser->json_to_bin(state, true, type, true);
|
|
751
|
-
while(!state.stack.empty()) {
|
|
752
|
-
f();
|
|
753
|
-
auto entry = state.stack.back();
|
|
754
|
-
auto* type = entry.type;
|
|
755
|
-
eosio::check(state.stack.size() <= max_stack_size,
|
|
756
|
-
eosio::convert_abi_error(eosio::abi_error::recursion_limit_reached));
|
|
757
|
-
type->ser->json_to_bin(state, entry.allow_extensions, type, false);
|
|
758
|
-
}
|
|
759
|
-
eosio::check(state.complete(),
|
|
760
|
-
eosio::convert_json_error(eosio::from_json_error::expected_end));
|
|
761
|
-
|
|
762
|
-
size_t pos = 0;
|
|
763
|
-
for (auto& insertion : state.size_insertions) {
|
|
764
|
-
bin.insert(bin.end(), out_buf.begin() + pos, out_buf.begin() + insertion.position);
|
|
765
|
-
eosio::push_varuint32(bin, insertion.size);
|
|
766
|
-
pos = insertion.position;
|
|
767
|
-
}
|
|
768
|
-
bin.insert(bin.end(), out_buf.begin() + pos, out_buf.end());
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
inline void json_to_bin(pseudo_object*, json_to_bin_state& state, bool allow_extensions,
|
|
772
|
-
const abi_type* type, bool start) {
|
|
773
|
-
if (start) {
|
|
774
|
-
state.get_start_object();
|
|
775
|
-
if (trace_json_to_bin)
|
|
776
|
-
printf("%*s{ %d fields, allow_ex=%d\n", int(state.stack.size() * 4), "", int(type->as_struct()->fields.size()),
|
|
777
|
-
allow_extensions);
|
|
778
|
-
state.stack.push_back({type, allow_extensions});
|
|
779
|
-
}
|
|
780
|
-
auto& stack_entry = state.stack.back();
|
|
781
|
-
const std::vector<eosio::abi_field>& fields = type->as_struct()->fields;
|
|
782
|
-
if (state.get_end_object_pred()) {
|
|
783
|
-
if (stack_entry.position + 1 != (ptrdiff_t)fields.size()) {
|
|
784
|
-
auto& field = fields[stack_entry.position + 1];
|
|
785
|
-
if (!field.type->extension_of() || !allow_extensions) {
|
|
786
|
-
stack_entry.position = -1;
|
|
787
|
-
eosio::check(false, eosio::convert_json_error(eosio::from_json_error::expected_field));
|
|
788
|
-
}
|
|
789
|
-
++stack_entry.position;
|
|
790
|
-
state.skipped_extension = true;
|
|
791
|
-
}
|
|
792
|
-
if (trace_json_to_bin)
|
|
793
|
-
printf("%*s}\n", int((state.stack.size() - 1) * 4), "");
|
|
794
|
-
state.stack.pop_back();
|
|
795
|
-
return;
|
|
796
|
-
}
|
|
797
|
-
auto key = state.maybe_get_key();
|
|
798
|
-
if (key) {
|
|
799
|
-
eosio::check(!(++stack_entry.position >= (ptrdiff_t)fields.size() || state.skipped_extension),
|
|
800
|
-
eosio::convert_json_error(eosio::from_json_error::unexpected_field));
|
|
801
|
-
auto& field = fields[stack_entry.position];
|
|
802
|
-
if (*key != field.name) {
|
|
803
|
-
stack_entry.position = -1;
|
|
804
|
-
eosio::check(false, eosio::convert_json_error(eosio::from_json_error::expected_field));
|
|
805
|
-
}
|
|
806
|
-
} else {
|
|
807
|
-
auto& field = fields[stack_entry.position];
|
|
808
|
-
if (trace_json_to_bin)
|
|
809
|
-
printf("%*sfield %d/%d: %s\n", int(state.stack.size() * 4), "", int(stack_entry.position),
|
|
810
|
-
int(fields.size()), std::string{field.name}.c_str());
|
|
811
|
-
field.type->ser->json_to_bin(state, allow_extensions && &field == &fields.back(), field.type,
|
|
812
|
-
true);
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
inline void json_to_bin(pseudo_array*, json_to_bin_state& state, bool, const abi_type* type,
|
|
817
|
-
bool start) {
|
|
818
|
-
if (start) {
|
|
819
|
-
state.get_start_array();
|
|
820
|
-
if (trace_json_to_bin)
|
|
821
|
-
printf("%*s[\n", int(state.stack.size() * 4), "");
|
|
822
|
-
state.stack.push_back({type, false});
|
|
823
|
-
state.stack.back().size_insertion_index = state.size_insertions.size();
|
|
824
|
-
// FIXME: add Stream::tellp or similar.
|
|
825
|
-
state.size_insertions.push_back({state.writer.data.size()});
|
|
826
|
-
return;
|
|
827
|
-
}
|
|
828
|
-
auto& stack_entry = state.stack.back();
|
|
829
|
-
if (state.get_end_array_pred()) {
|
|
830
|
-
if (trace_json_to_bin)
|
|
831
|
-
printf("%*s]\n", int((state.stack.size() - 1) * 4), "");
|
|
832
|
-
state.size_insertions[stack_entry.size_insertion_index].size = stack_entry.position + 1;
|
|
833
|
-
state.stack.pop_back();
|
|
834
|
-
return;
|
|
835
|
-
}
|
|
836
|
-
++stack_entry.position;
|
|
837
|
-
if (trace_json_to_bin)
|
|
838
|
-
printf("%*sitem\n", int(state.stack.size() * 4), "");
|
|
839
|
-
const abi_type* t = type->array_of();
|
|
840
|
-
t->ser->json_to_bin(state, false, t, true);
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
inline void json_to_bin(pseudo_variant*, json_to_bin_state& state, bool allow_extensions,
|
|
844
|
-
const abi_type* type, bool start) {
|
|
845
|
-
if (start) {
|
|
846
|
-
state.get_start_array();
|
|
847
|
-
if (trace_json_to_bin)
|
|
848
|
-
printf("%*s[ variant\n", int(state.stack.size() * 4), "");
|
|
849
|
-
state.stack.push_back({type, allow_extensions});
|
|
850
|
-
return;
|
|
851
|
-
}
|
|
852
|
-
auto& stack_entry = state.stack.back();
|
|
853
|
-
++stack_entry.position;
|
|
854
|
-
if (state.get_end_array_pred()) {
|
|
855
|
-
eosio::check(stack_entry.position == 2,
|
|
856
|
-
eosio::convert_json_error(eosio::from_json_error::expected_variant));
|
|
857
|
-
if (trace_json_to_bin)
|
|
858
|
-
printf("%*s]\n", int((state.stack.size() - 1) * 4), "");
|
|
859
|
-
state.stack.pop_back();
|
|
860
|
-
return;
|
|
861
|
-
}
|
|
862
|
-
const std::vector<eosio::abi_field>& fields = *stack_entry.type->as_variant();
|
|
863
|
-
if (stack_entry.position == 0) {
|
|
864
|
-
auto typeName = state.get_string();
|
|
865
|
-
if (trace_json_to_bin)
|
|
866
|
-
printf("%*stype: %.*s\n", int(state.stack.size() * 4), "", (int)typeName.size(), typeName.data());
|
|
867
|
-
auto it = std::find_if(fields.begin(), fields.end(),
|
|
868
|
-
[&](auto& field) { return field.name == typeName; });
|
|
869
|
-
eosio::check(it != fields.end(),
|
|
870
|
-
eosio::convert_json_error(eosio::from_json_error::invalid_type_for_variant));
|
|
871
|
-
stack_entry.variant_type_index = it - fields.begin();
|
|
872
|
-
eosio::varuint32_to_bin(stack_entry.variant_type_index, state.writer);
|
|
873
|
-
} else if (stack_entry.position == 1) {
|
|
874
|
-
auto& field = fields[stack_entry.variant_type_index];
|
|
875
|
-
field.type->ser->json_to_bin(state, allow_extensions, field.type, true);
|
|
876
|
-
} else {
|
|
877
|
-
eosio::check(false, eosio::convert_json_error(eosio::from_json_error::expected_variant));
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
882
|
-
// bin_to_json
|
|
883
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
884
|
-
|
|
885
|
-
template<typename F>
|
|
886
|
-
inline void bin_to_json(eosio::input_stream& bin, const abi_type* type, std::string& dest, F&& f) {
|
|
887
|
-
// FIXME: Write directly to the string instead of creating an additional buffer
|
|
888
|
-
std::vector<char> buffer;
|
|
889
|
-
eosio::vector_stream writer{buffer};
|
|
890
|
-
bin_to_json_state state{bin, writer};
|
|
891
|
-
type->ser->bin_to_json(state, true, type, true);
|
|
892
|
-
while (!state.stack.empty()) {
|
|
893
|
-
f();
|
|
894
|
-
auto& entry = state.stack.back();
|
|
895
|
-
entry.type->ser->bin_to_json(state, entry.allow_extensions, entry.type, false);
|
|
896
|
-
eosio::check(state.stack.size() <= max_stack_size,
|
|
897
|
-
eosio::convert_abi_error(eosio::abi_error::recursion_limit_reached));
|
|
898
|
-
}
|
|
899
|
-
dest = std::string_view(writer.data.data(), writer.data.size());
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
inline void bin_to_json(bin_to_json_state& state, bool allow_extensions, const abi_type* type, bool start) {
|
|
903
|
-
type->ser->bin_to_json(state, allow_extensions, type, start);
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
inline void bin_to_json(pseudo_optional*, bin_to_json_state& state, bool allow_extensions,
|
|
907
|
-
const abi_type* type, bool) {
|
|
908
|
-
bool present;
|
|
909
|
-
from_bin(present, state.bin);
|
|
910
|
-
if (present)
|
|
911
|
-
return bin_to_json(state, allow_extensions, type->optional_of(), true);
|
|
912
|
-
state.writer.write("null", 4);
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
inline void bin_to_json(pseudo_extension*, bin_to_json_state& state, bool allow_extensions,
|
|
916
|
-
const abi_type* type, bool) {
|
|
917
|
-
bin_to_json(state, allow_extensions, type->extension_of(), true);
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
inline void bin_to_json(pseudo_object*, bin_to_json_state& state, bool allow_extensions,
|
|
921
|
-
const abi_type* type, bool start) {
|
|
922
|
-
if (start) {
|
|
923
|
-
if (trace_bin_to_json)
|
|
924
|
-
printf("%*s{ %d fields\n", int(state.stack.size() * 4), "", int(type->as_struct()->fields.size()));
|
|
925
|
-
state.stack.push_back({type, allow_extensions});
|
|
926
|
-
state.writer.write('{');
|
|
927
|
-
return;
|
|
928
|
-
}
|
|
929
|
-
auto& stack_entry = state.stack.back();
|
|
930
|
-
const std::vector<eosio::abi_field>& fields = type->as_struct()->fields;
|
|
931
|
-
if (++stack_entry.position < (ptrdiff_t)fields.size()) {
|
|
932
|
-
auto& field = fields[stack_entry.position];
|
|
933
|
-
if (trace_bin_to_json)
|
|
934
|
-
printf("%*sfield %d/%d: %s\n", int(state.stack.size() * 4), "", int(stack_entry.position),
|
|
935
|
-
int(fields.size()), std::string{field.name}.c_str());
|
|
936
|
-
if (state.bin.pos == state.bin.end && field.type->extension_of() && allow_extensions) {
|
|
937
|
-
state.skipped_extension = true;
|
|
938
|
-
return;
|
|
939
|
-
}
|
|
940
|
-
if(stack_entry.position != 0) { state.writer.write(','); };
|
|
941
|
-
to_json(field.name, state.writer);
|
|
942
|
-
state.writer.write(':');
|
|
943
|
-
bin_to_json(state, allow_extensions && &field == &fields.back(), field.type, true);
|
|
944
|
-
} else {
|
|
945
|
-
if (trace_bin_to_json)
|
|
946
|
-
printf("%*s}\n", int((state.stack.size() - 1) * 4), "");
|
|
947
|
-
state.stack.pop_back();
|
|
948
|
-
state.writer.write('}');
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
inline void bin_to_json(pseudo_array*, bin_to_json_state& state, bool, const abi_type* type,
|
|
953
|
-
bool start) {
|
|
954
|
-
if (start) {
|
|
955
|
-
state.stack.push_back({type, false});
|
|
956
|
-
varuint32_from_bin(state.stack.back().array_size, state.bin);
|
|
957
|
-
if (trace_bin_to_json)
|
|
958
|
-
printf("%*s[ %d items\n", int(state.stack.size() * 4), "", int(state.stack.back().array_size));
|
|
959
|
-
return state.writer.write('[');
|
|
960
|
-
}
|
|
961
|
-
auto& stack_entry = state.stack.back();
|
|
962
|
-
if (++stack_entry.position < (ptrdiff_t)stack_entry.array_size) {
|
|
963
|
-
if (trace_bin_to_json)
|
|
964
|
-
printf("%*sitem %d/%d %p %s\n", int(state.stack.size() * 4), "", int(stack_entry.position),
|
|
965
|
-
int(stack_entry.array_size), type->array_of()->ser, type->array_of()->name.c_str());
|
|
966
|
-
if (stack_entry.position != 0) { state.writer.write(','); }
|
|
967
|
-
return bin_to_json(state, false, type->array_of(), true);
|
|
968
|
-
} else {
|
|
969
|
-
if (trace_bin_to_json)
|
|
970
|
-
printf("%*s]\n", int((state.stack.size()) * 4), "");
|
|
971
|
-
state.stack.pop_back();
|
|
972
|
-
return state.writer.write(']');
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
inline void bin_to_json(pseudo_variant*, bin_to_json_state& state, bool allow_extensions,
|
|
977
|
-
const abi_type* type, bool start) {
|
|
978
|
-
if (start) {
|
|
979
|
-
state.stack.push_back({type, allow_extensions});
|
|
980
|
-
if (trace_bin_to_json)
|
|
981
|
-
printf("%*s[ variant\n", int(state.stack.size() * 4), "");
|
|
982
|
-
return state.writer.write('[');
|
|
983
|
-
}
|
|
984
|
-
auto& stack_entry = state.stack.back();
|
|
985
|
-
if (++stack_entry.position == 0) {
|
|
986
|
-
uint32_t index;
|
|
987
|
-
varuint32_from_bin(index, state.bin);
|
|
988
|
-
const std::vector<eosio::abi_field>& fields = *stack_entry.type->as_variant();
|
|
989
|
-
eosio::check(index < fields.size(), eosio::convert_stream_error(eosio::stream_error::bad_variant_index));
|
|
990
|
-
auto& f = fields[index];
|
|
991
|
-
to_json(f.name, state.writer);
|
|
992
|
-
state.writer.write(',');
|
|
993
|
-
// FIXME: allow_extensions should be stack_entry.allow_extensions, so why are we combining them?
|
|
994
|
-
bin_to_json(state, allow_extensions && stack_entry.allow_extensions, f.type, true);
|
|
995
|
-
} else {
|
|
996
|
-
if (trace_bin_to_json)
|
|
997
|
-
printf("%*s]\n", int((state.stack.size()) * 4), "");
|
|
998
|
-
state.stack.pop_back();
|
|
999
|
-
state.writer.write(']');
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
template <typename T>
|
|
1004
|
-
auto bin_to_json(T* t, bin_to_json_state& state, bool, const abi_type*, bool start)
|
|
1005
|
-
-> std::void_t<decltype(from_bin(*t, state.bin)), decltype(to_json(*t, state.writer))> {
|
|
1006
|
-
T v;
|
|
1007
|
-
from_bin(v, state.bin);
|
|
1008
|
-
return to_json(v, state.writer);
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
} // namespace abieos
|