mirror of
https://github.com/Expand-sys/CCash
synced 2025-12-17 08:32:13 +11:00
401 lines
10 KiB
C++
401 lines
10 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
|
|
|
|
#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, ×tamp) != 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
|