You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2024/02/04 22:32:31 UTC
(celix) branch feature/674-add-element-type-to-array-list created (now f0ff9d94)
This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a change to branch feature/674-add-element-type-to-array-list
in repository https://gitbox.apache.org/repos/asf/celix.git
at f0ff9d94 #674 Add array list element type testing
This branch includes the following new commits:
new b4df54cc #674 Fix in push stream for gcc 13
new ba42e664 #674 Refactor array list compare in ctx, reg and rsa
new 21f379de #674 Add initial element type support for array list
new f0ff9d94 #674 Add array list element type testing
The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(celix) 01/04: #674 Fix in push stream for gcc 13
Posted by pn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a commit to branch feature/674-add-element-type-to-array-list
in repository https://gitbox.apache.org/repos/asf/celix.git
commit b4df54cc4626309d11b6e4337f9581d35c07dfac
Author: Pepijn Noltes <pn...@apache.org>
AuthorDate: Sun Feb 4 19:05:47 2024 +0100
#674 Fix in push stream for gcc 13
---
libs/pushstreams/api/celix/impl/BufferedPushStream.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libs/pushstreams/api/celix/impl/BufferedPushStream.h b/libs/pushstreams/api/celix/impl/BufferedPushStream.h
index 5172f42e..6a2d1e6f 100644
--- a/libs/pushstreams/api/celix/impl/BufferedPushStream.h
+++ b/libs/pushstreams/api/celix/impl/BufferedPushStream.h
@@ -98,10 +98,10 @@ void celix::BufferedPushStream<T>::startWorker() {
std::weak_ptr<std::queue<std::unique_ptr<PushEvent<T>>>> weak{queue};
auto lk = weak.lock();
if (lk) {
- std::unique_ptr<celix::PushEvent<T>> event = std::move(popQueue());
+ std::unique_ptr<celix::PushEvent<T>> event = popQueue();
while (event != nullptr) {
this->nextEvent.accept(*event);
- event = std::move(popQueue());
+ event = popQueue();
}
cv.notify_all();
}
(celix) 03/04: #674 Add initial element type support for array list
Posted by pn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a commit to branch feature/674-add-element-type-to-array-list
in repository https://gitbox.apache.org/repos/asf/celix.git
commit 21f379de8a0ef8923e64453b851747add74ebdc6
Author: Pepijn Noltes <pn...@apache.org>
AuthorDate: Sun Feb 4 19:07:44 2024 +0100
#674 Add initial element type support for array list
---
bundles/logging/log_admin/src/celix_log_admin.c | 14 +-
libs/utils/gtest/src/ArrayListTestSuite.cc | 2 +-
libs/utils/include/celix_array_list.h | 453 ++++++++++++++++++++---
libs/utils/src/array_list.c | 465 ++++++++++++++++++++----
libs/utils/src/array_list_private.h | 41 ---
5 files changed, 813 insertions(+), 162 deletions(-)
diff --git a/bundles/logging/log_admin/src/celix_log_admin.c b/bundles/logging/log_admin/src/celix_log_admin.c
index 5b983ef1..6b1be0f5 100644
--- a/bundles/logging/log_admin/src/celix_log_admin.c
+++ b/bundles/logging/log_admin/src/celix_log_admin.c
@@ -429,12 +429,12 @@ static size_t celix_logAdmin_setSinkEnabled(void *handle, const char* select, bo
static celix_array_list_t* celix_logAdmin_currentLogServices(void *handle) {
celix_log_admin_t* admin = handle;
- celix_array_list_t* loggers = celix_arrayList_create();
+ celix_array_list_t* loggers = celix_arrayList_createStringArray();
celixThreadRwlock_readLock(&admin->lock);
hash_map_iterator_t iter = hashMapIterator_construct(admin->loggers);
while (hashMapIterator_hasNext(&iter)) {
celix_log_service_entry_t* visit = hashMapIterator_nextValue(&iter);
- celix_arrayList_add(loggers, celix_utils_strdup(visit->name));
+ celix_arrayList_addString(loggers, visit->name);
}
celixThreadRwlock_unlock(&admin->lock);
return loggers;
@@ -442,12 +442,12 @@ static celix_array_list_t* celix_logAdmin_currentLogServices(void *handle) {
static celix_array_list_t* celix_logAdmin_currentSinks(void *handle) {
celix_log_admin_t* admin = handle;
- celix_array_list_t* sinks = celix_arrayList_create();
+ celix_array_list_t* sinks = celix_arrayList_createStringArray();
celixThreadRwlock_readLock(&admin->lock);
hash_map_iterator_t iter = hashMapIterator_construct(admin->sinks);
while (hashMapIterator_hasNext(&iter)) {
celix_log_sink_entry_t* entry = hashMapIterator_nextValue(&iter);
- celix_arrayList_add(sinks, celix_utils_strdup(entry->name));
+ celix_arrayList_addString(sinks, entry->name);
}
celixThreadRwlock_unlock(&admin->lock);
return sinks;
@@ -539,8 +539,8 @@ static void celix_logAdmin_setSinkEnabledCmd(celix_log_admin_t* admin, const cha
static void celix_logAdmin_InfoCmd(celix_log_admin_t* admin, FILE* outStream, FILE* errorStream CELIX_UNUSED) {
celix_array_list_t* logServices = celix_logAdmin_currentLogServices(admin);
celix_array_list_t* sinks = celix_logAdmin_currentSinks(admin);
- celix_arrayList_sort(logServices, (void*)strcmp);
- celix_arrayList_sort(sinks, (void*)strcmp);
+ celix_arrayList_sort(logServices);
+ celix_arrayList_sort(sinks);
fprintf(outStream, "Log Admin provided log services:\n");
for (int i = 0 ; i < celix_arrayList_size(logServices); ++i) {
@@ -552,7 +552,6 @@ static void celix_logAdmin_InfoCmd(celix_log_admin_t* admin, FILE* outStream, FI
fprintf(outStream, " |- %i) Log Service %20s, active log level %s, %s\n",
i+1, name, celix_logUtils_logLevelToString(level), detailed ? "detailed" : "brief");
}
- free(name);
}
celix_arrayList_destroy(logServices);
@@ -565,7 +564,6 @@ static void celix_logAdmin_InfoCmd(celix_log_admin_t* admin, FILE* outStream, FI
if (found) {
fprintf(outStream, " |- %i) Log Sink %20s, %s\n", i+1, name, enabled ? "enabled" : "disabled");
}
- free(name);
}
} else {
fprintf(outStream, "Log Admin has found 0 log sinks\n");
diff --git a/libs/utils/gtest/src/ArrayListTestSuite.cc b/libs/utils/gtest/src/ArrayListTestSuite.cc
index 5a0e60c3..488f069f 100644
--- a/libs/utils/gtest/src/ArrayListTestSuite.cc
+++ b/libs/utils/gtest/src/ArrayListTestSuite.cc
@@ -219,7 +219,7 @@ TEST_F(ArrayListTestSuite, TestSortForArrayList) {
EXPECT_EQ(celix_arrayList_getInt(list, 3), 4);
- celix_array_list_sort_entries_fp sort = [](celix_array_list_entry_t a, celix_array_list_entry_t b) -> int {
+ celix_array_list_compare_entries_fp sort = [](celix_array_list_entry_t a, celix_array_list_entry_t b) -> int {
return a.intVal - b.intVal;
};
celix_arrayList_sortEntries(list, sort);
diff --git a/libs/utils/include/celix_array_list.h b/libs/utils/include/celix_array_list.h
index b38772b8..25925c89 100644
--- a/libs/utils/include/celix_array_list.h
+++ b/libs/utils/include/celix_array_list.h
@@ -22,6 +22,7 @@
#include "celix_cleanup.h"
#include "celix_errno.h"
#include "celix_utils_export.h"
+#include "celix_version.h"
#ifndef CELIX_ARRAY_LIST_H_
#define CELIX_ARRAY_LIST_H_
@@ -40,36 +41,83 @@
extern "C" {
#endif
+/**
+ * @enum celix_array_list_element_type_t
+ * @brief An enumeration of the types of elements that can be stored in a Celix array list.
+ */
+typedef enum celix_array_list_element_type {
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED = 0, /**< Represents an undefined element type. */
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER = 1, /**< Represents a pointer element type. */
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING = 2, /**< Represents a string element type where the array list is the owner */
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING_REF =
+ 3, /**< Represents a string element type where the array list is not the owner */
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_INT = 4, /**< Represents an integer element type. */
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG = 5, /**< Represents a long integer element type. */
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_UINT = 6, /**< Represents an unsigned integer element type. */
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_ULONG = 7, /**< Represents an unsigned long integer element type. */
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_FLOAT = 8, /**< Represents a float element type. */
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE = 9, /**< Represents a double element type. */
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL = 10, /**< Represents a boolean element type. */
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE = 11, /**< Represents a size_t element type. */
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION = 12 /**< Represents a celix_version_t* element type. */
+} celix_array_list_element_type_t;
+
+/**
+ * @union celix_array_list_entry
+ * @brief A union representing an entry in a Celix array list.
+ *
+ * This union can hold different types of values, including pointers, strings, integers, long integers,
+ * unsigned integers, unsigned long integers, doubles, floats, booleans, and size_t values.
+ */
typedef union celix_array_list_entry {
- void *voidPtrVal;
- int intVal;
- long int longVal;
- unsigned int uintVal;
- unsigned long ulongVal;
- double doubleVal;
- float floatVal;
- bool boolVal;
- size_t sizeVal;
+ void* voidPtrVal; /**< A pointer value when the element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_PTR or
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
+ const char* stringVal; /**< A string value when the element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING,
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING_REF or CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
+ int intVal; /**< An integer value when the element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_INT or
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.*/
+ long int longVal; /**< A long integer value when the element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG or
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
+ unsigned int uintVal; /**< An unsigned integer value when the element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_UINT or
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
+ unsigned long ulongVal; /**< An unsigned long integer value when the element type is
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_ULONG or CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
+ double doubleVal; /**< A double value when the element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE or
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
+ float floatVal; /**< A float value when the element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_FLOAT or
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
+ bool boolVal; /**< A boolean value when the element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL or
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
+ size_t sizeVal; /**< A size_t value when the element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE or
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
+ const celix_version_t* versionVal; /**< A celix_version_t* value when the element type is
+ CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION or CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
} celix_array_list_entry_t;
+/**
+ * @brief A celix array list, which can store a list of undefined elements.
+ */
typedef struct celix_array_list celix_array_list_t;
+/**
+ * @brief Equals function for array list entries, can be provided when creating a array list.
+ */
typedef bool (*celix_arrayList_equals_fp)(celix_array_list_entry_t, celix_array_list_entry_t);
-typedef int (*celix_arrayList_sort_fp)(const void *, const void *);
-
/**
* @brief Compare function for array list entries, which can be used to sort a array list.
*/
typedef int (*celix_array_list_compare_entries_fp)(celix_array_list_entry_t a, celix_array_list_entry_t b);
-typedef celix_array_list_compare_entries_fp celix_array_list_sort_entries_fp __attribute__((deprecated("Use celix_arrayList_compare_entries_fp instead")));
-
-
/**
* Additional create options when creating a array list.
*/
typedef struct celix_array_list_create_options {
+ /**
+ * The element type of the array list. Default is CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ */
+ celix_array_list_element_type_t elementType CELIX_OPTS_INIT;
+
/**
* A simple removed callback, which if provided will be called if a entry is removed
* from the array list. The removed entry is provided as pointer.
@@ -104,7 +152,12 @@ typedef struct celix_array_list_create_options {
/**
* Equals callback used when trying to find a array list entry.
*/
- bool (*equalsCallback)(celix_array_list_entry_t a, celix_array_list_entry_t b) CELIX_OPTS_INIT;
+ celix_arrayList_equals_fp equalsCallback CELIX_OPTS_INIT;
+
+ /**
+ * Compare callback used when sorting the array list.
+ */
+ celix_array_list_compare_entries_fp compareCallback CELIX_OPTS_INIT;
} celix_array_list_create_options_t;
@@ -112,30 +165,137 @@ typedef struct celix_array_list_create_options {
/**
* @brief C Macro to create a empty string_hash_map_create_options_t type.
*/
-#define CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS { \
- .simpleRemovedCallback = NULL, \
- .removedCallbackData = NULL, \
- .removedCallback = NULL, \
- .equalsCallback = NULL \
-}
+#define CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS \
+ { \
+ .elementType = CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED, .simpleRemovedCallback = NULL, \
+ .removedCallbackData = NULL, .removedCallback = NULL, .equalsCallback = NULL, .compareCallback = NULL \
+ }
#endif
/**
- * @brief Creates a new empty array list.
+ * @brief Creates a new empty array list with an undefined element type.
+ *
+ * The remove, equals and compare callback will be NULL.
+ *
+ * @deprecated Use celix_arrayList_createWithOptions instead.
+ */
+CELIX_UTILS_DEPRECATED_EXPORT
+celix_array_list_t* celix_arrayList_create() __attribute__((deprecated("use create typed array list instead")));
+
+/**
+ * @brief Creates a new empty array list with a pointer element type where the array list is not the owner of the
+ * pointers.
+ *
+ * The remove, equals and compare callback will be NULL.
+ */
+CELIX_UTILS_EXPORT
+celix_array_list_t* celix_arrayList_createPointerArray();
+
+/**
+ * @brief Creates a new empty array list with a string element type where the array list is the owner of the strings.
+ *
+ * The remove callback will be configured to free the string, and equals and compare callback will be configured for
+ * string comparison.
+ */
+CELIX_UTILS_EXPORT
+celix_array_list_t* celix_arrayList_createStringArray();
+
+/**
+ * @brief Creates a new empty array list with a string element type where the array list is **not** the owner of the
+ * strings.
+ *
+ * The remove callback will be configured to NULL, and equals and compare callback will be configured for
+ * string comparison.
+ */
+CELIX_UTILS_EXPORT
+celix_array_list_t* celix_arrayList_createStringRefArray();
+
+/**
+ * @brief Creates a new empty array list with an integer element type.
+ *
+ * The remove callback will be configured to NULL, and equals and compare callback will be configured for
+ * integer comparison.
+ */
+CELIX_UTILS_EXPORT
+celix_array_list_t* celix_arrayList_createIntArray();
+
+/**
+ * @brief Creates a new empty array list with a long integer element type.
+ *
+ * The remove callback will be configured to NULL, and equals and compare callback will be configured for
+ * integer comparison.
+ */
+CELIX_UTILS_EXPORT
+celix_array_list_t* celix_arrayList_createLongArray();
+
+/**
+ * @brief Creates a new empty array list with an unsigned integer element type.
+ *
+ * The remove callback will be configured to NULL, and equals and compare callback will be configured for
+ * unsigned integer comparison.
+ */
+CELIX_UTILS_EXPORT
+celix_array_list_t* celix_arrayList_createUIntArray();
+
+/**
+ * @brief Creates a new empty array list with an unsigned long integer element type.
+ *
+ * The remove callback will be configured to NULL, and equals and compare callback will be configured for
+ * unsigned integer comparison.
*/
CELIX_UTILS_EXPORT
-celix_array_list_t* celix_arrayList_create();
+celix_array_list_t* celix_arrayList_createULongArray();
/**
- * @brief Creates a new empty array list, which uses the provided equals to check whether entries
- * are equal.
- * @deprecated This functions is deprecated, use celix_arrayList_createWithOptions instead.
+ * @brief Creates a new empty array list with a float element type.
+ *
+ * The remove callback will be configured to NULL, and equals and compare callback will be configured for
+ * float comparison.
+ */
+CELIX_UTILS_EXPORT
+celix_array_list_t* celix_arrayList_createFloatArray();
+
+/**
+ * @brief Creates a new empty array list with a double element type.
+ *
+ * The remove callback will be configured to NULL, and equals and compare callback will be configured for
+ * double comparison.
+ */
+CELIX_UTILS_EXPORT
+celix_array_list_t* celix_arrayList_createDoubleArray();
+
+/**
+ * @brief Creates a new empty array list with a boolean element type.
+ *
+ * The remove callback will be configured to NULL, and equals and compare callback will be configured for
+ * boolean comparison.
*/
CELIX_UTILS_EXPORT
-celix_array_list_t* celix_arrayList_createWithEquals(celix_arrayList_equals_fp equals);
+celix_array_list_t* celix_arrayList_createBoolArray();
/**
- * @brief Creates a new empty array listusing using the provided array list create options.
+ * @brief Creates a new empty array list with a size_t element type.
+ *
+ * The remove callback will be configured to NULL, and equals and compare callback will be configured for
+ * unsigned integer comparison.
+ */
+CELIX_UTILS_EXPORT
+celix_array_list_t* celix_arrayList_createSizeArray();
+
+/**
+ * @brief Creates a new empty array list with a celix_version_t* element type.
+ *
+ * The remove callback will be configured to free a celix version, and equals and compare callback will be configured
+ * for celix version comparison.
+ */
+CELIX_UTILS_EXPORT
+celix_array_list_t* celix_arrayList_createVersionArray();
+
+/**
+ * @brief Creates a new empty array list using using the provided array list create options.
+ *
+ * The underlying element type will be undefined, until the first element is added.
+ *
* @param opts The create options, only used during the creation of the array list.
*/
CELIX_UTILS_EXPORT
@@ -160,6 +320,9 @@ int celix_arrayList_size(const celix_array_list_t *list);
/**
* @brief Returns the value for the provided index.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param index The entry index to return.
* @return Returns the pointer value for the index. Returns NULL if index is out of bound.
@@ -170,6 +333,22 @@ void* celix_arrayList_get(const celix_array_list_t *list, int index);
/**
* @brief Returns the value for the provided index.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING,
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING_REF or CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
+ * @param list The array list.
+ * @param index The entry index to return.
+ * @return Returns the string value for the index. Returns NULL if index is out of bound.
+ */
+CELIX_UTILS_EXPORT
+const char* celix_arrayList_getString(const celix_array_list_t *list, int index);
+
+/**
+ * @brief Returns the value for the provided index.
+ *
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_INT or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param index The entry index to return.
* @return Returns the int value for the index. Returns 0 if index is out of bound.
@@ -180,6 +359,9 @@ int celix_arrayList_getInt(const celix_array_list_t *list, int index);
/**
* @brief Returns the value for the provided index.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param index The entry index to return.
* @return Returns the long value for the index. Returns 0 if index is out of bound.
@@ -190,6 +372,9 @@ long int celix_arrayList_getLong(const celix_array_list_t *list, int index);
/**
* @brief Returns the value for the provided index.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_UINT or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param index The entry index to return.
* @return Returns the unsigned int value for the index. Returns 0 if index is out of bound.
@@ -200,6 +385,9 @@ unsigned int celix_arrayList_getUInt(const celix_array_list_t *list, int index);
/**
* @brief Returns the value for the provided index.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_ULONG or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param index The entry index to return.
* @return Returns the unsigned long value for the index. Returns 0 if index is out of bound.
@@ -210,6 +398,9 @@ unsigned long int celix_arrayList_getULong(const celix_array_list_t *list, int i
/**
* @brief Returns the value for the provided index.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_FLOAT or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param index The entry index to return.
* @return Returns the float value for the index. Returns 0 if index is out of bound.
@@ -220,6 +411,9 @@ float celix_arrayList_getFloat(const celix_array_list_t *list, int index);
/**
* @brief Returns the value for the provided index.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param index The entry index to return.
* @return Returns the double value for the index. Returns 0 if index is out of bound.
@@ -230,6 +424,9 @@ double celix_arrayList_getDouble(const celix_array_list_t *list, int index);
/**
* @brief Returns the value for the provided index.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param index The entry index to return.
* @return Returns the bool value for the index. Returns false if index is out of bound.
@@ -240,6 +437,9 @@ bool celix_arrayList_getBool(const celix_array_list_t *list, int index);
/**
* @brief Returns the value for the provided index.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param index The entry index to return.
* @return Returns the size_t value for the index. Returns 0 if index is out of bound.
@@ -247,95 +447,197 @@ bool celix_arrayList_getBool(const celix_array_list_t *list, int index);
CELIX_UTILS_EXPORT
size_t celix_arrayList_getSize(const celix_array_list_t *list, int index);
+/**
+ * @brief Returns the value for the provided index.
+ *
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION,
+ * or CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
+ * @param list The array list.
+ * @param index The entry index to return.
+ * @return Returns the version value for the index. Returns NULL if index is out of bound.
+ */
+CELIX_UTILS_EXPORT
+const celix_version_t* celix_arrayList_getVersion(const celix_array_list_t *list, int index);
+
/**
* @brief add pointer entry to the back of the array list.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param value The pointer value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory.
*/
CELIX_UTILS_EXPORT
-celix_status_t celix_arrayList_add(celix_array_list_t *list, void* value);
+celix_status_t celix_arrayList_add(celix_array_list_t* list, void* value);
+
+/**
+ * @brief Add a string entry to the back of the array list.
+ *
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING,
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING_REF or CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
+ * If the array list element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING, the string will be copied, but
+ * if the array list element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING_REF or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED, the string will be added as reference (as-is).
+ *
+ * @param list The array list.
+ * @param value The string value to add to the array list.
+ * @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory.
+ */
+CELIX_UTILS_EXPORT
+celix_status_t celix_arrayList_addString(celix_array_list_t* list, const char* value);
+
+/**
+ * @brief Add a string entry to the back of a string array list.
+ *
+ * The string will not be copied and the array list will take ownership of the string.
+ *
+ * Can only be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING.
+ *
+ * @param list The array list.
+ * @param value The string value to add to the array list.
+ * @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory.
+ */
+CELIX_UTILS_EXPORT
+celix_status_t celix_arrayList_assignString(celix_array_list_t* list, char* value);
/**
* @brief add pointer entry to the back of the array list.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_INT or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param value The int value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory.
*/
CELIX_UTILS_EXPORT
-celix_status_t celix_arrayList_addInt(celix_array_list_t *list, int value);
+celix_status_t celix_arrayList_addInt(celix_array_list_t* list, int value);
/**
* @brief add pointer entry to the back of the array list.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param value The long value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory.
*/
CELIX_UTILS_EXPORT
-celix_status_t celix_arrayList_addLong(celix_array_list_t *list, long value);
+celix_status_t celix_arrayList_addLong(celix_array_list_t* list, long value);
/**
* @brief add pointer entry to the back of the array list.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_UINT or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param value The unsigned int value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory.
*/
CELIX_UTILS_EXPORT
-celix_status_t celix_arrayList_addUInt(celix_array_list_t *list, unsigned int value);
+celix_status_t celix_arrayList_addUInt(celix_array_list_t* list, unsigned int value);
/**
* @brief add pointer entry to the back of the array list.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_ULONG or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param value The unsigned long value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory.
*/
CELIX_UTILS_EXPORT
-celix_status_t celix_arrayList_addULong(celix_array_list_t *list, unsigned long value);
+celix_status_t celix_arrayList_addULong(celix_array_list_t* list, unsigned long value);
/**
* @brief add pointer entry to the back of the array list.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_FLOAT or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param value The float value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory.
*/
CELIX_UTILS_EXPORT
-celix_status_t celix_arrayList_addFloat(celix_array_list_t *list, float value);
+celix_status_t celix_arrayList_addFloat(celix_array_list_t* list, float value);
/**
* @brief add pointer entry to the back of the array list.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param value The double value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory.
*/
CELIX_UTILS_EXPORT
-celix_status_t celix_arrayList_addDouble(celix_array_list_t *list, double value);
+celix_status_t celix_arrayList_addDouble(celix_array_list_t* list, double value);
/**
* @brief add pointer entry to the back of the array list.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param value The bool value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory.
*/
CELIX_UTILS_EXPORT
-celix_status_t celix_arrayList_addBool(celix_array_list_t *list, bool value);
+celix_status_t celix_arrayList_addBool(celix_array_list_t* list, bool value);
/**
* @brief add pointer entry to the back of the array list.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* @param map The array list.
* @param value The size_t value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory.
*/
CELIX_UTILS_EXPORT
-celix_status_t celix_arrayList_addSize(celix_array_list_t *list, size_t value);
+celix_status_t celix_arrayList_addSize(celix_array_list_t* list, size_t value);
+
+/**
+ * @brief Add a version entry to the back of the version array list.
+ *
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION,
+ * or CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
+ * If the array list element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION, the version will be copied, but
+ * if the array list element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED,
+ * the string will be added as reference (as-is).
+ *
+ * @param list The array list.
+ * @param value The version value to add to the array list.
+ * @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory.
+ */
+CELIX_UTILS_EXPORT
+celix_status_t celix_arrayList_addVersion(celix_array_list_t* list, const celix_version_t* value);
+
+/**
+ * @brief Add a version entry to the back of a version array list.
+ *
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION.
+ * The version will not be copied and the array list will take ownership of the version.
+ *
+ *
+ * @param list The array list.
+ * @param value The version value to add to the array list.
+ * @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory.
+ */
+CELIX_UTILS_EXPORT
+celix_status_t celix_arrayList_assignVersion(celix_array_list_t* list, celix_version_t* value);
/**
* @brief Returns the index of the provided entry, if found.
@@ -383,83 +685,134 @@ void celix_arrayList_removeEntry(celix_array_list_t *list, celix_array_list_entr
/**
* @brief Remove the first pointer entry from array list which matches the provided value.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
+ * The equals callback provided when the array list was created will be used to find the entry.
+ * If there was no equals callback provided a direct memory compare will be done.
+ */
+CELIX_UTILS_EXPORT
+void celix_arrayList_remove(celix_array_list_t* list, void* value);
+
+/**
+ * @brief Remove the first string entry from array list which matches the provided value.
+ *
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING,
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING_REF and CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* The equals callback provided when the array list was created will be used to find the entry.
* If there was no equals callback provided a direct memory compare will be done.
*/
CELIX_UTILS_EXPORT
-void celix_arrayList_remove(celix_array_list_t *list, void *value);
+void celix_arrayList_removeString(celix_array_list_t* list, const char* value);
/**
* @brief Remove the first int entry from array list which matches the provided value.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_INT and
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* The equals callback provided when the array list was created will be used to find the entry.
* If there was no equals callback provided a direct memory compare will be done.
*/
CELIX_UTILS_EXPORT
-void celix_arrayList_removeInt(celix_array_list_t *list, int value);
+void celix_arrayList_removeInt(celix_array_list_t* list, int value);
/**
* @brief Remove the first long entry from array list which matches the provided value.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG and
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* The equals callback provided when the array list was created will be used to find the entry.
* If there was no equals callback provided a direct memory compare will be done.
*/
CELIX_UTILS_EXPORT
-void celix_arrayList_removeLong(celix_array_list_t *list, long value);
+void celix_arrayList_removeLong(celix_array_list_t* list, long value);
/**
* @brief Remove the first unsigned int entry from array list which matches the provided value.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_UINT and
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* The equals callback provided when the array list was created will be used to find the entry.
* If there was no equals callback provided a direct memory compare will be done.
*/
CELIX_UTILS_EXPORT
-void celix_arrayList_removeUInt(celix_array_list_t *list, unsigned int value);
+void celix_arrayList_removeUInt(celix_array_list_t* list, unsigned int value);
/**
* @brief Remove the first unsigned long entry from array list which matches the provided value.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_ULONG and
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* The equals callback provided when the array list was created will be used to find the entry.
* If there was no equals callback provided a direct memory compare will be done.
*/
CELIX_UTILS_EXPORT
-void celix_arrayList_removeULong(celix_array_list_t *list, unsigned long value);
+void celix_arrayList_removeULong(celix_array_list_t* list, unsigned long value);
/**
* @brief Remove the first float entry from array list which matches the provided value.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_FLOAT and
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* The equals callback provided when the array list was created will be used to find the entry.
* If there was no equals callback provided a direct memory compare will be done.
*/
CELIX_UTILS_EXPORT
-void celix_arrayList_removeFloat(celix_array_list_t *list, float value);
+void celix_arrayList_removeFloat(celix_array_list_t* list, float value);
/**
* @brief Remove the first double entry from array list which matches the provided value.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE and
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* The equals callback provided when the array list was created will be used to find the entry.
* If there was no equals callback provided a direct memory compare will be done.
*/
CELIX_UTILS_EXPORT
-void celix_arrayList_removeDouble(celix_array_list_t *list, double value);
+void celix_arrayList_removeDouble(celix_array_list_t* list, double value);
/**
* @brief Remove the first bool entry from array list which matches the provided value.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL and
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* The equals callback provided when the array list was created will be used to find the entry.
* If there was no equals callback provided a direct memory compare will be done.
*/
CELIX_UTILS_EXPORT
-void celix_arrayList_removeBool(celix_array_list_t *list, bool value);
+void celix_arrayList_removeBool(celix_array_list_t* list, bool value);
/**
* @brief Remove the first size entry from array list which matches the provided value.
*
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE or
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
* The equals callback provided when the array list was created will be used to find the entry.
* If there was no equals callback provided a direct memory compare will be done.
*/
CELIX_UTILS_EXPORT
-void celix_arrayList_removeSize(celix_array_list_t *list, size_t value);
+void celix_arrayList_removeSize(celix_array_list_t* list, size_t value);
+
+/**
+ * @brief Remove the first version entry from array list which matches the provided value.
+ *
+ * Can be used for array list with element type CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION and
+ * CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
+ *
+ * The equals callback provided when the array list was created will be used to find the entry.
+ * If there was no equals callback provided a direct memory compare will be done.
+ */
+CELIX_UTILS_EXPORT
+void celix_arrayList_removeVersion(celix_array_list_t* list, const celix_version_t* value);
/**
* @brief Sort the array list using the provided sort function.
@@ -468,11 +821,11 @@ CELIX_UTILS_EXPORT
void celix_arrayList_sortEntries(celix_array_list_t *list, celix_array_list_compare_entries_fp compare);
/**
- * @warning Never use this function with array of doubles, since on some 32-bit platform (sizeof(double)==8 && sizeof(void*)==4)
- * @deprecated This function is deprecated, use celix_arrayList_sortEntries instead.
+ * @brief Sort the array list using the array list configured compare function.
+ * Note that undefined the array list compare function can be NULL and in that case the array list will not be sorted.
*/
-CELIX_UTILS_DEPRECATED_EXPORT
-void celix_arrayList_sort(celix_array_list_t *list, celix_arrayList_sort_fp sortFp);
+CELIX_UTILS_EXPORT
+void celix_arrayList_sort(celix_array_list_t *list);
#ifdef __cplusplus
}
diff --git a/libs/utils/src/array_list.c b/libs/utils/src/array_list.c
index 5b7a16e2..807d21b2 100644
--- a/libs/utils/src/array_list.c
+++ b/libs/utils/src/array_list.c
@@ -24,26 +24,135 @@
* \copyright Apache License, Version 2.0
*/
-#include <stdlib.h>
+#include <assert.h>
+#include <stdint.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "celix_array_list.h"
-#include "array_list_private.h"
#include "celix_build_assert.h"
-
-static bool celix_arrayList_defaultEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+#include "celix_err.h"
+#include "celix_stdlib_cleanup.h"
+#include "celix_utils.h"
+
+struct celix_array_list {
+ celix_array_list_element_type_t elementType;
+ celix_array_list_entry_t* elementData;
+ size_t size;
+ size_t capacity;
+ unsigned int modCount;
+ celix_arrayList_equals_fp equalsCallback;
+ celix_array_list_compare_entries_fp compareCallback;
+ void (*simpleRemovedCallback)(void* value);
+ void* removedCallbackData;
+ void (*removedCallback)(void* data, celix_array_list_entry_t entry);
+};
+
+static bool celix_arrayList_undefinedEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
return memcmp(&a, &b, sizeof(a)) == 0;
}
+static int celix_arrayList_comparePtrEntries(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ uintptr_t ptrA = (uintptr_t)a.voidPtrVal;
+ uintptr_t ptrB = (uintptr_t)b.voidPtrVal;
+ return (int)(ptrA - ptrB);
+}
+
+static bool celix_arrayList_PtrEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return celix_arrayList_comparePtrEntries(a, b) == 0;
+}
+
+static int celix_arrayList_compareStringEntries(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return strcmp(a.stringVal, b.stringVal);
+}
+
+static bool celix_arrayList_stringEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return celix_arrayList_compareStringEntries(a, b) == 0;
+}
+
+static int celix_arrayList_compareIntEntries(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return a.intVal - b.intVal;
+}
+
+static bool celix_arrayList_intEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return celix_arrayList_compareIntEntries(a, b) == 0;
+}
+
+static int celix_arrayList_compareLongEntries(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return a.longVal > b.longVal ? 1 : (a.longVal < b.longVal ? -1 : 0);
+}
+
+static bool celix_arrayList_longEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return celix_arrayList_compareLongEntries(a, b) == 0;
+}
+
+static int celix_arrayList_compareUIntEntries(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return a.uintVal > b.uintVal ? 1 : (a.uintVal < b.uintVal ? -1 : 0);
+}
+
+static bool celix_arrayList_uintEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return celix_arrayList_compareUIntEntries(a, b) == 0;
+}
+
+static int celix_arrayList_compareULongEntries(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return a.ulongVal > b.ulongVal ? 1 : (a.ulongVal < b.ulongVal ? -1 : 0);
+}
+
+static bool celix_arrayList_ulongEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return celix_arrayList_compareULongEntries(a, b) == 0;
+}
+
+static int celix_arrayList_compareFloatEntries(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return a.floatVal > b.floatVal ? 1 : (a.floatVal < b.floatVal ? -1 : 0);
+}
+
+static bool celix_arrayList_floatEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return celix_arrayList_compareFloatEntries(a, b) == 0;
+}
+
+static int celix_arrayList_compareDoubleEntries(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return a.doubleVal > b.doubleVal ? 1 : (a.doubleVal < b.doubleVal ? -1 : 0);
+}
+
+static bool celix_arrayList_doubleEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return celix_arrayList_compareDoubleEntries(a, b) == 0;
+}
+
+static int celix_arrayList_compareBoolEntries(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return a.boolVal - b.boolVal;
+}
+
+static bool celix_arrayList_boolEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return celix_arrayList_compareBoolEntries(a, b) == 0;
+}
+
+static int celix_arrayList_compareSizeEntries(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return a.sizeVal > b.sizeVal ? 1 : (a.sizeVal < b.sizeVal ? -1 : 0);
+}
+
+static bool celix_arrayList_sizeEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return celix_arrayList_compareSizeEntries(a, b) == 0;
+}
+
+static int celix_arrayList_compareVersionEntries(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return celix_version_compareTo(a.versionVal, b.versionVal);
+}
+
+static bool celix_arrayList_versionEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return celix_arrayList_compareVersionEntries(a, b) == 0;
+}
+
static bool celix_arrayList_equalsForElement(celix_array_list_t *list, celix_array_list_entry_t a, celix_array_list_entry_t b) {
- bool equals = false;
- if (list != NULL) {
- if (list->equals != NULL) {
- equals = list->equals(a, b);
- }
+ if (list && list->equalsCallback != NULL) {
+ return list->equalsCallback(a, b);
}
- return equals;
+ return false;
+}
+
+static void celix_arrayList_destroyVersion(void* v) {
+ celix_version_t* version = v;
+ celix_version_destroy(version);
}
static void celix_arrayList_callRemovedCallback(celix_array_list_t *list, int index) {
@@ -75,24 +184,139 @@ static celix_status_t celix_arrayList_ensureCapacity(celix_array_list_t* list, i
return status;
}
+static void celix_arrayList_setTypeSpecificCallbacks(celix_array_list_t* list) {
+ switch (list->elementType) {
+ case CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER:
+ list->equalsCallback = celix_arrayList_PtrEquals;
+ list->compareCallback = celix_arrayList_comparePtrEntries;
+ break;
+ case CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING:
+ list->simpleRemovedCallback = free;
+ list->equalsCallback = celix_arrayList_stringEquals;
+ list->compareCallback = celix_arrayList_compareStringEntries;
+ break;
+ case CELIX_ARRAY_LIST_ELEMENT_TYPE_INT:
+ list->equalsCallback = celix_arrayList_intEquals;
+ list->compareCallback = celix_arrayList_compareIntEntries;
+ break;
+ case CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG:
+ list->equalsCallback = celix_arrayList_longEquals;
+ list->compareCallback = celix_arrayList_compareLongEntries;
+ break;
+ case CELIX_ARRAY_LIST_ELEMENT_TYPE_UINT:
+ list->equalsCallback = celix_arrayList_uintEquals;
+ list->compareCallback = celix_arrayList_compareUIntEntries;
+ break;
+ case CELIX_ARRAY_LIST_ELEMENT_TYPE_ULONG:
+ list->equalsCallback = celix_arrayList_ulongEquals;
+ list->compareCallback = celix_arrayList_compareULongEntries;
+ break;
+ case CELIX_ARRAY_LIST_ELEMENT_TYPE_FLOAT:
+ list->equalsCallback = celix_arrayList_floatEquals;
+ list->compareCallback = celix_arrayList_compareFloatEntries;
+ break;
+ case CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE:
+ list->equalsCallback = celix_arrayList_doubleEquals;
+ list->compareCallback = celix_arrayList_compareDoubleEntries;
+ break;
+ case CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL:
+ list->equalsCallback = celix_arrayList_boolEquals;
+ list->compareCallback = celix_arrayList_compareBoolEntries;
+ break;
+ case CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE:
+ list->equalsCallback = celix_arrayList_sizeEquals;
+ list->compareCallback = celix_arrayList_compareSizeEntries;
+ break;
+ case CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION:
+ list->simpleRemovedCallback = celix_arrayList_destroyVersion;
+ list->equalsCallback = celix_arrayList_versionEquals;
+ list->compareCallback = celix_arrayList_compareVersionEntries;
+ break;
+ default:
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
+ list->equalsCallback = celix_arrayList_undefinedEquals;
+ break;
+ }
+}
+
celix_array_list_t* celix_arrayList_createWithOptions(const celix_array_list_create_options_t* opts) {
- celix_array_list_t *list = calloc(1, sizeof(*list));
- if (list != NULL) {
+ celix_autofree celix_array_list_t *list = calloc(1, sizeof(*list));
+ if (list) {
list->capacity = 10;
list->elementData = malloc(sizeof(celix_array_list_entry_t) * list->capacity);
- list->equals = opts->equalsCallback == NULL ? celix_arrayList_defaultEquals : opts->equalsCallback;
- list->simpleRemovedCallback = opts->simpleRemovedCallback;
- list->removedCallbackData = opts->removedCallbackData;
- list->removedCallback = opts->removedCallback;
+ if (!list->elementData) {
+ celix_err_push("Failed to allocate memory for elementData");
+ return NULL;
+ }
+
+ list->elementType = opts->elementType;
+ celix_arrayList_setTypeSpecificCallbacks(list);
+
+ if (opts->simpleRemovedCallback) {
+ list->simpleRemovedCallback = opts->simpleRemovedCallback;
+ }
+ if (opts->removedCallback) {
+ list->removedCallback = opts->removedCallback;
+ list->removedCallbackData = opts->removedCallbackData;
+ }
}
- return list;
+ return celix_steal_ptr(list);
}
-celix_array_list_t* celix_arrayList_create() {
+static celix_array_list_t* celix_arrayList_createTypedArray(celix_array_list_element_type_t type) {
celix_array_list_create_options_t opts = CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS;
+ opts.elementType = type;
return celix_arrayList_createWithOptions(&opts);
}
+celix_array_list_t* celix_arrayList_create() {
+ return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
+}
+
+celix_array_list_t* celix_arrayList_createPointerArray() {
+ return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER);
+}
+
+celix_array_list_t* celix_arrayList_createStringArray() {
+ return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING);
+}
+
+celix_array_list_t* celix_arrayList_createStringRefArray() {
+ return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING_REF);
+}
+
+celix_array_list_t* celix_arrayList_createIntArray() {
+ return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_INT);
+}
+
+celix_array_list_t* celix_arrayList_createLongArray() {
+ return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG);
+}
+
+celix_array_list_t* celix_arrayList_createUIntArray() {
+ return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_UINT);
+}
+
+celix_array_list_t* celix_arrayList_createULongArray() {
+ return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_ULONG);
+}
+
+celix_array_list_t* celix_arrayList_createFloatArray() {
+ return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_FLOAT);
+}
+
+celix_array_list_t* celix_arrayList_createDoubleArray() {
+ return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE);
+}
+
+celix_array_list_t* celix_arrayList_createBoolArray() {
+ return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL);
+}
+
+celix_array_list_t* celix_arrayList_createSizeArray() {
+ return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE);
+}
+
celix_array_list_t* celix_arrayList_createWithEquals(celix_arrayList_equals_fp equals) {
celix_array_list_create_options_t opts = CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS;
opts.equalsCallback = equals;
@@ -108,7 +332,7 @@ void celix_arrayList_destroy(celix_array_list_t *list) {
}
int celix_arrayList_size(const celix_array_list_t *list) {
- return list->size;
+ return (int)list->size;
}
static celix_array_list_entry_t arrayList_getEntry(const celix_array_list_t *list, int index) {
@@ -120,41 +344,73 @@ static celix_array_list_entry_t arrayList_getEntry(const celix_array_list_t *lis
return entry;
}
-void* celix_arrayList_get(const celix_array_list_t *list, int index) {
+void* celix_arrayList_get(const celix_array_list_t* list, int index) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
return arrayList_getEntry(list, index).voidPtrVal;
}
-int celix_arrayList_getInt(const celix_array_list_t* list, int index) { return arrayList_getEntry(list, index).intVal; }
+const char* celix_arrayList_getString(const celix_array_list_t* list, int index) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING_REF ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
+ return arrayList_getEntry(list, index).stringVal;
+}
+
+int celix_arrayList_getInt(const celix_array_list_t* list, int index) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_INT ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
+ return arrayList_getEntry(list, index).intVal;
+}
long int celix_arrayList_getLong(const celix_array_list_t* list, int index) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
return arrayList_getEntry(list, index).longVal;
}
unsigned int celix_arrayList_getUInt(const celix_array_list_t* list, int index) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UINT ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
return arrayList_getEntry(list, index).uintVal;
}
unsigned long int celix_arrayList_getULong(const celix_array_list_t* list, int index) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_ULONG ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
return arrayList_getEntry(list, index).ulongVal;
}
float celix_arrayList_getFloat(const celix_array_list_t* list, int index) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_FLOAT ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
return arrayList_getEntry(list, index).floatVal;
}
double celix_arrayList_getDouble(const celix_array_list_t* list, int index) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
return arrayList_getEntry(list, index).doubleVal;
}
bool celix_arrayList_getBool(const celix_array_list_t* list, int index) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
return arrayList_getEntry(list, index).boolVal;
}
size_t celix_arrayList_getSize(const celix_array_list_t* list, int index) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
return arrayList_getEntry(list, index).sizeVal;
}
-static celix_status_t celix_arrayList_addEntry(celix_array_list_t *list, celix_array_list_entry_t entry) {
+const celix_version_t* celix_arrayList_getVersion(const celix_array_list_t* list, int index) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION);
+ return arrayList_getEntry(list, index).versionVal;
+}
+
+static celix_status_t celix_arrayList_addEntry(celix_array_list_t* list, celix_array_list_entry_t entry) {
celix_status_t status = celix_arrayList_ensureCapacity(list, (int)list->size + 1);
if (status == CELIX_SUCCESS) {
list->elementData[list->size++] = entry;
@@ -162,69 +418,139 @@ static celix_status_t celix_arrayList_addEntry(celix_array_list_t *list, celix_a
return status;
}
-celix_status_t celix_arrayList_add(celix_array_list_t *list, void * element) {
+celix_status_t celix_arrayList_add(celix_array_list_t* list, void* element) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.voidPtrVal = element;
return celix_arrayList_addEntry(list, entry);
}
-celix_status_t celix_arrayList_addInt(celix_array_list_t *list, int val) {
+celix_status_t celix_arrayList_addString(celix_array_list_t* list, const char* val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING_REF ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
+ celix_array_list_entry_t entry;
+ memset(&entry, 0, sizeof(entry));
+ if (list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING) {
+ entry.stringVal = celix_utils_strdup(val);
+ if (entry.stringVal == NULL) {
+ return CELIX_ENOMEM;
+ }
+ } else {
+ entry.stringVal = val;
+ }
+ return celix_arrayList_addEntry(list, entry);
+}
+
+celix_status_t celix_arrayList_assignString(celix_array_list_t* list, char* value) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING);
+ celix_array_list_entry_t entry;
+ memset(&entry, 0, sizeof(entry));
+ entry.stringVal = celix_utils_strdup(value);
+ if (entry.stringVal == NULL) {
+ return CELIX_ENOMEM;
+ }
+ return celix_arrayList_addEntry(list, entry);
+}
+
+celix_status_t celix_arrayList_addInt(celix_array_list_t* list, int val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_INT ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.intVal = val;
return celix_arrayList_addEntry(list, entry);
}
-celix_status_t celix_arrayList_addLong(celix_array_list_t *list, long val) {
+celix_status_t celix_arrayList_addLong(celix_array_list_t* list, long val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.longVal = val;
return celix_arrayList_addEntry(list, entry);
}
-celix_status_t celix_arrayList_addUInt(celix_array_list_t *list, unsigned int val) {
+celix_status_t celix_arrayList_addUInt(celix_array_list_t* list, unsigned int val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UINT ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.uintVal = val;
return celix_arrayList_addEntry(list, entry);
}
-celix_status_t celix_arrayList_addULong(celix_array_list_t *list, unsigned long val) {
+celix_status_t celix_arrayList_addULong(celix_array_list_t* list, unsigned long val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_ULONG ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.ulongVal = val;
return celix_arrayList_addEntry(list, entry);
}
-celix_status_t celix_arrayList_addDouble(celix_array_list_t *list, double val) {
+celix_status_t celix_arrayList_addDouble(celix_array_list_t* list, double val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.doubleVal = val;
return celix_arrayList_addEntry(list, entry);
}
-celix_status_t celix_arrayList_addFloat(celix_array_list_t *list, float val) {
+celix_status_t celix_arrayList_addFloat(celix_array_list_t* list, float val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_FLOAT ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.floatVal = val;
return celix_arrayList_addEntry(list, entry);
}
-celix_status_t celix_arrayList_addBool(celix_array_list_t *list, bool val) {
+celix_status_t celix_arrayList_addBool(celix_array_list_t* list, bool val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.boolVal = val;
return celix_arrayList_addEntry(list, entry);
}
-celix_status_t celix_arrayList_addSize(celix_array_list_t *list, size_t val) {
+celix_status_t celix_arrayList_addSize(celix_array_list_t* list, size_t val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.sizeVal = val;
return celix_arrayList_addEntry(list, entry);
}
+celix_status_t celix_arrayList_addVersion(celix_array_list_t* list, const celix_version_t* value) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
+ celix_array_list_entry_t entry;
+ memset(&entry, 0, sizeof(entry));
+ if (list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION) {
+ entry.versionVal = celix_version_copy(value);
+ if (entry.versionVal == NULL) {
+ return CELIX_ENOMEM;
+ }
+ } else {
+ entry.versionVal = value;
+ }
+ return celix_arrayList_addEntry(list, entry);
+}
+
+celix_status_t celix_arrayList_assignVersion(celix_array_list_t* list, celix_version_t* value) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION);
+ celix_array_list_entry_t entry;
+ memset(&entry, 0, sizeof(entry));
+ entry.versionVal = value;
+ return celix_arrayList_addEntry(list, entry);
+}
+
int celix_arrayList_indexOf(celix_array_list_t *list, celix_array_list_entry_t entry) {
size_t size = celix_arrayList_size(list);
int i;
@@ -253,70 +579,106 @@ void celix_arrayList_removeEntry(celix_array_list_t *list, celix_array_list_entr
celix_arrayList_removeAt(list, index);
}
-
-void celix_arrayList_remove(celix_array_list_t *list, void *ptr) {
+void celix_arrayList_remove(celix_array_list_t* list, void* ptr) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.voidPtrVal = ptr;
celix_arrayList_removeEntry(list, entry);
}
-void celix_arrayList_removeInt(celix_array_list_t *list, int val) {
+void celix_arrayList_removeString(celix_array_list_t* list, const char* val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING_REF ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
+ celix_array_list_entry_t entry;
+ memset(&entry, 0, sizeof(entry));
+ entry.stringVal = val;
+ celix_arrayList_removeEntry(list, entry);
+}
+
+void celix_arrayList_removeInt(celix_array_list_t* list, int val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_INT ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.intVal = val;
celix_arrayList_removeEntry(list, entry);
}
-void celix_arrayList_removeLong(celix_array_list_t *list, long val) {
+void celix_arrayList_removeLong(celix_array_list_t* list, long val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.longVal = val;
celix_arrayList_removeEntry(list, entry);
}
-void celix_arrayList_removeUInt(celix_array_list_t *list, unsigned int val) {
+void celix_arrayList_removeUInt(celix_array_list_t* list, unsigned int val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UINT ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.uintVal = val;
celix_arrayList_removeEntry(list, entry);
}
-void celix_arrayList_removeULong(celix_array_list_t *list, unsigned long val) {
+void celix_arrayList_removeULong(celix_array_list_t* list, unsigned long val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_ULONG ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.ulongVal = val;
celix_arrayList_removeEntry(list, entry);
}
-void celix_arrayList_removeFloat(celix_array_list_t *list, float val) {
+void celix_arrayList_removeFloat(celix_array_list_t* list, float val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_FLOAT ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.floatVal = val;
celix_arrayList_removeEntry(list, entry);
}
-void celix_arrayList_removeDouble(celix_array_list_t *list, double val) {
+void celix_arrayList_removeDouble(celix_array_list_t* list, double val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.doubleVal = val;
celix_arrayList_removeEntry(list, entry);
}
-void celix_arrayList_removeBool(celix_array_list_t *list, bool val) {
+void celix_arrayList_removeBool(celix_array_list_t* list, bool val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.boolVal = val;
celix_arrayList_removeEntry(list, entry);
}
-void celix_arrayList_removeSize(celix_array_list_t *list, size_t val) {
+void celix_arrayList_removeSize(celix_array_list_t* list, size_t val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
entry.sizeVal = val;
celix_arrayList_removeEntry(list, entry);
}
+void celix_arrayList_removeVersion(celix_array_list_t* list, const celix_version_t* val) {
+ assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION ||
+ list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
+ celix_array_list_entry_t entry;
+ memset(&entry, 0, sizeof(entry));
+ entry.versionVal = val;
+ celix_arrayList_removeEntry(list, entry);
+}
+
void celix_arrayList_clear(celix_array_list_t *list) {
list->modCount++;
for (int i = 0; i < list->size; ++i) {
@@ -344,24 +706,3 @@ void celix_arrayList_sortEntries(celix_array_list_t *list, celix_array_list_comp
qsort_r(list->elementData, list->size, sizeof(celix_array_list_entry_t), celix_arrayList_compareEntries, compare);
#endif
}
-
-#if defined(__APPLE__)
-static int celix_arrayList_compare(void *arg, const void * a, const void *b) {
-#else
-static int celix_arrayList_compare(const void * a, const void *b, void *arg) {
-#endif
- const celix_array_list_entry_t *aEntry = a;
- const celix_array_list_entry_t *bEntry = b;
-
- celix_arrayList_sort_fp sort = arg;
-
- return sort(aEntry->voidPtrVal, bEntry->voidPtrVal);
-}
-
-void celix_arrayList_sort(celix_array_list_t *list, celix_arrayList_sort_fp sortFp) {
-#if defined(__APPLE__)
- qsort_r(list->elementData, list->size, sizeof(celix_array_list_entry_t), sortFp, celix_arrayList_compare);
-#else
- qsort_r(list->elementData, list->size, sizeof(celix_array_list_entry_t), celix_arrayList_compare, sortFp);
-#endif
-}
diff --git a/libs/utils/src/array_list_private.h b/libs/utils/src/array_list_private.h
deleted file mode 100644
index 1746202d..00000000
--- a/libs/utils/src/array_list_private.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * array_list_private.h
- *
- * \date Aug 4, 2010
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef array_list_t_PRIVATE_H_
-#define array_list_t_PRIVATE_H_
-
-struct celix_array_list {
- celix_array_list_entry_t* elementData;
- size_t size;
- size_t capacity;
- unsigned int modCount;
- celix_arrayList_equals_fp equals;
- void (*simpleRemovedCallback)(void* value);
- void* removedCallbackData;
- void (*removedCallback)(void* data, celix_array_list_entry_t entry);
-};
-
-#endif /* array_list_t_PRIVATE_H_ */
(celix) 04/04: #674 Add array list element type testing
Posted by pn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a commit to branch feature/674-add-element-type-to-array-list
in repository https://gitbox.apache.org/repos/asf/celix.git
commit f0ff9d94eb83ba3589e644988c338086db251b18
Author: Pepijn Noltes <pn...@apache.org>
AuthorDate: Sun Feb 4 23:32:00 2024 +0100
#674 Add array list element type testing
---
.../log_admin/gtest/src/LogAdminTestSuite.cc | 8 -
bundles/logging/log_admin/src/celix_log_admin.c | 4 +-
.../log_service_api/include/celix_log_control.h | 12 +
libs/utils/gtest/CMakeLists.txt | 2 +-
libs/utils/gtest/src/ArrayListTestSuite.cc | 351 ++++++++++++++++-----
libs/utils/include/celix_array_list.h | 10 +-
libs/utils/src/array_list.c | 40 ++-
7 files changed, 330 insertions(+), 97 deletions(-)
diff --git a/bundles/logging/log_admin/gtest/src/LogAdminTestSuite.cc b/bundles/logging/log_admin/gtest/src/LogAdminTestSuite.cc
index 859a24a7..fe11a78f 100644
--- a/bundles/logging/log_admin/gtest/src/LogAdminTestSuite.cc
+++ b/bundles/logging/log_admin/gtest/src/LogAdminTestSuite.cc
@@ -208,10 +208,6 @@ TEST_F(LogBundleTestSuite, SinkLogControl) {
auto *list = control->currentSinks(control->handle);
EXPECT_EQ(3, celix_arrayList_size(list));
- for (int i = 0; i < celix_arrayList_size(list); ++i) {
- auto *item = celix_arrayList_get(list, i);
- free(item);
- }
celix_arrayList_destroy(list);
@@ -277,10 +273,6 @@ TEST_F(LogBundleTestSuite, LogServiceControl) {
auto *list = control->currentLogServices(control->handle);
EXPECT_EQ(4, celix_arrayList_size(list));
- for (int i = 0; i < celix_arrayList_size(list); ++i) {
- auto *item = celix_arrayList_get(list, i);
- free(item);
- }
celix_arrayList_destroy(list);
celix_bundleContext_stopTracker(ctx.get(), trkId1);
diff --git a/bundles/logging/log_admin/src/celix_log_admin.c b/bundles/logging/log_admin/src/celix_log_admin.c
index 6b1be0f5..5ed38d53 100644
--- a/bundles/logging/log_admin/src/celix_log_admin.c
+++ b/bundles/logging/log_admin/src/celix_log_admin.c
@@ -544,7 +544,7 @@ static void celix_logAdmin_InfoCmd(celix_log_admin_t* admin, FILE* outStream, FI
fprintf(outStream, "Log Admin provided log services:\n");
for (int i = 0 ; i < celix_arrayList_size(logServices); ++i) {
- char *name = celix_arrayList_get(logServices, i);
+ const char *name = celix_arrayList_getString(logServices, i);
celix_log_level_e level;
bool detailed;
bool found = celix_logAdmin_logServiceInfoEx(admin, name, &level, &detailed);
@@ -558,7 +558,7 @@ static void celix_logAdmin_InfoCmd(celix_log_admin_t* admin, FILE* outStream, FI
if (celix_arrayList_size(sinks) > 0) {
fprintf(outStream, "Log Admin found log sinks:\n");
for (int i = 0 ; i < celix_arrayList_size(sinks); ++i) {
- char *name = celix_arrayList_get(sinks, i);
+ const char *name = celix_arrayList_getString(sinks, i);
bool enabled;
bool found = celix_logAdmin_sinkInfo(admin, name, &enabled);
if (found) {
diff --git a/bundles/logging/log_service_api/include/celix_log_control.h b/bundles/logging/log_service_api/include/celix_log_control.h
index 5f3d82f3..98c9a31d 100644
--- a/bundles/logging/log_service_api/include/celix_log_control.h
+++ b/bundles/logging/log_service_api/include/celix_log_control.h
@@ -44,8 +44,20 @@ typedef struct celix_log_control {
size_t (*setSinkEnabled)(void *handle, const char* select, bool enabled);
+ /**
+ * @brief Get a list of names for the log service provided by the log service.
+ * @param handle The service handle.
+ * @return A string array list.
+ * The array list is owned by the caller and should be destroyed by calling celix_arrayList_destroy.
+ */
celix_array_list_t* (*currentLogServices)(void *handle);
+ /**
+ * @brief Get a list of sinks names used by the log service.
+ * @param handle The service handle.
+ * @return A string array list.
+ * The array list is owned by the caller and should be destroyed by calling celix_arrayList_destroy.
+ */
celix_array_list_t* (*currentSinks)(void *handle);
bool (*logServiceInfo)(void *handle, const char* loggerName, celix_log_level_e* outActiveLogLevel);
diff --git a/libs/utils/gtest/CMakeLists.txt b/libs/utils/gtest/CMakeLists.txt
index e1e22ef7..db39b903 100644
--- a/libs/utils/gtest/CMakeLists.txt
+++ b/libs/utils/gtest/CMakeLists.txt
@@ -34,6 +34,7 @@ add_executable(test_utils
src/ThreadsTestSuite.cc
src/CelixErrnoTestSuite.cc
src/CelixUtilsAutoCleanupTestSuite.cc
+ src/ArrayListTestSuite.cc
src/DeprecatedHashmapTestSuite.cc
)
@@ -45,7 +46,6 @@ configure_file(resources/properties.txt ${CMAKE_CURRENT_BINARY_DIR}/resources-te
if (CELIX_CXX17)
add_library(test_utils_cxx17tests OBJECT
- src/ArrayListTestSuite.cc #Uses constexpr
src/HashMapTestSuite.cc #Uses constexpr
)
target_link_libraries(test_utils_cxx17tests PRIVATE utils_cut Celix::utils GTest::gtest)
diff --git a/libs/utils/gtest/src/ArrayListTestSuite.cc b/libs/utils/gtest/src/ArrayListTestSuite.cc
index 488f069f..6a508188 100644
--- a/libs/utils/gtest/src/ArrayListTestSuite.cc
+++ b/libs/utils/gtest/src/ArrayListTestSuite.cc
@@ -83,76 +83,26 @@ TEST_F(ArrayListTestSuite, TestArrayListWithEquals) {
}
template<typename T>
-void testArrayListForTemplateType(int nrEntries) {
- auto* list = celix_arrayList_create();
+void testArrayListForTemplateType(const std::vector<T>& entries,
+ const std::function<celix_array_list_t*()>& create,
+ const std::function<celix_status_t(celix_array_list_t*, T)>& add,
+ const std::function<T(celix_array_list_t*, int)>& get,
+ const std::function<void(celix_array_list_t*, T)>& remove) {
+ auto* list = create();
//fill
- for (int i = 0; i < nrEntries; ++i) {
- if constexpr (std::is_same_v<void*, T>) {
- celix_arrayList_add(list, (void*)(intptr_t )i);
- } else if constexpr (std::is_same_v<int, T>) {
- celix_arrayList_addInt(list, i);
- } else if constexpr (std::is_same_v<long, T>) {
- celix_arrayList_addLong(list, i);
- } else if constexpr (std::is_same_v<unsigned int, T>) {
- celix_arrayList_addUInt(list, i);
- } else if constexpr (std::is_same_v<unsigned long, T>) {
- celix_arrayList_addULong(list, i);
- } else if constexpr (std::is_same_v<float, T>) {
- celix_arrayList_addFloat(list, i + 0.0f);
- } else if constexpr (std::is_same_v<double, T>) {
- celix_arrayList_addDouble(list, i + 0.0);
- } else if constexpr (std::is_same_v<bool, T>) {
- celix_arrayList_addBool(list, i % 2 == 0);
- } else if constexpr (std::is_same_v<size_t, T>) {
- celix_arrayList_addSize(list, i);
- }
+ for (const auto& entry : entries) {
+ add(list, entry);
}
- EXPECT_EQ(celix_arrayList_size(list), nrEntries);
+ EXPECT_EQ(celix_arrayList_size(list), entries.size());
//get
- for (int i = 0; i < nrEntries; ++i) {
- if constexpr (std::is_same_v<void*, T>) {
- EXPECT_EQ(celix_arrayList_get(list, i), (void*)(intptr_t )i);
- } else if constexpr (std::is_same_v<int, T>) {
- EXPECT_EQ(celix_arrayList_getInt(list, i), i);
- } else if constexpr (std::is_same_v<long, T>) {
- EXPECT_EQ(celix_arrayList_getLong(list, i), i);
- } else if constexpr (std::is_same_v<unsigned int, T>) {
- EXPECT_EQ(celix_arrayList_getUInt(list, i), i);
- } else if constexpr (std::is_same_v<unsigned long, T>) {
- EXPECT_EQ(celix_arrayList_getULong(list, i), i);
- } else if constexpr (std::is_same_v<float, T>) {
- EXPECT_EQ(celix_arrayList_getFloat(list, i), i + 0.0);
- } else if constexpr (std::is_same_v<double, T>) {
- EXPECT_EQ(celix_arrayList_getDouble(list, i), i + 0.0);
- } else if constexpr (std::is_same_v<bool, T>) {
- EXPECT_EQ(celix_arrayList_getBool(list, i), i % 2 == 0);
- } else if constexpr (std::is_same_v<size_t, T>) {
- EXPECT_EQ(celix_arrayList_getSize(list, i), i);
- }
+ for (int i = 0; i < (int)entries.size(); ++i) {
+ EXPECT_EQ(get(list, i), entries[i]);
}
//remove
- for (int i = 0; i < nrEntries; ++i) {
- if constexpr (std::is_same_v<void*, T>) {
- celix_arrayList_remove(list, (void*)(intptr_t)i);
- } else if constexpr (std::is_same_v<int, T>) {
- celix_arrayList_removeInt(list, i);
- } else if constexpr (std::is_same_v<long, T>) {
- celix_arrayList_removeLong(list, i);
- } else if constexpr (std::is_same_v<unsigned int, T>) {
- celix_arrayList_removeUInt(list, i);
- } else if constexpr (std::is_same_v<unsigned long, T>) {
- celix_arrayList_removeULong(list, i);
- } else if constexpr (std::is_same_v<float, T>) {
- celix_arrayList_removeFloat(list, i + 0.0);
- } else if constexpr (std::is_same_v<double, T>) {
- celix_arrayList_removeDouble(list, i + 0.0);
- } else if constexpr (std::is_same_v<bool, T>) {
- celix_arrayList_removeBool(list, i % 2 == 0);
- } else if constexpr (std::is_same_v<size_t, T>) {
- celix_arrayList_removeSize(list, i);
- }
+ for (int i = 0; i < (int)entries.size(); ++i) {
+ remove(list, entries[i]);
}
EXPECT_EQ(celix_arrayList_size(list), 0);
@@ -160,15 +110,270 @@ void testArrayListForTemplateType(int nrEntries) {
}
TEST_F(ArrayListTestSuite, TestDifferentEntyTypesForArrayList) {
- testArrayListForTemplateType<void*>(10);
- testArrayListForTemplateType<int>(10);
- testArrayListForTemplateType<long>(10);
- testArrayListForTemplateType<unsigned int>(10);
- testArrayListForTemplateType<unsigned long>(10);
- testArrayListForTemplateType<float>(10);
- testArrayListForTemplateType<double>(10);
- testArrayListForTemplateType<bool>(10);
- testArrayListForTemplateType<size_t>(10);
+ std::vector<int> intEntries{1, 2, 3, 4, 5};
+ testArrayListForTemplateType<int>(intEntries,
+ celix_arrayList_createIntArray,
+ celix_arrayList_addInt,
+ celix_arrayList_getInt,
+ celix_arrayList_removeInt);
+
+ std::vector<long> longEntries{1L, 2L, 3L, 4L, 5L};
+ testArrayListForTemplateType<long>(longEntries,
+ celix_arrayList_createLongArray,
+ celix_arrayList_addLong,
+ celix_arrayList_getLong,
+ celix_arrayList_removeLong);
+
+ std::vector<float> floatEntries{1.0f, 2.0f, 3.0f, 4.0f, 5.0f};
+ testArrayListForTemplateType<float>(floatEntries,
+ celix_arrayList_createFloatArray,
+ celix_arrayList_addFloat,
+ celix_arrayList_getFloat,
+ celix_arrayList_removeFloat);
+
+ std::vector<double> doubleEntries{1.0, 2.0, 3.0, 4.0, 5.0};
+ testArrayListForTemplateType<double>(doubleEntries,
+ celix_arrayList_createDoubleArray,
+ celix_arrayList_addDouble,
+ celix_arrayList_getDouble,
+ celix_arrayList_removeDouble);
+
+ std::vector<bool> boolEntries{true, false, true, false, true};
+ testArrayListForTemplateType<bool>(boolEntries,
+ celix_arrayList_createBoolArray,
+ celix_arrayList_addBool,
+ celix_arrayList_getBool,
+ celix_arrayList_removeBool);
+
+ std::vector<void*> voidPtrEntries{(void*)0x11, (void*)0x22, (void*)0x33, (void*)0x44, (void*)0x55};
+ testArrayListForTemplateType<void*>(voidPtrEntries,
+ celix_arrayList_createPointerArray,
+ celix_arrayList_add,
+ celix_arrayList_get,
+ celix_arrayList_remove);
+
+ std::vector<uint32_t> uintEntries{1, 2, 3, 4, 5};
+ testArrayListForTemplateType<uint32_t>(uintEntries,
+ celix_arrayList_createUIntArray,
+ celix_arrayList_addUInt,
+ celix_arrayList_getUInt,
+ celix_arrayList_removeUInt);
+
+ std::vector<uint64_t> ulongEntries{1, 2, 3, 4, 5};
+ testArrayListForTemplateType<uint64_t>(ulongEntries,
+ celix_arrayList_createULongArray,
+ celix_arrayList_addULong,
+ celix_arrayList_getULong,
+ celix_arrayList_removeULong);
+
+ std::vector<size_t> sizeEntries{1, 2, 3, 4, 5};
+ testArrayListForTemplateType<size_t>(sizeEntries,
+ celix_arrayList_createSizeArray,
+ celix_arrayList_addSize,
+ celix_arrayList_getSize,
+ celix_arrayList_removeSize);
+}
+
+TEST_F(ArrayListTestSuite, StringArrayList) {
+ celix_autoptr(celix_array_list_t) stringList = celix_arrayList_createStringArray();
+ const char* str1 = "1";
+ celix_arrayList_addString(stringList, str1);
+ celix_arrayList_addString(stringList, "2");
+ celix_arrayList_assignString(stringList, strdup("3"));
+
+ EXPECT_EQ(3, celix_arrayList_size(stringList));
+ EXPECT_STREQ("1", celix_arrayList_getString(stringList, 0));
+ EXPECT_NE((void*)str1, (void*)celix_arrayList_getString(stringList, 0)); //string is added as copy
+ EXPECT_STREQ("2", celix_arrayList_getString(stringList, 1));
+ EXPECT_STREQ("3", celix_arrayList_getString(stringList, 2));
+
+ celix_arrayList_removeString(stringList, "2");
+ EXPECT_EQ(2, celix_arrayList_size(stringList));
+
+ celix_autoptr(celix_array_list_t) stringRefList = celix_arrayList_createStringRefArray();
+ celix_arrayList_addString(stringRefList, str1);
+ celix_arrayList_addString(stringRefList, "2");
+ celix_arrayList_addString(stringRefList, "3");
+
+ EXPECT_EQ(3, celix_arrayList_size(stringRefList));
+ EXPECT_STREQ("1", celix_arrayList_getString(stringRefList, 0));
+ EXPECT_EQ((void*)str1, (void*)celix_arrayList_getString(stringRefList, 0)); //string is added as reference
+ EXPECT_STREQ("2", celix_arrayList_getString(stringRefList, 1));
+
+ celix_arrayList_removeString(stringRefList, "2");
+ EXPECT_EQ(2, celix_arrayList_size(stringRefList));
+}
+
+TEST_F(ArrayListTestSuite, VersionArrayList) {
+ celix_autoptr(celix_array_list_t) versionList = celix_arrayList_createVersionArray();
+ celix_version_t* v1 = celix_version_create(1, 2, 3, "a");
+ celix_arrayList_addVersion(versionList, v1); //copy
+ celix_arrayList_assignVersion(versionList, v1); //transfer ownership
+ celix_arrayList_assignVersion(versionList, celix_version_create(2, 3, 4, "b"));
+
+ EXPECT_EQ(3, celix_arrayList_size(versionList));
+ EXPECT_EQ(0, celix_version_compareToMajorMinor(celix_arrayList_getVersion(versionList, 0), 1, 2));
+ EXPECT_EQ(0, celix_version_compareToMajorMinor(celix_arrayList_getVersion(versionList, 1), 1, 2));
+ EXPECT_EQ(0, celix_version_compareToMajorMinor(celix_arrayList_getVersion(versionList, 2), 2, 3));
+
+ EXPECT_NE((void*)v1, (void*)celix_arrayList_getVersion(versionList, 0)); //version is added as copy
+ EXPECT_EQ((void*)v1, (void*)celix_arrayList_getVersion(versionList, 1)); //version is added as reference
+
+ celix_autoptr(celix_version_t) vRef = celix_version_create(1, 2, 3, "a");
+ celix_arrayList_removeVersion(versionList, vRef);
+ EXPECT_EQ(2, celix_arrayList_size(versionList));
+}
+
+TEST_F(ArrayListTestSuite, SortTypedArrayLists) {
+ // Given a ptr, string, int, long, uint, ulong, float, double, bool, size and version list
+ // with unsorted values (including duplicates)
+ celix_autoptr(celix_array_list_t) ptrList = celix_arrayList_createPointerArray();
+ celix_arrayList_add(ptrList, (void*)0x33);
+ celix_arrayList_add(ptrList, (void*)0x11);
+ celix_arrayList_add(ptrList, (void*)0x22);
+ celix_arrayList_add(ptrList, (void*)0x11);
+
+ celix_autoptr(celix_array_list_t) stringList = celix_arrayList_createStringArray();
+ celix_arrayList_addString(stringList, "3");
+ celix_arrayList_addString(stringList, "1");
+ celix_arrayList_addString(stringList, "2");
+ celix_arrayList_addString(stringList, "1");
+
+ celix_autoptr(celix_array_list_t) intList = celix_arrayList_createIntArray();
+ celix_arrayList_addInt(intList, 3);
+ celix_arrayList_addInt(intList, 1);
+ celix_arrayList_addInt(intList, 2);
+ celix_arrayList_addInt(intList, 1);
+
+ celix_autoptr(celix_array_list_t) longList = celix_arrayList_createLongArray();
+ celix_arrayList_addLong(longList, 3L);
+ celix_arrayList_addLong(longList, 1L);
+ celix_arrayList_addLong(longList, 2L);
+ celix_arrayList_addLong(longList, 1L);
+
+ celix_autoptr(celix_array_list_t) uintList = celix_arrayList_createUIntArray();
+ celix_arrayList_addUInt(uintList, 3U);
+ celix_arrayList_addUInt(uintList, 1U);
+ celix_arrayList_addUInt(uintList, 2U);
+ celix_arrayList_addUInt(uintList, 1U);
+
+ celix_autoptr(celix_array_list_t) ulongList = celix_arrayList_createULongArray();
+ celix_arrayList_addULong(ulongList, 3UL);
+ celix_arrayList_addULong(ulongList, 1UL);
+ celix_arrayList_addULong(ulongList, 2UL);
+ celix_arrayList_addULong(ulongList, 1UL);
+
+ celix_autoptr(celix_array_list_t) floatList = celix_arrayList_createFloatArray();
+ celix_arrayList_addFloat(floatList, 3.0f);
+ celix_arrayList_addFloat(floatList, 1.0f);
+ celix_arrayList_addFloat(floatList, 2.0f);
+ celix_arrayList_addFloat(floatList, 1.0f);
+
+ celix_autoptr(celix_array_list_t) doubleList = celix_arrayList_createDoubleArray();
+ celix_arrayList_addDouble(doubleList, 3.0);
+ celix_arrayList_addDouble(doubleList, 1.0);
+ celix_arrayList_addDouble(doubleList, 2.0);
+ celix_arrayList_addDouble(doubleList, 1.0);
+
+ celix_autoptr(celix_array_list_t) boolList = celix_arrayList_createBoolArray();
+ celix_arrayList_addBool(boolList, false);
+ celix_arrayList_addBool(boolList, true);
+ celix_arrayList_addBool(boolList, false);
+
+ celix_autoptr(celix_array_list_t) sizeList = celix_arrayList_createSizeArray();
+ celix_arrayList_addSize(sizeList, 3);
+ celix_arrayList_addSize(sizeList, 1);
+ celix_arrayList_addSize(sizeList, 2);
+ celix_arrayList_addSize(sizeList, 1);
+
+ celix_autoptr(celix_array_list_t) versionList = celix_arrayList_createVersionArray();
+ celix_arrayList_assignVersion(versionList, celix_version_create(2, 1, 0, ""));
+ celix_arrayList_assignVersion(versionList, celix_version_create(3, 2, 1, ""));
+ celix_arrayList_assignVersion(versionList, celix_version_create(2, 1, 0, ""));
+ celix_arrayList_assignVersion(versionList, celix_version_create(1, 0, 0, "b"));
+ celix_arrayList_assignVersion(versionList, celix_version_create(1, 0, 0, "a"));
+
+ // Then the element type is correctly set
+ EXPECT_EQ(CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER, celix_arrayList_getElementType(ptrList));
+ EXPECT_EQ(CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING, celix_arrayList_getElementType(stringList));
+ EXPECT_EQ(CELIX_ARRAY_LIST_ELEMENT_TYPE_INT, celix_arrayList_getElementType(intList));
+ EXPECT_EQ(CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG, celix_arrayList_getElementType(longList));
+ EXPECT_EQ(CELIX_ARRAY_LIST_ELEMENT_TYPE_UINT, celix_arrayList_getElementType(uintList));
+ EXPECT_EQ(CELIX_ARRAY_LIST_ELEMENT_TYPE_ULONG, celix_arrayList_getElementType(ulongList));
+ EXPECT_EQ(CELIX_ARRAY_LIST_ELEMENT_TYPE_FLOAT, celix_arrayList_getElementType(floatList));
+ EXPECT_EQ(CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE, celix_arrayList_getElementType(doubleList));
+ EXPECT_EQ(CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL, celix_arrayList_getElementType(boolList));
+ EXPECT_EQ(CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE, celix_arrayList_getElementType(sizeList));
+ EXPECT_EQ(CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION, celix_arrayList_getElementType(versionList));
+
+ // When sorting the lists
+ celix_arrayList_sort(ptrList);
+ celix_arrayList_sort(stringList);
+ celix_arrayList_sort(intList);
+ celix_arrayList_sort(longList);
+ celix_arrayList_sort(uintList);
+ celix_arrayList_sort(ulongList);
+ celix_arrayList_sort(floatList);
+ celix_arrayList_sort(doubleList);
+ celix_arrayList_sort(boolList);
+ celix_arrayList_sort(sizeList);
+ celix_arrayList_sort(versionList);
+
+ // Then the lists are sorted
+ EXPECT_EQ((void*)0x11, celix_arrayList_get(ptrList, 0));
+ EXPECT_EQ((void*)0x11, celix_arrayList_get(ptrList, 1));
+ EXPECT_EQ((void*)0x22, celix_arrayList_get(ptrList, 2));
+ EXPECT_EQ((void*)0x33, celix_arrayList_get(ptrList, 3));
+
+ EXPECT_STREQ("1", celix_arrayList_getString(stringList, 0));
+ EXPECT_STREQ("1", celix_arrayList_getString(stringList, 1));
+ EXPECT_STREQ("2", celix_arrayList_getString(stringList, 2));
+ EXPECT_STREQ("3", celix_arrayList_getString(stringList, 3));
+
+ EXPECT_EQ(1, celix_arrayList_getInt(intList, 0));
+ EXPECT_EQ(1, celix_arrayList_getInt(intList, 1));
+ EXPECT_EQ(2, celix_arrayList_getInt(intList, 2));
+ EXPECT_EQ(3, celix_arrayList_getInt(intList, 3));
+
+ EXPECT_EQ(1L, celix_arrayList_getLong(longList, 0));
+ EXPECT_EQ(1L, celix_arrayList_getLong(longList, 1));
+ EXPECT_EQ(2L, celix_arrayList_getLong(longList, 2));
+ EXPECT_EQ(3L, celix_arrayList_getLong(longList, 3));
+
+ EXPECT_EQ(1U, celix_arrayList_getUInt(uintList, 0));
+ EXPECT_EQ(1U, celix_arrayList_getUInt(uintList, 1));
+ EXPECT_EQ(2U, celix_arrayList_getUInt(uintList, 2));
+ EXPECT_EQ(3U, celix_arrayList_getUInt(uintList, 3));
+
+ EXPECT_EQ(1UL, celix_arrayList_getULong(ulongList, 0));
+ EXPECT_EQ(1UL, celix_arrayList_getULong(ulongList, 1));
+ EXPECT_EQ(2UL, celix_arrayList_getULong(ulongList, 2));
+ EXPECT_EQ(3UL, celix_arrayList_getULong(ulongList, 3));
+
+ EXPECT_FLOAT_EQ(1.0f, celix_arrayList_getFloat(floatList, 0));
+ EXPECT_FLOAT_EQ(1.0f, celix_arrayList_getFloat(floatList, 1));
+ EXPECT_FLOAT_EQ(2.0f, celix_arrayList_getFloat(floatList, 2));
+ EXPECT_FLOAT_EQ(3.0f, celix_arrayList_getFloat(floatList, 3));
+
+ EXPECT_DOUBLE_EQ(1.0, celix_arrayList_getDouble(doubleList, 0));
+ EXPECT_DOUBLE_EQ(1.0, celix_arrayList_getDouble(doubleList, 1));
+ EXPECT_DOUBLE_EQ(2.0, celix_arrayList_getDouble(doubleList, 2));
+ EXPECT_DOUBLE_EQ(3.0, celix_arrayList_getDouble(doubleList, 3));
+
+ EXPECT_FALSE(celix_arrayList_getBool(boolList, 0));
+ EXPECT_FALSE(celix_arrayList_getBool(boolList, 1));
+ EXPECT_TRUE(celix_arrayList_getBool(boolList, 2));
+
+ EXPECT_EQ(1, celix_arrayList_getSize(sizeList, 0));
+ EXPECT_EQ(1, celix_arrayList_getSize(sizeList, 1));
+ EXPECT_EQ(2, celix_arrayList_getSize(sizeList, 2));
+ EXPECT_EQ(3, celix_arrayList_getSize(sizeList, 3));
+
+ EXPECT_EQ(0, celix_version_compareToMajorMinor(celix_arrayList_getVersion(versionList, 0), 1, 0));
+ EXPECT_EQ(0, celix_version_compareToMajorMinor(celix_arrayList_getVersion(versionList, 1), 1, 0));
+ EXPECT_EQ(0, celix_version_compareToMajorMinor(celix_arrayList_getVersion(versionList, 2), 2, 1));
+ EXPECT_EQ(0, celix_version_compareToMajorMinor(celix_arrayList_getVersion(versionList, 3), 2, 1));
+ EXPECT_EQ(0, celix_version_compareToMajorMinor(celix_arrayList_getVersion(versionList, 4), 3, 2));
}
TEST_F(ArrayListTestSuite, TestSimpleRemovedCallbacksForArrayList) {
@@ -261,4 +466,4 @@ TEST_F(ArrayListTestSuite, TestReturnStatusAddFunctions) {
TEST_F(ArrayListTestSuite, AutoCleanupTest) {
celix_autoptr(celix_array_list_t) list = celix_arrayList_create();
EXPECT_NE(nullptr, list);
-}
\ No newline at end of file
+}
diff --git a/libs/utils/include/celix_array_list.h b/libs/utils/include/celix_array_list.h
index 25925c89..b4c2dc58 100644
--- a/libs/utils/include/celix_array_list.h
+++ b/libs/utils/include/celix_array_list.h
@@ -294,7 +294,9 @@ celix_array_list_t* celix_arrayList_createVersionArray();
/**
* @brief Creates a new empty array list using using the provided array list create options.
*
- * The underlying element type will be undefined, until the first element is added.
+ * If the element type is set to something other than CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED, the remove, equals,
+ * and compare callbacks will be set according to the corresponding celix_arrayList_create*Array function.
+ * The provided callbacks in the options will override the default callbacks.
*
* @param opts The create options, only used during the creation of the array list.
*/
@@ -311,6 +313,12 @@ void celix_arrayList_destroy(celix_array_list_t *list);
CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(celix_array_list_t, celix_arrayList_destroy)
+/**
+ * @brief Return the element type of the array list.
+ */
+CELIX_UTILS_EXPORT
+celix_array_list_element_type_t celix_arrayList_getElementType(const celix_array_list_t *list);
+
/**
* @brief Returns the size of the array list.
*/
diff --git a/libs/utils/src/array_list.c b/libs/utils/src/array_list.c
index 807d21b2..cf668150 100644
--- a/libs/utils/src/array_list.c
+++ b/libs/utils/src/array_list.c
@@ -16,13 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * array_list.c
- *
- * \date Aug 4, 2010
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
#include <assert.h>
#include <stdint.h>
@@ -50,7 +43,7 @@ struct celix_array_list {
};
static bool celix_arrayList_undefinedEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
- return memcmp(&a, &b, sizeof(a)) == 0;
+ return memcmp(&a.voidPtrVal, &b.voidPtrVal, sizeof(a)) == 0;
}
static int celix_arrayList_comparePtrEntries(celix_array_list_entry_t a, celix_array_list_entry_t b) {
@@ -195,6 +188,10 @@ static void celix_arrayList_setTypeSpecificCallbacks(celix_array_list_t* list) {
list->equalsCallback = celix_arrayList_stringEquals;
list->compareCallback = celix_arrayList_compareStringEntries;
break;
+ case CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING_REF:
+ list->equalsCallback = celix_arrayList_stringEquals;
+ list->compareCallback = celix_arrayList_compareStringEntries;
+ break;
case CELIX_ARRAY_LIST_ELEMENT_TYPE_INT:
list->equalsCallback = celix_arrayList_intEquals;
list->compareCallback = celix_arrayList_compareIntEntries;
@@ -252,6 +249,7 @@ celix_array_list_t* celix_arrayList_createWithOptions(const celix_array_list_cre
list->elementType = opts->elementType;
celix_arrayList_setTypeSpecificCallbacks(list);
+ //if opts contains callbacks, use them and override the default ones
if (opts->simpleRemovedCallback) {
list->simpleRemovedCallback = opts->simpleRemovedCallback;
}
@@ -259,6 +257,12 @@ celix_array_list_t* celix_arrayList_createWithOptions(const celix_array_list_cre
list->removedCallback = opts->removedCallback;
list->removedCallbackData = opts->removedCallbackData;
}
+ if (opts->equalsCallback) {
+ list->equalsCallback = opts->equalsCallback;
+ }
+ if (opts->compareCallback) {
+ list->compareCallback = opts->compareCallback;
+ }
}
return celix_steal_ptr(list);
}
@@ -317,6 +321,11 @@ celix_array_list_t* celix_arrayList_createSizeArray() {
return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE);
}
+celix_array_list_t* celix_arrayList_createVersionArray() {
+ return celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION);
+}
+
+
celix_array_list_t* celix_arrayList_createWithEquals(celix_arrayList_equals_fp equals) {
celix_array_list_create_options_t opts = CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS;
opts.equalsCallback = equals;
@@ -331,6 +340,10 @@ void celix_arrayList_destroy(celix_array_list_t *list) {
}
}
+celix_array_list_element_type_t celix_arrayList_getElementType(const celix_array_list_t *list) {
+ return list->elementType;
+}
+
int celix_arrayList_size(const celix_array_list_t *list) {
return (int)list->size;
}
@@ -448,10 +461,7 @@ celix_status_t celix_arrayList_assignString(celix_array_list_t* list, char* valu
assert(list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
- entry.stringVal = celix_utils_strdup(value);
- if (entry.stringVal == NULL) {
- return CELIX_ENOMEM;
- }
+ entry.stringVal = value;
return celix_arrayList_addEntry(list, entry);
}
@@ -699,6 +709,12 @@ static int celix_arrayList_compareEntries(const void* voidA, const void* voidB,
return compare(*a, *b);
}
+void celix_arrayList_sort(celix_array_list_t *list) {
+ if (list->compareCallback) {
+ celix_arrayList_sortEntries(list, list->compareCallback);
+ }
+}
+
void celix_arrayList_sortEntries(celix_array_list_t *list, celix_array_list_compare_entries_fp compare) {
#if defined(__APPLE__)
qsort_r(list->elementData, list->size, sizeof(celix_array_list_entry_t), compare, celix_arrayList_compareEntries);
(celix) 02/04: #674 Refactor array list compare in ctx, reg and rsa
Posted by pn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a commit to branch feature/674-add-element-type-to-array-list
in repository https://gitbox.apache.org/repos/asf/celix.git
commit ba42e664ca5eff9e43a2d0df1400538161cac2d7
Author: Pepijn Noltes <pn...@apache.org>
AuthorDate: Sun Feb 4 19:07:24 2024 +0100
#674 Refactor array list compare in ctx, reg and rsa
---
.../discovery_common/src/endpoint_discovery_poller.c | 8 ++++++--
.../rsa_common/src/remote_interceptors_handler.c | 10 +++++-----
libs/framework/include_deprecated/service_registry.h | 2 +-
libs/framework/src/bundle_context.c | 4 ++--
libs/framework/src/service_registry.c | 10 +++++-----
5 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/bundles/remote_services/discovery_common/src/endpoint_discovery_poller.c b/bundles/remote_services/discovery_common/src/endpoint_discovery_poller.c
index edf560fc..567ff84b 100644
--- a/bundles/remote_services/discovery_common/src/endpoint_discovery_poller.c
+++ b/bundles/remote_services/discovery_common/src/endpoint_discovery_poller.c
@@ -195,7 +195,9 @@ celix_status_t endpointDiscoveryPoller_addDiscoveryEndpoint(endpoint_discovery_p
// Avoid memory leaks when adding an already existing URL...
celix_array_list_t* endpoints = hashMap_get(poller->entries, url);
if (endpoints == NULL) {
- endpoints = celix_arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals);
+ celix_array_list_create_options_t opts = CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS;
+ opts.equalsCallback = endpointDiscoveryPoller_endpointDescriptionEquals;
+ endpoints = celix_arrayList_createWithOptions(&opts);
if (endpoints) {
celix_logHelper_debug(*poller->loghelper, "ENDPOINT_POLLER: add new discovery endpoint with url %s", url);
@@ -253,7 +255,9 @@ celix_status_t endpointDiscoveryPoller_removeDiscoveryEndpoint(endpoint_discover
celix_status_t
endpointDiscoveryPoller_poll(endpoint_discovery_poller_t* poller, char* url, celix_array_list_t* currentEndpoints) {
// create an arraylist with a custom equality test to ensure we can find endpoints properly...
- celix_array_list_t* updatedEndpoints = celix_arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals);
+ celix_array_list_create_options_t opts = CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS;
+ opts.equalsCallback = endpointDiscoveryPoller_endpointDescriptionEquals;
+ celix_array_list_t* updatedEndpoints = celix_arrayList_createWithOptions(&opts);
if (!updatedEndpoints) {
return CELIX_ENOMEM;
}
diff --git a/bundles/remote_services/rsa_common/src/remote_interceptors_handler.c b/bundles/remote_services/rsa_common/src/remote_interceptors_handler.c
index 65c25207..591e7322 100644
--- a/bundles/remote_services/rsa_common/src/remote_interceptors_handler.c
+++ b/bundles/remote_services/rsa_common/src/remote_interceptors_handler.c
@@ -42,7 +42,7 @@ struct remote_interceptors_handler {
celix_thread_mutex_t lock;
};
-static int referenceCompare(const void *a, const void *b);
+static int referenceCompare(celix_array_list_entry_t a, celix_array_list_entry_t b);
static void remoteInterceptorsHandler_addInterceptor(void *handle, void *svc, const celix_properties_t *props);
static void remoteInterceptorsHandler_removeInterceptor(void *handle, void *svc, const celix_properties_t *props);
@@ -104,7 +104,7 @@ void remoteInterceptorsHandler_addInterceptor(void *handle, void *svc, const cel
entry->interceptor = svc;
celix_arrayList_add(handler->interceptors, entry);
- celix_arrayList_sort(handler->interceptors, referenceCompare);
+ celix_arrayList_sortEntries(handler->interceptors, referenceCompare);
}
celixThreadMutex_unlock(&handler->lock);
@@ -197,9 +197,9 @@ void remoteInterceptorHandler_invokePostProxyCall(remote_interceptors_handler_t
celixThreadMutex_unlock(&handler->lock);
}
-int referenceCompare(const void *a, const void *b) {
- const entry_t *aEntry = a;
- const entry_t *bEntry = b;
+int referenceCompare(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ const entry_t *aEntry = a.voidPtrVal;
+ const entry_t *bEntry = b.voidPtrVal;
long servIdA = celix_properties_getAsLong(aEntry->properties, CELIX_FRAMEWORK_SERVICE_ID, 0);
long servIdB = celix_properties_getAsLong(bEntry->properties, CELIX_FRAMEWORK_SERVICE_ID, 0);
diff --git a/libs/framework/include_deprecated/service_registry.h b/libs/framework/include_deprecated/service_registry.h
index 84a55104..7cdb785d 100644
--- a/libs/framework/include_deprecated/service_registry.h
+++ b/libs/framework/include_deprecated/service_registry.h
@@ -152,7 +152,7 @@ CELIX_FRAMEWORK_EXPORT char* celix_serviceRegistry_createFilterFor(
* Find services and return a array list of service ids (long).
* Caller is responsible for freeing the returned array list.
*/
-CELIX_FRAMEWORK_EXPORT celix_array_list_t* celix_serviceRegisrty_findServices(celix_service_registry_t* registry, const char* filter);
+CELIX_FRAMEWORK_EXPORT celix_array_list_t* celix_serviceRegistry_findServices(celix_service_registry_t* registry, const char* filterStr);
#ifdef __cplusplus
diff --git a/libs/framework/src/bundle_context.c b/libs/framework/src/bundle_context.c
index 0f0bc344..e1075e71 100644
--- a/libs/framework/src/bundle_context.c
+++ b/libs/framework/src/bundle_context.c
@@ -1365,7 +1365,7 @@ long celix_bundleContext_findServiceWithOptions(celix_bundle_context_t *ctx, con
long result = -1L;
char* filter = celix_serviceRegistry_createFilterFor(ctx->framework->registry, opts->serviceName, opts->versionRange, opts->filter);
if (filter != NULL) {
- celix_array_list_t *svcIds = celix_serviceRegisrty_findServices(ctx->framework->registry, filter);
+ celix_array_list_t *svcIds = celix_serviceRegistry_findServices(ctx->framework->registry, filter);
if (svcIds != NULL && celix_arrayList_size(svcIds) > 0) {
result = celix_arrayList_getLong(svcIds, 0);
}
@@ -1388,7 +1388,7 @@ celix_array_list_t* celix_bundleContext_findServicesWithOptions(celix_bundle_con
celix_array_list_t* result = NULL;
char* filter = celix_serviceRegistry_createFilterFor(ctx->framework->registry, opts->serviceName, opts->versionRange, opts->filter);
if (filter != NULL) {
- result = celix_serviceRegisrty_findServices(ctx->framework->registry, filter);
+ result = celix_serviceRegistry_findServices(ctx->framework->registry, filter);
free(filter);
}
return result;
diff --git a/libs/framework/src/service_registry.c b/libs/framework/src/service_registry.c
index 467925bb..0afcd4ae 100644
--- a/libs/framework/src/service_registry.c
+++ b/libs/framework/src/service_registry.c
@@ -843,9 +843,9 @@ char* celix_serviceRegistry_createFilterFor(celix_service_registry_t* registry,
return filter;
}
-static int celix_serviceRegistry_compareRegistrations(const void *a, const void *b) {
- const service_registration_t* regA = a;
- const service_registration_t* regB = b;
+static int celix_serviceRegistry_compareRegistrations(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ const service_registration_t* regA = a.voidPtrVal;
+ const service_registration_t* regB = b.voidPtrVal;
celix_properties_t* propsA = NULL;
celix_properties_t* propsB = NULL;
@@ -861,7 +861,7 @@ static int celix_serviceRegistry_compareRegistrations(const void *a, const void
return celix_utils_compareServiceIdsAndRanking(servIdA, servRankingA, servIdB, servRankingB);
}
-celix_array_list_t* celix_serviceRegisrty_findServices(
+celix_array_list_t* celix_serviceRegistry_findServices(
celix_service_registry_t* registry,
const char* filterStr) {
@@ -892,7 +892,7 @@ celix_array_list_t* celix_serviceRegisrty_findServices(
//sort matched registration and add the svc id to the result list.
if (celix_arrayList_size(matchedRegistrations) > 1) {
- celix_arrayList_sort(matchedRegistrations, celix_serviceRegistry_compareRegistrations);
+ celix_arrayList_sortEntries(matchedRegistrations, celix_serviceRegistry_compareRegistrations);
}
for (int i = 0; i < celix_arrayList_size(matchedRegistrations); ++i) {
service_registration_t* reg = celix_arrayList_get(matchedRegistrations, i);