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/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);
+}