#include "MetaCoreFoundation/MetaCoreAssetGuid.h" #include #include #include #include namespace MetaCore { namespace { [[nodiscard]] std::optional MetaCoreParseHexNibble(char value) { if (value >= '0' && value <= '9') { return static_cast(value - '0'); } if (value >= 'a' && value <= 'f') { return static_cast(10 + value - 'a'); } if (value >= 'A' && value <= 'F') { return static_cast(10 + value - 'A'); } return std::nullopt; } } // namespace bool MetaCoreAssetGuid::IsValid() const { for (std::uint8_t byteValue : Bytes) { if (byteValue != 0) { return true; } } return false; } std::string MetaCoreAssetGuid::ToString() const { std::ostringstream stream; stream << std::hex << std::setfill('0'); for (std::size_t index = 0; index < Bytes.size(); ++index) { if (index == 4 || index == 6 || index == 8 || index == 10) { stream << '-'; } stream << std::setw(2) << static_cast(Bytes[index]); } return stream.str(); } MetaCoreAssetGuid MetaCoreAssetGuid::Generate() { static thread_local std::mt19937_64 generator(std::random_device{}()); MetaCoreAssetGuid guid; for (std::size_t index = 0; index < guid.Bytes.size(); index += sizeof(std::uint64_t)) { const std::uint64_t randomValue = generator(); for (std::size_t byteIndex = 0; byteIndex < sizeof(std::uint64_t) && (index + byteIndex) < guid.Bytes.size(); ++byteIndex) { guid.Bytes[index + byteIndex] = static_cast((randomValue >> (byteIndex * 8U)) & 0xFFU); } } guid.Bytes[6] = static_cast((guid.Bytes[6] & 0x0FU) | 0x40U); guid.Bytes[8] = static_cast((guid.Bytes[8] & 0x3FU) | 0x80U); return guid; } std::optional MetaCoreAssetGuid::Parse(std::string_view value) { std::array hexDigits{}; std::size_t digitCount = 0; for (char character : value) { if (character == '-') { continue; } if (digitCount >= hexDigits.size()) { return std::nullopt; } hexDigits[digitCount++] = character; } if (digitCount != hexDigits.size()) { return std::nullopt; } MetaCoreAssetGuid guid; for (std::size_t index = 0; index < guid.Bytes.size(); ++index) { const auto highNibble = MetaCoreParseHexNibble(hexDigits[index * 2]); const auto lowNibble = MetaCoreParseHexNibble(hexDigits[index * 2 + 1]); if (!highNibble.has_value() || !lowNibble.has_value()) { return std::nullopt; } guid.Bytes[index] = static_cast((highNibble.value() << 4U) | lowNibble.value()); } return guid; } std::size_t MetaCoreAssetGuidHasher::operator()(const MetaCoreAssetGuid& guid) const noexcept { std::size_t hashValue = 1469598103934665603ULL; for (std::uint8_t byteValue : guid.Bytes) { hashValue ^= static_cast(byteValue); hashValue *= 1099511628211ULL; } return hashValue; } } // namespace MetaCore