CCash/fbe/user_model/fbe.h
EntireTwix 0130f3c971 🎉 FBE
2021-07-14 22:56:10 -07:00

650 lines
27 KiB
C++

// 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