#include #include #include #include #include #include #include /*** PRIVATE DATA *************************************************************/ struct b_uuid_p { union b_uuid_bytes uuid_bytes; }; /*** PRIVATE FUNCTIONS ********************************************************/ static b_status uuid_to_cstr( const struct b_uuid_p *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; } static void uuid_get_bytes( const struct b_uuid_p *uuid, unsigned char bytes[B_UUID_NBYTES]) { memcpy(bytes, uuid->uuid_bytes.uuid_bytes, B_UUID_NBYTES); } static void uuid_get_uuid_bytes( const struct b_uuid_p *uuid, union b_uuid_bytes *bytes) { memcpy(bytes, &uuid->uuid_bytes, sizeof *bytes); } static union b_uuid_bytes *uuid_ptr(struct b_uuid_p *uuid) { return &uuid->uuid_bytes; } /*** PUBLIC FUNCTIONS *********************************************************/ 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) { b_uuid *uuid = b_uuid_create(); if (!uuid) { return NULL; } struct b_uuid_p *p = b_object_get_private(uuid, B_TYPE_UUID); 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; return uuid; } b_uuid *b_uuid_create_from_bytev(const unsigned char bytes[B_UUID_NBYTES]) { b_uuid *uuid = b_uuid_create(); if (!uuid) { return NULL; } struct b_uuid_p *p = b_object_get_private(uuid, B_TYPE_UUID); memcpy(p->uuid_bytes.uuid_bytes, bytes, B_UUID_NBYTES); return uuid; } b_uuid *b_uuid_create_from_cstr(const char *str) { union 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_cstr(const b_uuid *uuid, char out[B_UUID_STRING_MAX]) { B_CLASS_DISPATCH_STATIC(B_TYPE_UUID, uuid_to_cstr, uuid, out); } void b_uuid_get_bytes(const b_uuid *uuid, unsigned char bytes[B_UUID_NBYTES]) { B_CLASS_DISPATCH_STATIC(B_TYPE_UUID, uuid_get_bytes, uuid, bytes); } void b_uuid_get_uuid_bytes(const b_uuid *uuid, union b_uuid_bytes *bytes) { B_CLASS_DISPATCH_STATIC(B_TYPE_UUID, uuid_get_uuid_bytes, uuid, bytes); } union b_uuid_bytes *b_uuid_ptr(b_uuid *uuid) { B_CLASS_DISPATCH_STATIC_0(B_TYPE_UUID, uuid_ptr, uuid); } /*** PUBLIC ALIAS FUNCTIONS ***************************************************/ b_uuid *b_uuid_create_from_uuid_bytes(const union b_uuid_bytes *bytes) { return b_uuid_create_from_bytev(bytes->uuid_bytes); } b_uuid *b_uuid_create_from_string(const b_string *string) { return b_uuid_create_from_cstr(b_string_ptr(string)); } /*** VIRTUAL FUNCTIONS ********************************************************/ static void uuid_init(b_object *obj, void *priv) { struct b_uuid_p *uuid = priv; } static void uuid_fini(b_object *obj, void *priv) { struct b_uuid_p *uuid = priv; } static void uuid_to_string(const b_object *uuid, b_stream *out) { char str[B_UUID_STRING_MAX]; b_uuid_to_cstr(uuid, str); b_stream_write_string(out, str, NULL); } /*** CLASS DEFINITION *********************************************************/ B_TYPE_CLASS_DEFINITION_BEGIN(b_uuid) B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT) B_INTERFACE_ENTRY(to_string) = uuid_to_string; B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT) B_TYPE_CLASS_DEFINITION_END(b_uuid) B_TYPE_DEFINITION_BEGIN(b_uuid) B_TYPE_ID(0x17037068, 0x92f7, 0x4582, 0xad1f, 0x0dea43b628de); B_TYPE_CLASS(b_uuid_class); B_TYPE_INSTANCE_PRIVATE(struct b_uuid_p); B_TYPE_INSTANCE_INIT(uuid_init); B_TYPE_INSTANCE_FINI(uuid_fini); B_TYPE_DEFINITION_END(b_uuid)