From f0ff9d94eb83ba3589e644988c338086db251b18 Mon Sep 17 00:00:00 2001 From: Pepijn Noltes Date: Sun, 4 Feb 2024 23:32:00 +0100 Subject: [PATCH] #674 Add array list element type testing --- .../log_admin/gtest/src/LogAdminTestSuite.cc | 8 - .../logging/log_admin/src/celix_log_admin.c | 4 +- .../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 859a24a72..fe11a78f5 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 6b1be0f5a..5ed38d53d 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 5f3d82f34..98c9a31da 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 e1e22ef7e..db39b9035 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 488f069f2..6a5081886 100644 --- a/libs/utils/gtest/src/ArrayListTestSuite.cc +++ b/libs/utils/gtest/src/ArrayListTestSuite.cc @@ -83,76 +83,26 @@ TEST_F(ArrayListTestSuite, TestArrayListWithEquals) { } template -void testArrayListForTemplateType(int nrEntries) { - auto* list = celix_arrayList_create(); +void testArrayListForTemplateType(const std::vector& entries, + const std::function& create, + const std::function& add, + const std::function& get, + const std::function& remove) { + auto* list = create(); //fill - for (int i = 0; i < nrEntries; ++i) { - if constexpr (std::is_same_v) { - celix_arrayList_add(list, (void*)(intptr_t )i); - } else if constexpr (std::is_same_v) { - celix_arrayList_addInt(list, i); - } else if constexpr (std::is_same_v) { - celix_arrayList_addLong(list, i); - } else if constexpr (std::is_same_v) { - celix_arrayList_addUInt(list, i); - } else if constexpr (std::is_same_v) { - celix_arrayList_addULong(list, i); - } else if constexpr (std::is_same_v) { - celix_arrayList_addFloat(list, i + 0.0f); - } else if constexpr (std::is_same_v) { - celix_arrayList_addDouble(list, i + 0.0); - } else if constexpr (std::is_same_v) { - celix_arrayList_addBool(list, i % 2 == 0); - } else if constexpr (std::is_same_v) { - 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) { - EXPECT_EQ(celix_arrayList_get(list, i), (void*)(intptr_t )i); - } else if constexpr (std::is_same_v) { - EXPECT_EQ(celix_arrayList_getInt(list, i), i); - } else if constexpr (std::is_same_v) { - EXPECT_EQ(celix_arrayList_getLong(list, i), i); - } else if constexpr (std::is_same_v) { - EXPECT_EQ(celix_arrayList_getUInt(list, i), i); - } else if constexpr (std::is_same_v) { - EXPECT_EQ(celix_arrayList_getULong(list, i), i); - } else if constexpr (std::is_same_v) { - EXPECT_EQ(celix_arrayList_getFloat(list, i), i + 0.0); - } else if constexpr (std::is_same_v) { - EXPECT_EQ(celix_arrayList_getDouble(list, i), i + 0.0); - } else if constexpr (std::is_same_v) { - EXPECT_EQ(celix_arrayList_getBool(list, i), i % 2 == 0); - } else if constexpr (std::is_same_v) { - 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) { - celix_arrayList_remove(list, (void*)(intptr_t)i); - } else if constexpr (std::is_same_v) { - celix_arrayList_removeInt(list, i); - } else if constexpr (std::is_same_v) { - celix_arrayList_removeLong(list, i); - } else if constexpr (std::is_same_v) { - celix_arrayList_removeUInt(list, i); - } else if constexpr (std::is_same_v) { - celix_arrayList_removeULong(list, i); - } else if constexpr (std::is_same_v) { - celix_arrayList_removeFloat(list, i + 0.0); - } else if constexpr (std::is_same_v) { - celix_arrayList_removeDouble(list, i + 0.0); - } else if constexpr (std::is_same_v) { - celix_arrayList_removeBool(list, i % 2 == 0); - } else if constexpr (std::is_same_v) { - 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(10); - testArrayListForTemplateType(10); - testArrayListForTemplateType(10); - testArrayListForTemplateType(10); - testArrayListForTemplateType(10); - testArrayListForTemplateType(10); - testArrayListForTemplateType(10); - testArrayListForTemplateType(10); - testArrayListForTemplateType(10); + std::vector intEntries{1, 2, 3, 4, 5}; + testArrayListForTemplateType(intEntries, + celix_arrayList_createIntArray, + celix_arrayList_addInt, + celix_arrayList_getInt, + celix_arrayList_removeInt); + + std::vector longEntries{1L, 2L, 3L, 4L, 5L}; + testArrayListForTemplateType(longEntries, + celix_arrayList_createLongArray, + celix_arrayList_addLong, + celix_arrayList_getLong, + celix_arrayList_removeLong); + + std::vector floatEntries{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + testArrayListForTemplateType(floatEntries, + celix_arrayList_createFloatArray, + celix_arrayList_addFloat, + celix_arrayList_getFloat, + celix_arrayList_removeFloat); + + std::vector doubleEntries{1.0, 2.0, 3.0, 4.0, 5.0}; + testArrayListForTemplateType(doubleEntries, + celix_arrayList_createDoubleArray, + celix_arrayList_addDouble, + celix_arrayList_getDouble, + celix_arrayList_removeDouble); + + std::vector boolEntries{true, false, true, false, true}; + testArrayListForTemplateType(boolEntries, + celix_arrayList_createBoolArray, + celix_arrayList_addBool, + celix_arrayList_getBool, + celix_arrayList_removeBool); + + std::vector voidPtrEntries{(void*)0x11, (void*)0x22, (void*)0x33, (void*)0x44, (void*)0x55}; + testArrayListForTemplateType(voidPtrEntries, + celix_arrayList_createPointerArray, + celix_arrayList_add, + celix_arrayList_get, + celix_arrayList_remove); + + std::vector uintEntries{1, 2, 3, 4, 5}; + testArrayListForTemplateType(uintEntries, + celix_arrayList_createUIntArray, + celix_arrayList_addUInt, + celix_arrayList_getUInt, + celix_arrayList_removeUInt); + + std::vector ulongEntries{1, 2, 3, 4, 5}; + testArrayListForTemplateType(ulongEntries, + celix_arrayList_createULongArray, + celix_arrayList_addULong, + celix_arrayList_getULong, + celix_arrayList_removeULong); + + std::vector sizeEntries{1, 2, 3, 4, 5}; + testArrayListForTemplateType(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 25925c891..b4c2dc587 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 807d21b29..cf6681504 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 Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ #include #include @@ -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);