Index: ossp-pkg/uuid/uuid.c RCS File: /v/ossp/cvs/ossp-pkg/uuid/Attic/uuid.c,v rcsdiff -q -kk '-r1.4' '-r1.5' -u '/v/ossp/cvs/ossp-pkg/uuid/Attic/uuid.c,v' 2>/dev/null --- uuid.c 2004/01/09 09:06:25 1.4 +++ uuid.c 2004/01/09 11:28:56 1.5 @@ -32,6 +32,7 @@ #include #include #include +#include #include "config.h" #include "uuid.h" @@ -92,7 +93,14 @@ #error unexpected: no type found for uuid_uint32_t #endif -/* private data type declaration */ +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE !FALSE +#endif + +/* UUID binary representation according to UUID standards */ struct uuid_st { uuid_uint32_t time_low; uuid_uint16_t time_mid; @@ -104,39 +112,41 @@ uuid_rc_t uuid_create(uuid_t **uuid) { + /* argument sanity check */ if (uuid == NULL) return UUID_RC_ARG; + + /* allocate UUID binary representation buffer */ if ((*uuid = (uuid_t *)malloc(sizeof(uuid_t))) == NULL) return UUID_RC_MEM; - uuid_null(*uuid); + + /* set initially to "nil UUID" */ + uuid_nil(*uuid); + return UUID_RC_OK; } uuid_rc_t uuid_destroy(uuid_t *uuid) { + /* argument sanity check */ if (uuid == NULL) return UUID_RC_ARG; + + /* free UUID binary representation buffer */ free(uuid); + return UUID_RC_OK; } -uuid_rc_t uuid_null(uuid_t *uuid) +uuid_rc_t uuid_nil(uuid_t *uuid) { + /* argument sanity check */ if (uuid == NULL) return UUID_RC_ARG; - memset(uuid, '\0', sizeof(uuid_t)); - return UUID_RC_OK; -} -uuid_rc_t uuid_generate(uuid_t *uuid, unsigned int mode, ...) -{ - va_list ap; + /* clear all octets to create "nil UUID" */ + memset(uuid, '\0', sizeof(uuid_t)); - if (uuid == NULL) - return UUID_RC_ARG; - va_start(ap, mode); - /* FIXME */ - va_end(ap); return UUID_RC_OK; } @@ -144,112 +154,268 @@ { int r; + /* argument sanity check */ if (result == NULL) return UUID_RC_ARG; - /* deal with NULL or equal pointers. */ - if (a == b) { - *result = 0; - return UUID_RC_OK; - } - if (a == NULL && b == NULL) { - *result = 0; - return UUID_RC_OK; - } - if (a == NULL) { - *result = ((uuid_isnil(b, &r), r) ? 0 : -1); - return UUID_RC_OK; - } - if (b == NULL) { - *result = ((uuid_isnil(a, &r), r) ? 0 : 1); - return UUID_RC_OK; - } + /* convinience macro for setting result */ +# define RESULT(r) \ + do { \ + *result = (r); \ + goto result_exit; \ + } while (0) + + /* special cases: NULL or equal UUIDs */ + if (a == b) + RESULT(0); + if (a == NULL && b == NULL) + RESULT(0); + if (a == NULL) + RESULT((uuid_isnil(b, &r), r) ? 0 : -1); + if (b == NULL) + RESULT((uuid_isnil(a, &r), r) ? 0 : 1); + + /* standard cases: regular different UUIDs */ + if (a->time_low != b->time_low) + RESULT((a->time_low < b->time_low) ? -1 : 1); + if ((r = (int)a->time_mid + - (int)b->time_mid) != 0) + RESULT((r < 0) ? -1 : 1); + if ((r = (int)a->time_hi_and_version + - (int)b->time_hi_and_version) != 0) + RESULT((r < 0) ? -1 : 1); + if ((r = (int)a->clock_seq_hi_and_reserved + - (int)b->clock_seq_hi_and_reserved) != 0) + RESULT((r < 0) ? -1 : 1); + if ((r = (int)a->clock_seq_low + - (int)b->clock_seq_low) != 0) + RESULT((r < 0) ? -1 : 1); + if ((r = memcmp(a->node, b->node, sizeof(a->node))) != 0) + RESULT((r < 0) ? -1 : 1); - /* we have to compare the hard way. */ - if (a->time_low != b->time_low) { - *result = ((a->time_low < b->time_low) ? -1 : 1); - return UUID_RC_OK; - } - if ((r = (int)a->time_mid - (int)b->time_mid) != 0) { - *result = ((r < 0) ? -1 : 1); - return UUID_RC_OK; - } - if ((r = (int)a->time_hi_and_version - (int)b->time_hi_and_version) != 0) { - *result = ((r < 0) ? -1 : 1); - return UUID_RC_OK; - } - if ((r = (int)a->clock_seq_hi_and_reserved - (int)b->clock_seq_hi_and_reserved) != 0) { - *result = ((r < 0) ? -1 : 1); - return UUID_RC_OK; - } - if ((r = (int)a->clock_seq_low - (int)b->clock_seq_low) != 0) { - *result = ((r < 0) ? -1 : 1); - return UUID_RC_OK; - } - if ((r = memcmp(a->node, b->node, sizeof(a->node))) != 0) { - *result = ((r < 0) ? -1 : 1); - return UUID_RC_OK; - } - - /* else the keys are equal */ + /* default case: the keys are equal */ *result = 0; + + result_exit: return UUID_RC_OK; } uuid_rc_t uuid_isnil(uuid_t *uuid, int *result) { + const unsigned char *ucp; + int i; + + /* sanity check argument(s) */ if (uuid == NULL || result == NULL) return UUID_RC_ARG; - *result = 0; - if ( uuid->time_low == 0 - && uuid->time_mid == 0 - && uuid->time_hi_and_version == 0 - && uuid->clock_seq_hi_and_reserved == 0 - && uuid->clock_seq_low == 0 - && uuid->node[0] == 0 - && uuid->node[1] == 0 - && uuid->node[2] == 0 - && uuid->node[3] == 0 - && uuid->node[4] == 0 - && uuid->node[5] == 0) - *result = 1; + + /* a "nil UUID" is defined as all octets zero, so check for this case */ + *result = TRUE; + for (i = 0, ucp = (unsigned char *)uuid; i < UUID_LEN_BIN; i++) { + if (*ucp++ != '\0') { + *result = FALSE; + break; + } + } + return UUID_RC_OK; } -uuid_rc_t uuid_parse(uuid_t *uuid, const char *str) +uuid_rc_t uuid_unpack(uuid_t *uuid, const void *buf) { - if (uuid == NULL) + const uuid_uint8_t *in; + uuid_uint32_t tmp32; + uuid_uint16_t tmp16; + int i; + + /* sanity check argument(s) */ + if (uuid == NULL || buf == NULL) return UUID_RC_ARG; - /* FIXME */ + + /* treat input buffer as octet stream */ + in = (const uuid_uint8_t *)buf; + + /* unpack "time_low" field */ + tmp32 = *in++; + tmp32 = (tmp32 << 8) | *in++; + tmp32 = (tmp32 << 8) | *in++; + tmp32 = (tmp32 << 8) | *in++; + uuid->time_low = tmp32; + + /* unpack "time_mid" field */ + tmp16 = *in++; + tmp16 = (tmp16 << 8) | *in++; + uuid->time_mid = tmp16; + + /* unpack "time_hi_and_version" field */ + tmp16 = *in++; + tmp16 = (tmp16 << 8) | *in++; + uuid->time_hi_and_version = tmp16; + + /* unpack "clock_seq_hi_and_reserved" field */ + uuid->clock_seq_hi_and_reserved = *in++; + + /* unpack "clock_seq_low" field */ + uuid->clock_seq_low = *in++; + + /* unpack "node" field */ + for (i = 0; i < sizeof(uuid->node); i++) + uuid->node[i] = *in++; + return UUID_RC_OK; } -uuid_rc_t uuid_format(uuid_t *uuid, char **str) +uuid_rc_t uuid_pack(uuid_t *uuid, void **buf) { + uuid_uint8_t *out; + uuid_uint32_t tmp32; + uuid_uint16_t tmp16; + int i; + + /* sanity check argument(s) */ + if (uuid == NULL || buf == NULL) + return UUID_RC_ARG; + + /* optionally allocate octet buffer */ + if (*buf == NULL) + if ((*buf = malloc(sizeof(uuid_t))) == NULL) + return UUID_RC_MEM; + + /* treat output buffer as octet stream */ + out = (uuid_uint8_t *)(*buf); + + /* pack "time_low" field */ + tmp32 = uuid->time_low; + out[3] = (uuid_uint8_t)(tmp32 & 0xff); tmp32 >>= 8; + out[2] = (uuid_uint8_t)(tmp32 & 0xff); tmp32 >>= 8; + out[1] = (uuid_uint8_t)(tmp32 & 0xff); tmp32 >>= 8; + out[0] = (uuid_uint8_t)(tmp32 & 0xff); + + /* pack "time_mid" field */ + tmp16 = uuid->time_mid; + out[5] = (uuid_uint8_t)(tmp16 & 0xff); tmp16 >>= 8; + out[4] = (uuid_uint8_t)(tmp16 & 0xff); + + /* pack "time_hi_and_version" field */ + tmp16 = uuid->time_hi_and_version; + out[7] = (uuid_uint8_t)(tmp16 & 0xff); tmp16 >>= 8; + out[6] = (uuid_uint8_t)(tmp16 & 0xff); + + /* pack "clock_seq_hi_and_reserved" field */ + out[8] = uuid->clock_seq_hi_and_reserved; + + /* pack "clock_seq_low" field */ + out[9] = uuid->clock_seq_low; + + /* pack "node" field */ + for (i = 0; i < sizeof(uuid->node); i++) + out[10+i] = uuid->node[i]; + + return UUID_RC_OK; +} + +uuid_rc_t uuid_parse(uuid_t *uuid, const char *str) +{ + uuid_t uuid_tmp; + uuid_uint16_t tmp16; + const char *cp; + char hexbuf[3]; + int i; + + /* sanity check argument(s) */ if (uuid == NULL || str == NULL) return UUID_RC_ARG; - /* FIXME */ + + /* + * pass 1: check UUID string representation syntax + * example reference: + * f81d4fae-7dec-11d0-a765-00a0c91e6bf6 + * 012345678901234567890123456789012345 + * 0 1 2 3 + */ + if (strlen(str) != UUID_LEN_STR) + return UUID_RC_ARG; + for (i = 0, cp = str; i <= UUID_LEN_STR; i++, cp++) { + if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) { + if (*cp == '-') + continue; + else + return -1; + } + if (i == UUID_LEN_STR) + if (*cp == '\0') + continue; + if (!isxdigit(*cp)) + return UUID_RC_ARG; + } + + /* + * pass 2: parse hex values of string representation syntax + */ + uuid_tmp.time_low = (uuid_uint32_t)strtoul(str, NULL, 16); + uuid_tmp.time_mid = (uuid_uint16_t)strtoul(str+9, NULL, 16); + uuid_tmp.time_hi_and_version = (uuid_uint16_t)strtoul(str+14, NULL, 16); + tmp16 = (uuid_uint16_t)strtoul(str+19, NULL, 16); + uuid_tmp.clock_seq_low = (uuid_uint8_t)(tmp16 & 0xff); tmp16 >>= 8; + uuid_tmp.clock_seq_hi_and_reserved = (uuid_uint8_t)(tmp16 & 0xff); + cp = str+24; + hexbuf[2] = '\0'; + for (i = 0; i < sizeof(uuid_tmp.node); i++) { + hexbuf[0] = *cp++; + hexbuf[1] = *cp++; + uuid_tmp.node[i] = strtoul(hexbuf, NULL, 16); + } + return UUID_RC_OK; } -uuid_rc_t uuid_read(uuid_t *uuid, const void *buf) +uuid_rc_t uuid_unparse(uuid_t *uuid, char **str) { - if (uuid == NULL) + uuid_t uuid_tmp; + + /* sanity check argument(s) */ + if (uuid == NULL || str == NULL) return UUID_RC_ARG; - /* FIXME */ + + /* optionally allocate string buffer */ + if (*str == NULL) + if ((*str = (char *)malloc(UUID_LEN_STR+1)) == NULL) + return UUID_RC_MEM; + + /* format UUID into string representation */ + sprintf(*str, + "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + (unsigned long)uuid_tmp.time_low, + (unsigned int)uuid_tmp.time_mid, + (unsigned int)uuid_tmp.time_hi_and_version, + (unsigned int)uuid_tmp.clock_seq_hi_and_reserved, + (unsigned int)uuid_tmp.clock_seq_low, + (unsigned int)uuid_tmp.node[0], + (unsigned int)uuid_tmp.node[1], + (unsigned int)uuid_tmp.node[2], + (unsigned int)uuid_tmp.node[3], + (unsigned int)uuid_tmp.node[4], + (unsigned int)uuid_tmp.node[5]); + return UUID_RC_OK; } -uuid_rc_t uuid_write(uuid_t *uuid, void **buf) +uuid_rc_t uuid_generate(uuid_t *uuid, unsigned int mode, ...) { - if (uuid == NULL || buf == NULL) + va_list ap; + + /* sanity check argument(s) */ + if (uuid == NULL) return UUID_RC_ARG; + va_start(ap, mode); /* FIXME */ + va_end(ap); return UUID_RC_OK; } uuid_rc_t uuid_dump(uuid_t *uuid, char **str) { + /* sanity check argument(s) */ if (uuid == NULL || str == NULL) return UUID_RC_ARG; /* FIXME */ Index: ossp-pkg/uuid/uuid.h RCS File: /v/ossp/cvs/ossp-pkg/uuid/Attic/uuid.h,v rcsdiff -q -kk '-r1.4' '-r1.5' -u '/v/ossp/cvs/ossp-pkg/uuid/Attic/uuid.h,v' 2>/dev/null --- uuid.h 2004/01/09 09:06:25 1.4 +++ uuid.h 2004/01/09 11:28:56 1.5 @@ -69,7 +69,7 @@ /* encoding octet stream lengths */ #define UUID_LEN_BIN (128 / 8 /*bytes*/) -#define UUID_LEN_STR (128 / 4 /*nibbles*/ + 4 /*hyphens*/ + 1 /*nul*/) +#define UUID_LEN_STR (128 / 4 /*nibbles*/ + 4 /*hyphens*/) /* return codes */ typedef enum { @@ -94,24 +94,22 @@ /* object handling */ extern uuid_rc_t uuid_create (uuid_t **uuid); extern uuid_rc_t uuid_destroy (uuid_t *uuid); -extern uuid_rc_t uuid_null (uuid_t *uuid); +extern uuid_rc_t uuid_nil (uuid_t *uuid); /* UUID comparison */ extern uuid_rc_t uuid_compare (uuid_t *uuid, uuid_t *uuid2, int *result); extern uuid_rc_t uuid_isnil (uuid_t *uuid, int *result); -/* UUID generation */ -extern uuid_rc_t uuid_generate (uuid_t *uuid, unsigned int mode, ...); +/* binary representation handling */ +extern uuid_rc_t uuid_unpack (uuid_t *uuid, const void *buf); +extern uuid_rc_t uuid_pack (uuid_t *uuid, void **buf); /* string representation handling */ extern uuid_rc_t uuid_parse (uuid_t *uuid, const char *str); -extern uuid_rc_t uuid_format (uuid_t *uuid, char **str); +extern uuid_rc_t uuid_unparse (uuid_t *uuid, char **str); -/* binary representation handling */ -extern uuid_rc_t uuid_read (uuid_t *uuid, const void *buf); -extern uuid_rc_t uuid_write (uuid_t *uuid, void **buf); - -/* UUID dumping */ +/* UUID generation and dumping */ +extern uuid_rc_t uuid_generate (uuid_t *uuid, unsigned int mode, ...); extern uuid_rc_t uuid_dump (uuid_t *uuid, char **str); /* error handling */ Index: ossp-pkg/uuid/uuid_cli.c RCS File: /v/ossp/cvs/ossp-pkg/uuid/Attic/uuid_cli.c,v rcsdiff -q -kk '-r1.3' '-r1.4' -u '/v/ossp/cvs/ossp-pkg/uuid/Attic/uuid_cli.c,v' 2>/dev/null --- uuid_cli.c 2004/01/08 21:31:47 1.3 +++ uuid_cli.c 2004/01/09 11:28:56 1.4 @@ -156,8 +156,8 @@ } for (i = 0; i < count; i++) { if (iterate) { - if ((rc = uuid_null(uuid)) != UUID_RC_OK) - error(1, "uuid_null: %s", uuid_error(rc)); + if ((rc = uuid_nil(uuid)) != UUID_RC_OK) + error(1, "uuid_nil: %s", uuid_error(rc)); } if (version == UUID_VERSION3) rc = uuid_generate(uuid, version, argv[0]); @@ -167,15 +167,15 @@ error(1, "uuid_generate: %s", uuid_error(rc)); if (ascii) { cp = NULL; - if ((rc = uuid_format(uuid, &cp)) != UUID_RC_OK) - error(1, "uuid_format: %s", uuid_error(rc)); + if ((rc = uuid_unparse(uuid, &cp)) != UUID_RC_OK) + error(1, "uuid_unparse: %s", uuid_error(rc)); fprintf(fp, "%s\n", cp); free(cp); } else { vp = NULL; - if ((rc = uuid_write(uuid, &vp)) != UUID_RC_OK) - error(1, "uuid_format: %s", uuid_error(rc)); + if ((rc = uuid_unpack(uuid, &vp)) != UUID_RC_OK) + error(1, "uuid_unpack: %s", uuid_error(rc)); fwrite(vp, UUID_LEN_BIN, 1, fp); free(vp); }