// vim:fileencoding=utf-8:foldmethod=marker #include "uuid.h" #include "../common/aliases/aliases.h" #include "../common/assert/assert.h" #include "../base/strings/str8/str8.h" #include "../prng/xorshift/xorshift.h" #include #define UUID_STR_FORMAT ("%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.12" PRIx64) typedef struct UUID4 UUID4; struct UUID4 { u64 high; u64 low; }; wapp_intern UUID4 generate_uuid4(void); wapp_intern void uuid4_to_uuid(const UUID4* uuid4, WUUID *uuid); WUUID *wapp_uuid_init_uuid4(WUUID *uuid) { wapp_debug_assert(uuid != NULL, "`uuid` should not be NULL"); UUID4 uuid4 = generate_uuid4(); uuid4_to_uuid(&uuid4, uuid); return uuid; } wapp_intern UUID4 generate_uuid4(void) { wapp_persist XOR256State state = {0}; wapp_persist b8 initialised = false; if (!initialised) { initialised = true; state = wapp_prng_xorshift_init_state(); } UUID4 uuid = (UUID4){ .high = wapp_prng_xorshift_256(&state), .low = wapp_prng_xorshift_256(&state), }; uuid.high = (uuid.high & 0xffffffffffff0fff) | 0x0000000000004000; uuid.low = (uuid.low & 0x3fffffffffffffff) | 0x8000000000000000; return uuid; } wapp_intern void uuid4_to_uuid(const UUID4* uuid4, WUUID *uuid) { u64 group1 = uuid4->high >> 32; u64 group2 = (uuid4->high << 32) >> 48; u64 group3 = (uuid4->high << 48) >> 48; u64 group4 = uuid4->low >> 48; u64 group5 = (uuid4->low << 16) >> 16; wapp_str8_format(&(uuid->uuid), UUID_STR_FORMAT, group1, group2, group3, group4, group5); }