From a0f6cc161c779db655dc91160f0fd1b296ad4269 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Sat, 13 Feb 2021 12:53:17 +0000 Subject: [PATCH] Add a UUID struct for holding and generating RFC4122 UUIDs Time uses UUIDs for clock identification. --- app/CMakeLists.txt | 1 + app/src/main/cpp/skyline/common/uuid.cpp | 76 ++++++++++++++++++++++++ app/src/main/cpp/skyline/common/uuid.h | 27 +++++++++ 3 files changed, 104 insertions(+) create mode 100644 app/src/main/cpp/skyline/common/uuid.cpp create mode 100644 app/src/main/cpp/skyline/common/uuid.h diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index d5d41dbe..7f82c8b9 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -39,6 +39,7 @@ add_library(skyline SHARED ${source_DIR}/skyline/common.cpp ${source_DIR}/skyline/common/settings.cpp ${source_DIR}/skyline/common/signal.cpp + ${source_DIR}/skyline/common/uuid.cpp ${source_DIR}/skyline/nce/guest.S ${source_DIR}/skyline/nce.cpp ${source_DIR}/skyline/jvm.cpp diff --git a/app/src/main/cpp/skyline/common/uuid.cpp b/app/src/main/cpp/skyline/common/uuid.cpp new file mode 100644 index 00000000..9b3bfa61 --- /dev/null +++ b/app/src/main/cpp/skyline/common/uuid.cpp @@ -0,0 +1,76 @@ +#include +#include "uuid.h" + +namespace skyline { + namespace { + union UuidLayout { + struct { + u64 high; + u64 low; + }; + + struct { + u32 timeLow; + u16 timeMid; + union { + u16 timeHighAndVersion; + + struct { + u16 timeHigh : 12; + u8 version : 4; + }; + }; + + union { + u8 clockSeqHighAndReserved; + + struct { + u8 clockSeqHigh : 6; + u8 reserved : 2; + }; + }; + u8 clockSeqLow; + + union __attribute__((packed)) { + u64 node : 48; + + struct { + std::array nodeRaw; + }; + }; + }; + + UUID Swap() { + UuidLayout swappedLayout{*this}; + swappedLayout.timeLow = util::SwapEndianness(timeLow); + swappedLayout.timeMid = util::SwapEndianness(timeMid); + swappedLayout.timeHighAndVersion = util::SwapEndianness(timeHighAndVersion); + swappedLayout.nodeRaw = util::SwapEndianness(nodeRaw); + + UUID out; + std::memcpy(&out, &swappedLayout, sizeof(UUID)); + return out; + } + }; + static_assert(sizeof(UuidLayout) == 0x10); + } + + UUID UUID::GenerateUuidV4() { + constexpr u8 reserved{0x1}; // RFC4122 variant + constexpr u8 version{0x4}; // v4 UUIDs are generated entirely from random numbers + + std::random_device rd; + std::mt19937_64 gen(rd()); + + std::uniform_int_distribution dist; + + UuidLayout uuid; + uuid.low = dist(gen); + uuid.high = dist(gen); + + uuid.reserved = reserved; + uuid.version = version; + + return uuid.Swap(); + } +} \ No newline at end of file diff --git a/app/src/main/cpp/skyline/common/uuid.h b/app/src/main/cpp/skyline/common/uuid.h new file mode 100644 index 00000000..591f8d63 --- /dev/null +++ b/app/src/main/cpp/skyline/common/uuid.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +namespace skyline { + /** + * @brief Contains an RFC4122 BE format UUID + */ + struct UUID { + u128 raw{}; + + /** + * @brief Generates a random version 4 UUID + */ + static UUID GenerateUuidV4(); + + /** + * @brief Checks if a UUID is an invalid nil UUID + */ + bool Valid() { + return raw != 0; + } + + auto operator<=>(const UUID &) const = default; + }; +} \ No newline at end of file