Add a UUID struct for holding and generating RFC4122 UUIDs

Time uses UUIDs for clock identification.
This commit is contained in:
Billy Laws 2021-02-13 12:53:17 +00:00 committed by ◱ Mark
parent 937e3d6f68
commit a0f6cc161c
3 changed files with 104 additions and 0 deletions

View File

@ -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

View File

@ -0,0 +1,76 @@
#include <random>
#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<u8, 6> 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 <u64> dist;
UuidLayout uuid;
uuid.low = dist(gen);
uuid.high = dist(gen);
uuid.reserved = reserved;
uuid.version = version;
return uuid.Swap();
}
}

View File

@ -0,0 +1,27 @@
#pragma once
#include <compare>
#include <common.h>
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;
};
}