-
Notifications
You must be signed in to change notification settings - Fork 2
/
ee_genesis_serializer.hpp
89 lines (66 loc) · 2.53 KB
/
ee_genesis_serializer.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#pragma once
#include <boost/filesystem/fstream.hpp>
#include <cyberway/chaindb/common.hpp>
#include <cyberway/genesis/ee_genesis_container.hpp>
#include <eosio/chain/abi_serializer.hpp>
namespace cyberway { namespace genesis {
using namespace chaindb;
namespace bfs = boost::filesystem;
FC_DECLARE_EXCEPTION(ee_genesis_exception, 10000000, "event engine genesis create exception");
//const fc::microseconds abi_serializer_max_time = fc::seconds(10);
struct ee_genesis_serializer {
private:
bfs::ofstream out;
ee_table_header _section;
uint64_t _section_offset = 0;
abi_serializer serializer;
public:
void start(const bfs::path& out_file, const fc::sha256& hash, const abi_def& abi,
const fc::microseconds abi_serializer_max_time = fc::seconds(10)) {
out.exceptions(std::ofstream::failbit | std::ofstream::badbit);
out.open(out_file, std::ios_base::binary);
ee_genesis_header hdr;
out.write((char*)(&hdr), sizeof(hdr));
fc::raw::pack(out, abi);
serializer.set_abi(abi, abi_serializer_max_time);
}
void finalize() {
finish_section();
}
void start_section(account_name code, table_name name, std::string abi_type) {
finish_section();
ee_table_header h{code, name, abi_type, 0};
wlog("Starting section: ${s}", ("s", h));
_section_offset = out.tellp();
fc::raw::pack(out, h);
_section = h;
}
void finish_section(fc::optional<uint32_t> count = fc::optional<uint32_t>()) {
if (_section_offset == 0) {
// No section yet
return;
}
if (count.valid()) {
EOS_ASSERT(*count == _section.count, ee_genesis_exception, "Section contains wrong number of rows",
("section",_section)("expected",*count)("diff", _section.count - *count));
}
auto pos = out.tellp();
out.seekp(_section_offset);
fc::raw::pack(out, _section);
out.seekp(pos);
wlog("Finished section: ${s}", ("s", _section));
_section_offset = 0;
}
void insert(const variant& v, const fc::microseconds abi_serializer_max_time = fc::seconds(10)) {
bytes data = serializer.variant_to_binary(_section.abi_type, v, abi_serializer_max_time);
out.write(data.data(), data.size());
_section.count++;
}
template<typename T, typename Lambda>
void emplace(Lambda&& constructor) {
T obj(constructor, 0);
fc::raw::pack(out, obj);
_section.count++;
}
};
}} // cyberway::genesis