//------------------------------------------------------------------------------ // Automatically generated by the Fast Binary Encoding compiler, do not modify! // https://github.com/chronoxor/FastBinaryEncoding // Source: FBE // FBE version: 1.14.1.0 //------------------------------------------------------------------------------ #include "fbe.h" #if defined(_WIN32) || defined(_WIN64) #include #include #undef DELETE #undef ERROR #undef HOST_NOT_FOUND #undef Yield #undef min #undef max #undef uuid_t #endif 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 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 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& 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& 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