🎉 FBE

This commit is contained in:
EntireTwix 2021-07-14 22:56:10 -07:00
parent e04dcc926d
commit 0130f3c971
15 changed files with 6995 additions and 0 deletions

27
fbe/user_model.fbe Normal file
View file

@ -0,0 +1,27 @@
package bank_dom
struct Transaction
{
string from = "";
string to = "";
uint32 amount = 0;
timestamp time;
}
struct Logs
{
Transaction[] data;
}
struct User
{
uint32 balance = 0;
uint64 password = 0;
Logs? logs = null;
}
struct Global
{
string[] keys;
User[] users;
}

197
fbe/user_model/bank_dom.cpp Normal file
View file

@ -0,0 +1,197 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: user_model.fbe
// Version: 1.7.0.0
#include "bank_dom.h"
namespace bank_dom {
Transaction::Transaction()
: from("")
, to("")
, amount((uint32_t)0ull)
, time((uint64_t)0ull)
{}
Transaction::Transaction(const std::string& arg_from, const std::string& arg_to, uint32_t arg_amount, uint64_t arg_time)
: from(arg_from)
, to(arg_to)
, amount(arg_amount)
, time(arg_time)
{}
bool Transaction::operator==(const Transaction& other) const noexcept
{
return (
true
);
}
bool Transaction::operator<(const Transaction& other) const noexcept
{
return false;
}
void Transaction::swap(Transaction& other) noexcept
{
using std::swap;
swap(from, other.from);
swap(to, other.to);
swap(amount, other.amount);
swap(time, other.time);
}
std::ostream& operator<<(std::ostream& stream, const Transaction& value)
{
stream << "Transaction(";
stream << "from="; stream << "\"" << value.from << "\"";
stream << ",to="; stream << "\"" << value.to << "\"";
stream << ",amount="; stream << value.amount;
stream << ",time="; stream << value.time;
stream << ")";
return stream;
}
Logs::Logs()
: data()
{}
Logs::Logs(const std::vector<::bank_dom::Transaction>& arg_data)
: data(arg_data)
{}
bool Logs::operator==(const Logs& other) const noexcept
{
return (
true
);
}
bool Logs::operator<(const Logs& other) const noexcept
{
return false;
}
void Logs::swap(Logs& other) noexcept
{
using std::swap;
swap(data, other.data);
}
std::ostream& operator<<(std::ostream& stream, const Logs& value)
{
stream << "Logs(";
{
bool first = true;
stream << "data=[" << value.data.size() << "][";
for (const auto& it : value.data)
{
stream << std::string(first ? "" : ",") << it;
first = false;
}
stream << "]";
}
stream << ")";
return stream;
}
User::User()
: balance((uint32_t)0ull)
, password((uint64_t)0ull)
, logs(std::nullopt)
{}
User::User(uint32_t arg_balance, uint64_t arg_password, const std::optional<::bank_dom::Logs>& arg_logs)
: balance(arg_balance)
, password(arg_password)
, logs(arg_logs)
{}
bool User::operator==(const User& other) const noexcept
{
return (
true
);
}
bool User::operator<(const User& other) const noexcept
{
return false;
}
void User::swap(User& other) noexcept
{
using std::swap;
swap(balance, other.balance);
swap(password, other.password);
swap(logs, other.logs);
}
std::ostream& operator<<(std::ostream& stream, const User& value)
{
stream << "User(";
stream << "balance="; stream << value.balance;
stream << ",password="; stream << value.password;
stream << ",logs="; if (value.logs) stream << *value.logs; else stream << "null";
stream << ")";
return stream;
}
Global::Global()
: keys()
, users()
{}
Global::Global(const std::vector<std::string>& arg_keys, const std::vector<::bank_dom::User>& arg_users)
: keys(arg_keys)
, users(arg_users)
{}
bool Global::operator==(const Global& other) const noexcept
{
return (
true
);
}
bool Global::operator<(const Global& other) const noexcept
{
return false;
}
void Global::swap(Global& other) noexcept
{
using std::swap;
swap(keys, other.keys);
swap(users, other.users);
}
std::ostream& operator<<(std::ostream& stream, const Global& value)
{
stream << "Global(";
{
bool first = true;
stream << "keys=[" << value.keys.size() << "][";
for (const auto& it : value.keys)
{
stream << std::string(first ? "" : ",") << "\"" << it << "\"";
first = false;
}
stream << "]";
}
{
bool first = true;
stream << ",users=[" << value.users.size() << "][";
for (const auto& it : value.users)
{
stream << std::string(first ? "" : ",") << it;
first = false;
}
stream << "]";
}
stream << ")";
return stream;
}
} // namespace bank_dom

238
fbe/user_model/bank_dom.h Normal file
View file

@ -0,0 +1,238 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: user_model.fbe
// Version: 1.7.0.0
#pragma once
#if defined(__clang__)
#pragma clang system_header
#elif defined(__GNUC__)
#pragma GCC system_header
#elif defined(_MSC_VER)
#pragma system_header
#endif
#include "fbe.h"
namespace bank_dom {
using namespace FBE;
} // namespace bank_dom
namespace FBE {
using namespace ::bank_dom;
} // namespace FBE
namespace bank_dom {
struct Transaction
{
std::string from;
std::string to;
uint32_t amount;
uint64_t time;
size_t fbe_type() const noexcept { return 1; }
Transaction();
Transaction(const std::string& arg_from, const std::string& arg_to, uint32_t arg_amount, uint64_t arg_time);
Transaction(const Transaction& other) = default;
Transaction(Transaction&& other) = default;
~Transaction() = default;
Transaction& operator=(const Transaction& other) = default;
Transaction& operator=(Transaction&& other) = default;
bool operator==(const Transaction& other) const noexcept;
bool operator!=(const Transaction& other) const noexcept { return !operator==(other); }
bool operator<(const Transaction& other) const noexcept;
bool operator<=(const Transaction& other) const noexcept { return operator<(other) || operator==(other); }
bool operator>(const Transaction& other) const noexcept { return !operator<=(other); }
bool operator>=(const Transaction& other) const noexcept { return !operator<(other); }
std::string string() const { std::stringstream ss; ss << *this; return ss.str(); }
friend std::ostream& operator<<(std::ostream& stream, const Transaction& value);
void swap(Transaction& other) noexcept;
friend void swap(Transaction& value1, Transaction& value2) noexcept { value1.swap(value2); }
};
} // namespace bank_dom
namespace std {
template<>
struct hash<bank_dom::Transaction>
{
typedef bank_dom::Transaction argument_type;
typedef size_t result_type;
result_type operator() (const argument_type& value) const
{
result_type result = 17;
return result;
}
};
} // namespace std
namespace bank_dom {
struct Logs
{
std::vector<::bank_dom::Transaction> data;
size_t fbe_type() const noexcept { return 2; }
Logs();
explicit Logs(const std::vector<::bank_dom::Transaction>& arg_data);
Logs(const Logs& other) = default;
Logs(Logs&& other) = default;
~Logs() = default;
Logs& operator=(const Logs& other) = default;
Logs& operator=(Logs&& other) = default;
bool operator==(const Logs& other) const noexcept;
bool operator!=(const Logs& other) const noexcept { return !operator==(other); }
bool operator<(const Logs& other) const noexcept;
bool operator<=(const Logs& other) const noexcept { return operator<(other) || operator==(other); }
bool operator>(const Logs& other) const noexcept { return !operator<=(other); }
bool operator>=(const Logs& other) const noexcept { return !operator<(other); }
std::string string() const { std::stringstream ss; ss << *this; return ss.str(); }
friend std::ostream& operator<<(std::ostream& stream, const Logs& value);
void swap(Logs& other) noexcept;
friend void swap(Logs& value1, Logs& value2) noexcept { value1.swap(value2); }
};
} // namespace bank_dom
namespace std {
template<>
struct hash<bank_dom::Logs>
{
typedef bank_dom::Logs argument_type;
typedef size_t result_type;
result_type operator() (const argument_type& value) const
{
result_type result = 17;
return result;
}
};
} // namespace std
namespace bank_dom {
struct User
{
uint32_t balance;
uint64_t password;
std::optional<::bank_dom::Logs> logs;
size_t fbe_type() const noexcept { return 3; }
User();
User(uint32_t arg_balance, uint64_t arg_password, const std::optional<::bank_dom::Logs>& arg_logs);
User(const User& other) = default;
User(User&& other) = default;
~User() = default;
User& operator=(const User& other) = default;
User& operator=(User&& other) = default;
bool operator==(const User& other) const noexcept;
bool operator!=(const User& other) const noexcept { return !operator==(other); }
bool operator<(const User& other) const noexcept;
bool operator<=(const User& other) const noexcept { return operator<(other) || operator==(other); }
bool operator>(const User& other) const noexcept { return !operator<=(other); }
bool operator>=(const User& other) const noexcept { return !operator<(other); }
std::string string() const { std::stringstream ss; ss << *this; return ss.str(); }
friend std::ostream& operator<<(std::ostream& stream, const User& value);
void swap(User& other) noexcept;
friend void swap(User& value1, User& value2) noexcept { value1.swap(value2); }
};
} // namespace bank_dom
namespace std {
template<>
struct hash<bank_dom::User>
{
typedef bank_dom::User argument_type;
typedef size_t result_type;
result_type operator() (const argument_type& value) const
{
result_type result = 17;
return result;
}
};
} // namespace std
namespace bank_dom {
struct Global
{
std::vector<std::string> keys;
std::vector<::bank_dom::User> users;
size_t fbe_type() const noexcept { return 4; }
Global();
Global(const std::vector<std::string>& arg_keys, const std::vector<::bank_dom::User>& arg_users);
Global(const Global& other) = default;
Global(Global&& other) = default;
~Global() = default;
Global& operator=(const Global& other) = default;
Global& operator=(Global&& other) = default;
bool operator==(const Global& other) const noexcept;
bool operator!=(const Global& other) const noexcept { return !operator==(other); }
bool operator<(const Global& other) const noexcept;
bool operator<=(const Global& other) const noexcept { return operator<(other) || operator==(other); }
bool operator>(const Global& other) const noexcept { return !operator<=(other); }
bool operator>=(const Global& other) const noexcept { return !operator<(other); }
std::string string() const { std::stringstream ss; ss << *this; return ss.str(); }
friend std::ostream& operator<<(std::ostream& stream, const Global& value);
void swap(Global& other) noexcept;
friend void swap(Global& value1, Global& value2) noexcept { value1.swap(value2); }
};
} // namespace bank_dom
namespace std {
template<>
struct hash<bank_dom::Global>
{
typedef bank_dom::Global argument_type;
typedef size_t result_type;
result_type operator() (const argument_type& value) const
{
result_type result = 17;
return result;
}
};
} // namespace std
namespace bank_dom {
} // namespace bank_dom

View file

@ -0,0 +1,638 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: user_model.fbe
// Version: 1.7.0.0
#include "bank_dom_final_models.h"
namespace FBE {
FinalModel<::bank_dom::Transaction>::FinalModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset)
, from(buffer, 0)
, to(buffer, 0)
, amount(buffer, 0)
, time(buffer, 0)
{}
size_t FinalModel<::bank_dom::Transaction>::fbe_allocation_size(const ::bank_dom::Transaction& fbe_value) const noexcept
{
size_t fbe_result = 0
+ from.fbe_allocation_size(fbe_value.from)
+ to.fbe_allocation_size(fbe_value.to)
+ amount.fbe_allocation_size(fbe_value.amount)
+ time.fbe_allocation_size(fbe_value.time)
;
return fbe_result;
}
size_t FinalModel<::bank_dom::Transaction>::verify() const noexcept
{
_buffer.shift(fbe_offset());
size_t fbe_result = verify_fields();
_buffer.unshift(fbe_offset());
return fbe_result;
}
size_t FinalModel<::bank_dom::Transaction>::verify_fields() const noexcept
{
size_t fbe_current_offset = 0;
size_t fbe_field_size;
from.fbe_offset(fbe_current_offset);
fbe_field_size = from.verify();
if (fbe_field_size == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_current_offset += fbe_field_size;
to.fbe_offset(fbe_current_offset);
fbe_field_size = to.verify();
if (fbe_field_size == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_current_offset += fbe_field_size;
amount.fbe_offset(fbe_current_offset);
fbe_field_size = amount.verify();
if (fbe_field_size == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_current_offset += fbe_field_size;
time.fbe_offset(fbe_current_offset);
fbe_field_size = time.verify();
if (fbe_field_size == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_current_offset += fbe_field_size;
return fbe_current_offset;
}
size_t FinalModel<::bank_dom::Transaction>::get(::bank_dom::Transaction& fbe_value) const noexcept
{
_buffer.shift(fbe_offset());
size_t fbe_result = get_fields(fbe_value);
_buffer.unshift(fbe_offset());
return fbe_result;
}
size_t FinalModel<::bank_dom::Transaction>::get_fields(::bank_dom::Transaction& fbe_value) const noexcept
{
size_t fbe_current_offset = 0;
size_t fbe_current_size = 0;
size_t fbe_field_size;
from.fbe_offset(fbe_current_offset);
fbe_field_size = from.get(fbe_value.from);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
to.fbe_offset(fbe_current_offset);
fbe_field_size = to.get(fbe_value.to);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
amount.fbe_offset(fbe_current_offset);
fbe_field_size = amount.get(fbe_value.amount);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
time.fbe_offset(fbe_current_offset);
fbe_field_size = time.get(fbe_value.time);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
return fbe_current_size;
}
size_t FinalModel<::bank_dom::Transaction>::set(const ::bank_dom::Transaction& fbe_value) noexcept
{
_buffer.shift(fbe_offset());
size_t fbe_result = set_fields(fbe_value);
_buffer.unshift(fbe_offset());
return fbe_result;
}
size_t FinalModel<::bank_dom::Transaction>::set_fields(const ::bank_dom::Transaction& fbe_value) noexcept
{
size_t fbe_current_offset = 0;
size_t fbe_current_size = 0;
size_t fbe_field_size;
from.fbe_offset(fbe_current_offset);
fbe_field_size = from.set(fbe_value.from);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
to.fbe_offset(fbe_current_offset);
fbe_field_size = to.set(fbe_value.to);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
amount.fbe_offset(fbe_current_offset);
fbe_field_size = amount.set(fbe_value.amount);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
time.fbe_offset(fbe_current_offset);
fbe_field_size = time.set(fbe_value.time);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
return fbe_current_size;
}
namespace bank_dom {
bool TransactionFinalModel::verify()
{
if ((this->buffer().offset() + _model.fbe_offset()) > this->buffer().size())
return false;
size_t fbe_struct_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 8));
size_t fbe_struct_type = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 4));
if ((fbe_struct_size == 0) || (fbe_struct_type != fbe_type()))
return false;
return ((8 + _model.verify()) == fbe_struct_size);
}
size_t TransactionFinalModel::serialize(const ::bank_dom::Transaction& value)
{
size_t fbe_initial_size = this->buffer().size();
uint32_t fbe_struct_type = (uint32_t)fbe_type();
uint32_t fbe_struct_size = (uint32_t)(8 + _model.fbe_allocation_size(value));
uint32_t fbe_struct_offset = (uint32_t)(this->buffer().allocate(fbe_struct_size) - this->buffer().offset());
assert(((this->buffer().offset() + fbe_struct_offset + fbe_struct_size) <= this->buffer().size()) && "Model is broken!");
if ((this->buffer().offset() + fbe_struct_offset + fbe_struct_size) > this->buffer().size())
return 0;
fbe_struct_size = (uint32_t)(8 + _model.set(value));
this->buffer().resize(fbe_initial_size + fbe_struct_size);
*((uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 8)) = fbe_struct_size;
*((uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 4)) = fbe_struct_type;
return fbe_struct_size;
}
size_t TransactionFinalModel::deserialize(::bank_dom::Transaction& value) const noexcept
{
assert(((this->buffer().offset() + _model.fbe_offset()) <= this->buffer().size()) && "Model is broken!");
if ((this->buffer().offset() + _model.fbe_offset()) > this->buffer().size())
return 0;
size_t fbe_struct_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 8));
size_t fbe_struct_type = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 4));
assert(((fbe_struct_size > 0) && (fbe_struct_type == fbe_type())) && "Model is broken!");
if ((fbe_struct_size == 0) || (fbe_struct_type != fbe_type()))
return 8;
return 8 + _model.get(value);
}
} // namespace bank_dom
FinalModel<::bank_dom::Logs>::FinalModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset)
, data(buffer, 0)
{}
size_t FinalModel<::bank_dom::Logs>::fbe_allocation_size(const ::bank_dom::Logs& fbe_value) const noexcept
{
size_t fbe_result = 0
+ data.fbe_allocation_size(fbe_value.data)
;
return fbe_result;
}
size_t FinalModel<::bank_dom::Logs>::verify() const noexcept
{
_buffer.shift(fbe_offset());
size_t fbe_result = verify_fields();
_buffer.unshift(fbe_offset());
return fbe_result;
}
size_t FinalModel<::bank_dom::Logs>::verify_fields() const noexcept
{
size_t fbe_current_offset = 0;
size_t fbe_field_size;
data.fbe_offset(fbe_current_offset);
fbe_field_size = data.verify();
if (fbe_field_size == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_current_offset += fbe_field_size;
return fbe_current_offset;
}
size_t FinalModel<::bank_dom::Logs>::get(::bank_dom::Logs& fbe_value) const noexcept
{
_buffer.shift(fbe_offset());
size_t fbe_result = get_fields(fbe_value);
_buffer.unshift(fbe_offset());
return fbe_result;
}
size_t FinalModel<::bank_dom::Logs>::get_fields(::bank_dom::Logs& fbe_value) const noexcept
{
size_t fbe_current_offset = 0;
size_t fbe_current_size = 0;
size_t fbe_field_size;
data.fbe_offset(fbe_current_offset);
fbe_field_size = data.get(fbe_value.data);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
return fbe_current_size;
}
size_t FinalModel<::bank_dom::Logs>::set(const ::bank_dom::Logs& fbe_value) noexcept
{
_buffer.shift(fbe_offset());
size_t fbe_result = set_fields(fbe_value);
_buffer.unshift(fbe_offset());
return fbe_result;
}
size_t FinalModel<::bank_dom::Logs>::set_fields(const ::bank_dom::Logs& fbe_value) noexcept
{
size_t fbe_current_offset = 0;
size_t fbe_current_size = 0;
size_t fbe_field_size;
data.fbe_offset(fbe_current_offset);
fbe_field_size = data.set(fbe_value.data);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
return fbe_current_size;
}
namespace bank_dom {
bool LogsFinalModel::verify()
{
if ((this->buffer().offset() + _model.fbe_offset()) > this->buffer().size())
return false;
size_t fbe_struct_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 8));
size_t fbe_struct_type = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 4));
if ((fbe_struct_size == 0) || (fbe_struct_type != fbe_type()))
return false;
return ((8 + _model.verify()) == fbe_struct_size);
}
size_t LogsFinalModel::serialize(const ::bank_dom::Logs& value)
{
size_t fbe_initial_size = this->buffer().size();
uint32_t fbe_struct_type = (uint32_t)fbe_type();
uint32_t fbe_struct_size = (uint32_t)(8 + _model.fbe_allocation_size(value));
uint32_t fbe_struct_offset = (uint32_t)(this->buffer().allocate(fbe_struct_size) - this->buffer().offset());
assert(((this->buffer().offset() + fbe_struct_offset + fbe_struct_size) <= this->buffer().size()) && "Model is broken!");
if ((this->buffer().offset() + fbe_struct_offset + fbe_struct_size) > this->buffer().size())
return 0;
fbe_struct_size = (uint32_t)(8 + _model.set(value));
this->buffer().resize(fbe_initial_size + fbe_struct_size);
*((uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 8)) = fbe_struct_size;
*((uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 4)) = fbe_struct_type;
return fbe_struct_size;
}
size_t LogsFinalModel::deserialize(::bank_dom::Logs& value) const noexcept
{
assert(((this->buffer().offset() + _model.fbe_offset()) <= this->buffer().size()) && "Model is broken!");
if ((this->buffer().offset() + _model.fbe_offset()) > this->buffer().size())
return 0;
size_t fbe_struct_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 8));
size_t fbe_struct_type = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 4));
assert(((fbe_struct_size > 0) && (fbe_struct_type == fbe_type())) && "Model is broken!");
if ((fbe_struct_size == 0) || (fbe_struct_type != fbe_type()))
return 8;
return 8 + _model.get(value);
}
} // namespace bank_dom
FinalModel<::bank_dom::User>::FinalModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset)
, balance(buffer, 0)
, password(buffer, 0)
, logs(buffer, 0)
{}
size_t FinalModel<::bank_dom::User>::fbe_allocation_size(const ::bank_dom::User& fbe_value) const noexcept
{
size_t fbe_result = 0
+ balance.fbe_allocation_size(fbe_value.balance)
+ password.fbe_allocation_size(fbe_value.password)
+ logs.fbe_allocation_size(fbe_value.logs)
;
return fbe_result;
}
size_t FinalModel<::bank_dom::User>::verify() const noexcept
{
_buffer.shift(fbe_offset());
size_t fbe_result = verify_fields();
_buffer.unshift(fbe_offset());
return fbe_result;
}
size_t FinalModel<::bank_dom::User>::verify_fields() const noexcept
{
size_t fbe_current_offset = 0;
size_t fbe_field_size;
balance.fbe_offset(fbe_current_offset);
fbe_field_size = balance.verify();
if (fbe_field_size == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_current_offset += fbe_field_size;
password.fbe_offset(fbe_current_offset);
fbe_field_size = password.verify();
if (fbe_field_size == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_current_offset += fbe_field_size;
logs.fbe_offset(fbe_current_offset);
fbe_field_size = logs.verify();
if (fbe_field_size == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_current_offset += fbe_field_size;
return fbe_current_offset;
}
size_t FinalModel<::bank_dom::User>::get(::bank_dom::User& fbe_value) const noexcept
{
_buffer.shift(fbe_offset());
size_t fbe_result = get_fields(fbe_value);
_buffer.unshift(fbe_offset());
return fbe_result;
}
size_t FinalModel<::bank_dom::User>::get_fields(::bank_dom::User& fbe_value) const noexcept
{
size_t fbe_current_offset = 0;
size_t fbe_current_size = 0;
size_t fbe_field_size;
balance.fbe_offset(fbe_current_offset);
fbe_field_size = balance.get(fbe_value.balance);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
password.fbe_offset(fbe_current_offset);
fbe_field_size = password.get(fbe_value.password);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
logs.fbe_offset(fbe_current_offset);
fbe_field_size = logs.get(fbe_value.logs);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
return fbe_current_size;
}
size_t FinalModel<::bank_dom::User>::set(const ::bank_dom::User& fbe_value) noexcept
{
_buffer.shift(fbe_offset());
size_t fbe_result = set_fields(fbe_value);
_buffer.unshift(fbe_offset());
return fbe_result;
}
size_t FinalModel<::bank_dom::User>::set_fields(const ::bank_dom::User& fbe_value) noexcept
{
size_t fbe_current_offset = 0;
size_t fbe_current_size = 0;
size_t fbe_field_size;
balance.fbe_offset(fbe_current_offset);
fbe_field_size = balance.set(fbe_value.balance);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
password.fbe_offset(fbe_current_offset);
fbe_field_size = password.set(fbe_value.password);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
logs.fbe_offset(fbe_current_offset);
fbe_field_size = logs.set(fbe_value.logs);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
return fbe_current_size;
}
namespace bank_dom {
bool UserFinalModel::verify()
{
if ((this->buffer().offset() + _model.fbe_offset()) > this->buffer().size())
return false;
size_t fbe_struct_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 8));
size_t fbe_struct_type = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 4));
if ((fbe_struct_size == 0) || (fbe_struct_type != fbe_type()))
return false;
return ((8 + _model.verify()) == fbe_struct_size);
}
size_t UserFinalModel::serialize(const ::bank_dom::User& value)
{
size_t fbe_initial_size = this->buffer().size();
uint32_t fbe_struct_type = (uint32_t)fbe_type();
uint32_t fbe_struct_size = (uint32_t)(8 + _model.fbe_allocation_size(value));
uint32_t fbe_struct_offset = (uint32_t)(this->buffer().allocate(fbe_struct_size) - this->buffer().offset());
assert(((this->buffer().offset() + fbe_struct_offset + fbe_struct_size) <= this->buffer().size()) && "Model is broken!");
if ((this->buffer().offset() + fbe_struct_offset + fbe_struct_size) > this->buffer().size())
return 0;
fbe_struct_size = (uint32_t)(8 + _model.set(value));
this->buffer().resize(fbe_initial_size + fbe_struct_size);
*((uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 8)) = fbe_struct_size;
*((uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 4)) = fbe_struct_type;
return fbe_struct_size;
}
size_t UserFinalModel::deserialize(::bank_dom::User& value) const noexcept
{
assert(((this->buffer().offset() + _model.fbe_offset()) <= this->buffer().size()) && "Model is broken!");
if ((this->buffer().offset() + _model.fbe_offset()) > this->buffer().size())
return 0;
size_t fbe_struct_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 8));
size_t fbe_struct_type = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 4));
assert(((fbe_struct_size > 0) && (fbe_struct_type == fbe_type())) && "Model is broken!");
if ((fbe_struct_size == 0) || (fbe_struct_type != fbe_type()))
return 8;
return 8 + _model.get(value);
}
} // namespace bank_dom
FinalModel<::bank_dom::Global>::FinalModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset)
, keys(buffer, 0)
, users(buffer, 0)
{}
size_t FinalModel<::bank_dom::Global>::fbe_allocation_size(const ::bank_dom::Global& fbe_value) const noexcept
{
size_t fbe_result = 0
+ keys.fbe_allocation_size(fbe_value.keys)
+ users.fbe_allocation_size(fbe_value.users)
;
return fbe_result;
}
size_t FinalModel<::bank_dom::Global>::verify() const noexcept
{
_buffer.shift(fbe_offset());
size_t fbe_result = verify_fields();
_buffer.unshift(fbe_offset());
return fbe_result;
}
size_t FinalModel<::bank_dom::Global>::verify_fields() const noexcept
{
size_t fbe_current_offset = 0;
size_t fbe_field_size;
keys.fbe_offset(fbe_current_offset);
fbe_field_size = keys.verify();
if (fbe_field_size == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_current_offset += fbe_field_size;
users.fbe_offset(fbe_current_offset);
fbe_field_size = users.verify();
if (fbe_field_size == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_current_offset += fbe_field_size;
return fbe_current_offset;
}
size_t FinalModel<::bank_dom::Global>::get(::bank_dom::Global& fbe_value) const noexcept
{
_buffer.shift(fbe_offset());
size_t fbe_result = get_fields(fbe_value);
_buffer.unshift(fbe_offset());
return fbe_result;
}
size_t FinalModel<::bank_dom::Global>::get_fields(::bank_dom::Global& fbe_value) const noexcept
{
size_t fbe_current_offset = 0;
size_t fbe_current_size = 0;
size_t fbe_field_size;
keys.fbe_offset(fbe_current_offset);
fbe_field_size = keys.get(fbe_value.keys);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
users.fbe_offset(fbe_current_offset);
fbe_field_size = users.get(fbe_value.users);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
return fbe_current_size;
}
size_t FinalModel<::bank_dom::Global>::set(const ::bank_dom::Global& fbe_value) noexcept
{
_buffer.shift(fbe_offset());
size_t fbe_result = set_fields(fbe_value);
_buffer.unshift(fbe_offset());
return fbe_result;
}
size_t FinalModel<::bank_dom::Global>::set_fields(const ::bank_dom::Global& fbe_value) noexcept
{
size_t fbe_current_offset = 0;
size_t fbe_current_size = 0;
size_t fbe_field_size;
keys.fbe_offset(fbe_current_offset);
fbe_field_size = keys.set(fbe_value.keys);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
users.fbe_offset(fbe_current_offset);
fbe_field_size = users.set(fbe_value.users);
fbe_current_offset += fbe_field_size;
fbe_current_size += fbe_field_size;
return fbe_current_size;
}
namespace bank_dom {
bool GlobalFinalModel::verify()
{
if ((this->buffer().offset() + _model.fbe_offset()) > this->buffer().size())
return false;
size_t fbe_struct_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 8));
size_t fbe_struct_type = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 4));
if ((fbe_struct_size == 0) || (fbe_struct_type != fbe_type()))
return false;
return ((8 + _model.verify()) == fbe_struct_size);
}
size_t GlobalFinalModel::serialize(const ::bank_dom::Global& value)
{
size_t fbe_initial_size = this->buffer().size();
uint32_t fbe_struct_type = (uint32_t)fbe_type();
uint32_t fbe_struct_size = (uint32_t)(8 + _model.fbe_allocation_size(value));
uint32_t fbe_struct_offset = (uint32_t)(this->buffer().allocate(fbe_struct_size) - this->buffer().offset());
assert(((this->buffer().offset() + fbe_struct_offset + fbe_struct_size) <= this->buffer().size()) && "Model is broken!");
if ((this->buffer().offset() + fbe_struct_offset + fbe_struct_size) > this->buffer().size())
return 0;
fbe_struct_size = (uint32_t)(8 + _model.set(value));
this->buffer().resize(fbe_initial_size + fbe_struct_size);
*((uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 8)) = fbe_struct_size;
*((uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 4)) = fbe_struct_type;
return fbe_struct_size;
}
size_t GlobalFinalModel::deserialize(::bank_dom::Global& value) const noexcept
{
assert(((this->buffer().offset() + _model.fbe_offset()) <= this->buffer().size()) && "Model is broken!");
if ((this->buffer().offset() + _model.fbe_offset()) > this->buffer().size())
return 0;
size_t fbe_struct_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 8));
size_t fbe_struct_type = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + _model.fbe_offset() - 4));
assert(((fbe_struct_size > 0) && (fbe_struct_type == fbe_type())) && "Model is broken!");
if ((fbe_struct_size == 0) || (fbe_struct_type != fbe_type()))
return 8;
return 8 + _model.get(value);
}
} // namespace bank_dom
} // namespace FBE

View file

@ -0,0 +1,320 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: user_model.fbe
// Version: 1.7.0.0
#pragma once
#if defined(__clang__)
#pragma clang system_header
#elif defined(__GNUC__)
#pragma GCC system_header
#elif defined(_MSC_VER)
#pragma system_header
#endif
#include "fbe_final_models.h"
#include "bank_dom.h"
namespace FBE {
// Fast Binary Encoding ::bank_dom::Transaction final model
template <>
class FinalModel<::bank_dom::Transaction>
{
public:
FinalModel(FBEBuffer& buffer, size_t offset) noexcept;
// Get the allocation size
size_t fbe_allocation_size(const ::bank_dom::Transaction& fbe_value) const noexcept;
// Get the final offset
size_t fbe_offset() const noexcept { return _offset; }
// Set the final offset
size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; }
// Get the final type
static constexpr size_t fbe_type() noexcept { return 1; }
// Shift the current final offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current final offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the struct value is valid
size_t verify() const noexcept;
// Check if the struct fields are valid
size_t verify_fields() const noexcept;
// Get the struct value
size_t get(::bank_dom::Transaction& fbe_value) const noexcept;
// Get the struct fields values
size_t get_fields(::bank_dom::Transaction& fbe_value) const noexcept;
// Set the struct value
size_t set(const ::bank_dom::Transaction& fbe_value) noexcept;
// Set the struct fields values
size_t set_fields(const ::bank_dom::Transaction& fbe_value) noexcept;
private:
FBEBuffer& _buffer;
mutable size_t _offset;
public:
FinalModel<std::string> from;
FinalModel<std::string> to;
FinalModel<uint32_t> amount;
FinalModel<uint64_t> time;
};
namespace bank_dom {
// Fast Binary Encoding Transaction final model
class TransactionFinalModel : public FBE::Model
{
public:
TransactionFinalModel() : _model(this->buffer(), 8) {}
TransactionFinalModel(const std::shared_ptr<FBEBuffer>& buffer) : FBE::Model(buffer), _model(this->buffer(), 8) {}
// Get the model type
static constexpr size_t fbe_type() noexcept { return FinalModel<::bank_dom::Transaction>::fbe_type(); }
// Check if the struct value is valid
bool verify();
// Serialize the struct value
size_t serialize(const ::bank_dom::Transaction& value);
// Deserialize the struct value
size_t deserialize(::bank_dom::Transaction& value) const noexcept;
// Move to the next struct value
void next(size_t prev) noexcept { _model.fbe_shift(prev); }
private:
FinalModel<::bank_dom::Transaction> _model;
};
} // namespace bank_dom
// Fast Binary Encoding ::bank_dom::Logs final model
template <>
class FinalModel<::bank_dom::Logs>
{
public:
FinalModel(FBEBuffer& buffer, size_t offset) noexcept;
// Get the allocation size
size_t fbe_allocation_size(const ::bank_dom::Logs& fbe_value) const noexcept;
// Get the final offset
size_t fbe_offset() const noexcept { return _offset; }
// Set the final offset
size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; }
// Get the final type
static constexpr size_t fbe_type() noexcept { return 2; }
// Shift the current final offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current final offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the struct value is valid
size_t verify() const noexcept;
// Check if the struct fields are valid
size_t verify_fields() const noexcept;
// Get the struct value
size_t get(::bank_dom::Logs& fbe_value) const noexcept;
// Get the struct fields values
size_t get_fields(::bank_dom::Logs& fbe_value) const noexcept;
// Set the struct value
size_t set(const ::bank_dom::Logs& fbe_value) noexcept;
// Set the struct fields values
size_t set_fields(const ::bank_dom::Logs& fbe_value) noexcept;
private:
FBEBuffer& _buffer;
mutable size_t _offset;
public:
FinalModelVector<::bank_dom::Transaction> data;
};
namespace bank_dom {
// Fast Binary Encoding Logs final model
class LogsFinalModel : public FBE::Model
{
public:
LogsFinalModel() : _model(this->buffer(), 8) {}
LogsFinalModel(const std::shared_ptr<FBEBuffer>& buffer) : FBE::Model(buffer), _model(this->buffer(), 8) {}
// Get the model type
static constexpr size_t fbe_type() noexcept { return FinalModel<::bank_dom::Logs>::fbe_type(); }
// Check if the struct value is valid
bool verify();
// Serialize the struct value
size_t serialize(const ::bank_dom::Logs& value);
// Deserialize the struct value
size_t deserialize(::bank_dom::Logs& value) const noexcept;
// Move to the next struct value
void next(size_t prev) noexcept { _model.fbe_shift(prev); }
private:
FinalModel<::bank_dom::Logs> _model;
};
} // namespace bank_dom
// Fast Binary Encoding ::bank_dom::User final model
template <>
class FinalModel<::bank_dom::User>
{
public:
FinalModel(FBEBuffer& buffer, size_t offset) noexcept;
// Get the allocation size
size_t fbe_allocation_size(const ::bank_dom::User& fbe_value) const noexcept;
// Get the final offset
size_t fbe_offset() const noexcept { return _offset; }
// Set the final offset
size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; }
// Get the final type
static constexpr size_t fbe_type() noexcept { return 3; }
// Shift the current final offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current final offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the struct value is valid
size_t verify() const noexcept;
// Check if the struct fields are valid
size_t verify_fields() const noexcept;
// Get the struct value
size_t get(::bank_dom::User& fbe_value) const noexcept;
// Get the struct fields values
size_t get_fields(::bank_dom::User& fbe_value) const noexcept;
// Set the struct value
size_t set(const ::bank_dom::User& fbe_value) noexcept;
// Set the struct fields values
size_t set_fields(const ::bank_dom::User& fbe_value) noexcept;
private:
FBEBuffer& _buffer;
mutable size_t _offset;
public:
FinalModel<uint32_t> balance;
FinalModel<uint64_t> password;
FinalModel<std::optional<::bank_dom::Logs>> logs;
};
namespace bank_dom {
// Fast Binary Encoding User final model
class UserFinalModel : public FBE::Model
{
public:
UserFinalModel() : _model(this->buffer(), 8) {}
UserFinalModel(const std::shared_ptr<FBEBuffer>& buffer) : FBE::Model(buffer), _model(this->buffer(), 8) {}
// Get the model type
static constexpr size_t fbe_type() noexcept { return FinalModel<::bank_dom::User>::fbe_type(); }
// Check if the struct value is valid
bool verify();
// Serialize the struct value
size_t serialize(const ::bank_dom::User& value);
// Deserialize the struct value
size_t deserialize(::bank_dom::User& value) const noexcept;
// Move to the next struct value
void next(size_t prev) noexcept { _model.fbe_shift(prev); }
private:
FinalModel<::bank_dom::User> _model;
};
} // namespace bank_dom
// Fast Binary Encoding ::bank_dom::Global final model
template <>
class FinalModel<::bank_dom::Global>
{
public:
FinalModel(FBEBuffer& buffer, size_t offset) noexcept;
// Get the allocation size
size_t fbe_allocation_size(const ::bank_dom::Global& fbe_value) const noexcept;
// Get the final offset
size_t fbe_offset() const noexcept { return _offset; }
// Set the final offset
size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; }
// Get the final type
static constexpr size_t fbe_type() noexcept { return 4; }
// Shift the current final offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current final offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the struct value is valid
size_t verify() const noexcept;
// Check if the struct fields are valid
size_t verify_fields() const noexcept;
// Get the struct value
size_t get(::bank_dom::Global& fbe_value) const noexcept;
// Get the struct fields values
size_t get_fields(::bank_dom::Global& fbe_value) const noexcept;
// Set the struct value
size_t set(const ::bank_dom::Global& fbe_value) noexcept;
// Set the struct fields values
size_t set_fields(const ::bank_dom::Global& fbe_value) noexcept;
private:
FBEBuffer& _buffer;
mutable size_t _offset;
public:
FinalModelVector<std::string> keys;
FinalModelVector<::bank_dom::User> users;
};
namespace bank_dom {
// Fast Binary Encoding Global final model
class GlobalFinalModel : public FBE::Model
{
public:
GlobalFinalModel() : _model(this->buffer(), 8) {}
GlobalFinalModel(const std::shared_ptr<FBEBuffer>& buffer) : FBE::Model(buffer), _model(this->buffer(), 8) {}
// Get the model type
static constexpr size_t fbe_type() noexcept { return FinalModel<::bank_dom::Global>::fbe_type(); }
// Check if the struct value is valid
bool verify();
// Serialize the struct value
size_t serialize(const ::bank_dom::Global& value);
// Deserialize the struct value
size_t deserialize(::bank_dom::Global& value) const noexcept;
// Move to the next struct value
void next(size_t prev) noexcept { _model.fbe_shift(prev); }
private:
FinalModel<::bank_dom::Global> _model;
};
} // namespace bank_dom
} // namespace FBE

View file

@ -0,0 +1,930 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: user_model.fbe
// Version: 1.7.0.0
#include "bank_dom_models.h"
namespace FBE {
FieldModel<::bank_dom::Transaction>::FieldModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset)
, from(buffer, 4 + 4)
, to(buffer, from.fbe_offset() + from.fbe_size())
, amount(buffer, to.fbe_offset() + to.fbe_size())
, time(buffer, amount.fbe_offset() + amount.fbe_size())
{}
size_t FieldModel<::bank_dom::Transaction>::fbe_body() const noexcept
{
size_t fbe_result = 4 + 4
+ from.fbe_size()
+ to.fbe_size()
+ amount.fbe_size()
+ time.fbe_size()
;
return fbe_result;
}
size_t FieldModel<::bank_dom::Transaction>::fbe_extra() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_struct_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + 4) > _buffer.size()))
return 0;
_buffer.shift(fbe_struct_offset);
size_t fbe_result = fbe_body()
+ from.fbe_extra()
+ to.fbe_extra()
+ amount.fbe_extra()
+ time.fbe_extra()
;
_buffer.unshift(fbe_struct_offset);
return fbe_result;
}
bool FieldModel<::bank_dom::Transaction>::verify(bool fbe_verify_type) const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return true;
uint32_t fbe_struct_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + 4 + 4) > _buffer.size()))
return false;
uint32_t fbe_struct_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset));
if (fbe_struct_size < (4 + 4))
return false;
uint32_t fbe_struct_type = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset + 4));
if (fbe_verify_type && (fbe_struct_type != fbe_type()))
return false;
_buffer.shift(fbe_struct_offset);
bool fbe_result = verify_fields(fbe_struct_size);
_buffer.unshift(fbe_struct_offset);
return fbe_result;
}
bool FieldModel<::bank_dom::Transaction>::verify_fields(size_t fbe_struct_size) const noexcept
{
size_t fbe_current_size = 4 + 4;
if ((fbe_current_size + from.fbe_size()) > fbe_struct_size)
return true;
if (!from.verify())
return false;
fbe_current_size += from.fbe_size();
if ((fbe_current_size + to.fbe_size()) > fbe_struct_size)
return true;
if (!to.verify())
return false;
fbe_current_size += to.fbe_size();
if ((fbe_current_size + amount.fbe_size()) > fbe_struct_size)
return true;
if (!amount.verify())
return false;
fbe_current_size += amount.fbe_size();
if ((fbe_current_size + time.fbe_size()) > fbe_struct_size)
return true;
if (!time.verify())
return false;
fbe_current_size += time.fbe_size();
return true;
}
size_t FieldModel<::bank_dom::Transaction>::get_begin() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_struct_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
assert(((fbe_struct_offset > 0) && ((_buffer.offset() + fbe_struct_offset + 4 + 4) <= _buffer.size())) && "Model is broken!");
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + 4 + 4) > _buffer.size()))
return 0;
uint32_t fbe_struct_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset));
assert((fbe_struct_size >= (4 + 4)) && "Model is broken!");
if (fbe_struct_size < (4 + 4))
return 0;
_buffer.shift(fbe_struct_offset);
return fbe_struct_offset;
}
void FieldModel<::bank_dom::Transaction>::get_end(size_t fbe_begin) const noexcept
{
_buffer.unshift(fbe_begin);
}
void FieldModel<::bank_dom::Transaction>::get(::bank_dom::Transaction& fbe_value) const noexcept
{
size_t fbe_begin = get_begin();
if (fbe_begin == 0)
return;
uint32_t fbe_struct_size = *((const uint32_t*)(_buffer.data() + _buffer.offset()));
get_fields(fbe_value, fbe_struct_size);
get_end(fbe_begin);
}
void FieldModel<::bank_dom::Transaction>::get_fields(::bank_dom::Transaction& fbe_value, size_t fbe_struct_size) const noexcept
{
size_t fbe_current_size = 4 + 4;
if ((fbe_current_size + from.fbe_size()) <= fbe_struct_size)
from.get(fbe_value.from, "");
else
fbe_value.from = "";
fbe_current_size += from.fbe_size();
if ((fbe_current_size + to.fbe_size()) <= fbe_struct_size)
to.get(fbe_value.to, "");
else
fbe_value.to = "";
fbe_current_size += to.fbe_size();
if ((fbe_current_size + amount.fbe_size()) <= fbe_struct_size)
amount.get(fbe_value.amount, (uint32_t)0ull);
else
fbe_value.amount = (uint32_t)0ull;
fbe_current_size += amount.fbe_size();
if ((fbe_current_size + time.fbe_size()) <= fbe_struct_size)
time.get(fbe_value.time);
else
fbe_value.time = (uint64_t)0ull;
fbe_current_size += time.fbe_size();
}
size_t FieldModel<::bank_dom::Transaction>::set_begin()
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_struct_size = (uint32_t)fbe_body();
uint32_t fbe_struct_offset = (uint32_t)(_buffer.allocate(fbe_struct_size) - _buffer.offset());
assert(((fbe_struct_offset > 0) && ((_buffer.offset() + fbe_struct_offset + fbe_struct_size) <= _buffer.size())) && "Model is broken!");
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + fbe_struct_size) > _buffer.size()))
return 0;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_struct_offset;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset)) = fbe_struct_size;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset + 4)) = (uint32_t)fbe_type();
_buffer.shift(fbe_struct_offset);
return fbe_struct_offset;
}
void FieldModel<::bank_dom::Transaction>::set_end(size_t fbe_begin)
{
_buffer.unshift(fbe_begin);
}
void FieldModel<::bank_dom::Transaction>::set(const ::bank_dom::Transaction& fbe_value) noexcept
{
size_t fbe_begin = set_begin();
if (fbe_begin == 0)
return;
set_fields(fbe_value);
set_end(fbe_begin);
}
void FieldModel<::bank_dom::Transaction>::set_fields(const ::bank_dom::Transaction& fbe_value) noexcept
{
from.set(fbe_value.from);
to.set(fbe_value.to);
amount.set(fbe_value.amount);
time.set(fbe_value.time);
}
namespace bank_dom {
bool TransactionModel::verify()
{
if ((this->buffer().offset() + model.fbe_offset() - 4) > this->buffer().size())
return false;
uint32_t fbe_full_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + model.fbe_offset() - 4));
if (fbe_full_size < model.fbe_size())
return false;
return model.verify();
}
size_t TransactionModel::create_begin()
{
size_t fbe_begin = this->buffer().allocate(4 + model.fbe_size());
return fbe_begin;
}
size_t TransactionModel::create_end(size_t fbe_begin)
{
size_t fbe_end = this->buffer().size();
uint32_t fbe_full_size = (uint32_t)(fbe_end - fbe_begin);
*((uint32_t*)(this->buffer().data() + this->buffer().offset() + model.fbe_offset() - 4)) = fbe_full_size;
return fbe_full_size;
}
size_t TransactionModel::serialize(const ::bank_dom::Transaction& value)
{
size_t fbe_begin = create_begin();
model.set(value);
size_t fbe_full_size = create_end(fbe_begin);
return fbe_full_size;
}
size_t TransactionModel::deserialize(::bank_dom::Transaction& value) const noexcept
{
if ((this->buffer().offset() + model.fbe_offset() - 4) > this->buffer().size())
return 0;
uint32_t fbe_full_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + model.fbe_offset() - 4));
assert((fbe_full_size >= model.fbe_size()) && "Model is broken!");
if (fbe_full_size < model.fbe_size())
return 0;
model.get(value);
return fbe_full_size;
}
} // namespace bank_dom
FieldModel<::bank_dom::Logs>::FieldModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset)
, data(buffer, 4 + 4)
{}
size_t FieldModel<::bank_dom::Logs>::fbe_body() const noexcept
{
size_t fbe_result = 4 + 4
+ data.fbe_size()
;
return fbe_result;
}
size_t FieldModel<::bank_dom::Logs>::fbe_extra() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_struct_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + 4) > _buffer.size()))
return 0;
_buffer.shift(fbe_struct_offset);
size_t fbe_result = fbe_body()
+ data.fbe_extra()
;
_buffer.unshift(fbe_struct_offset);
return fbe_result;
}
bool FieldModel<::bank_dom::Logs>::verify(bool fbe_verify_type) const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return true;
uint32_t fbe_struct_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + 4 + 4) > _buffer.size()))
return false;
uint32_t fbe_struct_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset));
if (fbe_struct_size < (4 + 4))
return false;
uint32_t fbe_struct_type = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset + 4));
if (fbe_verify_type && (fbe_struct_type != fbe_type()))
return false;
_buffer.shift(fbe_struct_offset);
bool fbe_result = verify_fields(fbe_struct_size);
_buffer.unshift(fbe_struct_offset);
return fbe_result;
}
bool FieldModel<::bank_dom::Logs>::verify_fields(size_t fbe_struct_size) const noexcept
{
size_t fbe_current_size = 4 + 4;
if ((fbe_current_size + data.fbe_size()) > fbe_struct_size)
return true;
if (!data.verify())
return false;
fbe_current_size += data.fbe_size();
return true;
}
size_t FieldModel<::bank_dom::Logs>::get_begin() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_struct_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
assert(((fbe_struct_offset > 0) && ((_buffer.offset() + fbe_struct_offset + 4 + 4) <= _buffer.size())) && "Model is broken!");
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + 4 + 4) > _buffer.size()))
return 0;
uint32_t fbe_struct_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset));
assert((fbe_struct_size >= (4 + 4)) && "Model is broken!");
if (fbe_struct_size < (4 + 4))
return 0;
_buffer.shift(fbe_struct_offset);
return fbe_struct_offset;
}
void FieldModel<::bank_dom::Logs>::get_end(size_t fbe_begin) const noexcept
{
_buffer.unshift(fbe_begin);
}
void FieldModel<::bank_dom::Logs>::get(::bank_dom::Logs& fbe_value) const noexcept
{
size_t fbe_begin = get_begin();
if (fbe_begin == 0)
return;
uint32_t fbe_struct_size = *((const uint32_t*)(_buffer.data() + _buffer.offset()));
get_fields(fbe_value, fbe_struct_size);
get_end(fbe_begin);
}
void FieldModel<::bank_dom::Logs>::get_fields(::bank_dom::Logs& fbe_value, size_t fbe_struct_size) const noexcept
{
size_t fbe_current_size = 4 + 4;
if ((fbe_current_size + data.fbe_size()) <= fbe_struct_size)
data.get(fbe_value.data);
else
fbe_value.data.clear();
fbe_current_size += data.fbe_size();
}
size_t FieldModel<::bank_dom::Logs>::set_begin()
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_struct_size = (uint32_t)fbe_body();
uint32_t fbe_struct_offset = (uint32_t)(_buffer.allocate(fbe_struct_size) - _buffer.offset());
assert(((fbe_struct_offset > 0) && ((_buffer.offset() + fbe_struct_offset + fbe_struct_size) <= _buffer.size())) && "Model is broken!");
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + fbe_struct_size) > _buffer.size()))
return 0;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_struct_offset;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset)) = fbe_struct_size;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset + 4)) = (uint32_t)fbe_type();
_buffer.shift(fbe_struct_offset);
return fbe_struct_offset;
}
void FieldModel<::bank_dom::Logs>::set_end(size_t fbe_begin)
{
_buffer.unshift(fbe_begin);
}
void FieldModel<::bank_dom::Logs>::set(const ::bank_dom::Logs& fbe_value) noexcept
{
size_t fbe_begin = set_begin();
if (fbe_begin == 0)
return;
set_fields(fbe_value);
set_end(fbe_begin);
}
void FieldModel<::bank_dom::Logs>::set_fields(const ::bank_dom::Logs& fbe_value) noexcept
{
data.set(fbe_value.data);
}
namespace bank_dom {
bool LogsModel::verify()
{
if ((this->buffer().offset() + model.fbe_offset() - 4) > this->buffer().size())
return false;
uint32_t fbe_full_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + model.fbe_offset() - 4));
if (fbe_full_size < model.fbe_size())
return false;
return model.verify();
}
size_t LogsModel::create_begin()
{
size_t fbe_begin = this->buffer().allocate(4 + model.fbe_size());
return fbe_begin;
}
size_t LogsModel::create_end(size_t fbe_begin)
{
size_t fbe_end = this->buffer().size();
uint32_t fbe_full_size = (uint32_t)(fbe_end - fbe_begin);
*((uint32_t*)(this->buffer().data() + this->buffer().offset() + model.fbe_offset() - 4)) = fbe_full_size;
return fbe_full_size;
}
size_t LogsModel::serialize(const ::bank_dom::Logs& value)
{
size_t fbe_begin = create_begin();
model.set(value);
size_t fbe_full_size = create_end(fbe_begin);
return fbe_full_size;
}
size_t LogsModel::deserialize(::bank_dom::Logs& value) const noexcept
{
if ((this->buffer().offset() + model.fbe_offset() - 4) > this->buffer().size())
return 0;
uint32_t fbe_full_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + model.fbe_offset() - 4));
assert((fbe_full_size >= model.fbe_size()) && "Model is broken!");
if (fbe_full_size < model.fbe_size())
return 0;
model.get(value);
return fbe_full_size;
}
} // namespace bank_dom
FieldModel<::bank_dom::User>::FieldModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset)
, balance(buffer, 4 + 4)
, password(buffer, balance.fbe_offset() + balance.fbe_size())
, logs(buffer, password.fbe_offset() + password.fbe_size())
{}
size_t FieldModel<::bank_dom::User>::fbe_body() const noexcept
{
size_t fbe_result = 4 + 4
+ balance.fbe_size()
+ password.fbe_size()
+ logs.fbe_size()
;
return fbe_result;
}
size_t FieldModel<::bank_dom::User>::fbe_extra() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_struct_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + 4) > _buffer.size()))
return 0;
_buffer.shift(fbe_struct_offset);
size_t fbe_result = fbe_body()
+ balance.fbe_extra()
+ password.fbe_extra()
+ logs.fbe_extra()
;
_buffer.unshift(fbe_struct_offset);
return fbe_result;
}
bool FieldModel<::bank_dom::User>::verify(bool fbe_verify_type) const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return true;
uint32_t fbe_struct_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + 4 + 4) > _buffer.size()))
return false;
uint32_t fbe_struct_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset));
if (fbe_struct_size < (4 + 4))
return false;
uint32_t fbe_struct_type = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset + 4));
if (fbe_verify_type && (fbe_struct_type != fbe_type()))
return false;
_buffer.shift(fbe_struct_offset);
bool fbe_result = verify_fields(fbe_struct_size);
_buffer.unshift(fbe_struct_offset);
return fbe_result;
}
bool FieldModel<::bank_dom::User>::verify_fields(size_t fbe_struct_size) const noexcept
{
size_t fbe_current_size = 4 + 4;
if ((fbe_current_size + balance.fbe_size()) > fbe_struct_size)
return true;
if (!balance.verify())
return false;
fbe_current_size += balance.fbe_size();
if ((fbe_current_size + password.fbe_size()) > fbe_struct_size)
return true;
if (!password.verify())
return false;
fbe_current_size += password.fbe_size();
if ((fbe_current_size + logs.fbe_size()) > fbe_struct_size)
return true;
if (!logs.verify())
return false;
fbe_current_size += logs.fbe_size();
return true;
}
size_t FieldModel<::bank_dom::User>::get_begin() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_struct_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
assert(((fbe_struct_offset > 0) && ((_buffer.offset() + fbe_struct_offset + 4 + 4) <= _buffer.size())) && "Model is broken!");
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + 4 + 4) > _buffer.size()))
return 0;
uint32_t fbe_struct_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset));
assert((fbe_struct_size >= (4 + 4)) && "Model is broken!");
if (fbe_struct_size < (4 + 4))
return 0;
_buffer.shift(fbe_struct_offset);
return fbe_struct_offset;
}
void FieldModel<::bank_dom::User>::get_end(size_t fbe_begin) const noexcept
{
_buffer.unshift(fbe_begin);
}
void FieldModel<::bank_dom::User>::get(::bank_dom::User& fbe_value) const noexcept
{
size_t fbe_begin = get_begin();
if (fbe_begin == 0)
return;
uint32_t fbe_struct_size = *((const uint32_t*)(_buffer.data() + _buffer.offset()));
get_fields(fbe_value, fbe_struct_size);
get_end(fbe_begin);
}
void FieldModel<::bank_dom::User>::get_fields(::bank_dom::User& fbe_value, size_t fbe_struct_size) const noexcept
{
size_t fbe_current_size = 4 + 4;
if ((fbe_current_size + balance.fbe_size()) <= fbe_struct_size)
balance.get(fbe_value.balance, (uint32_t)0ull);
else
fbe_value.balance = (uint32_t)0ull;
fbe_current_size += balance.fbe_size();
if ((fbe_current_size + password.fbe_size()) <= fbe_struct_size)
password.get(fbe_value.password, (uint64_t)0ull);
else
fbe_value.password = (uint64_t)0ull;
fbe_current_size += password.fbe_size();
if ((fbe_current_size + logs.fbe_size()) <= fbe_struct_size)
logs.get(fbe_value.logs, std::nullopt);
else
fbe_value.logs = std::nullopt;
fbe_current_size += logs.fbe_size();
}
size_t FieldModel<::bank_dom::User>::set_begin()
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_struct_size = (uint32_t)fbe_body();
uint32_t fbe_struct_offset = (uint32_t)(_buffer.allocate(fbe_struct_size) - _buffer.offset());
assert(((fbe_struct_offset > 0) && ((_buffer.offset() + fbe_struct_offset + fbe_struct_size) <= _buffer.size())) && "Model is broken!");
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + fbe_struct_size) > _buffer.size()))
return 0;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_struct_offset;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset)) = fbe_struct_size;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset + 4)) = (uint32_t)fbe_type();
_buffer.shift(fbe_struct_offset);
return fbe_struct_offset;
}
void FieldModel<::bank_dom::User>::set_end(size_t fbe_begin)
{
_buffer.unshift(fbe_begin);
}
void FieldModel<::bank_dom::User>::set(const ::bank_dom::User& fbe_value) noexcept
{
size_t fbe_begin = set_begin();
if (fbe_begin == 0)
return;
set_fields(fbe_value);
set_end(fbe_begin);
}
void FieldModel<::bank_dom::User>::set_fields(const ::bank_dom::User& fbe_value) noexcept
{
balance.set(fbe_value.balance);
password.set(fbe_value.password);
logs.set(fbe_value.logs);
}
namespace bank_dom {
bool UserModel::verify()
{
if ((this->buffer().offset() + model.fbe_offset() - 4) > this->buffer().size())
return false;
uint32_t fbe_full_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + model.fbe_offset() - 4));
if (fbe_full_size < model.fbe_size())
return false;
return model.verify();
}
size_t UserModel::create_begin()
{
size_t fbe_begin = this->buffer().allocate(4 + model.fbe_size());
return fbe_begin;
}
size_t UserModel::create_end(size_t fbe_begin)
{
size_t fbe_end = this->buffer().size();
uint32_t fbe_full_size = (uint32_t)(fbe_end - fbe_begin);
*((uint32_t*)(this->buffer().data() + this->buffer().offset() + model.fbe_offset() - 4)) = fbe_full_size;
return fbe_full_size;
}
size_t UserModel::serialize(const ::bank_dom::User& value)
{
size_t fbe_begin = create_begin();
model.set(value);
size_t fbe_full_size = create_end(fbe_begin);
return fbe_full_size;
}
size_t UserModel::deserialize(::bank_dom::User& value) const noexcept
{
if ((this->buffer().offset() + model.fbe_offset() - 4) > this->buffer().size())
return 0;
uint32_t fbe_full_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + model.fbe_offset() - 4));
assert((fbe_full_size >= model.fbe_size()) && "Model is broken!");
if (fbe_full_size < model.fbe_size())
return 0;
model.get(value);
return fbe_full_size;
}
} // namespace bank_dom
FieldModel<::bank_dom::Global>::FieldModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset)
, keys(buffer, 4 + 4)
, users(buffer, keys.fbe_offset() + keys.fbe_size())
{}
size_t FieldModel<::bank_dom::Global>::fbe_body() const noexcept
{
size_t fbe_result = 4 + 4
+ keys.fbe_size()
+ users.fbe_size()
;
return fbe_result;
}
size_t FieldModel<::bank_dom::Global>::fbe_extra() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_struct_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + 4) > _buffer.size()))
return 0;
_buffer.shift(fbe_struct_offset);
size_t fbe_result = fbe_body()
+ keys.fbe_extra()
+ users.fbe_extra()
;
_buffer.unshift(fbe_struct_offset);
return fbe_result;
}
bool FieldModel<::bank_dom::Global>::verify(bool fbe_verify_type) const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return true;
uint32_t fbe_struct_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + 4 + 4) > _buffer.size()))
return false;
uint32_t fbe_struct_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset));
if (fbe_struct_size < (4 + 4))
return false;
uint32_t fbe_struct_type = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset + 4));
if (fbe_verify_type && (fbe_struct_type != fbe_type()))
return false;
_buffer.shift(fbe_struct_offset);
bool fbe_result = verify_fields(fbe_struct_size);
_buffer.unshift(fbe_struct_offset);
return fbe_result;
}
bool FieldModel<::bank_dom::Global>::verify_fields(size_t fbe_struct_size) const noexcept
{
size_t fbe_current_size = 4 + 4;
if ((fbe_current_size + keys.fbe_size()) > fbe_struct_size)
return true;
if (!keys.verify())
return false;
fbe_current_size += keys.fbe_size();
if ((fbe_current_size + users.fbe_size()) > fbe_struct_size)
return true;
if (!users.verify())
return false;
fbe_current_size += users.fbe_size();
return true;
}
size_t FieldModel<::bank_dom::Global>::get_begin() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_struct_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
assert(((fbe_struct_offset > 0) && ((_buffer.offset() + fbe_struct_offset + 4 + 4) <= _buffer.size())) && "Model is broken!");
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + 4 + 4) > _buffer.size()))
return 0;
uint32_t fbe_struct_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset));
assert((fbe_struct_size >= (4 + 4)) && "Model is broken!");
if (fbe_struct_size < (4 + 4))
return 0;
_buffer.shift(fbe_struct_offset);
return fbe_struct_offset;
}
void FieldModel<::bank_dom::Global>::get_end(size_t fbe_begin) const noexcept
{
_buffer.unshift(fbe_begin);
}
void FieldModel<::bank_dom::Global>::get(::bank_dom::Global& fbe_value) const noexcept
{
size_t fbe_begin = get_begin();
if (fbe_begin == 0)
return;
uint32_t fbe_struct_size = *((const uint32_t*)(_buffer.data() + _buffer.offset()));
get_fields(fbe_value, fbe_struct_size);
get_end(fbe_begin);
}
void FieldModel<::bank_dom::Global>::get_fields(::bank_dom::Global& fbe_value, size_t fbe_struct_size) const noexcept
{
size_t fbe_current_size = 4 + 4;
if ((fbe_current_size + keys.fbe_size()) <= fbe_struct_size)
keys.get(fbe_value.keys);
else
fbe_value.keys.clear();
fbe_current_size += keys.fbe_size();
if ((fbe_current_size + users.fbe_size()) <= fbe_struct_size)
users.get(fbe_value.users);
else
fbe_value.users.clear();
fbe_current_size += users.fbe_size();
}
size_t FieldModel<::bank_dom::Global>::set_begin()
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_struct_size = (uint32_t)fbe_body();
uint32_t fbe_struct_offset = (uint32_t)(_buffer.allocate(fbe_struct_size) - _buffer.offset());
assert(((fbe_struct_offset > 0) && ((_buffer.offset() + fbe_struct_offset + fbe_struct_size) <= _buffer.size())) && "Model is broken!");
if ((fbe_struct_offset == 0) || ((_buffer.offset() + fbe_struct_offset + fbe_struct_size) > _buffer.size()))
return 0;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_struct_offset;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset)) = fbe_struct_size;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_struct_offset + 4)) = (uint32_t)fbe_type();
_buffer.shift(fbe_struct_offset);
return fbe_struct_offset;
}
void FieldModel<::bank_dom::Global>::set_end(size_t fbe_begin)
{
_buffer.unshift(fbe_begin);
}
void FieldModel<::bank_dom::Global>::set(const ::bank_dom::Global& fbe_value) noexcept
{
size_t fbe_begin = set_begin();
if (fbe_begin == 0)
return;
set_fields(fbe_value);
set_end(fbe_begin);
}
void FieldModel<::bank_dom::Global>::set_fields(const ::bank_dom::Global& fbe_value) noexcept
{
keys.set(fbe_value.keys);
users.set(fbe_value.users);
}
namespace bank_dom {
bool GlobalModel::verify()
{
if ((this->buffer().offset() + model.fbe_offset() - 4) > this->buffer().size())
return false;
uint32_t fbe_full_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + model.fbe_offset() - 4));
if (fbe_full_size < model.fbe_size())
return false;
return model.verify();
}
size_t GlobalModel::create_begin()
{
size_t fbe_begin = this->buffer().allocate(4 + model.fbe_size());
return fbe_begin;
}
size_t GlobalModel::create_end(size_t fbe_begin)
{
size_t fbe_end = this->buffer().size();
uint32_t fbe_full_size = (uint32_t)(fbe_end - fbe_begin);
*((uint32_t*)(this->buffer().data() + this->buffer().offset() + model.fbe_offset() - 4)) = fbe_full_size;
return fbe_full_size;
}
size_t GlobalModel::serialize(const ::bank_dom::Global& value)
{
size_t fbe_begin = create_begin();
model.set(value);
size_t fbe_full_size = create_end(fbe_begin);
return fbe_full_size;
}
size_t GlobalModel::deserialize(::bank_dom::Global& value) const noexcept
{
if ((this->buffer().offset() + model.fbe_offset() - 4) > this->buffer().size())
return 0;
uint32_t fbe_full_size = *((const uint32_t*)(this->buffer().data() + this->buffer().offset() + model.fbe_offset() - 4));
assert((fbe_full_size >= model.fbe_size()) && "Model is broken!");
if (fbe_full_size < model.fbe_size())
return 0;
model.get(value);
return fbe_full_size;
}
} // namespace bank_dom
} // namespace FBE

View file

@ -0,0 +1,396 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: user_model.fbe
// Version: 1.7.0.0
#pragma once
#if defined(__clang__)
#pragma clang system_header
#elif defined(__GNUC__)
#pragma GCC system_header
#elif defined(_MSC_VER)
#pragma system_header
#endif
#include "fbe_models.h"
#include "bank_dom.h"
namespace FBE {
// Fast Binary Encoding ::bank_dom::Transaction field model
template <>
class FieldModel<::bank_dom::Transaction>
{
public:
FieldModel(FBEBuffer& buffer, size_t offset) noexcept;
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Get the field size
size_t fbe_size() const noexcept { return 4; }
// Get the field body size
size_t fbe_body() const noexcept;
// Get the field extra size
size_t fbe_extra() const noexcept;
// Get the field type
static constexpr size_t fbe_type() noexcept { return 1; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the struct value is valid
bool verify(bool fbe_verify_type = true) const noexcept;
// Check if the struct fields are valid
bool verify_fields(size_t fbe_struct_size) const noexcept;
// Get the struct value (begin phase)
size_t get_begin() const noexcept;
// Get the struct value (end phase)
void get_end(size_t fbe_begin) const noexcept;
// Get the struct value
void get(::bank_dom::Transaction& fbe_value) const noexcept;
// Get the struct fields values
void get_fields(::bank_dom::Transaction& fbe_value, size_t fbe_struct_size) const noexcept;
// Set the struct value (begin phase)
size_t set_begin();
// Set the struct value (end phase)
void set_end(size_t fbe_begin);
// Set the struct value
void set(const ::bank_dom::Transaction& fbe_value) noexcept;
// Set the struct fields values
void set_fields(const ::bank_dom::Transaction& fbe_value) noexcept;
private:
FBEBuffer& _buffer;
size_t _offset;
public:
FieldModel<std::string> from;
FieldModel<std::string> to;
FieldModel<uint32_t> amount;
FieldModel<uint64_t> time;
};
namespace bank_dom {
// Fast Binary Encoding Transaction model
class TransactionModel : public FBE::Model
{
public:
TransactionModel() : model(this->buffer(), 4) {}
TransactionModel(const std::shared_ptr<FBEBuffer>& buffer) : FBE::Model(buffer), model(this->buffer(), 4) {}
// Get the model size
size_t fbe_size() const noexcept { return model.fbe_size() + model.fbe_extra(); }
// Get the model type
static constexpr size_t fbe_type() noexcept { return FieldModel<::bank_dom::Transaction>::fbe_type(); }
// Check if the struct value is valid
bool verify();
// Create a new model (begin phase)
size_t create_begin();
// Create a new model (end phase)
size_t create_end(size_t fbe_begin);
// Serialize the struct value
size_t serialize(const ::bank_dom::Transaction& value);
// Deserialize the struct value
size_t deserialize(::bank_dom::Transaction& value) const noexcept;
// Move to the next struct value
void next(size_t prev) noexcept { model.fbe_shift(prev); }
public:
FieldModel<::bank_dom::Transaction> model;
};
} // namespace bank_dom
// Fast Binary Encoding ::bank_dom::Logs field model
template <>
class FieldModel<::bank_dom::Logs>
{
public:
FieldModel(FBEBuffer& buffer, size_t offset) noexcept;
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Get the field size
size_t fbe_size() const noexcept { return 4; }
// Get the field body size
size_t fbe_body() const noexcept;
// Get the field extra size
size_t fbe_extra() const noexcept;
// Get the field type
static constexpr size_t fbe_type() noexcept { return 2; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the struct value is valid
bool verify(bool fbe_verify_type = true) const noexcept;
// Check if the struct fields are valid
bool verify_fields(size_t fbe_struct_size) const noexcept;
// Get the struct value (begin phase)
size_t get_begin() const noexcept;
// Get the struct value (end phase)
void get_end(size_t fbe_begin) const noexcept;
// Get the struct value
void get(::bank_dom::Logs& fbe_value) const noexcept;
// Get the struct fields values
void get_fields(::bank_dom::Logs& fbe_value, size_t fbe_struct_size) const noexcept;
// Set the struct value (begin phase)
size_t set_begin();
// Set the struct value (end phase)
void set_end(size_t fbe_begin);
// Set the struct value
void set(const ::bank_dom::Logs& fbe_value) noexcept;
// Set the struct fields values
void set_fields(const ::bank_dom::Logs& fbe_value) noexcept;
private:
FBEBuffer& _buffer;
size_t _offset;
public:
FieldModelVector<::bank_dom::Transaction> data;
};
namespace bank_dom {
// Fast Binary Encoding Logs model
class LogsModel : public FBE::Model
{
public:
LogsModel() : model(this->buffer(), 4) {}
LogsModel(const std::shared_ptr<FBEBuffer>& buffer) : FBE::Model(buffer), model(this->buffer(), 4) {}
// Get the model size
size_t fbe_size() const noexcept { return model.fbe_size() + model.fbe_extra(); }
// Get the model type
static constexpr size_t fbe_type() noexcept { return FieldModel<::bank_dom::Logs>::fbe_type(); }
// Check if the struct value is valid
bool verify();
// Create a new model (begin phase)
size_t create_begin();
// Create a new model (end phase)
size_t create_end(size_t fbe_begin);
// Serialize the struct value
size_t serialize(const ::bank_dom::Logs& value);
// Deserialize the struct value
size_t deserialize(::bank_dom::Logs& value) const noexcept;
// Move to the next struct value
void next(size_t prev) noexcept { model.fbe_shift(prev); }
public:
FieldModel<::bank_dom::Logs> model;
};
} // namespace bank_dom
// Fast Binary Encoding ::bank_dom::User field model
template <>
class FieldModel<::bank_dom::User>
{
public:
FieldModel(FBEBuffer& buffer, size_t offset) noexcept;
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Get the field size
size_t fbe_size() const noexcept { return 4; }
// Get the field body size
size_t fbe_body() const noexcept;
// Get the field extra size
size_t fbe_extra() const noexcept;
// Get the field type
static constexpr size_t fbe_type() noexcept { return 3; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the struct value is valid
bool verify(bool fbe_verify_type = true) const noexcept;
// Check if the struct fields are valid
bool verify_fields(size_t fbe_struct_size) const noexcept;
// Get the struct value (begin phase)
size_t get_begin() const noexcept;
// Get the struct value (end phase)
void get_end(size_t fbe_begin) const noexcept;
// Get the struct value
void get(::bank_dom::User& fbe_value) const noexcept;
// Get the struct fields values
void get_fields(::bank_dom::User& fbe_value, size_t fbe_struct_size) const noexcept;
// Set the struct value (begin phase)
size_t set_begin();
// Set the struct value (end phase)
void set_end(size_t fbe_begin);
// Set the struct value
void set(const ::bank_dom::User& fbe_value) noexcept;
// Set the struct fields values
void set_fields(const ::bank_dom::User& fbe_value) noexcept;
private:
FBEBuffer& _buffer;
size_t _offset;
public:
FieldModel<uint32_t> balance;
FieldModel<uint64_t> password;
FieldModel<std::optional<::bank_dom::Logs>> logs;
};
namespace bank_dom {
// Fast Binary Encoding User model
class UserModel : public FBE::Model
{
public:
UserModel() : model(this->buffer(), 4) {}
UserModel(const std::shared_ptr<FBEBuffer>& buffer) : FBE::Model(buffer), model(this->buffer(), 4) {}
// Get the model size
size_t fbe_size() const noexcept { return model.fbe_size() + model.fbe_extra(); }
// Get the model type
static constexpr size_t fbe_type() noexcept { return FieldModel<::bank_dom::User>::fbe_type(); }
// Check if the struct value is valid
bool verify();
// Create a new model (begin phase)
size_t create_begin();
// Create a new model (end phase)
size_t create_end(size_t fbe_begin);
// Serialize the struct value
size_t serialize(const ::bank_dom::User& value);
// Deserialize the struct value
size_t deserialize(::bank_dom::User& value) const noexcept;
// Move to the next struct value
void next(size_t prev) noexcept { model.fbe_shift(prev); }
public:
FieldModel<::bank_dom::User> model;
};
} // namespace bank_dom
// Fast Binary Encoding ::bank_dom::Global field model
template <>
class FieldModel<::bank_dom::Global>
{
public:
FieldModel(FBEBuffer& buffer, size_t offset) noexcept;
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Get the field size
size_t fbe_size() const noexcept { return 4; }
// Get the field body size
size_t fbe_body() const noexcept;
// Get the field extra size
size_t fbe_extra() const noexcept;
// Get the field type
static constexpr size_t fbe_type() noexcept { return 4; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the struct value is valid
bool verify(bool fbe_verify_type = true) const noexcept;
// Check if the struct fields are valid
bool verify_fields(size_t fbe_struct_size) const noexcept;
// Get the struct value (begin phase)
size_t get_begin() const noexcept;
// Get the struct value (end phase)
void get_end(size_t fbe_begin) const noexcept;
// Get the struct value
void get(::bank_dom::Global& fbe_value) const noexcept;
// Get the struct fields values
void get_fields(::bank_dom::Global& fbe_value, size_t fbe_struct_size) const noexcept;
// Set the struct value (begin phase)
size_t set_begin();
// Set the struct value (end phase)
void set_end(size_t fbe_begin);
// Set the struct value
void set(const ::bank_dom::Global& fbe_value) noexcept;
// Set the struct fields values
void set_fields(const ::bank_dom::Global& fbe_value) noexcept;
private:
FBEBuffer& _buffer;
size_t _offset;
public:
FieldModelVector<std::string> keys;
FieldModelVector<::bank_dom::User> users;
};
namespace bank_dom {
// Fast Binary Encoding Global model
class GlobalModel : public FBE::Model
{
public:
GlobalModel() : model(this->buffer(), 4) {}
GlobalModel(const std::shared_ptr<FBEBuffer>& buffer) : FBE::Model(buffer), model(this->buffer(), 4) {}
// Get the model size
size_t fbe_size() const noexcept { return model.fbe_size() + model.fbe_extra(); }
// Get the model type
static constexpr size_t fbe_type() noexcept { return FieldModel<::bank_dom::Global>::fbe_type(); }
// Check if the struct value is valid
bool verify();
// Create a new model (begin phase)
size_t create_begin();
// Create a new model (end phase)
size_t create_end(size_t fbe_begin);
// Serialize the struct value
size_t serialize(const ::bank_dom::Global& value);
// Deserialize the struct value
size_t deserialize(::bank_dom::Global& value) const noexcept;
// Move to the next struct value
void next(size_t prev) noexcept { model.fbe_shift(prev); }
public:
FieldModel<::bank_dom::Global> model;
};
} // namespace bank_dom
} // namespace FBE

401
fbe/user_model/fbe.cpp Normal file
View file

@ -0,0 +1,401 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
#include "fbe.h"
namespace FBE {
std::string buffer_t::base64encode() const
{
const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string result;
int val = 0;
int valb = -6;
for (auto c : _data)
{
val = (val << 8) + c;
valb += 8;
while (valb >= 0)
{
result.push_back(base64[(val >> valb) & 0x3F]);
valb -= 6;
}
}
if (valb > -6)
result.push_back(base64[((val << 8) >> (valb + 8)) & 0x3F]);
while (result.size() % 4)
result.push_back('=');
return result;
}
buffer_t buffer_t::base64decode(const std::string& str)
{
const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
buffer_t result;
std::vector<int> pattern(256, -1);
for (int i = 0; i < 64; ++i)
pattern[base64[i]] = i;
int val = 0;
int valb = -8;
for (auto c : str)
{
if (pattern[c] == -1)
break;
val = (val << 6) + pattern[c];
valb += 6;
if (valb >= 0)
{
result.push_back((uint8_t)((val >> valb) & 0xFF));
valb -= 8;
}
}
return result;
}
uint64_t utc()
{
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
struct timespec timestamp;
if (clock_gettime(CLOCK_REALTIME, &timestamp) != 0)
throw std::runtime_error("Cannot get value of CLOCK_REALTIME timer!");
return (timestamp.tv_sec * 1000000000) + timestamp.tv_nsec;
#elif defined(_WIN32) || defined(_WIN64)
FILETIME ft;
GetSystemTimePreciseAsFileTime(&ft);
ULARGE_INTEGER result;
result.LowPart = ft.dwLowDateTime;
result.HighPart = ft.dwHighDateTime;
return (result.QuadPart - 116444736000000000ull) * 100;
#endif
}
uint8_t unhex(char ch)
{
if ((ch >= '0') && (ch <= '9'))
return ch - '0';
else if ((ch >= 'a') && (ch <= 'f'))
return 10 + ch - 'a';
else if ((ch >= 'A') && (ch <= 'F'))
return 10 + ch - 'A';
else
return 255;
}
uuid_t::uuid_t(const std::string& uuid)
{
char v1 = 0;
char v2 = 0;
bool pack = false;
size_t index = 0;
// Parse UUID string
for (auto ch : uuid)
{
if ((ch == '-') || (ch == '{') || (ch == '}'))
continue;
if (pack)
{
v2 = ch;
pack = false;
uint8_t ui1 = unhex(v1);
uint8_t ui2 = unhex(v2);
if ((ui1 > 15) || (ui2 > 15))
throw std::invalid_argument("Invalid UUID string: " + uuid);
_data[index++] = ui1 * 16 + ui2;
if (index >= 16)
break;
}
else
{
v1 = ch;
pack = true;
}
}
// Fill remaining data with zeros
for (; index < 16; ++index)
_data[index++] = 0;
}
std::string uuid_t::string() const
{
const char* digits = "0123456789abcdef";
std::string result(36, '0');
int index = 0;
for (auto value : _data)
{
result[index++] = digits[(value >> 4) & 0x0F];
result[index++] = digits[(value >> 0) & 0x0F];
if ((index == 8) || (index == 13) || (index == 18) || (index == 23))
result[index++] = '-';
}
return result;
}
uuid_t uuid_t::sequential()
{
uuid_t result;
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
::uuid_t uuid;
uuid_generate_time(uuid);
result._data[0] = uuid[0];
result._data[1] = uuid[1];
result._data[2] = uuid[2];
result._data[3] = uuid[3];
result._data[4] = uuid[4];
result._data[5] = uuid[5];
result._data[6] = uuid[6];
result._data[7] = uuid[7];
result._data[8] = uuid[8];
result._data[9] = uuid[9];
result._data[10] = uuid[10];
result._data[11] = uuid[11];
result._data[12] = uuid[12];
result._data[13] = uuid[13];
result._data[14] = uuid[14];
result._data[15] = uuid[15];
#elif defined(_WIN32) || defined(_WIN64)
::UUID uuid;
if (UuidCreateSequential(&uuid) != RPC_S_OK)
throw std::runtime_error("Cannot generate sequential UUID!");
result._data[0] = (uuid.Data1 >> 24) & 0xFF;
result._data[1] = (uuid.Data1 >> 16) & 0xFF;
result._data[2] = (uuid.Data1 >> 8) & 0xFF;
result._data[3] = (uuid.Data1 >> 0) & 0xFF;
result._data[4] = (uuid.Data2 >> 8) & 0xFF;
result._data[5] = (uuid.Data2 >> 0) & 0xFF;
result._data[6] = (uuid.Data3 >> 8) & 0xFF;
result._data[7] = (uuid.Data3 >> 0) & 0xFF;
result._data[8] = uuid.Data4[0];
result._data[9] = uuid.Data4[1];
result._data[10] = uuid.Data4[2];
result._data[11] = uuid.Data4[3];
result._data[12] = uuid.Data4[4];
result._data[13] = uuid.Data4[5];
result._data[14] = uuid.Data4[6];
result._data[15] = uuid.Data4[7];
#endif
return result;
}
uuid_t uuid_t::random()
{
uuid_t result;
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
::uuid_t uuid;
uuid_generate_random(uuid);
result._data[0] = uuid[0];
result._data[1] = uuid[1];
result._data[2] = uuid[2];
result._data[3] = uuid[3];
result._data[4] = uuid[4];
result._data[5] = uuid[5];
result._data[6] = uuid[6];
result._data[7] = uuid[7];
result._data[8] = uuid[8];
result._data[9] = uuid[9];
result._data[10] = uuid[10];
result._data[11] = uuid[11];
result._data[12] = uuid[12];
result._data[13] = uuid[13];
result._data[14] = uuid[14];
result._data[15] = uuid[15];
#elif defined(_WIN32) || defined(_WIN64)
::UUID uuid;
if (UuidCreate(&uuid) != RPC_S_OK)
throw std::runtime_error("Cannot generate random UUID!");
result._data[0] = (uuid.Data1 >> 24) & 0xFF;
result._data[1] = (uuid.Data1 >> 16) & 0xFF;
result._data[2] = (uuid.Data1 >> 8) & 0xFF;
result._data[3] = (uuid.Data1 >> 0) & 0xFF;
result._data[4] = (uuid.Data2 >> 8) & 0xFF;
result._data[5] = (uuid.Data2 >> 0) & 0xFF;
result._data[6] = (uuid.Data3 >> 8) & 0xFF;
result._data[7] = (uuid.Data3 >> 0) & 0xFF;
result._data[8] = uuid.Data4[0];
result._data[9] = uuid.Data4[1];
result._data[10] = uuid.Data4[2];
result._data[11] = uuid.Data4[3];
result._data[12] = uuid.Data4[4];
result._data[13] = uuid.Data4[5];
result._data[14] = uuid.Data4[6];
result._data[15] = uuid.Data4[7];
#endif
return result;
}
#if defined(LOGGING_PROTOCOL)
CppLogging::Record& operator<<(CppLogging::Record& record, const uuid_t& uuid)
{
const char* digits = "0123456789abcdef";
std::array<char, 36> result;
int index = 0;
for (auto value : uuid.data())
{
result[index++] = digits[(value >> 4) & 0x0F];
result[index++] = digits[(value >> 0) & 0x0F];
if ((index == 8) || (index == 13) || (index == 18) || (index == 23))
result[index++] = '-';
}
return record.StoreCustom(std::string_view(result.data(), result.size()));
}
#endif
void FBEBuffer::attach(const void* data, size_t size, size_t offset)
{
assert((data != nullptr) && "Invalid buffer!");
if (data == nullptr)
throw std::invalid_argument("Invalid buffer!");
assert((size > 0) && "Invalid size!");
if (size == 0)
throw std::invalid_argument("Invalid size!");
assert((offset <= size) && "Invalid offset!");
if (offset > size)
throw std::invalid_argument("Invalid offset!");
_data = (uint8_t*)data;
_capacity = 0;
_size = size;
_offset = offset;
}
void FBEBuffer::attach(const std::vector<uint8_t>& buffer, size_t offset)
{
assert((buffer.data() != nullptr) && "Invalid buffer!");
if (buffer.data() == nullptr)
throw std::invalid_argument("Invalid buffer!");
assert((buffer.size() > 0) && "Invalid size!");
if (buffer.size() == 0)
throw std::invalid_argument("Invalid size!");
assert((offset <= buffer.size()) && "Invalid offset!");
if (offset > buffer.size())
throw std::invalid_argument("Invalid offset!");
_data = (uint8_t*)buffer.data();
_capacity = 0;
_size = buffer.size();
_offset = offset;
}
void FBEBuffer::clone(const void* data, size_t size, size_t offset)
{
assert((offset <= size) && "Invalid offset!");
if (offset > size)
throw std::invalid_argument("Invalid offset!");
reserve(size);
std::memcpy(_data, data, size);
_capacity = size;
_size = size;
_offset = offset;
}
void FBEBuffer::clone(const std::vector<uint8_t>& buffer, size_t offset)
{
assert((offset <= buffer.size()) && "Invalid offset!");
if (offset > buffer.size())
throw std::invalid_argument("Invalid offset!");
size_t size = buffer.size();
reserve(size);
std::memcpy(_data, buffer.data(), size);
_capacity = size;
_size = size;
_offset = offset;
}
size_t FBEBuffer::allocate(size_t size)
{
size_t offset = _size;
// Calculate a new buffer size
size_t total = _size + size;
if (total <= _capacity)
{
_size = total;
return offset;
}
_capacity = std::max(total, 2 * _capacity);
uint8_t* data = (uint8_t*)std::malloc(_capacity);
std::memcpy(data, _data, _size);
std::free(_data);
_data = data;
_size = total;
return offset;
}
void FBEBuffer::remove(size_t offset, size_t size)
{
assert(((offset + size) <= _size) && "Invalid offset & size!");
if ((offset + size) > _size)
throw std::invalid_argument("Invalid offset & size!");
std::memcpy(_data + offset, _data + offset + size, _size - size - offset);
_size -= size;
if (_offset >= (offset + size))
_offset -= size;
else if (_offset >= offset)
{
_offset -= _offset - offset;
if (_offset > _size)
_offset = _size;
}
}
void FBEBuffer::reserve(size_t capacity)
{
if (capacity > _capacity)
{
_capacity = std::max(capacity, 2 * _capacity);
uint8_t* data = (uint8_t*)std::malloc(_capacity);
std::memcpy(data, _data, _size);
std::free(_data);
_data = data;
}
}
void FBEBuffer::resize(size_t size)
{
reserve(size);
_size = size;
if (_offset > _size)
_offset = _size;
}
void FBEBuffer::reset()
{
_size = 0;
_offset = 0;
}
} // namespace FBE

650
fbe/user_model/fbe.h Normal file
View file

@ -0,0 +1,650 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
#pragma once
#if defined(__clang__)
#pragma clang system_header
#elif defined(__GNUC__)
#pragma GCC system_header
#elif defined(_MSC_VER)
#pragma system_header
#endif
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstring>
#include <cctype>
#include <future>
#include <iomanip>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <optional>
#include <set>
#include <sstream>
#include <stdexcept>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <vector>
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
#include <time.h>
#include <uuid/uuid.h>
#undef HOST_NOT_FOUND
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#undef DELETE
#undef ERROR
#undef HOST_NOT_FOUND
#undef Yield
#undef min
#undef max
#undef uuid_t
#endif
namespace FBE {
//! Bytes buffer type
/*!
Represents bytes buffer which is a lightweight wrapper around std::vector<uint8_t>
with similar interface.
*/
class buffer_t
{
public:
typedef std::vector<uint8_t>::iterator iterator;
typedef std::vector<uint8_t>::const_iterator const_iterator;
typedef std::vector<uint8_t>::reverse_iterator reverse_iterator;
typedef std::vector<uint8_t>::const_reverse_iterator const_reverse_iterator;
buffer_t() = default;
buffer_t(size_t capacity) { reserve(capacity); }
buffer_t(const std::string& str) { assign(str); }
buffer_t(size_t size, uint8_t value) { assign(size, value); }
buffer_t(const uint8_t* data, size_t size) { assign(data, size); }
buffer_t(const std::vector<uint8_t>& other) : _data(other) {}
buffer_t(std::vector<uint8_t>&& other) : _data(std::move(other)) {}
buffer_t(const buffer_t& other) = default;
buffer_t(buffer_t&& other) = default;
~buffer_t() = default;
buffer_t& operator=(const std::string& str) { assign(str); return *this; }
buffer_t& operator=(const std::vector<uint8_t>& other) { _data = other; return *this; }
buffer_t& operator=(std::vector<uint8_t>&& other) { _data = std::move(other); return *this; }
buffer_t& operator=(const buffer_t& other) = default;
buffer_t& operator=(buffer_t&& other) = default;
uint8_t& operator[](size_t index) { return _data[index]; }
const uint8_t& operator[](size_t index) const { return _data[index]; }
bool empty() const { return _data.empty(); }
size_t capacity() const { return _data.capacity(); }
size_t size() const { return _data.size(); }
size_t max_size() const { return _data.max_size(); }
std::vector<uint8_t>& buffer() noexcept { return _data; }
const std::vector<uint8_t>& buffer() const noexcept { return _data; }
uint8_t* data() noexcept { return _data.data(); }
const uint8_t* data() const noexcept { return _data.data(); }
uint8_t& at(size_t index) { return _data.at(index); }
const uint8_t& at(size_t index) const { return _data.at(index); }
uint8_t& front() { return _data.front(); }
const uint8_t& front() const { return _data.front(); }
uint8_t& back() { return _data.back(); }
const uint8_t& back() const { return _data.back(); }
void reserve(size_t capacity) { _data.reserve(capacity); }
void resize(size_t size, uint8_t value = 0) { _data.resize(size, value); }
void shrink_to_fit() { _data.shrink_to_fit(); }
void assign(const std::string& str) { assign((const uint8_t*)str.c_str(), str.size()); }
void assign(const std::vector<uint8_t>& vec) { assign(vec.begin(), vec.end()); }
void assign(size_t size, uint8_t value) { _data.assign(size, value); }
void assign(const uint8_t* data, size_t size) { _data.assign(data, data + size); }
template <class InputIterator>
void assign(InputIterator first, InputIterator last) { _data.assign(first, last); }
iterator insert(const_iterator position, uint8_t value) { return _data.insert(position, value); }
iterator insert(const_iterator position, const std::string& str) { return insert(position, (const uint8_t*)str.c_str(), str.size()); }
iterator insert(const_iterator position, const std::vector<uint8_t>& vec) { return insert(position, vec.begin(), vec.end()); }
iterator insert(const_iterator position, size_t size, uint8_t value) { return _data.insert(position, size, value); }
iterator insert(const_iterator position, const uint8_t* data, size_t size) { return _data.insert(position, data, data + size); }
template <class InputIterator>
iterator insert(const_iterator position, InputIterator first, InputIterator last) { return _data.insert(position, first, last); }
iterator erase(const_iterator position) { return _data.erase(position); }
iterator erase(const_iterator first, const_iterator last) { return _data.erase(first, last); }
void clear() noexcept { _data.clear(); }
void push_back(uint8_t value) { _data.push_back(value); }
void pop_back() { _data.pop_back(); }
template <class... Args>
iterator emplace(const_iterator position, Args&&... args) { return _data.emplace(position, args...); }
template <class... Args>
void emplace_back(Args&&... args) { _data.emplace_back(args...); }
iterator begin() noexcept { return _data.begin(); }
const_iterator begin() const noexcept { return _data.begin(); }
const_iterator cbegin() const noexcept { return _data.cbegin(); }
reverse_iterator rbegin() noexcept { return _data.rbegin(); }
const_reverse_iterator rbegin() const noexcept { return _data.rbegin(); }
const_reverse_iterator crbegin() const noexcept { return _data.crbegin(); }
iterator end() noexcept { return _data.end(); }
const_iterator end() const noexcept { return _data.end(); }
const_iterator cend() const noexcept { return _data.cend(); }
reverse_iterator rend() noexcept { return _data.rend(); }
const_reverse_iterator rend() const noexcept { return _data.rend(); }
const_reverse_iterator crend() const noexcept { return _data.crend(); }
//! Get the string equivalent from the bytes buffer
std::string string() const { return std::string(_data.begin(), _data.end()); }
//! Encode the Base64 string from the bytes buffer
std::string base64encode() const;
//! Decode the bytes buffer from the Base64 string
static buffer_t base64decode(const std::string& str);
//! Swap two instances
void swap(buffer_t& value) noexcept
{ using std::swap; swap(_data, value._data); }
friend void swap(buffer_t& value1, buffer_t& value2) noexcept
{ value1.swap(value2); }
private:
std::vector<uint8_t> _data;
};
//! Decimal type
/*!
Represents decimal type using double and provides basic arithmetic operations.
*/
class decimal_t
{
public:
decimal_t() noexcept { _value = 0.0; }
decimal_t(int8_t value) noexcept { _value = (double)value; }
decimal_t(uint8_t value) noexcept { _value = (double)value; }
decimal_t(int16_t value) noexcept { _value = (double)value; }
decimal_t(uint16_t value) noexcept { _value = (double)value; }
decimal_t(int32_t value) noexcept { _value = (double)value; }
decimal_t(uint32_t value) noexcept { _value = (double)value; }
decimal_t(int64_t value) noexcept { _value = (double)value; }
decimal_t(uint64_t value) noexcept { _value = (double)value; }
decimal_t(float value) noexcept { _value = (double)value; }
decimal_t(double value) noexcept { _value = value; }
template <typename T>
explicit decimal_t(const T& value) noexcept { _value = (double)value; }
decimal_t(const decimal_t& value) noexcept = default;
decimal_t(decimal_t&& value) noexcept = default;
~decimal_t() noexcept = default;
template <typename T>
decimal_t& operator=(const T& value) noexcept { _value = (double)value; return *this; }
decimal_t& operator=(const decimal_t& value) noexcept = default;
decimal_t& operator=(decimal_t&& value) noexcept = default;
// Arithmetic operators
decimal_t operator+() const noexcept { return decimal_t(_value); }
decimal_t operator-() const noexcept { return decimal_t(-_value); }
decimal_t& operator++() noexcept { return *this += 1; }
decimal_t operator++(int) noexcept { decimal_t temp(*this); ++*this; return temp; }
decimal_t& operator--() noexcept { return *this -= 1; }
decimal_t operator--(int) noexcept { decimal_t temp(*this); --*this; return temp; }
decimal_t& operator+=(const decimal_t& value) noexcept { return *this = *this + value; }
decimal_t& operator-=(const decimal_t& value) noexcept { return *this = *this - value; }
decimal_t& operator*=(const decimal_t& value) noexcept { return *this = *this * value; }
decimal_t& operator/=(const decimal_t& value) { return *this = *this / value; }
template <typename T>
decimal_t& operator+=(const T& value) noexcept { return *this = *this + decimal_t(value); }
template <typename T>
decimal_t& operator-=(const T& value) noexcept { return *this = *this - decimal_t(value); }
template <typename T>
decimal_t& operator*=(const T& value) noexcept { return *this = *this * decimal_t(value); }
template <typename T>
decimal_t& operator/=(const T& value) { return *this = *this / decimal_t(value); }
template <typename T>
friend T& operator+=(T& value1, const decimal_t& value2) noexcept { return value1 = (T)(decimal_t(value1) + value2); }
template <typename T>
friend T& operator-=(T& value1, const decimal_t& value2) noexcept { return value1 = (T)(decimal_t(value1) - value2); }
template <typename T>
friend T& operator*=(T& value1, const decimal_t& value2) noexcept { return value1 = (T)(decimal_t(value1) * value2); }
template <typename T>
friend T& operator/=(T& value1, const decimal_t& value2) { return value1 = (T)(decimal_t(value1) / value2); }
template <typename T>
friend decimal_t operator+(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) + value2; }
template <typename T>
friend decimal_t operator+(const decimal_t& value1, const T& value2) noexcept { return value1 + decimal_t(value2); }
friend decimal_t operator+(const decimal_t& value1, const decimal_t& value2) noexcept { return decimal_t(value1._value + value2._value); }
template <typename T>
friend decimal_t operator-(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) - value2; }
template <typename T>
friend decimal_t operator-(const decimal_t& value1, const T& value2) noexcept { return value1 - decimal_t(value2); }
friend decimal_t operator-(const decimal_t& value1, const decimal_t& value2) noexcept { return decimal_t(value1._value - value2._value); }
template <typename T>
friend decimal_t operator*(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) * value2; }
template <typename T>
friend decimal_t operator*(const decimal_t& value1, const T& value2) noexcept { return value1 * decimal_t(value2); }
friend decimal_t operator*(const decimal_t& value1, const decimal_t& value2) noexcept { return decimal_t(value1._value * value2._value); }
template <typename T>
friend decimal_t operator/(const T& value1, const decimal_t& value2) { return decimal_t(value1) / value2; }
template <typename T>
friend decimal_t operator/(const decimal_t& value1, const T& value2) { return value1 / decimal_t(value2); }
friend decimal_t operator/(const decimal_t& value1, const decimal_t& value2) { return decimal_t(value1._value / value2._value); }
// Comparison operators
template <typename T>
friend bool operator==(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) == value2; }
template <typename T>
friend bool operator==(const decimal_t& value1, const T& value2) noexcept { return value1 == decimal_t(value2); }
friend bool operator==(const decimal_t& value1, const decimal_t& value2) noexcept { return value1._value == value2._value; }
template <typename T>
friend bool operator!=(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) != value2; }
template <typename T>
friend bool operator!=(const decimal_t& value1, const T& value2) noexcept { return value1 != decimal_t(value2); }
friend bool operator!=(const decimal_t& value1, const decimal_t& value2) noexcept { return value1._value != value2._value; }
template <typename T>
friend bool operator<(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) < value2; }
template <typename T>
friend bool operator<(const decimal_t& value1, const T& value2) noexcept { return value1 < decimal_t(value2); }
friend bool operator<(const decimal_t& value1, const decimal_t& value2) noexcept { return value1._value < value2._value; }
template <typename T>
friend bool operator>(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) > value2; }
template <typename T>
friend bool operator>(const decimal_t& value1, const T& value2) noexcept { return value1 > decimal_t(value2); }
friend bool operator>(const decimal_t& value1, const decimal_t& value2) noexcept { return value1._value > value2._value; }
template <typename T>
friend bool operator<=(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) <= value2; }
template <typename T>
friend bool operator<=(const decimal_t& value1, const T& value2) noexcept { return value1 <= decimal_t(value2); }
friend bool operator<=(const decimal_t& value1, const decimal_t& value2) noexcept { return value1._value <= value2._value; }
template <typename T>
friend bool operator>=(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) >= value2; }
template <typename T>
friend bool operator>=(const decimal_t& value1, const T& value2) noexcept { return value1 >= decimal_t(value2); }
friend bool operator>=(const decimal_t& value1, const decimal_t& value2) noexcept { return value1._value >= value2._value; }
// Type cast
operator bool() const noexcept { return (_value != 0.0); }
operator uint8_t() const noexcept { return (uint8_t)_value; }
operator uint16_t() const noexcept { return (uint16_t)_value; }
operator uint32_t() const noexcept { return (uint32_t)_value; }
operator uint64_t() const noexcept { return (uint64_t)_value; }
operator float() const noexcept { return (float)_value; }
operator double() const noexcept { return (double)_value; }
//! Get string from the current decimal value
std::string string() const { return std::to_string(_value); }
//! Input instance from the given input stream
friend std::istream& operator>>(std::istream& is, decimal_t& value)
{ is >> value._value; return is; }
//! Output instance into the given output stream
friend std::ostream& operator<<(std::ostream& os, const decimal_t& value)
{ os << value.string(); return os; }
#if defined(LOGGING_PROTOCOL)
//! Store logging format
friend CppLogging::Record& operator<<(CppLogging::Record& record, const decimal_t& value)
{ return record.StoreCustom(value._value); }
#endif
//! Swap two instances
void swap(decimal_t& value) noexcept
{ using std::swap; swap(_value, value._value); }
friend void swap(decimal_t& value1, decimal_t& value2) noexcept
{ value1.swap(value2); }
private:
double _value;
};
} // namespace FBE
namespace std {
template <>
struct hash<FBE::decimal_t>
{
typedef FBE::decimal_t argument_type;
typedef size_t result_type;
result_type operator() (const argument_type& value) const
{
result_type result = 17;
result = result * 31 + std::hash<double>()((double)value);
return result;
}
};
} // namespace std
namespace FBE {
// Register a new enum-based flags macro
#define FBE_ENUM_FLAGS(type)\
inline FBE::Flags<type> operator|(type f1, type f2) noexcept { return FBE::Flags<type>(f1) | FBE::Flags<type>(f2); }\
inline FBE::Flags<type> operator&(type f1, type f2) noexcept { return FBE::Flags<type>(f1) & FBE::Flags<type>(f2); }\
inline FBE::Flags<type> operator^(type f1, type f2) noexcept { return FBE::Flags<type>(f1) ^ FBE::Flags<type>(f2); }
// Enum-based flags
template <typename TEnum>
class Flags
{
// Enum underlying type
typedef typename std::make_unsigned<typename std::underlying_type<TEnum>::type>::type type;
public:
Flags() noexcept : _value(0) {}
explicit Flags(type value) noexcept : _value(value) {}
explicit Flags(TEnum value) noexcept : _value((type)value) {}
Flags(const Flags&) noexcept = default;
Flags(Flags&&) noexcept = default;
~Flags() noexcept = default;
Flags& operator=(type value) noexcept
{ _value = value; return *this; }
Flags& operator=(TEnum value) noexcept
{ _value = (type)value; return *this; }
Flags& operator=(const Flags&) noexcept = default;
Flags& operator=(Flags&&) noexcept = default;
// Is any flag set?
explicit operator bool() const noexcept { return isset(); }
// Is no flag set?
bool operator!() const noexcept { return !isset(); }
// Reverse all flags
Flags operator~() const noexcept { return Flags(~_value); }
// Flags logical assign operators
Flags& operator&=(const Flags& flags) noexcept
{ _value &= flags._value; return *this; }
Flags& operator|=(const Flags& flags) noexcept
{ _value |= flags._value; return *this; }
Flags& operator^=(const Flags& flags) noexcept
{ _value ^= flags._value; return *this; }
// Flags logical friend operators
friend Flags operator&(const Flags& flags1, const Flags& flags2) noexcept
{ return Flags(flags1._value & flags2._value); }
friend Flags operator|(const Flags& flags1, const Flags& flags2) noexcept
{ return Flags(flags1._value | flags2._value); }
friend Flags operator^(const Flags& flags1, const Flags& flags2) noexcept
{ return Flags(flags1._value ^ flags2._value); }
// Flags comparison
friend bool operator==(const Flags& flags1, const Flags& flags2) noexcept
{ return flags1._value == flags2._value; }
friend bool operator!=(const Flags& flags1, const Flags& flags2) noexcept
{ return flags1._value != flags2._value; }
// Convert to the enum value
operator TEnum() const noexcept { return (TEnum)_value; }
//! Is any flag set?
bool isset() const noexcept { return (_value != 0); }
//! Is the given flag set?
bool isset(type value) const noexcept { return (_value & value) != 0; }
//! Is the given flag set?
bool isset(TEnum value) const noexcept { return (_value & (type)value) != 0; }
// Get the enum value
TEnum value() const noexcept { return (TEnum)_value; }
// Get the underlying enum value
type underlying() const noexcept { return _value; }
// Get the bitset value
std::bitset<sizeof(type) * 8> bitset() const noexcept { return {_value}; }
// Swap two instances
void swap(Flags& flags) noexcept { using std::swap; swap(_value, flags._value); }
template <typename UEnum>
friend void swap(Flags<UEnum>& flags1, Flags<UEnum>& flags2) noexcept;
private:
type _value;
};
template <typename TEnum>
inline void swap(Flags<TEnum>& flags1, Flags<TEnum>& flags2) noexcept
{
flags1.swap(flags2);
}
// Get Epoch timestamp
inline uint64_t epoch() { return 0ull; }
// Get UTC timestamp
uint64_t utc();
//! Universally unique identifier (UUID)
/*!
A universally unique identifier (UUID) is an identifier standard used
in software construction. This implementation generates the following
UUID types:
- Nil UUID0 (all bits set to zero)
- Sequential UUID1 (time based version)
- Random UUID4 (randomly or pseudo-randomly generated version)
A UUID is simply a 128-bit value: "123e4567-e89b-12d3-a456-426655440000"
https://en.wikipedia.org/wiki/Universally_unique_identifier
https://www.ietf.org/rfc/rfc4122.txt
*/
class uuid_t
{
public:
//! Default constructor
uuid_t() : _data() { _data.fill(0); }
//! Initialize UUID with a given string
/*!
\param uuid - UUID string
*/
explicit uuid_t(const std::string& uuid);
//! Initialize UUID with a given 16 bytes data buffer
/*!
\param data - UUID 16 bytes data buffer
*/
explicit uuid_t(const std::array<uint8_t, 16>& data) : _data(data) {}
uuid_t(const uuid_t&) = default;
uuid_t(uuid_t&&) noexcept = default;
~uuid_t() = default;
uuid_t& operator=(const std::string& uuid)
{ _data = uuid_t(uuid).data(); return *this; }
uuid_t& operator=(const std::array<uint8_t, 16>& data)
{ _data = data; return *this; }
uuid_t& operator=(const uuid_t&) = default;
uuid_t& operator=(uuid_t&&) noexcept = default;
// UUID comparison
friend bool operator==(const uuid_t& uuid1, const uuid_t& uuid2)
{ return uuid1._data == uuid2._data; }
friend bool operator!=(const uuid_t& uuid1, const uuid_t& uuid2)
{ return uuid1._data != uuid2._data; }
friend bool operator<(const uuid_t& uuid1, const uuid_t& uuid2)
{ return uuid1._data < uuid2._data; }
friend bool operator>(const uuid_t& uuid1, const uuid_t& uuid2)
{ return uuid1._data > uuid2._data; }
friend bool operator<=(const uuid_t& uuid1, const uuid_t& uuid2)
{ return uuid1._data <= uuid2._data; }
friend bool operator>=(const uuid_t& uuid1, const uuid_t& uuid2)
{ return uuid1._data >= uuid2._data; }
//! Check if the UUID is nil UUID0 (all bits set to zero)
explicit operator bool() const noexcept { return *this != nil(); }
//! Get the UUID data buffer
std::array<uint8_t, 16>& data() noexcept { return _data; }
//! Get the UUID data buffer
const std::array<uint8_t, 16>& data() const noexcept { return _data; }
//! Get string from the current UUID in format "00000000-0000-0000-0000-000000000000"
std::string string() const;
//! Generate nil UUID0 (all bits set to zero)
static uuid_t nil() { return uuid_t(); }
//! Generate sequential UUID1 (time based version)
static uuid_t sequential();
//! Generate random UUID4 (randomly or pseudo-randomly generated version)
static uuid_t random();
//! Output instance into the given output stream
friend std::ostream& operator<<(std::ostream& os, const uuid_t& uuid)
{ os << uuid.string(); return os; }
#if defined(LOGGING_PROTOCOL)
//! Store logging format
friend CppLogging::Record& operator<<(CppLogging::Record& record, const uuid_t& uuid);
#endif
//! Swap two instances
void swap(uuid_t& uuid) noexcept
{ using std::swap; swap(_data, uuid._data); }
friend void swap(uuid_t& uuid1, uuid_t& uuid2) noexcept
{ uuid1.swap(uuid2); }
private:
std::array<uint8_t, 16> _data;
};
} // namespace FBE
namespace std {
template <>
struct hash<FBE::uuid_t>
{
typedef FBE::uuid_t argument_type;
typedef size_t result_type;
result_type operator() (const argument_type& value) const
{
result_type result = 17;
std::hash<uint8_t> hasher;
for (size_t i = 0; i < value.data().size(); ++i)
result = result * 31 + hasher(value.data()[i]);
return result;
}
};
} // namespace std
namespace FBE {
// Fast Binary Encoding buffer based on the dynamic byte buffer
class FBEBuffer
{
public:
FBEBuffer() : _data(nullptr), _capacity(0), _size(0), _offset(0) {}
// Initialize the read buffer with the given byte buffer and offset
explicit FBEBuffer(const void* data, size_t size, size_t offset = 0) { attach(data, size, offset); }
// Initialize the read buffer with the given byte vector and offset
explicit FBEBuffer(const std::vector<uint8_t>& buffer, size_t offset = 0) { attach(buffer, offset); }
// Initialize the read buffer with another buffer and offset
explicit FBEBuffer(const FBEBuffer& buffer, size_t offset = 0) { attach(buffer.data(), buffer.size(), offset); }
// Initialize the write buffer with the given capacity
explicit FBEBuffer(size_t capacity) : FBEBuffer() { reserve(capacity); }
FBEBuffer(const FBEBuffer&) = delete;
FBEBuffer(FBEBuffer&&) noexcept = delete;
~FBEBuffer() { if (_capacity > 0) std::free(_data); }
FBEBuffer& operator=(const FBEBuffer&) = delete;
FBEBuffer& operator=(FBEBuffer&&) noexcept = delete;
bool empty() const noexcept { return (_data == nullptr) || (_size == 0); }
const uint8_t* data() const noexcept { return _data; }
uint8_t* data() noexcept { return _data; }
size_t capacity() const noexcept { return _capacity; }
size_t size() const noexcept { return _size; }
size_t offset() const noexcept { return _offset; }
// Attach the given buffer with a given offset to the current read buffer
void attach(const void* data, size_t size, size_t offset = 0);
// Attach the given byte vector with a given offset to the current read buffer
void attach(const std::vector<uint8_t>& buffer, size_t offset = 0);
// Clone the given buffer with a given offset to the current buffer
void clone(const void* data, size_t size, size_t offset = 0);
// Clone the given vector with a given offset to the current buffer
void clone(const std::vector<uint8_t>& buffer, size_t offset = 0);
// Allocate memory in the current write buffer and return offset to the allocated memory block
size_t allocate(size_t size);
// Remove some memory of the given size from the current write buffer
void remove(size_t offset, size_t size);
// Reserve memory of the given capacity in the current write buffer
void reserve(size_t capacity);
// Resize the current write buffer
void resize(size_t size);
// Reset the current write buffer and its offset
void reset();
// Shift the current write buffer offset
void shift(size_t offset) { _offset += offset; }
// Unshift the current write buffer offset
void unshift(size_t offset) { _offset -= offset; }
private:
uint8_t* _data;
size_t _capacity;
size_t _size;
size_t _offset;
};
// Fast Binary Encoding base model
class Model
{
public:
Model() : Model(nullptr) {}
Model(const std::shared_ptr<FBEBuffer>& buffer) { _buffer = buffer ? buffer : std::make_shared<FBEBuffer>(); }
Model(const Model&) = default;
Model(Model&&) noexcept = default;
~Model() = default;
Model& operator=(const Model&) = default;
Model& operator=(Model&&) noexcept = default;
// Get the model buffer
FBEBuffer& buffer() noexcept { return *_buffer; }
const FBEBuffer& buffer() const noexcept { return *_buffer; }
// Attach the model buffer
void attach(const void* data, size_t size, size_t offset = 0) { _buffer->attach(data, size, offset); }
void attach(const std::vector<uint8_t>& buffer, size_t offset = 0) { _buffer->attach(buffer, offset); }
void attach(const FBEBuffer& buffer, size_t offset = 0) { _buffer->attach(buffer.data(), buffer.size(), offset); }
// Model buffer operations
size_t allocate(size_t size) { return _buffer->allocate(size); }
void remove(size_t offset, size_t size) { _buffer->remove(offset, size); }
void reserve(size_t capacity) { _buffer->reserve(capacity); }
void resize(size_t size) { _buffer->resize(size); }
void reset() { _buffer->reset(); }
void shift(size_t offset) { _buffer->shift(offset); }
void unshift(size_t offset) { _buffer->unshift(offset); }
private:
std::shared_ptr<FBEBuffer> _buffer;
};
} // namespace FBE

View file

@ -0,0 +1,436 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
#include "fbe_final_models.h"
namespace FBE {
uint64_t FinalModel<decimal_t>::extract(double a) noexcept
{
uint64_t result;
std::memcpy(&result, &a, sizeof(double));
return result;
}
uint64_t FinalModel<decimal_t>::uint32x32(uint32_t a, uint32_t b) noexcept
{
return (uint64_t)a * (uint64_t)b;
}
void FinalModel<decimal_t>::uint64x64(uint64_t a, uint64_t b, uint64_t& low64, uint32_t& high32) noexcept
{
uint64_t low = uint32x32((uint32_t)a, (uint32_t)b);
uint64_t mid = uint32x32((uint32_t)a, (uint32_t)(b >> 32));
uint64_t high = uint32x32((uint32_t)(a >> 32), (uint32_t)(b >> 32));
high += (mid >> 32);
low += (mid <<= 32);
// Test for carry
if (low < mid)
high++;
mid = uint32x32((uint32_t)(a >> 32), (uint32_t)b);
high += (mid >> 32);
low += (mid <<= 32);
// Test for carry
if (low < mid)
high++;
if (high > 0xFFFFFFFFu)
{
low64 = 0;
high32 = 0;
}
low64 = low;
high32 = (uint32_t)high;
}
size_t FinalModel<decimal_t>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return std::numeric_limits<std::size_t>::max();
return fbe_size();
}
size_t FinalModel<decimal_t>::get(decimal_t& value) const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
// Value taken via reverse engineering the double that corresponds to 2^64
const double ds2to64 = 1.8446744073709552e+019;
// Read decimal parts
uint64_t low = *((const uint64_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
uint32_t high = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 8));
uint32_t flags = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 12));
// Calculate decimal value
double dValue = ((double)low + (double)high * ds2to64) / pow(10.0, (uint8_t)(flags >> 16));
if (flags & 0x80000000)
dValue = -dValue;
value = dValue;
return fbe_size();
}
size_t FinalModel<decimal_t>::set(decimal_t value) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
// The most we can scale by is 10^28, which is just slightly more
// than 2^93. So a float with an exponent of -94 could just
// barely reach 0.5, but smaller exponents will always round to zero.
const uint32_t DBLBIAS = 1022;
// Get exponent value
double dValue = (double)value;
int32_t iExp = (int32_t)(((uint32_t)(extract(dValue) >> 52) & 0x7FFu) - DBLBIAS);
if ((iExp < -94) || (iExp > 96))
{
// Value too big for .NET Decimal (exponent is limited to [-94, 96])
memset((uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()), 0, 16);
return fbe_size();
}
uint32_t flags = 0;
if (dValue < 0)
{
dValue = -dValue;
flags = 0x80000000;
}
// Round the input to a 15-digit integer. The R8 format has
// only 15 digits of precision, and we want to keep garbage digits
// out of the Decimal were making.
// Calculate max power of 10 input value could have by multiplying
// the exponent by log10(2). Using scaled integer multiplcation,
// log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
int32_t iPower = 14 - ((iExp * 19728) >> 16);
// iPower is between -14 and 43
if (iPower >= 0)
{
// We have less than 15 digits, scale input up.
if (iPower > 28)
iPower = 28;
dValue *= pow(10.0, iPower);
}
else
{
if ((iPower != -1) || (dValue >= 1E15))
dValue /= pow(10.0, -iPower);
else
iPower = 0; // didn't scale it
}
assert(dValue < 1E15);
if ((dValue < 1E14) && (iPower < 28))
{
dValue *= 10;
iPower++;
assert(dValue >= 1E14);
}
// Round to int64
uint64_t ulMant;
ulMant = (uint64_t)(int64_t)dValue;
dValue -= (int64_t)ulMant; // difference between input & integer
if ((dValue > 0.5) || ((dValue == 0.5) && ((ulMant & 1) != 0)))
ulMant++;
if (ulMant == 0)
{
// Mantissa is 0
memset((uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()), 0, 16);
return fbe_size();
}
if (iPower < 0)
{
// Add -iPower factors of 10, -iPower <= (29 - 15) = 14
iPower = -iPower;
if (iPower < 10)
{
double pow10 = (double)powl(10.0, iPower);
uint64_t low64 = uint32x32((uint32_t)ulMant, (uint32_t)pow10);
uint64_t high64 = uint32x32((uint32_t)(ulMant >> 32), (uint32_t)pow10);
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = (uint32_t)low64;
high64 += low64 >> 32;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 4)) = (uint32_t)high64;
high64 >>= 32;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 8)) = (uint32_t)high64;
}
else
{
// Have a big power of 10.
assert(iPower <= 14);
uint64_t low64;
uint32_t high32;
uint64x64(ulMant, (uint64_t)pow(10.0, iPower), low64, high32);
*((uint64_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = low64;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 8)) = high32;
}
}
else
{
// Factor out powers of 10 to reduce the scale, if possible.
// The maximum number we could factor out would be 14. This
// comes from the fact we have a 15-digit number, and the
// MSD must be non-zero -- but the lower 14 digits could be
// zero. Note also the scale factor is never negative, so
// we can't scale by any more than the power we used to
// get the integer.
int lmax = iPower;
if (lmax > 14)
lmax = 14;
if ((((uint8_t)ulMant) == 0) && (lmax >= 8))
{
const uint32_t den = 100000000;
uint64_t div = ulMant / den;
if ((uint32_t)ulMant == (uint32_t)(div * den))
{
ulMant = div;
iPower -= 8;
lmax -= 8;
}
}
if ((((uint32_t)ulMant & 0xF) == 0) && (lmax >= 4))
{
const uint32_t den = 10000;
uint64_t div = ulMant / den;
if ((uint32_t)ulMant == (uint32_t)(div * den))
{
ulMant = div;
iPower -= 4;
lmax -= 4;
}
}
if ((((uint32_t)ulMant & 3) == 0) && (lmax >= 2))
{
const uint32_t den = 100;
uint64_t div = ulMant / den;
if ((uint32_t)ulMant == (uint32_t)(div * den))
{
ulMant = div;
iPower -= 2;
lmax -= 2;
}
}
if ((((uint32_t)ulMant & 1) == 0) && (lmax >= 1))
{
const uint32_t den = 10;
uint64_t div = ulMant / den;
if ((uint32_t)ulMant == (uint32_t)(div * den))
{
ulMant = div;
iPower--;
}
}
flags |= (uint32_t)iPower << 16;
*((uint64_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = ulMant;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 8)) = 0;
}
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 12)) = flags;
return fbe_size();
}
size_t FinalModel<uuid_t>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return std::numeric_limits<std::size_t>::max();
return fbe_size();
}
size_t FinalModel<uuid_t>::get(uuid_t& value) const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
std::memcpy(value.data().data(), (const uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()), fbe_size());
return fbe_size();
}
size_t FinalModel<uuid_t>::set(uuid_t value) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
std::memcpy((uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()), value.data().data(), fbe_size());
return fbe_size();
}
size_t FinalModel<buffer_t>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return std::numeric_limits<std::size_t>::max();
uint32_t fbe_bytes_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((_buffer.offset() + fbe_offset() + 4 + fbe_bytes_size) > _buffer.size())
return std::numeric_limits<std::size_t>::max();
return 4 + fbe_bytes_size;
}
size_t FinalModel<buffer_t>::get(void* data, size_t size) const noexcept
{
assert(((size == 0) || (data != nullptr)) && "Invalid buffer!");
if ((size > 0) && (data == nullptr))
return 0;
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
uint32_t fbe_bytes_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
assert(((_buffer.offset() + fbe_offset() + 4 + fbe_bytes_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4 + fbe_bytes_size) > _buffer.size())
return 4;
size_t result = std::min(size, (size_t)fbe_bytes_size);
memcpy(data, (const char*)(_buffer.data() + _buffer.offset() + fbe_offset() + 4), result);
return 4 + fbe_bytes_size;
}
size_t FinalModel<buffer_t>::get(std::vector<uint8_t>& value) const noexcept
{
value.clear();
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
uint32_t fbe_bytes_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
assert(((_buffer.offset() + fbe_offset() + 4 + fbe_bytes_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4 + fbe_bytes_size) > _buffer.size())
return 4;
const char* fbe_bytes = (const char*)(_buffer.data() + _buffer.offset() + fbe_offset() + 4);
value.assign(fbe_bytes, fbe_bytes + fbe_bytes_size);
return 4 + fbe_bytes_size;
}
size_t FinalModel<buffer_t>::set(const void* data, size_t size)
{
assert(((size == 0) || (data != nullptr)) && "Invalid buffer!");
if ((size > 0) && (data == nullptr))
return 0;
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
uint32_t fbe_bytes_size = (uint32_t)size;
assert(((_buffer.offset() + fbe_offset() + 4 + fbe_bytes_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4 + fbe_bytes_size) > _buffer.size())
return 4;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_bytes_size;
memcpy((char*)(_buffer.data() + _buffer.offset() + fbe_offset() + 4), data, fbe_bytes_size);
return 4 + fbe_bytes_size;
}
size_t FinalModel<std::string>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return std::numeric_limits<std::size_t>::max();
uint32_t fbe_string_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((_buffer.offset() + fbe_offset() + 4 + fbe_string_size) > _buffer.size())
return std::numeric_limits<std::size_t>::max();
return 4 + fbe_string_size;
}
size_t FinalModel<std::string>::get(char* data, size_t size) const noexcept
{
assert(((size == 0) || (data != nullptr)) && "Invalid buffer!");
if ((size > 0) && (data == nullptr))
return 0;
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
uint32_t fbe_string_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
assert(((_buffer.offset() + fbe_offset() + 4 + fbe_string_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4 + fbe_string_size) > _buffer.size())
return 4;
size_t result = std::min(size, (size_t)fbe_string_size);
memcpy(data, (const char*)(_buffer.data() + _buffer.offset() + fbe_offset() + 4), result);
return 4 + fbe_string_size;
}
size_t FinalModel<std::string>::get(std::string& value) const noexcept
{
value.clear();
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
uint32_t fbe_string_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
assert(((_buffer.offset() + fbe_offset() + 4 + fbe_string_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4 + fbe_string_size) > _buffer.size())
return 4;
value.assign((const char*)(_buffer.data() + _buffer.offset() + fbe_offset() + 4), fbe_string_size);
return 4 + fbe_string_size;
}
size_t FinalModel<std::string>::set(const char* data, size_t size)
{
assert(((size == 0) || (data != nullptr)) && "Invalid buffer!");
if ((size > 0) && (data == nullptr))
return 0;
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
uint32_t fbe_string_size = (uint32_t)size;
assert(((_buffer.offset() + fbe_offset() + 4 + fbe_string_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4 + fbe_string_size) > _buffer.size())
return 4;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_string_size;
memcpy((char*)(_buffer.data() + _buffer.offset() + fbe_offset() + 4), data, fbe_string_size);
return 4 + fbe_string_size;
}
size_t FinalModel<std::string>::set(const std::string& value)
{
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
uint32_t fbe_string_size = (uint32_t)value.size();
assert(((_buffer.offset() + fbe_offset() + 4 + fbe_string_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4 + fbe_string_size) > _buffer.size())
return 4;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_string_size;
memcpy((char*)(_buffer.data() + _buffer.offset() + fbe_offset() + 4), value.data(), fbe_string_size);
return 4 + fbe_string_size;
}
} // namespace FBE

View file

@ -0,0 +1,457 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
#pragma once
#if defined(__clang__)
#pragma clang system_header
#elif defined(__GNUC__)
#pragma GCC system_header
#elif defined(_MSC_VER)
#pragma system_header
#endif
#include "fbe.h"
namespace FBE {
// Fast Binary Encoding base final model
template <typename T, typename TBase = T>
class FinalModelBase
{
public:
FinalModelBase(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the allocation size
size_t fbe_allocation_size(T value) const noexcept { return fbe_size(); }
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Set the field offset
size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; }
// Get the final size
size_t fbe_size() const noexcept { return sizeof(TBase); }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the value is valid
size_t verify() const noexcept;
// Get the field value
size_t get(T& value) const noexcept;
// Set the field value
size_t set(T value) noexcept;
private:
FBEBuffer& _buffer;
mutable size_t _offset;
};
// Fast Binary Encoding final model
template <typename T>
class FinalModel : public FinalModelBase<T>
{
public:
using FinalModelBase<T>::FinalModelBase;
};
// Fast Binary Encoding final model bool specialization
template <>
class FinalModel<bool> : public FinalModelBase<bool, uint8_t>
{
public:
using FinalModelBase<bool, uint8_t>::FinalModelBase;
};
// Fast Binary Encoding final model char specialization
template <>
class FinalModel<char> : public FinalModelBase<char, uint8_t>
{
public:
using FinalModelBase<char, uint8_t>::FinalModelBase;
};
// Fast Binary Encoding final model wchar specialization
template <>
class FinalModel<wchar_t> : public FinalModelBase<wchar_t, uint32_t>
{
public:
using FinalModelBase<wchar_t, uint32_t>::FinalModelBase;
};
// Fast Binary Encoding final model decimal specialization
template <>
class FinalModel<decimal_t>
{
public:
FinalModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the allocation size
size_t fbe_allocation_size(decimal_t value) const noexcept { return fbe_size(); }
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Set the field offset
size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; }
// Get the final size
size_t fbe_size() const noexcept { return 16; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the decimal value is valid
size_t verify() const noexcept;
// Get the decimal value
size_t get(decimal_t& value) const noexcept;
// Set the decimal value
size_t set(decimal_t value) noexcept;
private:
FBEBuffer& _buffer;
mutable size_t _offset;
static uint64_t extract(double a) noexcept;
static uint64_t uint32x32(uint32_t a, uint32_t b) noexcept;
static void uint64x64(uint64_t a, uint64_t b, uint64_t& low64, uint32_t& high32) noexcept;
};
// Fast Binary Encoding final model UUID specialization
template <>
class FinalModel<uuid_t>
{
public:
FinalModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the allocation size
size_t fbe_allocation_size(uuid_t value) const noexcept { return fbe_size(); }
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Set the field offset
size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; }
// Get the final size
size_t fbe_size() const noexcept { return 16; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the UUID value is valid
size_t verify() const noexcept;
// Get the UUID value
size_t get(uuid_t& value) const noexcept;
// Set the UUID value
size_t set(uuid_t value) noexcept;
private:
FBEBuffer& _buffer;
mutable size_t _offset;
};
// Fast Binary Encoding final model bytes specialization
template <>
class FinalModel<buffer_t>
{
public:
FinalModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the allocation size
size_t fbe_allocation_size(const void* data, size_t size) const noexcept { return 4 + size; }
template <size_t N>
size_t fbe_allocation_size(const uint8_t (&data)[N]) const noexcept { return 4 + N; }
template <size_t N>
size_t fbe_allocation_size(const std::array<uint8_t, N>& data) const noexcept { return 4 + N; }
size_t fbe_allocation_size(const std::vector<uint8_t>& value) const noexcept { return 4 + value.size(); }
size_t fbe_allocation_size(const buffer_t& value) const noexcept { return 4 + value.size(); }
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Set the field offset
size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the bytes value is valid
size_t verify() const noexcept;
// Get the bytes value
size_t get(void* data, size_t size) const noexcept;
// Get the bytes value
template <size_t N>
size_t get(uint8_t (&data)[N]) const noexcept { return get(data, N); }
// Get the bytes value
template <size_t N>
size_t get(std::array<uint8_t, N>& data) const noexcept { return get(data.data(), data.size()); }
// Get the bytes value
size_t get(std::vector<uint8_t>& value) const noexcept;
// Get the bytes value
size_t get(buffer_t& value) const noexcept { return get(value.buffer()); }
// Set the bytes value
size_t set(const void* data, size_t size);
// Set the bytes value
template <size_t N>
size_t set(const uint8_t (&data)[N]) { return set(data, N); }
// Set the bytes value
template <size_t N>
size_t set(const std::array<uint8_t, N>& data) { return set(data.data(), data.size()); }
// Set the bytes value
size_t set(const std::vector<uint8_t>& value) { return set(value.data(), value.size()); }
// Set the bytes value
size_t set(const buffer_t& value) { return set(value.buffer()); }
private:
FBEBuffer& _buffer;
mutable size_t _offset;
};
// Fast Binary Encoding final model string specialization
template <>
class FinalModel<std::string>
{
public:
FinalModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the allocation size
size_t fbe_allocation_size(const char* data, size_t size) const noexcept { return 4 + size; }
template <size_t N>
size_t fbe_allocation_size(const char (&data)[N]) const noexcept { return 4 + N; }
template <size_t N>
size_t fbe_allocation_size(const std::array<char, N>& data) const noexcept { return 4 + N; }
size_t fbe_allocation_size(const std::string& value) const noexcept { return 4 + value.size(); }
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Set the field offset
size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the string value is valid
size_t verify() const noexcept;
// Get the string value
size_t get(char* data, size_t size) const noexcept;
// Get the string value
template <size_t N>
size_t get(char (&data)[N]) const noexcept { return get(data, N); }
// Get the string value
template <size_t N>
size_t get(std::array<char, N>& data) const noexcept { return get(data.data(), data.size()); }
// Get the string value
size_t get(std::string& value) const noexcept;
// Set the string value
size_t set(const char* data, size_t size);
// Set the string value
template <size_t N>
size_t set(const char (&data)[N]) { return set(data, N); }
// Set the string value
template <size_t N>
size_t set(const std::array<char, N>& data) { return set(data.data(), data.size()); }
// Set the string value
size_t set(const std::string& value);
private:
FBEBuffer& _buffer;
mutable size_t _offset;
};
// Fast Binary Encoding final model optional specialization
template <typename T>
class FinalModel<std::optional<T>>
{
public:
FinalModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset), value(buffer, 0) {}
// Get the allocation size
size_t fbe_allocation_size(const std::optional<T>& opt) const noexcept { return 1 + (opt ? value.fbe_allocation_size(opt.value()) : 0); }
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Set the field offset
size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
//! Is the value present?
explicit operator bool() const noexcept { return has_value(); }
// Checks if the object contains a value
bool has_value() const noexcept;
// Check if the optional value is valid
size_t verify() const noexcept;
// Get the optional value
size_t get(std::optional<T>& opt) const noexcept;
// Set the optional value
size_t set(const std::optional<T>& opt);
private:
FBEBuffer& _buffer;
mutable size_t _offset;
public:
// Base final model value
FinalModel<T> value;
};
// Fast Binary Encoding final model array
template <typename T, size_t N>
class FinalModelArray
{
public:
FinalModelArray(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the allocation size
template <size_t S>
size_t fbe_allocation_size(const T (&values)[S]) const noexcept;
template <size_t S>
size_t fbe_allocation_size(const std::array<T, S>& values) const noexcept;
size_t fbe_allocation_size(const std::vector<T>& values) const noexcept;
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Set the field offset
size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the array is valid
size_t verify() const noexcept;
// Get the array as C-array
template <size_t S>
size_t get(T (&values)[S]) const noexcept;
// Get the array as std::array
template <size_t S>
size_t get(std::array<T, S>& values) const noexcept;
// Get the array as std::vector
size_t get(std::vector<T>& values) const noexcept;
// Set the array as C-array
template <size_t S>
size_t set(const T (&values)[S]) noexcept;
// Set the array as std::array
template <size_t S>
size_t set(const std::array<T, S>& values) noexcept;
// Set the array as std::vector
size_t set(const std::vector<T>& values) noexcept;
private:
FBEBuffer& _buffer;
mutable size_t _offset;
};
// Fast Binary Encoding final model vector
template <typename T>
class FinalModelVector
{
public:
FinalModelVector(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the allocation size
size_t fbe_allocation_size(const std::vector<T>& values) const noexcept;
size_t fbe_allocation_size(const std::list<T>& values) const noexcept;
size_t fbe_allocation_size(const std::set<T>& values) const noexcept;
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Set the field offset
size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the vector is valid
size_t verify() const noexcept;
// Get the vector as std::vector
size_t get(std::vector<T>& values) const noexcept;
// Get the vector as std::list
size_t get(std::list<T>& values) const noexcept;
// Get the vector as std::set
size_t get(std::set<T>& values) const noexcept;
// Set the vector as std::vector
size_t set(const std::vector<T>& values) noexcept;
// Set the vector as std::list
size_t set(const std::list<T>& values) noexcept;
// Set the vector as std::set
size_t set(const std::set<T>& values) noexcept;
private:
FBEBuffer& _buffer;
mutable size_t _offset;
};
// Fast Binary Encoding final model map
template <typename TKey, typename TValue>
class FinalModelMap
{
public:
FinalModelMap(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the allocation size
size_t fbe_allocation_size(const std::map<TKey, TValue>& values) const noexcept;
size_t fbe_allocation_size(const std::unordered_map<TKey, TValue>& values) const noexcept;
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Set the field offset
size_t fbe_offset(size_t offset) const noexcept { return _offset = offset; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the map is valid
size_t verify() const noexcept;
// Get the map as std::map
size_t get(std::map<TKey, TValue>& values) const noexcept;
// Get the map as std::unordered_map
size_t get(std::unordered_map<TKey, TValue>& values) const noexcept;
// Set the map as std::map
size_t set(const std::map<TKey, TValue>& values) noexcept;
// Set the map as std::unordered_map
size_t set(const std::unordered_map<TKey, TValue>& values) noexcept;
private:
FBEBuffer& _buffer;
mutable size_t _offset;
};
} // namespace FBE
#include "fbe_final_models.inl"

View file

@ -0,0 +1,635 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
namespace FBE {
template <typename T, typename TBase>
inline size_t FinalModelBase<T, TBase>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return std::numeric_limits<std::size_t>::max();
return fbe_size();
}
template <typename T, typename TBase>
inline size_t FinalModelBase<T, TBase>::get(T& value) const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
value = (T)(*((const TBase*)(_buffer.data() + _buffer.offset() + fbe_offset())));
return fbe_size();
}
template <typename T, typename TBase>
inline size_t FinalModelBase<T, TBase>::set(T value) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
*((TBase*)(_buffer.data() + _buffer.offset() + fbe_offset())) = (TBase)value;
return fbe_size();
}
template <typename T>
inline bool FinalModel<std::optional<T>>::has_value() const noexcept
{
if ((_buffer.offset() + fbe_offset() + 1) > _buffer.size())
return false;
uint8_t fbe_has_value = *((const uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
return (fbe_has_value != 0);
}
template <typename T>
inline size_t FinalModel<std::optional<T>>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + 1) > _buffer.size())
return std::numeric_limits<std::size_t>::max();
uint8_t fbe_has_value = *((const uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_has_value == 0)
return 1;
_buffer.shift(fbe_offset() + 1);
size_t fbe_result = value.verify();
_buffer.unshift(fbe_offset() + 1);
return 1 + fbe_result;
}
template <typename T>
inline size_t FinalModel<std::optional<T>>::get(std::optional<T>& opt) const noexcept
{
opt = std::nullopt;
assert(((_buffer.offset() + fbe_offset() + 1) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 1) > _buffer.size())
return 0;
if (!has_value())
return 1;
_buffer.shift(fbe_offset() + 1);
T temp = T();
size_t size = value.get(temp);
opt.emplace(temp);
_buffer.unshift(fbe_offset() + 1);
return 1 + size;
}
template <typename T>
inline size_t FinalModel<std::optional<T>>::set(const std::optional<T>& opt)
{
assert(((_buffer.offset() + fbe_offset() + 1) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 1) > _buffer.size())
return 0;
uint8_t fbe_has_value = opt ? 1 : 0;
*((uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_has_value;
if (fbe_has_value == 0)
return 1;
_buffer.shift(fbe_offset() + 1);
size_t size = 0;
if (opt)
size = value.set(opt.value());
_buffer.unshift(fbe_offset() + 1);
return 1 + size;
}
template <typename T, size_t N>
template <size_t S>
inline size_t FinalModelArray<T, N>::fbe_allocation_size(const T (&values)[S]) const noexcept
{
size_t size = 0;
FinalModel<T> fbe_model(_buffer, fbe_offset());
for (size_t i = 0; (i < S) && (i < N); ++i)
size += fbe_model.fbe_allocation_size(values[i]);
return size;
}
template <typename T, size_t N>
template <size_t S>
inline size_t FinalModelArray<T, N>::fbe_allocation_size(const std::array<T, S>& values) const noexcept
{
size_t size = 0;
FinalModel<T> fbe_model(_buffer, fbe_offset());
for (size_t i = 0; (i < S) && (i < N); ++i)
size += fbe_model.fbe_allocation_size(values[i]);
return size;
}
template <typename T, size_t N>
inline size_t FinalModelArray<T, N>::fbe_allocation_size(const std::vector<T>& values) const noexcept
{
size_t size = 0;
FinalModel<T> fbe_model(_buffer, fbe_offset());
for (size_t i = 0; (i < values.size()) && (i < N); ++i)
size += fbe_model.fbe_allocation_size(values[i]);
return size;
}
template <typename T, size_t N>
inline size_t FinalModelArray<T, N>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset()) > _buffer.size())
return std::numeric_limits<std::size_t>::max();
size_t size = 0;
FinalModel<T> fbe_model(_buffer, fbe_offset());
for (size_t i = N; i-- > 0;)
{
size_t offset = fbe_model.verify();
if (offset == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename T, size_t N>
template <size_t S>
inline size_t FinalModelArray<T, N>::get(T (&values)[S]) const noexcept
{
assert(((_buffer.offset() + fbe_offset()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset()) > _buffer.size())
return 0;
size_t size = 0;
FinalModel<T> fbe_model(_buffer, fbe_offset());
for (size_t i = 0; (i < S) && (i < N); ++i)
{
size_t offset = fbe_model.get(values[i]);
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename T, size_t N>
template <size_t S>
inline size_t FinalModelArray<T, N>::get(std::array<T, S>& values) const noexcept
{
assert(((_buffer.offset() + fbe_offset()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset()) > _buffer.size())
return 0;
size_t size = 0;
FinalModel<T> fbe_model(_buffer, fbe_offset());
for (size_t i = 0; (i < S) && (i < N); ++i)
{
size_t offset = fbe_model.get(values[i]);
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename T, size_t N>
inline size_t FinalModelArray<T, N>::get(std::vector<T>& values) const noexcept
{
values.clear();
assert(((_buffer.offset() + fbe_offset()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset()) > _buffer.size())
return 0;
values.reserve(N);
size_t size = 0;
FinalModel<T> fbe_model(_buffer, fbe_offset());
for (size_t i = N; i-- > 0;)
{
T value = T();
size_t offset = fbe_model.get(value);
values.emplace_back(value);
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename T, size_t N>
template <size_t S>
inline size_t FinalModelArray<T, N>::set(const T (&values)[S]) noexcept
{
assert(((_buffer.offset() + fbe_offset()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset()) > _buffer.size())
return 0;
size_t size = 0;
FinalModel<T> fbe_model(_buffer, fbe_offset());
for (size_t i = 0; (i < S) && (i < N); ++i)
{
size_t offset = fbe_model.set(values[i]);
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename T, size_t N>
template <size_t S>
inline size_t FinalModelArray<T, N>::set(const std::array<T, S>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset()) > _buffer.size())
return 0;
size_t size = 0;
FinalModel<T> fbe_model(_buffer, fbe_offset());
for (size_t i = 0; (i < S) && (i < N); ++i)
{
size_t offset = fbe_model.set(values[i]);
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename T, size_t N>
inline size_t FinalModelArray<T, N>::set(const std::vector<T>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset()) > _buffer.size())
return 0;
size_t size = 0;
FinalModel<T> fbe_model(_buffer, fbe_offset());
for (size_t i = 0; (i < values.size()) && (i < N); ++i)
{
size_t offset = fbe_model.set(values[i]);
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename T>
inline size_t FinalModelVector<T>::fbe_allocation_size(const std::vector<T>& values) const noexcept
{
size_t size = 4;
FinalModel<T> fbe_model(_buffer, fbe_offset() + 4);
for (const auto& value : values)
size += fbe_model.fbe_allocation_size(value);
return size;
}
template <typename T>
inline size_t FinalModelVector<T>::fbe_allocation_size(const std::list<T>& values) const noexcept
{
size_t size = 4;
FinalModel<T> fbe_model(_buffer, fbe_offset() + 4);
for (const auto& value : values)
size += fbe_model.fbe_allocation_size(value);
return size;
}
template <typename T>
inline size_t FinalModelVector<T>::fbe_allocation_size(const std::set<T>& values) const noexcept
{
size_t size = 4;
FinalModel<T> fbe_model(_buffer, fbe_offset() + 4);
for (const auto& value : values)
size += fbe_model.fbe_allocation_size(value);
return size;
}
template <typename T>
inline size_t FinalModelVector<T>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return std::numeric_limits<std::size_t>::max();
uint32_t fbe_vector_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
size_t size = 4;
FinalModel<T> fbe_model(_buffer, fbe_offset() + 4);
for (size_t i = fbe_vector_size; i-- > 0;)
{
size_t offset = fbe_model.verify();
if (offset == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename T>
inline size_t FinalModelVector<T>::get(std::vector<T>& values) const noexcept
{
values.clear();
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
size_t fbe_vector_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_vector_size == 0)
return 4;
values.reserve(fbe_vector_size);
size_t size = 4;
FinalModel<T> fbe_model(_buffer, fbe_offset() + 4);
for (size_t i = fbe_vector_size; i-- > 0;)
{
T value = T();
size_t offset = fbe_model.get(value);
values.emplace_back(value);
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename T>
inline size_t FinalModelVector<T>::get(std::list<T>& values) const noexcept
{
values.clear();
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
size_t fbe_vector_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_vector_size == 0)
return 4;
size_t size = 4;
FinalModel<T> fbe_model(_buffer, fbe_offset() + 4);
for (size_t i = fbe_vector_size; i-- > 0;)
{
T value = T();
size_t offset = fbe_model.get(value);
values.emplace_back(value);
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename T>
inline size_t FinalModelVector<T>::get(std::set<T>& values) const noexcept
{
values.clear();
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
size_t fbe_vector_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_vector_size == 0)
return 4;
size_t size = 4;
FinalModel<T> fbe_model(_buffer, fbe_offset() + 4);
for (size_t i = fbe_vector_size; i-- > 0;)
{
T value = T();
size_t offset = fbe_model.get(value);
values.emplace(value);
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename T>
inline size_t FinalModelVector<T>::set(const std::vector<T>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = (uint32_t)values.size();
size_t size = 4;
FinalModel<T> fbe_model(_buffer, fbe_offset() + 4);
for (const auto& value : values)
{
size_t offset = fbe_model.set(value);
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename T>
inline size_t FinalModelVector<T>::set(const std::list<T>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = (uint32_t)values.size();
size_t size = 4;
FinalModel<T> fbe_model(_buffer, fbe_offset() + 4);
for (const auto& value : values)
{
size_t offset = fbe_model.set(value);
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename T>
inline size_t FinalModelVector<T>::set(const std::set<T>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = (uint32_t)values.size();
size_t size = 4;
FinalModel<T> fbe_model(_buffer, fbe_offset() + 4);
for (const auto& value : values)
{
size_t offset = fbe_model.set(value);
fbe_model.fbe_shift(offset);
size += offset;
}
return size;
}
template <typename TKey, typename TValue>
inline size_t FinalModelMap<TKey, TValue>::fbe_allocation_size(const std::map<TKey, TValue>& values) const noexcept
{
size_t size = 4;
FinalModel<TKey> fbe_model_key(_buffer, fbe_offset() + 4);
FinalModel<TValue> fbe_model_value(_buffer, fbe_offset() + 4);
for (const auto& value : values)
{
size += fbe_model_key.fbe_allocation_size(value.first);
size += fbe_model_value.fbe_allocation_size(value.second);
}
return size;
}
template <typename TKey, typename TValue>
inline size_t FinalModelMap<TKey, TValue>::fbe_allocation_size(const std::unordered_map<TKey, TValue>& values) const noexcept
{
size_t size = 4;
FinalModel<TKey> fbe_model_key(_buffer, fbe_offset() + 4);
FinalModel<TValue> fbe_model_value(_buffer, fbe_offset() + 4);
for (const auto& value : values)
{
size += fbe_model_key.fbe_allocation_size(value.first);
size += fbe_model_value.fbe_allocation_size(value.second);
}
return size;
}
template <typename TKey, typename TValue>
inline size_t FinalModelMap<TKey, TValue>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return std::numeric_limits<std::size_t>::max();
uint32_t fbe_map_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
size_t size = 4;
FinalModel<TKey> fbe_model_key(_buffer, fbe_offset() + 4);
FinalModel<TValue> fbe_model_value(_buffer, fbe_offset() + 4);
for (size_t i = fbe_map_size; i-- > 0;)
{
size_t offset_key = fbe_model_key.verify();
if (offset_key == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_model_key.fbe_shift(offset_key);
fbe_model_value.fbe_shift(offset_key);
size += offset_key;
size_t offset_value = fbe_model_value.verify();
if (offset_value == std::numeric_limits<std::size_t>::max())
return std::numeric_limits<std::size_t>::max();
fbe_model_key.fbe_shift(offset_value);
fbe_model_value.fbe_shift(offset_value);
size += offset_value;
}
return size;
}
template <typename TKey, typename TValue>
inline size_t FinalModelMap<TKey, TValue>::get(std::map<TKey, TValue>& values) const noexcept
{
values.clear();
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
size_t fbe_map_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_map_size == 0)
return 4;
size_t size = 4;
FinalModel<TKey> fbe_model_key(_buffer, fbe_offset() + 4);
FinalModel<TValue> fbe_model_value(_buffer, fbe_offset() + 4);
for (size_t i = fbe_map_size; i-- > 0;)
{
TKey key;
TValue value;
size_t offset_key = fbe_model_key.get(key);
fbe_model_key.fbe_shift(offset_key);
fbe_model_value.fbe_shift(offset_key);
size_t offset_value = fbe_model_value.get(value);
fbe_model_key.fbe_shift(offset_value);
fbe_model_value.fbe_shift(offset_value);
values.emplace(key, value);
size += offset_key + offset_value;
}
return size;
}
template <typename TKey, typename TValue>
inline size_t FinalModelMap<TKey, TValue>::get(std::unordered_map<TKey, TValue>& values) const noexcept
{
values.clear();
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
size_t fbe_map_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_map_size == 0)
return 4;
size_t size = 4;
FinalModel<TKey> fbe_model_key(_buffer, fbe_offset() + 4);
FinalModel<TValue> fbe_model_value(_buffer, fbe_offset() + 4);
for (size_t i = fbe_map_size; i-- > 0;)
{
TKey key;
TValue value;
size_t offset_key = fbe_model_key.get(key);
fbe_model_key.fbe_shift(offset_key);
fbe_model_value.fbe_shift(offset_key);
size_t offset_value = fbe_model_value.get(value);
fbe_model_key.fbe_shift(offset_value);
fbe_model_value.fbe_shift(offset_value);
values.emplace(key, value);
size += offset_key + offset_value;
}
return size;
}
template <typename TKey, typename TValue>
inline size_t FinalModelMap<TKey, TValue>::set(const std::map<TKey, TValue>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = (uint32_t)values.size();
size_t size = 4;
FinalModel<TKey> fbe_model_key(_buffer, fbe_offset() + 4);
FinalModel<TValue> fbe_model_value(_buffer, fbe_offset() + 4);
for (const auto& value : values)
{
size_t offset_key = fbe_model_key.set(value.first);
fbe_model_key.fbe_shift(offset_key);
fbe_model_value.fbe_shift(offset_key);
size_t offset_value = fbe_model_value.set(value.second);
fbe_model_key.fbe_shift(offset_value);
fbe_model_value.fbe_shift(offset_value);
size += offset_key + offset_value;
}
return size;
}
template <typename TKey, typename TValue>
inline size_t FinalModelMap<TKey, TValue>::set(const std::unordered_map<TKey, TValue>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset() + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + 4) > _buffer.size())
return 0;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = (uint32_t)values.size();
size_t size = 4;
FinalModel<TKey> fbe_model_key(_buffer, fbe_offset() + 4);
FinalModel<TValue> fbe_model_value(_buffer, fbe_offset() + 4);
for (const auto& value : values)
{
size_t offset_key = fbe_model_key.set(value.first);
fbe_model_key.fbe_shift(offset_key);
fbe_model_value.fbe_shift(offset_key);
size_t offset_value = fbe_model_value.set(value.second);
fbe_model_key.fbe_shift(offset_value);
fbe_model_value.fbe_shift(offset_value);
size += offset_key + offset_value;
}
return size;
}
} // namespace FBE

View file

@ -0,0 +1,514 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
#include "fbe_models.h"
namespace FBE {
uint64_t FieldModel<decimal_t>::extract(double a) noexcept
{
uint64_t result;
std::memcpy(&result, &a, sizeof(double));
return result;
}
uint64_t FieldModel<decimal_t>::uint32x32(uint32_t a, uint32_t b) noexcept
{
return (uint64_t)a * (uint64_t)b;
}
void FieldModel<decimal_t>::uint64x64(uint64_t a, uint64_t b, uint64_t& low64, uint32_t& high32) noexcept
{
uint64_t low = uint32x32((uint32_t)a, (uint32_t)b);
uint64_t mid = uint32x32((uint32_t)a, (uint32_t)(b >> 32));
uint64_t high = uint32x32((uint32_t)(a >> 32), (uint32_t)(b >> 32));
high += (mid >> 32);
low += (mid <<= 32);
// Test for carry
if (low < mid)
high++;
mid = uint32x32((uint32_t)(a >> 32), (uint32_t)b);
high += (mid >> 32);
low += (mid <<= 32);
// Test for carry
if (low < mid)
high++;
if (high > 0xFFFFFFFFu)
{
low64 = 0;
high32 = 0;
}
low64 = low;
high32 = (uint32_t)high;
}
void FieldModel<decimal_t>::get(decimal_t& value, decimal_t defaults) const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
{
value = defaults;
return;
}
// Value taken via reverse engineering the double that corresponds to 2^64
const double ds2to64 = 1.8446744073709552e+019;
// Read decimal parts
uint64_t low = *((const uint64_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
uint32_t high = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 8));
uint32_t flags = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 12));
// Calculate decimal value
double dValue = ((double)low + (double)high * ds2to64) / pow(10.0, (uint8_t)(flags >> 16));
if (flags & 0x80000000)
dValue = -dValue;
value = dValue;
}
void FieldModel<decimal_t>::set(decimal_t value) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
// The most we can scale by is 10^28, which is just slightly more
// than 2^93. So a float with an exponent of -94 could just
// barely reach 0.5, but smaller exponents will always round to zero.
const uint32_t DBLBIAS = 1022;
// Get exponent value
double dValue = (double)value;
int32_t iExp = (int32_t)(((uint32_t)(extract(dValue) >> 52) & 0x7FFu) - DBLBIAS);
if ((iExp < -94) || (iExp > 96))
{
// Value too big for .NET Decimal (exponent is limited to [-94, 96])
memset((uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()), 0, 16);
return;
}
uint32_t flags = 0;
if (dValue < 0)
{
dValue = -dValue;
flags = 0x80000000;
}
// Round the input to a 15-digit integer. The R8 format has
// only 15 digits of precision, and we want to keep garbage digits
// out of the Decimal were making.
// Calculate max power of 10 input value could have by multiplying
// the exponent by log10(2). Using scaled integer multiplcation,
// log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
int32_t iPower = 14 - ((iExp * 19728) >> 16);
// iPower is between -14 and 43
if (iPower >= 0)
{
// We have less than 15 digits, scale input up.
if (iPower > 28)
iPower = 28;
dValue *= pow(10.0, iPower);
}
else
{
if ((iPower != -1) || (dValue >= 1E15))
dValue /= pow(10.0, -iPower);
else
iPower = 0; // didn't scale it
}
assert(dValue < 1E15);
if ((dValue < 1E14) && (iPower < 28))
{
dValue *= 10;
iPower++;
assert(dValue >= 1E14);
}
// Round to int64
uint64_t ulMant;
ulMant = (uint64_t)(int64_t)dValue;
dValue -= (int64_t)ulMant; // difference between input & integer
if ((dValue > 0.5) || ((dValue == 0.5) && ((ulMant & 1) != 0)))
ulMant++;
if (ulMant == 0)
{
// Mantissa is 0
memset((uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()), 0, 16);
return;
}
if (iPower < 0)
{
// Add -iPower factors of 10, -iPower <= (29 - 15) = 14
iPower = -iPower;
if (iPower < 10)
{
double pow10 = (double)powl(10.0, iPower);
uint64_t low64 = uint32x32((uint32_t)ulMant, (uint32_t)pow10);
uint64_t high64 = uint32x32((uint32_t)(ulMant >> 32), (uint32_t)pow10);
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = (uint32_t)low64;
high64 += low64 >> 32;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 4)) = (uint32_t)high64;
high64 >>= 32;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 8)) = (uint32_t)high64;
}
else
{
// Have a big power of 10.
assert(iPower <= 14);
uint64_t low64;
uint32_t high32;
uint64x64(ulMant, (uint64_t)pow(10.0, iPower), low64, high32);
*((uint64_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = low64;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 8)) = high32;
}
}
else
{
// Factor out powers of 10 to reduce the scale, if possible.
// The maximum number we could factor out would be 14. This
// comes from the fact we have a 15-digit number, and the
// MSD must be non-zero -- but the lower 14 digits could be
// zero. Note also the scale factor is never negative, so
// we can't scale by any more than the power we used to
// get the integer.
int lmax = iPower;
if (lmax > 14)
lmax = 14;
if ((((uint8_t)ulMant) == 0) && (lmax >= 8))
{
const uint32_t den = 100000000;
uint64_t div = ulMant / den;
if ((uint32_t)ulMant == (uint32_t)(div * den))
{
ulMant = div;
iPower -= 8;
lmax -= 8;
}
}
if ((((uint32_t)ulMant & 0xF) == 0) && (lmax >= 4))
{
const uint32_t den = 10000;
uint64_t div = ulMant / den;
if ((uint32_t)ulMant == (uint32_t)(div * den))
{
ulMant = div;
iPower -= 4;
lmax -= 4;
}
}
if ((((uint32_t)ulMant & 3) == 0) && (lmax >= 2))
{
const uint32_t den = 100;
uint64_t div = ulMant / den;
if ((uint32_t)ulMant == (uint32_t)(div * den))
{
ulMant = div;
iPower -= 2;
lmax -= 2;
}
}
if ((((uint32_t)ulMant & 1) == 0) && (lmax >= 1))
{
const uint32_t den = 10;
uint64_t div = ulMant / den;
if ((uint32_t)ulMant == (uint32_t)(div * den))
{
ulMant = div;
iPower--;
}
}
flags |= (uint32_t)iPower << 16;
*((uint64_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = ulMant;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 8)) = 0;
}
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 12)) = flags;
}
void FieldModel<uuid_t>::get(uuid_t& value, uuid_t defaults) const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
{
value = defaults;
return;
}
std::memcpy(value.data().data(), (const uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()), fbe_size());
}
void FieldModel<uuid_t>::set(uuid_t value) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
std::memcpy((uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()), value.data().data(), fbe_size());
}
size_t FieldModel<buffer_t>::fbe_extra() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_bytes_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_bytes_offset == 0) || ((_buffer.offset() + fbe_bytes_offset + 4) > _buffer.size()))
return 0;
uint32_t fbe_bytes_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset));
return (size_t)(4 + fbe_bytes_size);
}
bool FieldModel<buffer_t>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return true;
uint32_t fbe_bytes_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_bytes_offset == 0)
return true;
if ((_buffer.offset() + fbe_bytes_offset + 4) > _buffer.size())
return false;
uint32_t fbe_bytes_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset));
if ((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) > _buffer.size())
return false;
return true;
}
size_t FieldModel<buffer_t>::get(void* data, size_t size) const noexcept
{
assert(((size == 0) || (data != nullptr)) && "Invalid buffer!");
if ((size > 0) && (data == nullptr))
return 0;
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_bytes_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_bytes_offset == 0)
return 0;
assert(((_buffer.offset() + fbe_bytes_offset + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_bytes_offset + 4) > _buffer.size())
return 0;
uint32_t fbe_bytes_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset));
assert(((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) > _buffer.size())
return 0;
size_t result = std::min(size, (size_t)fbe_bytes_size);
memcpy(data, (const char*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset + 4), result);
return result;
}
void FieldModel<buffer_t>::get(std::vector<uint8_t>& value) const noexcept
{
value.clear();
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
uint32_t fbe_bytes_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_bytes_offset == 0)
return;
assert(((_buffer.offset() + fbe_bytes_offset + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_bytes_offset + 4) > _buffer.size())
return;
uint32_t fbe_bytes_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset));
assert(((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) > _buffer.size())
return;
const char* fbe_bytes = (const char*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset + 4);
value.assign(fbe_bytes, fbe_bytes + fbe_bytes_size);
}
void FieldModel<buffer_t>::set(const void* data, size_t size)
{
assert(((size == 0) || (data != nullptr)) && "Invalid buffer!");
if ((size > 0) && (data == nullptr))
return;
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
uint32_t fbe_bytes_size = (uint32_t)size;
uint32_t fbe_bytes_offset = (uint32_t)(_buffer.allocate(4 + fbe_bytes_size) - _buffer.offset());
assert(((fbe_bytes_offset > 0) && ((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) <= _buffer.size())) && "Model is broken!");
if ((fbe_bytes_offset == 0) || ((_buffer.offset() + fbe_bytes_offset + 4 + fbe_bytes_size) > _buffer.size()))
return;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_bytes_offset;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset)) = fbe_bytes_size;
memcpy((char*)(_buffer.data() + _buffer.offset() + fbe_bytes_offset + 4), data, fbe_bytes_size);
}
size_t FieldModel<std::string>::fbe_extra() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_string_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_string_offset == 0) || ((_buffer.offset() + fbe_string_offset + 4) > _buffer.size()))
return 0;
uint32_t fbe_string_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset));
return (size_t)(4 + fbe_string_size);
}
bool FieldModel<std::string>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return true;
uint32_t fbe_string_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_string_offset == 0)
return true;
if ((_buffer.offset() + fbe_string_offset + 4) > _buffer.size())
return false;
uint32_t fbe_string_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset));
if ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) > _buffer.size())
return false;
return true;
}
size_t FieldModel<std::string>::get(char* data, size_t size) const noexcept
{
assert(((size == 0) || (data != nullptr)) && "Invalid buffer!");
if ((size > 0) && (data == nullptr))
return 0;
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_string_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_string_offset == 0)
return 0;
assert(((_buffer.offset() + fbe_string_offset + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_string_offset + 4) > _buffer.size())
return 0;
uint32_t fbe_string_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset));
assert(((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) > _buffer.size())
return 0;
size_t result = std::min(size, (size_t)fbe_string_size);
memcpy(data, (const char*)(_buffer.data() + _buffer.offset() + fbe_string_offset + 4), result);
return result;
}
void FieldModel<std::string>::get(std::string& value) const noexcept
{
value.clear();
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
uint32_t fbe_string_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + _offset));
if (fbe_string_offset == 0)
return;
assert(((_buffer.offset() + fbe_string_offset + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_string_offset + 4) > _buffer.size())
return;
uint32_t fbe_string_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset));
assert(((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) > _buffer.size())
return;
value.assign((const char*)(_buffer.data() + _buffer.offset() + fbe_string_offset + 4), fbe_string_size);
}
void FieldModel<std::string>::get(std::string& value, const std::string& defaults) const noexcept
{
value = defaults;
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
uint32_t fbe_string_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + _offset));
if (fbe_string_offset == 0)
return;
assert(((_buffer.offset() + fbe_string_offset + 4) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_string_offset + 4) > _buffer.size())
return;
uint32_t fbe_string_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset));
assert(((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) > _buffer.size())
return;
value.assign((const char*)(_buffer.data() + _buffer.offset() + fbe_string_offset + 4), fbe_string_size);
}
void FieldModel<std::string>::set(const char* data, size_t size)
{
assert(((size == 0) || (data != nullptr)) && "Invalid buffer!");
if ((size > 0) && (data == nullptr))
return;
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
uint32_t fbe_string_size = (uint32_t)size;
uint32_t fbe_string_offset = (uint32_t)(_buffer.allocate(4 + fbe_string_size) - _buffer.offset());
assert(((fbe_string_offset > 0) && ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) <= _buffer.size())) && "Model is broken!");
if ((fbe_string_offset == 0) || ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) > _buffer.size()))
return;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_string_offset;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset)) = fbe_string_size;
memcpy((char*)(_buffer.data() + _buffer.offset() + fbe_string_offset + 4), data, fbe_string_size);
}
void FieldModel<std::string>::set(const std::string& value)
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
uint32_t fbe_string_size = (uint32_t)value.size();
uint32_t fbe_string_offset = (uint32_t)(_buffer.allocate(4 + fbe_string_size) - _buffer.offset());
assert(((fbe_string_offset > 0) && ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) <= _buffer.size())) && "Model is broken!");
if ((fbe_string_offset == 0) || ((_buffer.offset() + fbe_string_offset + 4 + fbe_string_size) > _buffer.size()))
return;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_string_offset;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_string_offset)) = fbe_string_size;
memcpy((char*)(_buffer.data() + _buffer.offset() + fbe_string_offset + 4), value.data(), fbe_string_size);
}
} // namespace FBE

469
fbe/user_model/fbe_models.h Normal file
View file

@ -0,0 +1,469 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
#pragma once
#if defined(__clang__)
#pragma clang system_header
#elif defined(__GNUC__)
#pragma GCC system_header
#elif defined(_MSC_VER)
#pragma system_header
#endif
#include "fbe.h"
namespace FBE {
// Fast Binary Encoding base field model
template <typename T, typename TBase = T>
class FieldModelBase
{
public:
FieldModelBase(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Get the field size
size_t fbe_size() const noexcept { return sizeof(TBase); }
// Get the field extra size
size_t fbe_extra() const noexcept { return 0; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the value is valid
bool verify() const noexcept { return true; }
// Get the field value
void get(T& value, T defaults = (T)0) const noexcept;
// Set the field value
void set(T value) noexcept;
private:
FBEBuffer& _buffer;
size_t _offset;
};
// Fast Binary Encoding field model
template <typename T>
class FieldModel : public FieldModelBase<T>
{
public:
using FieldModelBase<T>::FieldModelBase;
};
// Fast Binary Encoding field model bool specialization
template <>
class FieldModel<bool> : public FieldModelBase<bool, uint8_t>
{
public:
using FieldModelBase<bool, uint8_t>::FieldModelBase;
};
// Fast Binary Encoding field model char specialization
template <>
class FieldModel<char> : public FieldModelBase<char, uint8_t>
{
public:
using FieldModelBase<char, uint8_t>::FieldModelBase;
};
// Fast Binary Encoding field model wchar specialization
template <>
class FieldModel<wchar_t> : public FieldModelBase<wchar_t, uint32_t>
{
public:
using FieldModelBase<wchar_t, uint32_t>::FieldModelBase;
};
// Fast Binary Encoding field model decimal specialization
template <>
class FieldModel<decimal_t>
{
public:
FieldModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Get the field size
size_t fbe_size() const noexcept { return 16; }
// Get the field extra size
size_t fbe_extra() const noexcept { return 0; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the decimal value is valid
bool verify() const noexcept { return true; }
// Get the decimal value
void get(decimal_t& value, decimal_t defaults = decimal_t()) const noexcept;
// Set the decimal value
void set(decimal_t value) noexcept;
private:
FBEBuffer& _buffer;
size_t _offset;
static uint64_t extract(double a) noexcept;
static uint64_t uint32x32(uint32_t a, uint32_t b) noexcept;
static void uint64x64(uint64_t a, uint64_t b, uint64_t& low64, uint32_t& high32) noexcept;
};
// Fast Binary Encoding field model UUID specialization
template <>
class FieldModel<uuid_t>
{
public:
FieldModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Get the field size
size_t fbe_size() const noexcept { return 16; }
// Get the field extra size
size_t fbe_extra() const noexcept { return 0; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the UUID value is valid
bool verify() const noexcept { return true; }
// Get the UUID value
void get(uuid_t& value, uuid_t defaults = uuid_t::nil()) const noexcept;
// Set the UUID value
void set(uuid_t value) noexcept;
private:
FBEBuffer& _buffer;
size_t _offset;
};
// Fast Binary Encoding field model bytes specialization
template <>
class FieldModel<buffer_t>
{
public:
FieldModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Get the field size
size_t fbe_size() const noexcept { return 4; }
// Get the field extra size
size_t fbe_extra() const noexcept;
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the bytes value is valid
bool verify() const noexcept;
// Get the bytes value
size_t get(void* data, size_t size) const noexcept;
// Get the bytes value
template <size_t N>
size_t get(uint8_t (&data)[N]) const noexcept { return get(data, N); }
// Get the bytes value
template <size_t N>
size_t get(std::array<uint8_t, N>& data) const noexcept { return get(data.data(), data.size()); }
// Get the bytes value
void get(std::vector<uint8_t>& value) const noexcept;
// Get the bytes value
void get(buffer_t& value) const noexcept { get(value.buffer()); }
// Set the bytes value
void set(const void* data, size_t size);
// Set the bytes value
template <size_t N>
void set(const uint8_t (&data)[N]) { set(data, N); }
// Set the bytes value
template <size_t N>
void set(const std::array<uint8_t, N>& data) { set(data.data(), data.size()); }
// Set the bytes value
void set(const std::vector<uint8_t>& value) { set(value.data(), value.size()); }
// Set the bytes value
void set(const buffer_t& value) { set(value.buffer()); }
private:
FBEBuffer& _buffer;
size_t _offset;
};
// Fast Binary Encoding field model string specialization
template <>
class FieldModel<std::string>
{
public:
FieldModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Get the field size
size_t fbe_size() const noexcept { return 4; }
// Get the field extra size
size_t fbe_extra() const noexcept;
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Check if the string value is valid
bool verify() const noexcept;
// Get the string value
size_t get(char* data, size_t size) const noexcept;
// Get the string value
template <size_t N>
size_t get(char (&data)[N]) const noexcept { return get(data, N); }
// Get the string value
template <size_t N>
size_t get(std::array<char, N>& data) const noexcept { return get(data.data(), data.size()); }
// Get the string value
void get(std::string& value) const noexcept;
// Get the string value
void get(std::string& value, const std::string& defaults) const noexcept;
// Set the string value
void set(const char* data, size_t size);
// Set the string value
template <size_t N>
void set(const char (&data)[N]) { set(data, N); }
// Set the string value
template <size_t N>
void set(const std::array<char, N>& data) { set(data.data(), data.size()); }
// Set the string value
void set(const std::string& value);
private:
FBEBuffer& _buffer;
size_t _offset;
};
// Fast Binary Encoding field model optional specialization
template <typename T>
class FieldModel<std::optional<T>>
{
public:
FieldModel(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset), value(buffer, 0) {}
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Get the field size
size_t fbe_size() const noexcept { return 1 + 4; }
// Get the field extra size
size_t fbe_extra() const noexcept;
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
//! Is the value present?
explicit operator bool() const noexcept { return has_value(); }
// Checks if the object contains a value
bool has_value() const noexcept;
// Check if the optional value is valid
bool verify() const noexcept;
// Get the optional value (being phase)
size_t get_begin() const noexcept;
// Get the optional value (end phase)
void get_end(size_t fbe_begin) const noexcept;
// Get the optional value
void get(std::optional<T>& opt, const std::optional<T>& defaults = std::nullopt) const noexcept;
// Set the optional value (begin phase)
size_t set_begin(bool has_value);
// Set the optional value (end phase)
void set_end(size_t fbe_begin);
// Set the optional value
void set(const std::optional<T>& opt);
private:
FBEBuffer& _buffer;
size_t _offset;
public:
// Base field model value
FieldModel<T> value;
};
// Fast Binary Encoding field model array
template <typename T, size_t N>
class FieldModelArray
{
public:
FieldModelArray(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset), _model(buffer, offset) {}
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Get the field size
size_t fbe_size() const noexcept { return N * _model.fbe_size(); }
// Get the field extra size
size_t fbe_extra() const noexcept { return 0; }
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Get the array
const uint8_t* data() const noexcept;
// Get the array
uint8_t* data() noexcept;
// Get the array offset
size_t offset() const noexcept { return 0; }
// Get the array size
size_t size() const noexcept { return N; }
// Array index operator
FieldModel<T> operator[](size_t index) const noexcept;
// Check if the array is valid
bool verify() const noexcept;
// Get the array as C-array
template <size_t S>
void get(T (&values)[S]) const noexcept;
// Get the array as std::array
template <size_t S>
void get(std::array<T, S>& values) const noexcept;
// Get the array as std::vector
void get(std::vector<T>& values) const noexcept;
// Set the array as C-array
template <size_t S>
void set(const T (&values)[S]) noexcept;
// Set the array as std::array
template <size_t S>
void set(const std::array<T, S>& values) noexcept;
// Set the array as std::vector
void set(const std::vector<T>& values) noexcept;
private:
FBEBuffer& _buffer;
size_t _offset;
FieldModel<T> _model;
};
// Fast Binary Encoding field model vector
template <typename T>
class FieldModelVector
{
public:
FieldModelVector(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Get the field size
size_t fbe_size() const noexcept { return 4; }
// Get the field extra size
size_t fbe_extra() const noexcept;
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Get the vector offset
size_t offset() const noexcept;
// Get the vector size
size_t size() const noexcept;
// Vector index operator
FieldModel<T> operator[](size_t index) const noexcept;
// Resize the vector and get its first model
FieldModel<T> resize(size_t size);
// Check if the vector is valid
bool verify() const noexcept;
// Get the vector as std::vector
void get(std::vector<T>& values) const noexcept;
// Get the vector as std::list
void get(std::list<T>& values) const noexcept;
// Get the vector as std::set
void get(std::set<T>& values) const noexcept;
// Set the vector as std::vector
void set(const std::vector<T>& values) noexcept;
// Set the vector as std::list
void set(const std::list<T>& values) noexcept;
// Set the vector as std::set
void set(const std::set<T>& values) noexcept;
private:
FBEBuffer& _buffer;
size_t _offset;
};
// Fast Binary Encoding field model map
template <typename TKey, typename TValue>
class FieldModelMap
{
public:
FieldModelMap(FBEBuffer& buffer, size_t offset) noexcept : _buffer(buffer), _offset(offset) {}
// Get the field offset
size_t fbe_offset() const noexcept { return _offset; }
// Get the field size
size_t fbe_size() const noexcept { return 4; }
// Get the field extra size
size_t fbe_extra() const noexcept;
// Shift the current field offset
void fbe_shift(size_t size) noexcept { _offset += size; }
// Unshift the current field offset
void fbe_unshift(size_t size) noexcept { _offset -= size; }
// Get the map offset
size_t offset() const noexcept;
// Get the map size
size_t size() const noexcept;
// Map index operator
std::pair<FieldModel<TKey>, FieldModel<TValue>> operator[](size_t index) const noexcept;
// Resize the map and get its first model
std::pair<FieldModel<TKey>, FieldModel<TValue>> resize(size_t size);
// Check if the map is valid
bool verify() const noexcept;
// Get the map as std::map
void get(std::map<TKey, TValue>& values) const noexcept;
// Get the map as std::unordered_map
void get(std::unordered_map<TKey, TValue>& values) const noexcept;
// Set the map as std::map
void set(const std::map<TKey, TValue>& values) noexcept;
// Set the map as std::unordered_map
void set(const std::unordered_map<TKey, TValue>& values) noexcept;
private:
FBEBuffer& _buffer;
size_t _offset;
};
} // namespace FBE
#include "fbe_models.inl"

View file

@ -0,0 +1,687 @@
// Automatically generated by the Fast Binary Encoding compiler, do not modify!
// https://github.com/chronoxor/FastBinaryEncoding
// Source: FBE
// Version: 1.7.0.0
namespace FBE {
template <typename T, typename TBase>
inline void FieldModelBase<T, TBase>::get(T& value, T defaults) const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
{
value = defaults;
return;
}
value = (T)(*((const TBase*)(_buffer.data() + _buffer.offset() + fbe_offset())));
}
template <typename T, typename TBase>
inline void FieldModelBase<T, TBase>::set(T value) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
*((TBase*)(_buffer.data() + _buffer.offset() + fbe_offset())) = (TBase)value;
}
template <typename T>
inline size_t FieldModel<std::optional<T>>::fbe_extra() const noexcept
{
if (!has_value())
return 0;
uint32_t fbe_optional_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 1));
if ((fbe_optional_offset == 0) || ((_buffer.offset() + fbe_optional_offset + 4) > _buffer.size()))
return 0;
_buffer.shift(fbe_optional_offset);
size_t fbe_result = value.fbe_size() + value.fbe_extra();
_buffer.unshift(fbe_optional_offset);
return fbe_result;
}
template <typename T>
inline bool FieldModel<std::optional<T>>::has_value() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return false;
uint8_t fbe_has_value = *((const uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
return (fbe_has_value != 0);
}
template <typename T>
inline bool FieldModel<std::optional<T>>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return true;
uint8_t fbe_has_value = *((const uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_has_value == 0)
return true;
uint32_t fbe_optional_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 1));
if (fbe_optional_offset == 0)
return false;
_buffer.shift(fbe_optional_offset);
bool fbe_result = value.verify();
_buffer.unshift(fbe_optional_offset);
return fbe_result;
}
template <typename T>
inline size_t FieldModel<std::optional<T>>::get_begin() const noexcept
{
if (!has_value())
return 0;
uint32_t fbe_optional_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 1));
assert((fbe_optional_offset > 0) && "Model is broken!");
if (fbe_optional_offset == 0)
return 0;
_buffer.shift(fbe_optional_offset);
return fbe_optional_offset;
}
template <typename T>
inline void FieldModel<std::optional<T>>::get_end(size_t fbe_begin) const noexcept
{
_buffer.unshift(fbe_begin);
}
template <typename T>
inline void FieldModel<std::optional<T>>::get(std::optional<T>& opt, const std::optional<T>& defaults) const noexcept
{
opt = defaults;
size_t fbe_begin = get_begin();
if (fbe_begin == 0)
return;
T temp = T();
value.get(temp);
opt.emplace(temp);
get_end(fbe_begin);
}
template <typename T>
inline size_t FieldModel<std::optional<T>>::set_begin(bool has_value)
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint8_t fbe_has_value = has_value ? 1 : 0;
*((uint8_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_has_value;
if (fbe_has_value == 0)
return 0;
uint32_t fbe_optional_size = (uint32_t)value.fbe_size();
uint32_t fbe_optional_offset = (uint32_t)(_buffer.allocate(fbe_optional_size) - _buffer.offset());
assert(((fbe_optional_offset > 0) && ((_buffer.offset() + fbe_optional_offset + fbe_optional_size) <= _buffer.size())) && "Model is broken!");
if ((fbe_optional_offset == 0) || ((_buffer.offset() + fbe_optional_offset + fbe_optional_size) > _buffer.size()))
return 0;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset() + 1)) = fbe_optional_offset;
_buffer.shift(fbe_optional_offset);
return fbe_optional_offset;
}
template <typename T>
inline void FieldModel<std::optional<T>>::set_end(size_t fbe_begin)
{
_buffer.unshift(fbe_begin);
}
template <typename T>
inline void FieldModel<std::optional<T>>::set(const std::optional<T>& opt)
{
size_t fbe_begin = set_begin(opt.has_value());
if (fbe_begin == 0)
return;
if (opt)
value.set(opt.value());
set_end(fbe_begin);
}
template <typename T, size_t N>
inline const uint8_t* FieldModelArray<T, N>::data() const noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
return _buffer.data() + _buffer.offset() + fbe_offset();
}
template <typename T, size_t N>
inline uint8_t* FieldModelArray<T, N>::data() noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
return _buffer.data() + _buffer.offset() + fbe_offset();
}
template <typename T, size_t N>
inline FieldModel<T> FieldModelArray<T, N>::operator[](size_t index) const noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
assert((index < N) && "Index is out of bounds!");
FieldModel<T> fbe_model(_buffer, fbe_offset());
fbe_model.fbe_shift(index * fbe_model.fbe_size());
return fbe_model;
}
template <typename T, size_t N>
inline bool FieldModelArray<T, N>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return false;
FieldModel<T> fbe_model(_buffer, fbe_offset());
for (size_t i = N; i-- > 0;)
{
if (!fbe_model.verify())
return false;
fbe_model.fbe_shift(fbe_model.fbe_size());
}
return true;
}
template <typename T, size_t N>
template <size_t S>
inline void FieldModelArray<T, N>::get(T (&values)[S]) const noexcept
{
auto fbe_model = (*this)[0];
for (size_t i = 0; (i < S) && (i < N); ++i)
{
fbe_model.get(values[i]);
fbe_model.fbe_shift(fbe_model.fbe_size());
}
}
template <typename T, size_t N>
template <size_t S>
inline void FieldModelArray<T, N>::get(std::array<T, S>& values) const noexcept
{
auto fbe_model = (*this)[0];
for (size_t i = 0; (i < S) && (i < N); ++i)
{
fbe_model.get(values[i]);
fbe_model.fbe_shift(fbe_model.fbe_size());
}
}
template <typename T, size_t N>
inline void FieldModelArray<T, N>::get(std::vector<T>& values) const noexcept
{
values.clear();
values.reserve(N);
auto fbe_model = (*this)[0];
for (size_t i = N; i-- > 0;)
{
T value = T();
fbe_model.get(value);
values.emplace_back(value);
fbe_model.fbe_shift(fbe_model.fbe_size());
}
}
template <typename T, size_t N>
template <size_t S>
inline void FieldModelArray<T, N>::set(const T (&values)[S]) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
auto fbe_model = (*this)[0];
for (size_t i = 0; (i < S) && (i < N); ++i)
{
fbe_model.set(values[i]);
fbe_model.fbe_shift(fbe_model.fbe_size());
}
}
template <typename T, size_t N>
template <size_t S>
inline void FieldModelArray<T, N>::set(const std::array<T, S>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
auto fbe_model = (*this)[0];
for (size_t i = 0; (i < S) && (i < N); ++i)
{
fbe_model.set(values[i]);
fbe_model.fbe_shift(fbe_model.fbe_size());
}
}
template <typename T, size_t N>
inline void FieldModelArray<T, N>::set(const std::vector<T>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
auto fbe_model = (*this)[0];
for (size_t i = 0; (i < values.size()) && (i < N); ++i)
{
fbe_model.set(values[i]);
fbe_model.fbe_shift(fbe_model.fbe_size());
}
}
template <typename T>
inline size_t FieldModelVector<T>::fbe_extra() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_vector_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_vector_offset == 0) || ((_buffer.offset() + fbe_vector_offset + 4) > _buffer.size()))
return 0;
uint32_t fbe_vector_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_vector_offset));
size_t fbe_result = 4;
FieldModel<T> fbe_model(_buffer, fbe_vector_offset + 4);
for (size_t i = fbe_vector_size; i-- > 0;)
{
fbe_result += fbe_model.fbe_size() + fbe_model.fbe_extra();
fbe_model.fbe_shift(fbe_model.fbe_size());
}
return fbe_result;
}
template <typename T>
inline size_t FieldModelVector<T>::offset() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_vector_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
return fbe_vector_offset;
}
template <typename T>
inline size_t FieldModelVector<T>::size() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_vector_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_vector_offset == 0) || ((_buffer.offset() + fbe_vector_offset + 4) > _buffer.size()))
return 0;
uint32_t fbe_vector_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_vector_offset));
return fbe_vector_size;
}
template <typename T>
inline FieldModel<T> FieldModelVector<T>::operator[](size_t index) const noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
uint32_t fbe_vector_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
assert(((fbe_vector_offset > 0) && ((_buffer.offset() + fbe_vector_offset + 4) <= _buffer.size())) && "Model is broken!");
[[maybe_unused]] uint32_t fbe_vector_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_vector_offset));
assert((index < fbe_vector_size) && "Index is out of bounds!");
FieldModel<T> fbe_model(_buffer, fbe_vector_offset + 4);
fbe_model.fbe_shift(index * fbe_model.fbe_size());
return fbe_model;
}
template <typename T>
inline FieldModel<T> FieldModelVector<T>::resize(size_t size)
{
FieldModel<T> fbe_model(_buffer, fbe_offset());
uint32_t fbe_vector_size = (uint32_t)(size * fbe_model.fbe_size());
uint32_t fbe_vector_offset = (uint32_t)(_buffer.allocate(4 + fbe_vector_size) - _buffer.offset());
assert(((fbe_vector_offset > 0) && ((_buffer.offset() + fbe_vector_offset + 4) <= _buffer.size())) && "Model is broken!");
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_vector_offset;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_vector_offset)) = (uint32_t)size;
memset((char*)(_buffer.data() + _buffer.offset() + fbe_vector_offset + 4), 0, fbe_vector_size);
return FieldModel<T>(_buffer, fbe_vector_offset + 4);
}
template <typename T>
inline bool FieldModelVector<T>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return true;
uint32_t fbe_vector_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_vector_offset == 0)
return true;
if ((_buffer.offset() + fbe_vector_offset + 4) > _buffer.size())
return false;
uint32_t fbe_vector_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_vector_offset));
FieldModel<T> fbe_model(_buffer, fbe_vector_offset + 4);
for (size_t i = fbe_vector_size; i-- > 0;)
{
if (!fbe_model.verify())
return false;
fbe_model.fbe_shift(fbe_model.fbe_size());
}
return true;
}
template <typename T>
inline void FieldModelVector<T>::get(std::vector<T>& values) const noexcept
{
values.clear();
size_t fbe_vector_size = size();
if (fbe_vector_size == 0)
return;
values.reserve(fbe_vector_size);
auto fbe_model = (*this)[0];
for (size_t i = fbe_vector_size; i-- > 0;)
{
T value = T();
fbe_model.get(value);
values.emplace_back(value);
fbe_model.fbe_shift(fbe_model.fbe_size());
}
}
template <typename T>
inline void FieldModelVector<T>::get(std::list<T>& values) const noexcept
{
values.clear();
size_t fbe_vector_size = size();
if (fbe_vector_size == 0)
return;
auto fbe_model = (*this)[0];
for (size_t i = fbe_vector_size; i-- > 0;)
{
T value = T();
fbe_model.get(value);
values.emplace_back(value);
fbe_model.fbe_shift(fbe_model.fbe_size());
}
}
template <typename T>
inline void FieldModelVector<T>::get(std::set<T>& values) const noexcept
{
values.clear();
size_t fbe_vector_size = size();
if (fbe_vector_size == 0)
return;
auto fbe_model = (*this)[0];
for (size_t i = fbe_vector_size; i-- > 0;)
{
T value = T();
fbe_model.get(value);
values.emplace(value);
fbe_model.fbe_shift(fbe_model.fbe_size());
}
}
template <typename T>
inline void FieldModelVector<T>::set(const std::vector<T>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
auto fbe_model = resize(values.size());
for (const auto& value : values)
{
fbe_model.set(value);
fbe_model.fbe_shift(fbe_model.fbe_size());
}
}
template <typename T>
inline void FieldModelVector<T>::set(const std::list<T>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
auto fbe_model = resize(values.size());
for (const auto& value : values)
{
fbe_model.set(value);
fbe_model.fbe_shift(fbe_model.fbe_size());
}
}
template <typename T>
inline void FieldModelVector<T>::set(const std::set<T>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
auto fbe_model = resize(values.size());
for (const auto& value : values)
{
fbe_model.set(value);
fbe_model.fbe_shift(fbe_model.fbe_size());
}
}
template <typename TKey, typename TValue>
inline size_t FieldModelMap<TKey, TValue>::fbe_extra() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_map_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_map_offset == 0) || ((_buffer.offset() + fbe_map_offset + 4) > _buffer.size()))
return 0;
uint32_t fbe_map_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_map_offset));
size_t fbe_result = 4;
FieldModel<TKey> fbe_model_key(_buffer, fbe_map_offset + 4);
FieldModel<TValue> fbe_model_value(_buffer, fbe_map_offset + 4 + fbe_model_key.fbe_size());
for (size_t i = fbe_map_size; i-- > 0;)
{
fbe_result += fbe_model_key.fbe_size() + fbe_model_key.fbe_extra();
fbe_model_key.fbe_shift(fbe_model_key.fbe_size() + fbe_model_value.fbe_size());
fbe_result += fbe_model_value.fbe_size() + fbe_model_value.fbe_extra();
fbe_model_value.fbe_shift(fbe_model_key.fbe_size() + fbe_model_value.fbe_size());
}
return fbe_result;
}
template <typename TKey, typename TValue>
inline size_t FieldModelMap<TKey, TValue>::offset() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_map_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
return fbe_map_offset;
}
template <typename TKey, typename TValue>
inline size_t FieldModelMap<TKey, TValue>::size() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return 0;
uint32_t fbe_map_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if ((fbe_map_offset == 0) || ((_buffer.offset() + fbe_map_offset + 4) > _buffer.size()))
return 0;
uint32_t fbe_map_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_map_offset));
return fbe_map_size;
}
template <typename TKey, typename TValue>
inline std::pair<FieldModel<TKey>, FieldModel<TValue>> FieldModelMap<TKey, TValue>::operator[](size_t index) const noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
uint32_t fbe_map_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
assert(((fbe_map_offset > 0) && ((_buffer.offset() + fbe_map_offset + 4) <= _buffer.size())) && "Model is broken!");
[[maybe_unused]] uint32_t fbe_map_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_map_offset));
assert((index < fbe_map_size) && "Index is out of bounds!");
FieldModel<TKey> fbe_model_key(_buffer, fbe_map_offset + 4);
FieldModel<TValue> fbe_model_value(_buffer, fbe_map_offset + 4 + fbe_model_key.fbe_size());
fbe_model_key.fbe_shift(index * (fbe_model_key.fbe_size() + fbe_model_value.fbe_size()));
fbe_model_value.fbe_shift(index * (fbe_model_key.fbe_size() + fbe_model_value.fbe_size()));
return std::make_pair(fbe_model_key, fbe_model_value);
}
template <typename TKey, typename TValue>
inline std::pair<FieldModel<TKey>, FieldModel<TValue>> FieldModelMap<TKey, TValue>::resize(size_t size)
{
FieldModel<TKey> fbe_model_key(_buffer, fbe_offset());
FieldModel<TValue> fbe_model_value(_buffer, fbe_offset() + fbe_model_key.fbe_size());
uint32_t fbe_map_size = (uint32_t)(size * (fbe_model_key.fbe_size() + fbe_model_value.fbe_size()));
uint32_t fbe_map_offset = (uint32_t)(_buffer.allocate(4 + fbe_map_size) - _buffer.offset());
assert(((fbe_map_offset > 0) && ((_buffer.offset() + fbe_map_offset + 4 + fbe_map_size) <= _buffer.size())) && "Model is broken!");
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset())) = fbe_map_offset;
*((uint32_t*)(_buffer.data() + _buffer.offset() + fbe_map_offset)) = (uint32_t)size;
memset((char*)(_buffer.data() + _buffer.offset() + fbe_map_offset + 4), 0, fbe_map_size);
return std::make_pair(FieldModel<TKey>(_buffer, fbe_map_offset + 4), FieldModel<TValue>(_buffer, fbe_map_offset + 4 + fbe_model_key.fbe_size()));
}
template <typename TKey, typename TValue>
inline bool FieldModelMap<TKey, TValue>::verify() const noexcept
{
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return true;
uint32_t fbe_map_offset = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_offset()));
if (fbe_map_offset == 0)
return true;
if ((_buffer.offset() + fbe_map_offset + 4) > _buffer.size())
return false;
uint32_t fbe_map_size = *((const uint32_t*)(_buffer.data() + _buffer.offset() + fbe_map_offset));
FieldModel<TKey> fbe_model_key(_buffer, fbe_map_offset + 4);
FieldModel<TValue> fbe_model_value(_buffer, fbe_map_offset + 4 + fbe_model_key.fbe_size());
for (size_t i = fbe_map_size; i-- > 0;)
{
if (!fbe_model_key.verify())
return false;
fbe_model_key.fbe_shift(fbe_model_key.fbe_size() + fbe_model_value.fbe_size());
if (!fbe_model_value.verify())
return false;
fbe_model_value.fbe_shift(fbe_model_key.fbe_size() + fbe_model_value.fbe_size());
}
return true;
}
template <typename TKey, typename TValue>
inline void FieldModelMap<TKey, TValue>::get(std::map<TKey, TValue>& values) const noexcept
{
values.clear();
size_t fbe_map_size = size();
if (fbe_map_size == 0)
return;
auto fbe_model = (*this)[0];
for (size_t i = fbe_map_size; i-- > 0;)
{
TKey key;
TValue value;
fbe_model.first.get(key);
fbe_model.second.get(value);
values.emplace(key, value);
fbe_model.first.fbe_shift(fbe_model.first.fbe_size() + fbe_model.second.fbe_size());
fbe_model.second.fbe_shift(fbe_model.first.fbe_size() + fbe_model.second.fbe_size());
}
}
template <typename TKey, typename TValue>
inline void FieldModelMap<TKey, TValue>::get(std::unordered_map<TKey, TValue>& values) const noexcept
{
values.clear();
size_t fbe_map_size = size();
if (fbe_map_size == 0)
return;
auto fbe_model = (*this)[0];
for (size_t i = fbe_map_size; i-- > 0;)
{
TKey key;
TValue value;
fbe_model.first.get(key);
fbe_model.second.get(value);
values.emplace(key, value);
fbe_model.first.fbe_shift(fbe_model.first.fbe_size() + fbe_model.second.fbe_size());
fbe_model.second.fbe_shift(fbe_model.first.fbe_size() + fbe_model.second.fbe_size());
}
}
template <typename TKey, typename TValue>
inline void FieldModelMap<TKey, TValue>::set(const std::map<TKey, TValue>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
auto fbe_model = resize(values.size());
for (const auto& value : values)
{
fbe_model.first.set(value.first);
fbe_model.first.fbe_shift(fbe_model.first.fbe_size() + fbe_model.second.fbe_size());
fbe_model.second.set(value.second);
fbe_model.second.fbe_shift(fbe_model.first.fbe_size() + fbe_model.second.fbe_size());
}
}
template <typename TKey, typename TValue>
inline void FieldModelMap<TKey, TValue>::set(const std::unordered_map<TKey, TValue>& values) noexcept
{
assert(((_buffer.offset() + fbe_offset() + fbe_size()) <= _buffer.size()) && "Model is broken!");
if ((_buffer.offset() + fbe_offset() + fbe_size()) > _buffer.size())
return;
auto fbe_model = resize(values.size());
for (const auto& value : values)
{
fbe_model.first.set(value.first);
fbe_model.first.fbe_shift(fbe_model.first.fbe_size() + fbe_model.second.fbe_size());
fbe_model.second.set(value.second);
fbe_model.second.fbe_shift(fbe_model.first.fbe_size() + fbe_model.second.fbe_size());
}
}
} // namespace FBE