Add uuid wrapper API call ast_uuid_generate_str().
authorRichard Mudgett <rmudgett@digium.com>
Thu, 28 Mar 2013 23:59:20 +0000 (23:59 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Thu, 28 Mar 2013 23:59:20 +0000 (23:59 +0000)
* Updated test_uuid.c to test the new API call.

* Made system use the new API call to eliminate "10's of lines" where
used.

* Fixed untested ast_strdup() return in stasis_subscribe() by eliminating
the need for it.  struct stasis_subscription now contains the uniqueid[]
string.

* Fixed some issues in exchangecal_write_event():
  Create uid with enough space for a UUID string to avoid a realloc.
  Fix off by one error if the calendar event provided a UUID string.
  There is no need to check for NULL before calling ast_free().

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@384302 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/uuid.h
main/sorcery.c
main/stasis.c
main/uuid.c
res/res_calendar_exchange.c
res/res_sorcery_config.c
tests/test_uuid.c

index c10268d..223ad18 100644 (file)
@@ -24,7 +24,7 @@
 #define _ASTERISK_UUID_H
 
 /* Size of an RFC 4122 UUID string plus terminating null byte */
-#define AST_UUID_STR_LEN 37
+#define AST_UUID_STR_LEN (36 + 1)
 
 struct ast_uuid;
 
@@ -50,11 +50,22 @@ struct ast_uuid *ast_uuid_generate(void);
  * \param uuid The UUID to convert to a string
  * \param[out] buf The buffer where the UUID string will be stored
  * \param size The size of the buffer. Must be at least AST_UUID_STR_LEN.
- * \returns The UUID string (a pointer to buf)
+ * \return The UUID string (a pointer to buf)
  */
 char *ast_uuid_to_str(const struct ast_uuid *uuid, char *buf, size_t size);
 
 /*!
+ * \brief Generate a UUID string.
+ * \since 12.0.0
+ *
+ * \param buf The buffer where the UUID string will be stored
+ * \param size The size of the buffer. Must be at least AST_UUID_STR_LEN.
+ *
+ * \return The UUID string (a pointer to buf)
+ */
+char *ast_uuid_generate_str(char *buf, size_t size);
+
+/*!
  * \brief Convert a string to a UUID
  *
  * This function allocates memory on the heap. The returned
index f7731d9..d0f2e7d 100644 (file)
@@ -807,15 +807,7 @@ void *ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, con
        }
 
        if (ast_strlen_zero(id)) {
-               struct ast_uuid *uuid = ast_uuid_generate();
-
-               if (!uuid) {
-                       ao2_ref(details, -1);
-                       return NULL;
-               }
-
-               ast_uuid_to_str(uuid, details->id, AST_UUID_STR_LEN);
-               ast_free(uuid);
+               ast_uuid_generate_str(details->id, sizeof(details->id));
        } else {
                ast_copy_string(details->id, id, sizeof(details->id));
        }
index d1baa44..2bd432a 100644 (file)
@@ -106,7 +106,7 @@ const char *stasis_topic_name(const struct stasis_topic *topic)
 /*! \internal */
 struct stasis_subscription {
        /*! Unique ID for this subscription */
-       char *uniqueid;
+       char uniqueid[AST_UUID_STR_LEN];
        /*! Topic subscribed to. */
        struct stasis_topic *topic;
        /*! Mailbox for processing incoming messages. */
@@ -121,8 +121,6 @@ static void subscription_dtor(void *obj)
 {
        struct stasis_subscription *sub = obj;
        ast_assert(!stasis_subscription_is_subscribed(sub));
-       ast_free(sub->uniqueid);
-       sub->uniqueid = NULL;
        ao2_cleanup(sub->topic);
        sub->topic = NULL;
        ast_taskprocessor_unreference(sub->mailbox);
@@ -134,27 +132,19 @@ static void send_subscription_change_message(struct stasis_topic *topic, char *u
 struct stasis_subscription *stasis_subscribe(struct stasis_topic *topic, stasis_subscription_cb callback, void *data)
 {
        RAII_VAR(struct stasis_subscription *, sub, NULL, ao2_cleanup);
-       RAII_VAR(struct ast_uuid *, id, NULL, ast_free);
-       char uniqueid[AST_UUID_STR_LEN];
 
        sub = ao2_alloc(sizeof(*sub), subscription_dtor);
        if (!sub) {
                return NULL;
        }
 
-       id = ast_uuid_generate();
-       if (!id) {
-               ast_log(LOG_ERROR, "UUID generation failed\n");
-               return NULL;
-       }
-       ast_uuid_to_str(id, uniqueid, sizeof(uniqueid));
+       ast_uuid_generate_str(sub->uniqueid, sizeof(sub->uniqueid));
 
-       sub->mailbox = ast_threadpool_serializer(uniqueid, pool);
+       sub->mailbox = ast_threadpool_serializer(sub->uniqueid, pool);
        if (!sub->mailbox) {
                return NULL;
        }
 
-       sub->uniqueid = ast_strdup(uniqueid);
        ao2_ref(topic, +1);
        sub->topic = topic;
        sub->callback = callback;
@@ -163,7 +153,7 @@ struct stasis_subscription *stasis_subscribe(struct stasis_topic *topic, stasis_
        if (topic_add_subscription(topic, sub) != 0) {
                return NULL;
        }
-       send_subscription_change_message(topic, uniqueid, "Subscribe");
+       send_subscription_change_message(topic, sub->uniqueid, "Subscribe");
 
        ao2_ref(sub, +1);
        return sub;
index 46ac63d..e95a426 100644 (file)
@@ -38,13 +38,17 @@ struct ast_uuid {
        uuid_t uu;
 };
 
-struct ast_uuid *ast_uuid_generate(void)
+/*!
+ * \internal
+ * \brief Generate a UUID.
+ * \since 12.0.0
+ *
+ * \param uuid Fill this with a generated UUID.
+ *
+ * \return Nothing
+ */
+static void generate_uuid(struct ast_uuid *uuid)
 {
-       struct ast_uuid *uuid = ast_malloc(sizeof(*uuid));
-
-       if (!uuid) {
-               return NULL;
-       }
        /* libuuid provides three methods of generating uuids,
         * uuid_generate(), uuid_generate_random(), and uuid_generate_time().
         *
@@ -114,6 +118,16 @@ struct ast_uuid *ast_uuid_generate(void)
        if (!has_dev_urandom) {
                ast_mutex_unlock(&uuid_lock);
        }
+}
+
+struct ast_uuid *ast_uuid_generate(void)
+{
+       struct ast_uuid *uuid = ast_malloc(sizeof(*uuid));
+
+       if (!uuid) {
+               return NULL;
+       }
+       generate_uuid(uuid);
        return uuid;
 }
 
@@ -124,10 +138,19 @@ char *ast_uuid_to_str(const struct ast_uuid *uuid, char *buf, size_t size)
        return buf;
 }
 
+char *ast_uuid_generate_str(char *buf, size_t size)
+{
+       struct ast_uuid uuid;
+
+       generate_uuid(&uuid);
+       return ast_uuid_to_str(&uuid, buf, size);
+}
+
 struct ast_uuid *ast_str_to_uuid(const char *str)
 {
        struct ast_uuid *uuid = ast_malloc(sizeof(*uuid));
        int res;
+
        if (!uuid) {
                return NULL;
        }
@@ -143,6 +166,7 @@ struct ast_uuid *ast_str_to_uuid(const char *str)
 struct ast_uuid *ast_uuid_copy(const struct ast_uuid *src)
 {
        struct ast_uuid *dst = ast_malloc(sizeof(*dst));
+
        if (!dst) {
                return NULL;
        }
@@ -202,5 +226,4 @@ void ast_uuid_init(void)
        uuid_generate_random(uu);
 
        ast_debug(1, "UUID system initiated\n");
-       return;
 }
index ff711c5..acfdcee 100644 (file)
@@ -243,17 +243,9 @@ static void *unref_exchangecal(void *obj)
 static struct ast_str *generate_exchange_uuid(struct ast_str *uid)
 {
        char buffer[AST_UUID_STR_LEN];
-       struct ast_uuid *uuid = ast_uuid_generate();
-
-       if (!uuid) {
-               ast_str_set(&uid, 0, "%s", "");
-               return uid;
-       }
-
-       ast_str_set(&uid, 0, "%s", ast_uuid_to_str(uuid, buffer, AST_UUID_STR_LEN));
-
-       ast_free(uuid);
 
+       ast_uuid_generate_str(buffer, sizeof(buffer));
+       ast_str_set(&uid, 0, "%s", buffer);
        return uid;
 }
 
@@ -414,9 +406,17 @@ static struct ast_str *exchangecal_request(struct exchangecal_pvt *pvt, const ch
 
 static int exchangecal_write_event(struct ast_calendar_event *event)
 {
-       struct ast_str *body = NULL, *response = NULL, *subdir = NULL;
-       struct ast_str *uid = NULL, *summary = NULL, *description = NULL, *organizer = NULL,
-                      *location = NULL, *start = NULL, *end = NULL, *busystate = NULL;
+       struct ast_str *body = NULL;
+       struct ast_str *response = NULL;
+       struct ast_str *subdir = NULL;
+       struct ast_str *uid = NULL;
+       struct ast_str *summary = NULL;
+       struct ast_str *description = NULL;
+       struct ast_str *organizer = NULL;
+       struct ast_str *location = NULL;
+       struct ast_str *start = NULL;
+       struct ast_str *end = NULL;
+       struct ast_str *busystate = NULL;
        int ret = -1;
 
        if (!event) {
@@ -434,7 +434,7 @@ static int exchangecal_write_event(struct ast_calendar_event *event)
                goto write_cleanup;
        }
 
-       if (!(uid = ast_str_create(32)) ||
+       if (!(uid = ast_str_create(AST_UUID_STR_LEN)) ||
                !(summary = ast_str_create(32)) ||
                !(description = ast_str_create(32)) ||
                !(organizer = ast_str_create(32)) ||
@@ -449,7 +449,7 @@ static int exchangecal_write_event(struct ast_calendar_event *event)
        if (ast_strlen_zero(event->uid)) {
                uid = generate_exchange_uuid(uid);
        } else {
-               ast_str_set(&uid, 36, "%s", event->uid);
+               ast_str_set(&uid, AST_UUID_STR_LEN, "%s", event->uid);
        }
 
        if (!is_valid_uuid(uid)) {
@@ -496,7 +496,14 @@ static int exchangecal_write_event(struct ast_calendar_event *event)
                "      </a:prop>\n"
                "    </a:set>\n"
                "</a:propertyupdate>\n",
-               ast_str_buffer(uid), ast_str_buffer(summary), ast_str_buffer(description), ast_str_buffer(organizer), ast_str_buffer(location), ast_str_buffer(start), ast_str_buffer(end), ast_str_buffer(busystate));
+               ast_str_buffer(uid),
+               ast_str_buffer(summary),
+               ast_str_buffer(description),
+               ast_str_buffer(organizer),
+               ast_str_buffer(location),
+               ast_str_buffer(start),
+               ast_str_buffer(end),
+               ast_str_buffer(busystate));
        ast_verb(0, "\n\n%s\n\n", ast_str_buffer(body));
        ast_str_set(&subdir, 0, "/Calendar/%s.eml", ast_str_buffer(uid));
 
@@ -505,39 +512,17 @@ static int exchangecal_write_event(struct ast_calendar_event *event)
        }
 
 write_cleanup:
-       if (uid) {
-               ast_free(uid);
-       }
-       if (summary) {
-               ast_free(summary);
-       }
-       if (description) {
-               ast_free(description);
-       }
-       if (organizer) {
-               ast_free(organizer);
-       }
-       if (location) {
-               ast_free(location);
-       }
-       if (start) {
-               ast_free(start);
-       }
-       if (end) {
-               ast_free(end);
-       }
-       if (busystate) {
-               ast_free(busystate);
-       }
-       if (body) {
-               ast_free(body);
-       }
-       if (response) {
-               ast_free(response);
-       }
-       if (subdir) {
-               ast_free(subdir);
-       }
+       ast_free(uid);
+       ast_free(summary);
+       ast_free(description);
+       ast_free(organizer);
+       ast_free(location);
+       ast_free(start);
+       ast_free(end);
+       ast_free(busystate);
+       ast_free(body);
+       ast_free(response);
+       ast_free(subdir);
 
        return ret;
 }
index 10347ea..509538f 100644 (file)
@@ -305,19 +305,12 @@ static void *sorcery_config_open(const char *data)
 {
        char *tmp = ast_strdupa(data), *filename = strsep(&tmp, ","), *option;
        struct sorcery_config *config;
-       struct ast_uuid *uuid;
 
        if (ast_strlen_zero(filename) || !(config = ao2_alloc_options(sizeof(*config) + strlen(filename) + 1, sorcery_config_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK))) {
                return NULL;
        }
 
-       if (!(uuid = ast_uuid_generate())) {
-               ao2_ref(config, -1);
-               return NULL;
-       }
-
-       ast_uuid_to_str(uuid, config->uuid, AST_UUID_STR_LEN);
-       ast_free(uuid);
+       ast_uuid_generate_str(config->uuid, sizeof(config->uuid));
 
        ast_rwlock_init(&config->objects.lock);
        config->buckets = DEFAULT_OBJECT_BUCKETS;
index a76ec8b..70769ef 100644 (file)
@@ -50,7 +50,23 @@ AST_TEST_DEFINE(uuid)
                break;
        }
 
-       /* First, make sure that we can generate a UUID */
+       /* Use method of generating UUID directly as a string. */
+       ast_uuid_generate_str(uuid_str, sizeof(uuid_str));
+       if (strlen(uuid_str) != (AST_UUID_STR_LEN - 1)) {
+               ast_test_status_update(test, "Failed to directly generate UUID string\n");
+               goto end;
+       }
+       ast_test_status_update(test, "Generate UUID direct to string, got %s\n", uuid_str);
+
+       /* Now convert the direct UUID string to a UUID */
+       uuid1 = ast_str_to_uuid(uuid_str);
+       if (!uuid1) {
+               ast_test_status_update(test, "Unable to convert direct UUID string %s to UUID\n", uuid_str);
+               goto end;
+       }
+       ast_free(uuid1);
+
+       /* Make sure that we can generate a UUID */
        uuid1 = ast_uuid_generate();
        if (!uuid1) {
                ast_test_status_update(test, "Unable to generate a UUID\n");
@@ -71,7 +87,7 @@ AST_TEST_DEFINE(uuid)
                goto end;
        }
 
-       ast_test_status_update(test, "Converted uuid to string, got %s\n", uuid_str);
+       ast_test_status_update(test, "Second generated UUID converted to string, got %s\n", uuid_str);
 
        /* Now convert the string back to a UUID */
        uuid2 = ast_str_to_uuid(uuid_str);