From 705f1110587502a49dda51790fa14ac9843e135e Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Wed, 4 Aug 2021 03:55:48 -0400 Subject: common: uuid: Add hex string to UUID constructor This allows for easily converting a hex string into a Common::UUID, which is backed by a 128 bit unsigned integer. --- src/common/uuid.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'src/common/uuid.cpp') diff --git a/src/common/uuid.cpp b/src/common/uuid.cpp index 18303a1e3..d7435a6e9 100644 --- a/src/common/uuid.cpp +++ b/src/common/uuid.cpp @@ -6,10 +6,64 @@ #include +#include "common/assert.h" #include "common/uuid.h" namespace Common { +namespace { + +bool IsHexDigit(char c) { + return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); +} + +u8 HexCharToByte(char c) { + if (c >= '0' && c <= '9') { + return static_cast(c - '0'); + } + if (c >= 'a' && c <= 'f') { + return static_cast(c - 'a' + 10); + } + if (c >= 'A' && c <= 'F') { + return static_cast(c - 'A' + 10); + } + ASSERT_MSG(false, "{} is not a hexadecimal digit!", c); + return u8{0}; +} + +} // Anonymous namespace + +u128 HexStringToU128(std::string_view hex_string) { + const size_t length = hex_string.length(); + + // Detect "0x" prefix. + const bool has_0x_prefix = length > 2 && hex_string[0] == '0' && hex_string[1] == 'x'; + const size_t offset = has_0x_prefix ? 2 : 0; + + // Check length. + if (length > 32 + offset) { + ASSERT_MSG(false, "hex_string has more than 32 hexadecimal characters!"); + return INVALID_UUID; + } + + u64 lo = 0; + u64 hi = 0; + for (size_t i = 0; i < length - offset; ++i) { + const char c = hex_string[length - 1 - i]; + if (!IsHexDigit(c)) { + ASSERT_MSG(false, "{} is not a hexadecimal digit!", c); + return INVALID_UUID; + } + if (i < 16) { + lo |= u64{HexCharToByte(c)} << (i * 4); + } + if (i >= 16) { + hi |= u64{HexCharToByte(c)} << ((i - 16) * 4); + } + } + return u128{lo, hi}; +} + UUID UUID::Generate() { std::random_device device; std::mt19937 gen(device()); -- cgit v1.2.3