diff options
| author | Stefan Boberg <[email protected]> | 2021-08-18 13:03:33 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-08-18 13:03:33 +0200 |
| commit | b7d5adf55ccbb0588a62aeacac0c133756729edd (patch) | |
| tree | a76fac18b44202baa92c5dd6605440880e37891d /zencore/uid.cpp | |
| parent | Added ToNetworkOrder() functions (diff) | |
| download | zen-b7d5adf55ccbb0588a62aeacac0c133756729edd.tar.xz zen-b7d5adf55ccbb0588a62aeacac0c133756729edd.zip | |
Cleaned up ObjectId generation and made it portable
Diffstat (limited to 'zencore/uid.cpp')
| -rw-r--r-- | zencore/uid.cpp | 102 |
1 files changed, 16 insertions, 86 deletions
diff --git a/zencore/uid.cpp b/zencore/uid.cpp index 347333445..b22ac7896 100644 --- a/zencore/uid.cpp +++ b/zencore/uid.cpp @@ -2,16 +2,13 @@ #include <zencore/uid.h> +#include <zencore/endian.h> #include <zencore/string.h> -#if _WIN32 -# include <zencore/windows.h> -# include <bcrypt.h> -# pragma comment(lib, "bcrypt.lib") -#endif - #include <atomic> #include <bit> +#include <chrono> +#include <random> #include <set> #include <unordered_map> @@ -21,59 +18,10 @@ namespace zen { ////////////////////////////////////////////////////////////////////////// -template<typename T> -T -EndianSwap(T value) -{ - uint8_t dest[sizeof value]; - - memcpy(dest, &value, sizeof value); - - for (int i = 0; i < sizeof(value); i++) - { - uint8_t& other = dest[sizeof(value) - i - 1]; - - uint8_t temp = dest[i]; - dest[i] = other; - other = temp; - } - - T ret; - - memcpy(&ret, &value, sizeof value); - - return ret; -} - -#if _WIN32 -__forceinline uint16_t -EndianSwap(uint16_t value) -{ - return _byteswap_ushort(value); -} - -__forceinline uint32_t -EndianSwap(uint32_t value) -{ - return _byteswap_ulong(value); -} - -__forceinline uint64_t -EndianSwap(uint64_t value) -{ - return _byteswap_uint64(value); -} -#endif - -////////////////////////////////////////////////////////////////////////// - namespace detail { static bool OidInitialised; static uint32_t RunId; static std::atomic_uint32_t Serial; - - // Number of 100 nanosecond units from 1/1/1601 to 1/1/1970 - used for Windows impl - constexpr int64_t kEpochBias = 116'444'736'000'000'000ull; } // namespace detail ////////////////////////////////////////////////////////////////////////// @@ -84,48 +32,30 @@ const Oid Oid::Max = {{~0u, ~0u, ~0u}}; void Oid::Initialize() { - using namespace detail; - - if (OidInitialised) - return; - - OidInitialised = true; - -#if _WIN32 - char rng[8]; - BCryptGenRandom(NULL, (PUCHAR)rng, sizeof rng, BCRYPT_USE_SYSTEM_PREFERRED_RNG); + if (!detail::OidInitialised) + { + std::random_device Rng; + detail::RunId = Rng(); + detail::Serial = Rng(); - memcpy(&RunId, &rng[0], sizeof(RunId)); - memcpy((void*)&Serial, &rng[4], sizeof(Serial)); -#else -# error Must implement Oid::Initialize -#endif + detail::OidInitialised = true; + } } const Oid& Oid::Generate() { - using namespace detail; - - if (!OidInitialised) + if (!detail::OidInitialised) { Oid::Initialize(); } -#if _WIN32 - FILETIME filetime; - - GetSystemTimeAsFileTime(&filetime); // Time is UTC - - uint64_t filetime64; - memcpy(&filetime64, &filetime, sizeof filetime); + const uint64_t kOffset = 1'609'459'200; // Seconds from 1970 -> 2021 + const uint64_t Time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) - kOffset; - OidBits[0] = EndianSwap(uint32_t((filetime64 - kEpochBias) / 10'000'000l)); - OidBits[1] = EndianSwap(uint32_t(Serial++)); - OidBits[2] = RunId; -#else -# error Must implement Oid::Generate -#endif + OidBits[0] = ToNetworkOrder(uint32_t(Time)); + OidBits[1] = ToNetworkOrder(uint32_t(++detail::Serial)); + OidBits[2] = detail::RunId; return *this; } |