Add uuid methods to create canonical representation
To enable UUIDs to be printed in canonical form, this commit adds
functions to generate a canonical string from UUID octets in either
standard octet order or GUID octet order.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I43fb5cf82c11cb092ce8497568d6b84cdffaae9b
diff --git a/components/common/uuid/test/uuid_tests.cpp b/components/common/uuid/test/uuid_tests.cpp
index 9a278a6..a568a88 100644
--- a/components/common/uuid/test/uuid_tests.cpp
+++ b/components/common/uuid/test/uuid_tests.cpp
@@ -156,4 +156,26 @@
uuid_guid_octets_from_canonical(&uuid, "00000000-0000-0000-0000-000000000003");
CHECK_FALSE(uuid_is_nil(uuid.octets));
+}
+
+TEST(UuidTests, roundTrip) {
+
+ /* A valid UUID using lower-case */
+ const char *uuid_text = "d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0";
+ CHECK_TRUE(uuid_is_valid(uuid_text));
+
+ struct uuid_octets uuid;
+ struct uuid_canonical canonical_uuid;
+
+ /* Round trip using standard octet order */
+ uuid_octets_from_canonical(&uuid, uuid_text);
+ uuid_canonical_from_octets(&canonical_uuid, &uuid);
+
+ MEMCMP_EQUAL(uuid_text, canonical_uuid.characters, sizeof(canonical_uuid.characters));
+
+ /* Round trip using GUID octet order */
+ uuid_guid_octets_from_canonical(&uuid, uuid_text);
+ uuid_canonical_from_guid_octets(&canonical_uuid, &uuid);
+
+ MEMCMP_EQUAL(uuid_text, canonical_uuid.characters, sizeof(canonical_uuid.characters));
}
\ No newline at end of file
diff --git a/components/common/uuid/uuid.c b/components/common/uuid/uuid.c
index 7bf33ed..6d26cfa 100644
--- a/components/common/uuid/uuid.c
+++ b/components/common/uuid/uuid.c
@@ -23,6 +23,20 @@
return nibble;
}
+static char nibble_to_hex(uint8_t nibble)
+{
+ char hex;
+
+ nibble &= 0x0f;
+
+ if (nibble <= 9)
+ hex = '0' + nibble;
+ else
+ hex = 'a' + nibble - 10;
+
+ return hex;
+}
+
static uint8_t hex_to_byte(const char *hex)
{
/* Takes a validated input and returns the byte value */
@@ -35,7 +49,7 @@
{
size_t valid_chars = 0;
- /* Note that a vaild canonical uuid may be part of a longer string
+ /* Note that a valid canonical uuid may be part of a longer string
* such as a urn.
*/
size_t input_len = strnlen(canonical_form, UUID_CANONICAL_FORM_LEN);
@@ -195,3 +209,38 @@
assert(valid_chars == UUID_CANONICAL_FORM_LEN);
}
+
+void uuid_canonical_from_octets(struct uuid_canonical *canonical_form,
+ const struct uuid_octets *uuid_octets)
+{
+ unsigned int octet_index = 0;
+ unsigned int char_index = 0;
+
+ while (octet_index < UUID_OCTETS_LEN) {
+
+ canonical_form->characters[char_index++] =
+ nibble_to_hex(uuid_octets->octets[octet_index] >> 4);
+
+ canonical_form->characters[char_index++] =
+ nibble_to_hex(uuid_octets->octets[octet_index] & 0x0f);
+
+ ++octet_index;
+
+ if ((octet_index == 4) ||
+ (octet_index == 6) ||
+ (octet_index == 8) ||
+ (octet_index == 10))
+ canonical_form->characters[char_index++] = '-';
+ }
+
+ canonical_form->characters[char_index] = '\0';
+}
+
+void uuid_canonical_from_guid_octets(struct uuid_canonical *canonical_form,
+ const struct uuid_octets *uuid_octets)
+{
+ struct uuid_octets reversed_octets;
+
+ uuid_reverse_octets(uuid_octets, reversed_octets.octets, sizeof(reversed_octets.octets));
+ uuid_canonical_from_octets(canonical_form, &reversed_octets);
+}
diff --git a/components/common/uuid/uuid.h b/components/common/uuid/uuid.h
index 33921ee..4333ad2 100644
--- a/components/common/uuid/uuid.h
+++ b/components/common/uuid/uuid.h
@@ -101,6 +101,19 @@
void uuid_guid_octets_from_canonical(struct uuid_octets *uuid_octets,
const char *canonical_form);
+/*
+ * Converts an octet representation in standard byte order to a canonical string.
+ */
+void uuid_canonical_from_octets(struct uuid_canonical *canonical_form,
+ const struct uuid_octets *uuid_octets);
+
+/*
+ * Converts an octet representation in GUID byte order to a canonical string.
+ */
+void uuid_canonical_from_guid_octets(struct uuid_canonical *canonical_form,
+ const struct uuid_octets *uuid_octets);
+
+
#ifdef __cplusplus
}
#endif