Files
fx/ds/uuid.c

228 lines
5.7 KiB
C
Raw Normal View History

2026-03-16 10:35:43 +00:00
#include <fx/core/stringstream.h>
#include <fx/ds/string.h>
#include <fx/ds/uuid.h>
2024-10-24 19:24:54 +01:00
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
2024-10-24 19:24:54 +01:00
2025-10-19 13:10:45 +01:00
/*** PRIVATE DATA *************************************************************/
2026-03-16 10:35:43 +00:00
struct fx_uuid_p {
union fx_uuid_bytes uuid_bytes;
2024-10-24 19:24:54 +01:00
};
2025-10-19 13:10:45 +01:00
/*** PRIVATE FUNCTIONS ********************************************************/
2026-03-16 10:35:43 +00:00
static fx_status uuid_to_cstr(
const struct fx_uuid_p *uuid, char out[FX_UUID_STRING_MAX])
2024-10-24 19:24:54 +01:00
{
2025-10-19 13:10:45 +01:00
snprintf(
2026-03-16 10:35:43 +00:00
out, FX_UUID_STRING_MAX,
2025-10-19 13:10:45 +01:00
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%"
"02x%02x",
uuid->uuid_bytes.uuid_bytes[0], uuid->uuid_bytes.uuid_bytes[1],
uuid->uuid_bytes.uuid_bytes[2], uuid->uuid_bytes.uuid_bytes[3],
uuid->uuid_bytes.uuid_bytes[4], uuid->uuid_bytes.uuid_bytes[5],
uuid->uuid_bytes.uuid_bytes[6], uuid->uuid_bytes.uuid_bytes[7],
uuid->uuid_bytes.uuid_bytes[8], uuid->uuid_bytes.uuid_bytes[9],
uuid->uuid_bytes.uuid_bytes[10], uuid->uuid_bytes.uuid_bytes[11],
uuid->uuid_bytes.uuid_bytes[12], uuid->uuid_bytes.uuid_bytes[13],
uuid->uuid_bytes.uuid_bytes[14], uuid->uuid_bytes.uuid_bytes[15]);
2026-03-16 10:35:43 +00:00
return FX_SUCCESS;
2025-10-19 13:10:45 +01:00
}
static void uuid_get_bytes(
2026-03-16 10:35:43 +00:00
const struct fx_uuid_p *uuid, unsigned char bytes[FX_UUID_NBYTES])
2025-10-19 13:10:45 +01:00
{
2026-03-16 10:35:43 +00:00
memcpy(bytes, uuid->uuid_bytes.uuid_bytes, FX_UUID_NBYTES);
2025-10-19 13:10:45 +01:00
}
2024-10-24 19:24:54 +01:00
2025-10-19 13:10:45 +01:00
static void uuid_get_uuid_bytes(
2026-03-16 10:35:43 +00:00
const struct fx_uuid_p *uuid, union fx_uuid_bytes *bytes)
2025-10-19 13:10:45 +01:00
{
memcpy(bytes, &uuid->uuid_bytes, sizeof *bytes);
2024-10-24 19:24:54 +01:00
}
2026-03-16 10:35:43 +00:00
static union fx_uuid_bytes *uuid_ptr(struct fx_uuid_p *uuid)
2025-10-19 13:10:45 +01:00
{
return &uuid->uuid_bytes;
}
/*** PUBLIC FUNCTIONS *********************************************************/
2026-03-16 10:35:43 +00:00
fx_uuid *fx_uuid_create_from_bytes(
unsigned char u00, unsigned char u01, unsigned char u02,
unsigned char u03, unsigned char u04, unsigned char u05,
unsigned char u06, unsigned char u07, unsigned char u08,
unsigned char u09, unsigned char u10, unsigned char u11,
2024-10-24 19:24:54 +01:00
unsigned char u12, unsigned char u13, unsigned char u14, unsigned char u15)
{
2026-03-16 10:35:43 +00:00
fx_uuid *uuid = fx_uuid_create();
2024-10-24 19:24:54 +01:00
if (!uuid) {
return NULL;
}
2026-03-16 10:35:43 +00:00
struct fx_uuid_p *p = fx_object_get_private(uuid, FX_TYPE_UUID);
2025-10-19 13:10:45 +01:00
p->uuid_bytes.uuid_bytes[0] = u00;
p->uuid_bytes.uuid_bytes[1] = u01;
p->uuid_bytes.uuid_bytes[2] = u02;
p->uuid_bytes.uuid_bytes[3] = u03;
p->uuid_bytes.uuid_bytes[4] = u04;
p->uuid_bytes.uuid_bytes[5] = u05;
p->uuid_bytes.uuid_bytes[6] = u06;
p->uuid_bytes.uuid_bytes[7] = u07;
p->uuid_bytes.uuid_bytes[8] = u08;
p->uuid_bytes.uuid_bytes[9] = u09;
p->uuid_bytes.uuid_bytes[10] = u10;
p->uuid_bytes.uuid_bytes[11] = u11;
p->uuid_bytes.uuid_bytes[12] = u12;
p->uuid_bytes.uuid_bytes[13] = u13;
p->uuid_bytes.uuid_bytes[14] = u14;
p->uuid_bytes.uuid_bytes[15] = u15;
2024-10-24 19:24:54 +01:00
return uuid;
}
2026-03-16 10:35:43 +00:00
fx_uuid *fx_uuid_create_from_bytev(const unsigned char bytes[FX_UUID_NBYTES])
2024-10-24 19:24:54 +01:00
{
2026-03-16 10:35:43 +00:00
fx_uuid *uuid = fx_uuid_create();
2024-10-24 19:24:54 +01:00
if (!uuid) {
return NULL;
}
2026-03-16 10:35:43 +00:00
struct fx_uuid_p *p = fx_object_get_private(uuid, FX_TYPE_UUID);
2024-10-24 19:24:54 +01:00
2026-03-16 10:35:43 +00:00
memcpy(p->uuid_bytes.uuid_bytes, bytes, FX_UUID_NBYTES);
2024-10-24 19:24:54 +01:00
2025-10-19 13:10:45 +01:00
return uuid;
2024-10-24 19:24:54 +01:00
}
2026-03-16 10:35:43 +00:00
fx_uuid *fx_uuid_create_from_cstr(const char *str)
2024-10-24 19:24:54 +01:00
{
2026-03-16 10:35:43 +00:00
union fx_uuid_bytes bytes;
2024-10-24 19:24:54 +01:00
bool valid = true;
bool is_guid = false;
if (*str == '{') {
is_guid = true;
str++;
}
size_t i, byte = 0;
2026-03-16 10:35:43 +00:00
for (i = 0; str[i] && byte < FX_UUID_NBYTES;) {
2024-10-24 19:24:54 +01:00
if (i == 8 || i == 13 || i == 18 || i == 23) {
if (str[i] != '-') {
valid = false;
break;
}
i++;
continue;
}
char n[3];
n[0] = str[i];
n[1] = str[i + 1];
n[2] = '\0';
if (!isxdigit(n[0]) || !isxdigit(n[1])) {
valid = false;
break;
}
char *p;
unsigned long v = strtoul(n, &p, 16);
bytes.uuid_bytes[byte] = v;
byte++;
i += 2;
}
if (str[i] == '}') {
if (is_guid) {
i++;
} else {
valid = false;
}
}
2026-03-16 10:35:43 +00:00
if (str[i] != '\0' || byte != FX_UUID_NBYTES) {
2024-10-24 19:24:54 +01:00
valid = false;
}
if (!valid) {
return NULL;
}
2026-03-16 10:35:43 +00:00
return fx_uuid_create_from_uuid_bytes(&bytes);
2024-10-24 19:24:54 +01:00
}
2026-03-16 10:35:43 +00:00
fx_status fx_uuid_to_cstr(const fx_uuid *uuid, char out[FX_UUID_STRING_MAX])
2024-10-24 19:24:54 +01:00
{
2026-03-16 10:35:43 +00:00
FX_CLASS_DISPATCH_STATIC(FX_TYPE_UUID, uuid_to_cstr, uuid, out);
2025-10-19 13:10:45 +01:00
}
2024-10-24 19:24:54 +01:00
2026-03-16 10:35:43 +00:00
void fx_uuid_get_bytes(const fx_uuid *uuid, unsigned char bytes[FX_UUID_NBYTES])
2025-10-19 13:10:45 +01:00
{
2026-03-16 10:35:43 +00:00
FX_CLASS_DISPATCH_STATIC(FX_TYPE_UUID, uuid_get_bytes, uuid, bytes);
2024-10-24 19:24:54 +01:00
}
2026-03-16 10:35:43 +00:00
void fx_uuid_get_uuid_bytes(const fx_uuid *uuid, union fx_uuid_bytes *bytes)
2024-10-24 19:24:54 +01:00
{
2026-03-16 10:35:43 +00:00
FX_CLASS_DISPATCH_STATIC(FX_TYPE_UUID, uuid_get_uuid_bytes, uuid, bytes);
2025-10-19 13:10:45 +01:00
}
2026-03-16 10:35:43 +00:00
union fx_uuid_bytes *fx_uuid_ptr(fx_uuid *uuid)
2025-10-19 13:10:45 +01:00
{
2026-03-16 10:35:43 +00:00
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_UUID, uuid_ptr, uuid);
2025-10-19 13:10:45 +01:00
}
/*** PUBLIC ALIAS FUNCTIONS ***************************************************/
2026-03-16 10:35:43 +00:00
fx_uuid *fx_uuid_create_from_uuid_bytes(const union fx_uuid_bytes *bytes)
2025-10-19 13:10:45 +01:00
{
2026-03-16 10:35:43 +00:00
return fx_uuid_create_from_bytev(bytes->uuid_bytes);
2024-10-24 19:24:54 +01:00
}
2026-03-16 10:35:43 +00:00
fx_uuid *fx_uuid_create_from_string(const fx_string *string)
2025-10-19 13:10:45 +01:00
{
2026-03-16 10:35:43 +00:00
return fx_uuid_create_from_cstr(fx_string_ptr(string));
2025-10-19 13:10:45 +01:00
}
/*** VIRTUAL FUNCTIONS ********************************************************/
2026-03-16 10:35:43 +00:00
static void uuid_init(fx_object *obj, void *priv)
2024-10-24 19:24:54 +01:00
{
2026-03-16 10:35:43 +00:00
struct fx_uuid_p *uuid = priv;
2024-10-24 19:24:54 +01:00
}
2026-03-16 10:35:43 +00:00
static void uuid_fini(fx_object *obj, void *priv)
2024-10-24 19:24:54 +01:00
{
2026-03-16 10:35:43 +00:00
struct fx_uuid_p *uuid = priv;
2024-10-24 19:24:54 +01:00
}
2026-03-16 10:35:43 +00:00
static void uuid_to_string(const fx_object *uuid, fx_stream *out)
2024-10-24 19:24:54 +01:00
{
2026-03-16 10:35:43 +00:00
char str[FX_UUID_STRING_MAX];
fx_uuid_to_cstr(uuid, str);
fx_stream_write_string(out, str, NULL);
2024-10-24 19:24:54 +01:00
}
2025-10-19 13:10:45 +01:00
/*** CLASS DEFINITION *********************************************************/
2026-03-16 10:35:43 +00:00
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_uuid)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = uuid_to_string;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
FX_TYPE_CLASS_DEFINITION_END(fx_uuid)
FX_TYPE_DEFINITION_BEGIN(fx_uuid)
FX_TYPE_ID(0x17037068, 0x92f7, 0x4582, 0xad1f, 0x0dea43b628de);
FX_TYPE_CLASS(fx_uuid_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_uuid_p);
FX_TYPE_INSTANCE_INIT(uuid_init);
FX_TYPE_INSTANCE_FINI(uuid_fini);
FX_TYPE_DEFINITION_END(fx_uuid)