5namespace sysio {
namespace chain {
11 snapshot.set(
"version", current_snapshot_version );
16 current_section_name = section_name;
20 current_rows.emplace_back(row_writer.
to_variant());
24 snapshot[
"sections"].get_array().emplace_back(
fc::mutable_variant_object()(
"name", std::move(current_section_name))(
"rows", std::move(current_rows)));
39 SYS_ASSERT(snapshot.is_object(), snapshot_validation_exception,
40 "Variant snapshot is not an object");
44 "Variant snapshot has no version");
46 const auto& version = o[
"version"];
47 SYS_ASSERT(version.is_integer(), snapshot_validation_exception,
48 "Variant snapshot version is not an integer");
50 SYS_ASSERT(version.as_uint64() == (
uint64_t)current_snapshot_version, snapshot_validation_exception,
51 "Variant snapshot is an unsuppored version. Expected : ${expected}, Got: ${actual}",
52 (
"expected", current_snapshot_version)(
"actual",o[
"version"].as_uint64()));
55 "Variant snapshot has no sections");
57 const auto& sections = o[
"sections"];
58 SYS_ASSERT(sections.is_array(), snapshot_validation_exception,
"Variant snapshot sections is not an array");
60 const auto& section_array = sections.get_array();
61 for(
const auto& section: section_array ) {
62 SYS_ASSERT(section.is_object(), snapshot_validation_exception,
"Variant snapshot section is not an object");
64 const auto& so = section.get_object();
65 SYS_ASSERT(so.contains(
"name"), snapshot_validation_exception,
66 "Variant snapshot section has no name");
68 SYS_ASSERT(so[
"name"].is_string(), snapshot_validation_exception,
69 "Variant snapshot section name is not a string");
71 SYS_ASSERT(so.contains(
"rows"), snapshot_validation_exception,
72 "Variant snapshot section has no rows");
74 SYS_ASSERT(so[
"rows"].is_array(), snapshot_validation_exception,
75 "Variant snapshot section rows is not an array");
80 const auto& sections = snapshot[
"sections"].get_array();
81 for(
const auto& section: sections ) {
82 if (section[
"name"].as_string() == section_name) {
91 const auto& sections = snapshot[
"sections"].get_array();
92 for(
const auto& section: sections ) {
93 if (section[
"name"].as_string() == section_name) {
94 cur_section = §ion.get_object();
99 SYS_THROW(snapshot_exception,
"Variant snapshot has no section named ${n}", (
"n", section_name));
103 const auto& rows = (*cur_section)[
"rows"].get_array();
104 row_reader.
provide(rows.at(cur_row++));
105 return cur_row < rows.size();
109 const auto& rows = (*cur_section)[
"rows"].get_array();
114 cur_section =
nullptr;
124,header_pos(snapshot.tellp())
130 snapshot.write((
char*)&totem,
sizeof(totem));
133 auto version = current_snapshot_version;
134 snapshot.write((
char*)&version,
sizeof(version));
139 SYS_ASSERT(section_pos == std::streampos(-1), snapshot_exception,
"Attempting to write a new section without closing the previous section");
140 section_pos = snapshot.tellp();
143 uint64_t placeholder = std::numeric_limits<uint64_t>::max();
146 snapshot.write((
char*)&placeholder,
sizeof(placeholder));
149 snapshot.write((
char*)&placeholder,
sizeof(placeholder));
152 snapshot.write(section_name.data(), section_name.size());
157 auto restore = snapshot.tellp();
159 row_writer.
write(snapshot);
161 snapshot.seekp(restore);
168 auto restore = snapshot.tellp();
172 snapshot.seekp(section_pos);
175 snapshot.write((
char*)§ion_size,
sizeof(section_size));
178 snapshot.write((
char*)&row_count,
sizeof(row_count));
180 snapshot.seekp(restore);
182 section_pos = std::streampos(-1);
187 uint64_t end_marker = std::numeric_limits<uint64_t>::max();
190 snapshot.write((
char*)&end_marker,
sizeof(end_marker));
195,header_pos(snapshot.tellg())
206 snapshot.exceptions(ex);
209 snapshot.exceptions(std::istream::failbit|std::istream::eofbit);
214 decltype(expected_totem) actual_totem;
215 snapshot.read((
char*)&actual_totem,
sizeof(actual_totem));
216 SYS_ASSERT(actual_totem == expected_totem, snapshot_exception,
217 "Binary snapshot has unexpected magic number!");
220 auto expected_version = current_snapshot_version;
221 decltype(expected_version) actual_version;
222 snapshot.read((
char*)&actual_version,
sizeof(actual_version));
223 SYS_ASSERT(actual_version == expected_version, snapshot_exception,
224 "Binary snapshot is an unsuppored version. Expected : ${expected}, Got: ${actual}",
225 (
"expected", expected_version)(
"actual", actual_version));
227 while (validate_section()) {}
228 }
catch(
const std::exception& e ) { \
229 snapshot_exception fce(
FC_LOG_MESSAGE( warn,
"Binary snapshot validation threw IO exception (${what})",(
"what",e.what())));
234bool istream_snapshot_reader::validate_section()
const {
236 snapshot.read((
char*)§ion_size,
sizeof(section_size));
239 if (section_size == std::numeric_limits<uint64_t>::max()) {
244 snapshot.seekg(snapshot.tellg() + std::streamoff(section_size));
256 auto next_section_pos = header_pos + header_size;
259 snapshot.seekg(next_section_pos);
261 snapshot.read((
char*)§ion_size,
sizeof(section_size));
262 if (section_size == std::numeric_limits<uint64_t>::max()) {
266 next_section_pos = snapshot.tellg() + std::streamoff(section_size);
269 snapshot.read((
char*)&ignore,
sizeof(ignore));
272 for(
auto c : section_name) {
273 if(snapshot.get() != c) {
279 if (match && snapshot.get() == 0) {
294 auto next_section_pos = header_pos + header_size;
297 snapshot.seekg(next_section_pos);
299 snapshot.read((
char*)§ion_size,
sizeof(section_size));
300 if (section_size == std::numeric_limits<uint64_t>::max()) {
304 next_section_pos = snapshot.tellg() + std::streamoff(section_size);
307 snapshot.read((
char*)&row_count,
sizeof(row_count));
310 for(
auto c : section_name) {
311 if(snapshot.get() != c) {
317 if (match && snapshot.get() == 0) {
319 num_rows = row_count;
322 restore_pos.cancel();
327 SYS_THROW(snapshot_exception,
"Binary snapshot has no section named ${n}", (
"n", section_name));
332 return ++cur_row < num_rows;
336 return num_rows == 0;
345 snapshot.seekg( header_pos );
360 row_writer.
write(enc);
#define SYS_THROW(exc_type, FORMAT,...)
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
An order-preserving dictionary of variants.
An order-preserving dictionary of variants.
bool contains(const char *key) const
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
void write_end_section() override
void write_row(const detail::abstract_snapshot_row_writer &row_writer) override
integrity_hash_snapshot_writer(fc::sha256::encoder &enc)
void write_start_section(const std::string §ion_name) override
void clear_section() override
void set_section(const string §ion_name) override
istream_snapshot_reader(std::istream &snapshot)
bool read_row(detail::abstract_snapshot_row_reader &row_reader) override
void validate() const override
void return_to_header() override
bool has_section(const string §ion_name) override
static const uint32_t magic_number
void write_row(const detail::abstract_snapshot_row_writer &row_writer) override
void write_end_section() override
void write_start_section(const std::string §ion_name) override
ostream_snapshot_writer(std::ostream &snapshot)
void clear_section() override
bool has_section(const string §ion_name) override
void return_to_header() override
void set_section(const string §ion_name) override
void validate() const override
variant_snapshot_reader(const fc::variant &snapshot)
bool read_row(detail::abstract_snapshot_row_reader &row_reader) override
void write_start_section(const std::string §ion_name) override
void write_row(const detail::abstract_snapshot_row_writer &row_writer) override
void write_end_section() override
variant_snapshot_writer(fc::mutable_variant_object &snapshot)
#define FC_LOG_MESSAGE(LOG_LEVEL, FORMAT,...)
A helper method for generating log messages.
scoped_exit< Callback > make_scoped_exit(Callback &&c)
std::vector< fc::variant > variants
unsigned __int64 uint64_t
virtual void provide(std::istream &in) const =0
virtual void write(ostream_wrapper &out) const =0
virtual fc::variant to_variant() const =0