changeset 21833:ed5cbeee2ec7

lib: Add uuid support to guid
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Tue, 07 Mar 2017 13:32:15 +0200
parents a20bb72327c7
children 9b6003344c25
files src/lib/guid.c src/lib/guid.h src/lib/test-guid.c
diffstat 3 files changed, 62 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/guid.c	Thu Mar 23 14:09:01 2017 +0200
+++ b/src/lib/guid.c	Tue Mar 07 13:32:15 2017 +0200
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "ioloop.h"
 #include "buffer.h"
+#include "str.h"
 #include "sha1.h"
 #include "hash.h"
 #include "hex-binary.h"
@@ -132,3 +133,42 @@
 {
 	return memcmp(guid1, guid2, GUID_128_SIZE);
 }
+
+const char *guid_128_to_uuid_string(const guid_128_t guid, enum uuid_format format)
+{
+	switch(format) {
+	case FORMAT_COMPACT:
+		return guid_128_to_string(guid);
+	case FORMAT_RECORD:
+		return t_strdup_printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+				guid[0], guid[1], guid[2], guid[3], guid[4],
+				guid[5], guid[6], guid[7], guid[8], guid[9],
+				guid[10], guid[11], guid[12], guid[13], guid[14],
+				guid[15]);
+	case FORMAT_MICROSOFT:
+		return t_strdup_printf("{%s}", guid_128_to_uuid_string(guid, FORMAT_RECORD));
+	}
+	i_unreached();
+}
+
+int guid_128_from_uuid_string(const char *str, guid_128_t guid_r)
+{
+	size_t i,len,m=0;
+	int ret;
+	T_BEGIN {
+		len = strlen(str);
+		string_t *str2 = t_str_new(len);
+		for(i=0; i < len; i++) {
+			/* Microsoft format */
+			if (i==0 && str[i] == '{') { m=1; continue; }
+			else if (i == len-1 && str[i] == '}') continue;
+			/* 8-4-4-4-12 */
+			if (((i==8+m) || (i==13+m) || (i==18+m) || (i==23+m)) &&
+			    str[i] == '-') continue;
+			str_append_c(str2, str[i]);
+		}
+		ret = guid_128_from_string(str_c(str2), guid_r);
+	} T_END;
+
+	return ret;
+}
--- a/src/lib/guid.h	Thu Mar 23 14:09:01 2017 +0200
+++ b/src/lib/guid.h	Tue Mar 07 13:32:15 2017 +0200
@@ -8,6 +8,11 @@
 
 ARRAY_DEFINE_TYPE(guid_128_t, guid_128_t);
 
+enum uuid_format {
+	FORMAT_RECORD,
+	FORMAT_COMPACT,
+	FORMAT_MICROSOFT,
+};
 /* Generate a GUID (contains host name) */
 const char *guid_generate(void);
 /* Generate 128 bit GUID */
@@ -31,6 +36,11 @@
 /* Parse GUID from a string. Returns 0 if ok, -1 if GUID isn't valid. */
 int guid_128_from_string(const char *str, guid_128_t guid_r);
 
+/* Returns GUID as a UUID hex string. */
+const char *guid_128_to_uuid_string(const guid_128_t guid, enum uuid_format format);
+/* Parse GUID from a UUID string. Returns 0 if ok, -1 if UIID isn't valid. */
+int guid_128_from_uuid_string(const char *str, guid_128_t guid_r);
+
 /* guid_128 hash/cmp functions for hash.h */
 unsigned int guid_128_hash(const guid_128_t guid) ATTR_PURE;
 int guid_128_cmp(const guid_128_t guid1, const guid_128_t guid2) ATTR_PURE;
--- a/src/lib/test-guid.c	Thu Mar 23 14:09:01 2017 +0200
+++ b/src/lib/test-guid.c	Tue Mar 07 13:32:15 2017 +0200
@@ -77,5 +77,17 @@
 	test_assert(guid_128_from_string(guidbuf, guid3) < 0);
 	guidbuf[0] = ' ';
 	test_assert(guid_128_from_string(guidbuf, guid3) < 0);
+
+	test_assert(guid_128_from_uuid_string("fee0ceac-0327-11e7-ad39-52540078f374", guid3) == 0);
+	test_assert(guid_128_from_uuid_string("fee0ceac032711e7ad3952540078f374", guid2) == 0);
+	test_assert(guid_128_cmp(guid3, guid2) == 0);
+	test_assert(guid_128_from_uuid_string("{fee0ceac-0327-11e7-ad39-52540078f374}", guid2) == 0);
+	test_assert(guid_128_cmp(guid3, guid2) == 0);
+	test_assert(strcmp(guid_128_to_uuid_string(guid3, FORMAT_RECORD), "fee0ceac-0327-11e7-ad39-52540078f374")==0);
+	test_assert(strcmp(guid_128_to_uuid_string(guid3, FORMAT_COMPACT), "fee0ceac032711e7ad3952540078f374")==0);
+	test_assert(strcmp(guid_128_to_uuid_string(guid3, FORMAT_MICROSOFT), "{fee0ceac-0327-11e7-ad39-52540078f374}")==0);
+	/* failure test */
+	test_assert(guid_128_from_uuid_string("fe-e0ceac-0327-11e7-ad39-52540078f374", guid3) < 0);
+
 	test_end();
 }