#include "uuid.h" #include #include #include #include #include #include #include #include static struct b_dsref_type uuid_type = { .t_name = "corelib::uuid", .t_flags = B_DSREF_FUNDAMENTAL, .t_id = B_DSREF_TYPE_UUID, .t_instance_size = sizeof(struct b_uuid), }; struct b_uuid *b_uuid_create(void) { struct b_uuid *out = (struct b_uuid *)b_dsref_type_instantiate(&uuid_type); if (!out) { return NULL; } return out; } struct b_uuid *b_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, unsigned char u12, unsigned char u13, unsigned char u14, unsigned char u15) { struct b_uuid *uuid = b_uuid_create(); if (!uuid) { return NULL; } uuid->uuid_bytes.uuid_bytes[0] = u00; uuid->uuid_bytes.uuid_bytes[1] = u01; uuid->uuid_bytes.uuid_bytes[2] = u02; uuid->uuid_bytes.uuid_bytes[3] = u03; uuid->uuid_bytes.uuid_bytes[4] = u04; uuid->uuid_bytes.uuid_bytes[5] = u05; uuid->uuid_bytes.uuid_bytes[6] = u06; uuid->uuid_bytes.uuid_bytes[7] = u07; uuid->uuid_bytes.uuid_bytes[8] = u08; uuid->uuid_bytes.uuid_bytes[9] = u09; uuid->uuid_bytes.uuid_bytes[10] = u10; uuid->uuid_bytes.uuid_bytes[11] = u11; uuid->uuid_bytes.uuid_bytes[12] = u12; uuid->uuid_bytes.uuid_bytes[13] = u13; uuid->uuid_bytes.uuid_bytes[14] = u14; uuid->uuid_bytes.uuid_bytes[15] = u15; return uuid; } struct b_uuid *b_uuid_create_from_bytev(const unsigned char bytes[B_UUID_NBYTES]) { struct b_uuid *uuid = b_uuid_create(); if (!uuid) { return NULL; } memcpy(uuid->uuid_bytes.uuid_bytes, bytes, B_UUID_NBYTES); return uuid; } struct b_uuid *b_uuid_create_from_uuid_bytes(const struct b_uuid_bytes *bytes) { return b_uuid_create_from_bytev(bytes->uuid_bytes); } struct b_uuid *b_uuid_create_from_string(const struct b_string *string) { return b_uuid_create_from_cstr(b_string_ptr(string)); } struct b_uuid *b_uuid_create_from_cstr(const char *str) { struct b_uuid_bytes bytes; bool valid = true; bool is_guid = false; if (*str == '{') { is_guid = true; str++; } size_t i, byte = 0; for (i = 0; str[i] && byte < B_UUID_NBYTES;) { 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; } } if (str[i] != '\0' || byte != B_UUID_NBYTES) { valid = false; } if (!valid) { return NULL; } return b_uuid_create_from_uuid_bytes(&bytes); } b_status b_uuid_to_string(const struct b_uuid *uuid, struct b_string *out) { char str[B_UUID_STRING_MAX]; b_uuid_to_cstr(uuid, str); b_string_append_cstr(out, str); return B_SUCCESS; } b_status b_uuid_to_cstr(const struct b_uuid *uuid, char out[B_UUID_STRING_MAX]) { snprintf( out, B_UUID_STRING_MAX, "%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]); return B_SUCCESS; } b_status b_uuid_to_stringstream( const struct b_uuid *uuid, struct b_stringstream *out) { char str[B_UUID_STRING_MAX]; b_uuid_to_cstr(uuid, str); b_stringstream_add(out, str); return B_SUCCESS; } void b_uuid_get_bytes(const struct b_uuid *uuid, unsigned char bytes[B_UUID_NBYTES]) { memcpy(bytes, uuid->uuid_bytes.uuid_bytes, B_UUID_NBYTES); } void b_uuid_get_uuid_bytes(const struct b_uuid *uuid, struct b_uuid_bytes *bytes) { memcpy(bytes, &uuid->uuid_bytes, sizeof *bytes); } struct b_uuid_bytes *b_uuid_ptr(struct b_uuid *uuid) { return &uuid->uuid_bytes; } b_dsref_type_id b_uuid_type_id(void) { return (b_dsref_type_id)&uuid_type; }