replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / connectivity / common / src / uarraylist.c
index f1425e8..b795f10 100644 (file)
 
 #define TAG "UARRAYLIST"
 
+/**
+ * Use this default capacity when initialized
+ */
+#define U_ARRAYLIST_DEFAULT_CAPACITY 1
+
 u_arraylist_t *u_arraylist_create()
 {
-    u_arraylist_t *list = NULL;
-
-    if (!(list = (u_arraylist_t *) OICMalloc(sizeof(u_arraylist_t))))
+    u_arraylist_t *list = (u_arraylist_t *) OICCalloc(1, sizeof(u_arraylist_t));
+    if (!list)
     {
+        OIC_LOG(DEBUG, TAG, "Out of memory");
         return NULL;
     }
 
-    list->size = U_ARRAYLIST_DEFAULT_SIZE;
+    list->capacity = U_ARRAYLIST_DEFAULT_CAPACITY;
     list->length = 0;
 
-    if (!(list->data = (void *) OICMalloc(list->size * sizeof(void *))))
+    list->data = (void **) OICMalloc(list->capacity * sizeof(list->data[0]));
+    if (!list->data)
     {
         OIC_LOG(DEBUG, TAG, "Out of memory");
         OICFree(list);
@@ -47,27 +53,71 @@ u_arraylist_t *u_arraylist_create()
     return list;
 }
 
-CAResult_t u_arraylist_free(u_arraylist_t **list)
+void u_arraylist_free(u_arraylist_t **list)
 {
-    if (*list == NULL)
-        return CA_STATUS_INVALID_PARAM;
+    if (!list || !(*list))
+    {
+        return;
+    }
 
     OICFree((*list)->data);
     OICFree(*list);
 
     *list = NULL;
+}
+
+bool u_arraylist_reserve(u_arraylist_t *list, size_t count)
+{
+    if (list && (count > list->capacity))
+    {
+        void *tmp = OICRealloc(list->data, count * sizeof(list->data[0]));
+        if (!tmp)
+        {
+            OIC_LOG(DEBUG, TAG, "Memory reallocation failed.");
+            return false;
+        }
+        else
+        {
+            list->data = (void **) tmp;
+            list->capacity = count;
+        }
+    }
+    return true;
+}
 
-    return CA_STATUS_OK;
+void u_arraylist_shrink_to_fit(u_arraylist_t *list)
+{
+    if (!list)
+    {
+        return;
+    }
+
+    if ((list->capacity > list->length)
+        && (list->length >= U_ARRAYLIST_DEFAULT_CAPACITY))
+    {
+        void *tmp = OICRealloc(list->data,
+                               list->length * sizeof(list->data[0]));
+        if (!tmp)
+        {
+            OIC_LOG(DEBUG, TAG, "Memory reallocation failed.");
+            // Considered non-fatal as this call is non-binding.
+        }
+        else
+        {
+            list->data = (void **) tmp;
+            list->capacity = list->length;
+        }
+    }
 }
 
 void *u_arraylist_get(const u_arraylist_t *list, uint32_t index)
 {
-    if (index >= list->length)
+    if (!list )
     {
         return NULL;
     }
 
-    if (list->data)
+    if ((index < list->length) && (list->data))
     {
         return list->data[index];
     }
@@ -75,34 +125,64 @@ void *u_arraylist_get(const u_arraylist_t *list, uint32_t index)
     return NULL;
 }
 
-CAResult_t u_arraylist_add(u_arraylist_t *list, void *data)
+bool u_arraylist_get_index(const u_arraylist_t *list, const void *data, uint32_t *index)
 {
-    uint32_t new_size = 0;
-
-    if (list->size <= list->length)
+    if (!list || !data)
     {
+        return false;
+    }
 
-        new_size = list->size + 1;
-        if (!(list->data = (void **) realloc(list->data, new_size * sizeof(void *))))
+    for (uint32_t i = 0; i < list->length; i++)
+    {
+        if (data == list->data[i])
         {
-            return CA_MEMORY_ALLOC_FAILED;
+            *index = i;
+            return true;
         }
+    }
+
+    return false;
+}
+
+bool u_arraylist_add(u_arraylist_t *list, void *data)
+{
+    if (!list)
+    {
+        return false;
+    }
 
-        (void) memset(list->data + list->size, 0, (new_size - list->size) * sizeof(void *));
-        list->size = new_size;
+    if (list->capacity <= list->length)
+    {
+        // Does a non-FP calcuation of the 1.5 growth factor. Helpful for
+        // certain limited platforms.
+        size_t new_capacity = ((list->capacity * 3) + 1) / 2;
+
+        // In case the re-alloc returns null, use a local variable to avoid
+        // losing the current block of memory.
+        void *tmp = OICRealloc(list->data,
+                               new_capacity * sizeof(list->data[0]));
+        if (!tmp)
+        {
+            OIC_LOG(DEBUG, TAG, "Memory reallocation failed.");
+            return false;
+        }
+        list->data = (void **) tmp;
+        memset(list->data + list->capacity, 0,
+               (new_capacity - list->capacity) * sizeof(list->data[0]));
+        list->capacity = (uint32_t)new_capacity;
     }
 
     list->data[list->length] = data;
     list->length++;
 
-    return CA_STATUS_OK;
+    return true;
 }
 
 void *u_arraylist_remove(u_arraylist_t *list, uint32_t index)
 {
     void *removed = NULL;
 
-    if (index >= list->length)
+    if (!list || (index >= list->length))
     {
         return NULL;
     }
@@ -111,27 +191,19 @@ void *u_arraylist_remove(u_arraylist_t *list, uint32_t index)
 
     if (index < list->length - 1)
     {
-        memmove(&list->data[index], &list->data[index + 1],
-                (list->length - index - 1) * sizeof(void *));
+        memmove(&list->data[index],
+                &list->data[index + 1],
+                (list->length - index - 1) * sizeof(list->data[0]));
     }
 
-    list->size--;
     list->length--;
 
-    // check minimum size.
-    list->size = (list->size <= U_ARRAYLIST_DEFAULT_SIZE) ? U_ARRAYLIST_DEFAULT_SIZE : list->size;
-
-    if (!(list->data = (void **) realloc(list->data, list->size * sizeof(void *))))
-    {
-        return NULL;
-    }
-
     return removed;
 }
 
 uint32_t u_arraylist_length(const u_arraylist_t *list)
 {
-    if (NULL == list)
+    if (!list)
     {
         OIC_LOG(DEBUG, TAG, "Invalid Parameter");
         return 0;
@@ -139,22 +211,34 @@ uint32_t u_arraylist_length(const u_arraylist_t *list)
     return list->length;
 }
 
-uint8_t u_arraylist_contains(const u_arraylist_t *list, void *data)
+bool u_arraylist_contains(const u_arraylist_t *list, const void *data)
 {
-    uint32_t i = 0;
+    if (!list)
+    {
+        return false;
+    }
 
-    for (i = 0; i < u_arraylist_length(list); i++)
+    for (uint32_t i = 0; i < list->length; i++)
     {
-        if (data == u_arraylist_get(list, i))
-        {
-            return 1;
-        }
-        else
+        if (data == list->data[i])
         {
-            continue;
+            return true;
         }
     }
 
-    return 0;
+    return false;
 }
 
+// Assumes elements are shallow (have no pointers to allocated memory)
+void u_arraylist_destroy(u_arraylist_t *list)
+{
+    if (!list)
+    {
+        return;
+    }
+    for (uint32_t i = 0; i < list->length; i++)
+    {
+        OICFree(list->data[i]);
+    }
+    (void)u_arraylist_free(&list);
+}