This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch feature/674-improve-properties in repository https://gitbox.apache.org/repos/asf/celix.git
commit a8038ecf565df5afb952e1e3b0cd0dadb9e13e89 Author: Pepijn Noltes <[email protected]> AuthorDate: Sun Jan 7 17:25:55 2024 +0100 Add str, long, double, bool and version array support to properties --- libs/utils/gtest/src/PropertiesTestSuite.cc | 346 +++++++++++++++++-- libs/utils/include/celix_properties.h | 436 +++++++++++++++++++++++- libs/utils/src/properties.c | 495 ++++++++++++++++++++++++++-- 3 files changed, 1229 insertions(+), 48 deletions(-) diff --git a/libs/utils/gtest/src/PropertiesTestSuite.cc b/libs/utils/gtest/src/PropertiesTestSuite.cc index 8e969666..999b9a28 100644 --- a/libs/utils/gtest/src/PropertiesTestSuite.cc +++ b/libs/utils/gtest/src/PropertiesTestSuite.cc @@ -29,25 +29,28 @@ using ::testing::MatchesRegex; class PropertiesTestSuite : public ::testing::Test { -public: - PropertiesTestSuite() { - celix_err_resetErrors(); - } - - void printStats(const celix_properties_statistics_t* stats) { - printf("Properties statistics:\n"); - printf("|- nr of entries: %zu\n", stats->mapStatistics.nrOfEntries); - printf("|- nr of buckets: %zu\n", stats->mapStatistics.nrOfBuckets); - printf("|- average nr of entries in bucket: %f\n", stats->mapStatistics.averageNrOfEntriesPerBucket); - printf("|- stddev nr of entries in bucket: %f\n", stats->mapStatistics.stdDeviationNrOfEntriesPerBucket); - printf("|- resize count: %zu\n", stats->mapStatistics.resizeCount); - printf("|- size of keys and string values: %zu bytes\n", stats->sizeOfKeysAndStringValues); - printf("|- average size of keys and string values: %f bytes\n", stats->averageSizeOfKeysAndStringValues); - printf("|- fill string optimization buffer percentage: %f\n", stats->fillStringOptimizationBufferPercentage); - printf("|- fill entries optimization buffer percentage: %f\n", stats->fillEntriesOptimizationBufferPercentage); - } -}; + public: + PropertiesTestSuite() { celix_err_resetErrors(); } + + void printStats(const celix_properties_statistics_t* stats) { + printf("Properties statistics:\n"); + printf("|- nr of entries: %zu\n", stats->mapStatistics.nrOfEntries); + printf("|- nr of buckets: %zu\n", stats->mapStatistics.nrOfBuckets); + printf("|- average nr of entries in bucket: %f\n", stats->mapStatistics.averageNrOfEntriesPerBucket); + printf("|- stddev nr of entries in bucket: %f\n", stats->mapStatistics.stdDeviationNrOfEntriesPerBucket); + printf("|- resize count: %zu\n", stats->mapStatistics.resizeCount); + printf("|- size of keys and string values: %zu bytes\n", stats->sizeOfKeysAndStringValues); + printf("|- average size of keys and string values: %f bytes\n", stats->averageSizeOfKeysAndStringValues); + printf("|- fill string optimization buffer percentage: %f\n", stats->fillStringOptimizationBufferPercentage); + printf("|- fill entries optimization buffer percentage: %f\n", stats->fillEntriesOptimizationBufferPercentage); + } + void checkVersions(const celix_version_t* version1, const celix_version_t* version2) { + EXPECT_EQ(0, celix_version_compareTo(version1, version2)) + << "Expected version " << celix_version_toString(version1) << " to be equal to " + << celix_version_toString(version2); + } +}; TEST_F(PropertiesTestSuite, CreateTest) { auto* properties = celix_properties_create(); @@ -724,7 +727,42 @@ TEST_F(PropertiesTestSuite, SetDoubleWithLargeStringRepresentationTest) { ASSERT_EQ(CELIX_SUCCESS, celix_properties_setDouble(props, "large_str_value", 12345678901234567890.1234567890)); } -TEST_F(PropertiesTestSuite, LongArrayTestSuite) { +TEST_F(PropertiesTestSuite, GetLongDoubleBoolVersionAndStringTest) { + + celix_autoptr(celix_properties_t) props = celix_properties_create(); + celix_properties_setLong(props, "long", 42); + celix_properties_setDouble(props, "double", 3.14); + celix_properties_setBool(props, "bool", true); + celix_properties_set(props, "str", "value"); + celix_version_t* version = celix_version_create(1, 2, 3, nullptr); + celix_properties_assignVersion(props, "version", version); + + // check if the values are correctly returned + EXPECT_STREQ("value", celix_properties_get(props, "str", nullptr)); + EXPECT_EQ(42, celix_properties_getLong(props, "long", -1L)); + EXPECT_DOUBLE_EQ(3.14, celix_properties_getDouble(props, "double", -1.0)); + EXPECT_EQ(true, celix_properties_getBool(props, "bool", false)); + EXPECT_EQ(version, celix_properties_getVersion(props, "version", nullptr)); + + // check if the values are correctly returned if value is not found + EXPECT_EQ(nullptr, celix_properties_get(props, "non-existing", nullptr)); + EXPECT_EQ(-1L, celix_properties_getLong(props, "non-existing", -1L)); + EXPECT_DOUBLE_EQ(-1.0, celix_properties_getDouble(props, "non-existing", -1.0)); + EXPECT_EQ(false, celix_properties_getBool(props, "non-existing", false)); + EXPECT_EQ(nullptr, celix_properties_getVersion(props, "non-existing", nullptr)); + + // check if the values are correctly returned if the found value is not of the correct type + EXPECT_EQ(-1L, celix_properties_getLong(props, "str", -1L)); + EXPECT_DOUBLE_EQ(-1.0, celix_properties_getDouble(props, "str", -1.0)); + EXPECT_EQ(false, celix_properties_getBool(props, "str", false)); + EXPECT_EQ(nullptr, celix_properties_getVersion(props, "str", nullptr)); + + // check if a default ptr is correctly returned if value is not found for string and version + EXPECT_EQ("default", celix_properties_get(props, "non-existing", "default")); + EXPECT_EQ(version, celix_properties_getVersion(props, "non-existing", version)); +} + +TEST_F(PropertiesTestSuite, LongArrayListTest) { celix_autoptr(celix_properties_t) props = celix_properties_create(); long array1[] = {1, 2, 3, 4, 5}; @@ -767,8 +805,278 @@ TEST_F(PropertiesTestSuite, LongArrayTestSuite) { EXPECT_EQ(4, celix_arrayList_getLong(retrievedList3, 0)); EXPECT_EQ(5, celix_arrayList_getLong(retrievedList3, 1)); + celix_array_list* retrievedList4; + celix_autoptr(celix_array_list_t) defaultList = celix_arrayList_create(); + celix_arrayList_addLong(defaultList, 6); + EXPECT_EQ(CELIX_SUCCESS, celix_properties_getAsLongArrayList(props, "non-existing", defaultList, &retrievedList4)); + ASSERT_NE(nullptr, retrievedList4); + ASSERT_EQ(1, celix_arrayList_size(retrievedList4)); + EXPECT_EQ(6, celix_arrayList_getLong(retrievedList4, 0)); + celix_arrayList_destroy(retrievedList4); + auto* getList = celix_properties_getLongArrayList(props, "array2", nullptr); EXPECT_NE(array2, getList); getList = celix_properties_getLongArrayList(props, "array3", nullptr); EXPECT_EQ(array3, getList); } + +TEST_F(PropertiesTestSuite, DoubleArrayListTest) { + celix_autoptr(celix_properties_t) props = celix_properties_create(); + + double array1[] = {1.1, 2.2, 3.3, 4.4, 5.5}; + ASSERT_EQ(CELIX_SUCCESS, celix_properties_setDoubles(props, "array1", array1, 5)); + EXPECT_EQ(1, celix_properties_size(props)); + celix_autoptr(celix_array_list_t) retrievedList1; + celix_status_t status = celix_properties_getAsDoubleArrayList(props, "array1", nullptr, &retrievedList1); + ASSERT_EQ(CELIX_SUCCESS, status); + ASSERT_TRUE(retrievedList1 != nullptr); + EXPECT_EQ(5, celix_arrayList_size(retrievedList1)); + EXPECT_EQ(1.1, celix_arrayList_getDouble(retrievedList1, 0)); + EXPECT_EQ(5.5, celix_arrayList_getDouble(retrievedList1, 4)); + + celix_autoptr(celix_array_list_t) array2 = celix_arrayList_create(); + celix_arrayList_addDouble(array2, 1.1); + celix_arrayList_addDouble(array2, 2.2); + celix_arrayList_addDouble(array2, 3.3); + EXPECT_EQ(CELIX_SUCCESS, celix_properties_setDoubleArrayList(props, "array2", array2)); + EXPECT_EQ(2, celix_properties_size(props)); + celix_autoptr(celix_array_list_t) retrievedList2; + status = celix_properties_getAsDoubleArrayList(props, "array2", nullptr, &retrievedList2); + ASSERT_EQ(CELIX_SUCCESS, status); + ASSERT_TRUE(retrievedList2 != nullptr); + EXPECT_NE(array2, retrievedList2); + EXPECT_EQ(3, celix_arrayList_size(retrievedList2)); + EXPECT_EQ(1.1, celix_arrayList_getDouble(retrievedList2, 0)); + EXPECT_EQ(3.3, celix_arrayList_getDouble(retrievedList2, 2)); + + celix_array_list_t* array3 = celix_arrayList_create(); + celix_arrayList_addDouble(array3, 4.4); + celix_arrayList_addDouble(array3, 5.5); + EXPECT_EQ(CELIX_SUCCESS, celix_properties_assignDoubleArrayList(props, "array3", array3)); + EXPECT_EQ(3, celix_properties_size(props)); + celix_autoptr(celix_array_list_t) retrievedList3; + status = celix_properties_getAsDoubleArrayList(props, "array3", nullptr, &retrievedList3); + ASSERT_EQ(CELIX_SUCCESS, status); + ASSERT_TRUE(retrievedList3 != nullptr); + EXPECT_NE(array3, retrievedList3); + EXPECT_EQ(2, celix_arrayList_size(retrievedList3)); + EXPECT_EQ(4.4, celix_arrayList_getDouble(retrievedList3, 0)); + EXPECT_EQ(5.5, celix_arrayList_getDouble(retrievedList3, 1)); + + celix_array_list* retrievedList4; + celix_autoptr(celix_array_list_t) defaultList = celix_arrayList_create(); + celix_arrayList_addDouble(defaultList, 6.6); + EXPECT_EQ(CELIX_SUCCESS, + celix_properties_getAsDoubleArrayList(props, "non-existing", defaultList, &retrievedList4)); + ASSERT_NE(nullptr, retrievedList4); + ASSERT_EQ(1, celix_arrayList_size(retrievedList4)); + EXPECT_EQ(6.6, celix_arrayList_getDouble(retrievedList4, 0)); + celix_arrayList_destroy(retrievedList4); + + auto* getList = celix_properties_getDoubleArrayList(props, "array2", nullptr); + EXPECT_NE(array2, getList); + getList = celix_properties_getDoubleArrayList(props, "array3", nullptr); + EXPECT_EQ(array3, getList); +} + +TEST_F(PropertiesTestSuite, BoolArrayListTest) { + celix_autoptr(celix_properties_t) props = celix_properties_create(); + + bool array1[] = {true, false, true, false, true}; + ASSERT_EQ(CELIX_SUCCESS, celix_properties_setBooleans(props, "array1", array1, 5)); + EXPECT_EQ(1, celix_properties_size(props)); + celix_autoptr(celix_array_list_t) retrievedList1; + celix_status_t status = celix_properties_getAsBoolArrayList(props, "array1", nullptr, &retrievedList1); + ASSERT_EQ(CELIX_SUCCESS, status); + ASSERT_TRUE(retrievedList1 != nullptr); + EXPECT_EQ(5, celix_arrayList_size(retrievedList1)); + EXPECT_EQ(true, celix_arrayList_getBool(retrievedList1, 0)); + EXPECT_EQ(true, celix_arrayList_getBool(retrievedList1, 2)); + EXPECT_EQ(false, celix_arrayList_getBool(retrievedList1, 1)); + EXPECT_EQ(false, celix_arrayList_getBool(retrievedList1, 3)); + EXPECT_EQ(true, celix_arrayList_getBool(retrievedList1, 4)); + + celix_autoptr(celix_array_list_t) array2 = celix_arrayList_create(); + celix_arrayList_addBool(array2, true); + celix_arrayList_addBool(array2, false); + celix_arrayList_addBool(array2, true); + EXPECT_EQ(CELIX_SUCCESS, celix_properties_setBoolArrayList(props, "array2", array2)); + EXPECT_EQ(2, celix_properties_size(props)); + celix_autoptr(celix_array_list_t) retrievedList2; + status = celix_properties_getAsBoolArrayList(props, "array2", nullptr, &retrievedList2); + ASSERT_EQ(CELIX_SUCCESS, status); + ASSERT_TRUE(retrievedList2 != nullptr); + EXPECT_NE(array2, retrievedList2); + EXPECT_EQ(3, celix_arrayList_size(retrievedList2)); + EXPECT_EQ(true, celix_arrayList_getBool(retrievedList2, 0)); + EXPECT_EQ(true, celix_arrayList_getBool(retrievedList2, 2)); + EXPECT_EQ(false, celix_arrayList_getBool(retrievedList2, 1)); + + celix_array_list_t* array3 = celix_arrayList_create(); + celix_arrayList_addBool(array3, false); + celix_arrayList_addBool(array3, true); + EXPECT_EQ(CELIX_SUCCESS, celix_properties_assignBoolArrayList(props, "array3", array3)); + EXPECT_EQ(3, celix_properties_size(props)); + celix_autoptr(celix_array_list_t) retrievedList3; + status = celix_properties_getAsBoolArrayList(props, "array3", nullptr, &retrievedList3); + ASSERT_EQ(CELIX_SUCCESS, status); + ASSERT_TRUE(retrievedList3 != nullptr); + EXPECT_NE(array3, retrievedList3); + EXPECT_EQ(2, celix_arrayList_size(retrievedList3)); + EXPECT_EQ(false, celix_arrayList_getBool(retrievedList3, 0)); + EXPECT_EQ(true, celix_arrayList_getBool(retrievedList3, 1)); + + celix_array_list* retrievedList4; + celix_autoptr(celix_array_list_t) defaultList = celix_arrayList_create(); + celix_arrayList_addBool(defaultList, true); + EXPECT_EQ(CELIX_SUCCESS, celix_properties_getAsBoolArrayList(props, "non-existing", defaultList, &retrievedList4)); + ASSERT_NE(nullptr, retrievedList4); + ASSERT_EQ(1, celix_arrayList_size(retrievedList4)); + EXPECT_EQ(true, celix_arrayList_getBool(retrievedList4, 0)); + celix_arrayList_destroy(retrievedList4); + + auto* getList = celix_properties_getBoolArrayList(props, "array2", nullptr); + EXPECT_NE(array2, getList); + getList = celix_properties_getBoolArrayList(props, "array3", nullptr); + EXPECT_EQ(array3, getList); +} + +TEST_F(PropertiesTestSuite, StringArrayListTest) { + celix_autoptr(celix_properties_t) props = celix_properties_create(); + + const char* str1 = "string1"; + const char* str2 = "string2"; + const char* str3 = "string3"; + const char* str4 = "string4"; + const char* str5 = "string5"; + + const char* array1[] = {str1, str2, str3, str4, str5}; + ASSERT_EQ(CELIX_SUCCESS, celix_properties_setStrings(props, "array1", array1, 5)); + EXPECT_EQ(1, celix_properties_size(props)); + celix_autoptr(celix_array_list_t) retrievedList1; + celix_status_t status = celix_properties_getAsStringArrayList(props, "array1", nullptr, &retrievedList1); + ASSERT_EQ(CELIX_SUCCESS, status); + ASSERT_TRUE(retrievedList1 != nullptr); + EXPECT_EQ(5, celix_arrayList_size(retrievedList1)); + EXPECT_STREQ(str1, (const char*)celix_arrayList_get(retrievedList1, 0)); + EXPECT_STREQ(str2, (const char*)celix_arrayList_get(retrievedList1, 1)); + EXPECT_STREQ(str3, (const char*)celix_arrayList_get(retrievedList1, 2)); + EXPECT_STREQ(str4, (const char*)celix_arrayList_get(retrievedList1, 3)); + EXPECT_STREQ(str5, (const char*)celix_arrayList_get(retrievedList1, 4)); + + celix_autoptr(celix_array_list_t) array2 = celix_arrayList_create(); + celix_arrayList_addString(array2, str1); + celix_arrayList_addString(array2, str1); + celix_arrayList_addString(array2, str1); + EXPECT_EQ(CELIX_SUCCESS, celix_properties_setStringArrayList(props, "array2", array2)); + EXPECT_EQ(2, celix_properties_size(props)); + + celix_autoptr(celix_array_list_t) retrievedList2; + status = celix_properties_getAsStringArrayList(props, "array2", nullptr, &retrievedList2); + ASSERT_EQ(CELIX_SUCCESS, status); + ASSERT_TRUE(retrievedList2 != nullptr); + EXPECT_NE(array2, retrievedList2); + EXPECT_EQ(3, celix_arrayList_size(retrievedList2)); + EXPECT_STREQ(str1, (const char*)celix_arrayList_get(retrievedList2, 0)); + EXPECT_STREQ(str1, (const char*)celix_arrayList_get(retrievedList2, 1)); + EXPECT_STREQ(str1, (const char*)celix_arrayList_get(retrievedList2, 2)); + + celix_array_list_t* array3 = celix_arrayList_create(); + celix_arrayList_addString(array3, str4); + celix_arrayList_addString(array3, str5); + EXPECT_EQ(CELIX_SUCCESS, celix_properties_assignStringArrayList(props, "array3", array3)); + EXPECT_EQ(3, celix_properties_size(props)); + celix_autoptr(celix_array_list_t) retrievedList3; + status = celix_properties_getAsStringArrayList(props, "array3", nullptr, &retrievedList3); + ASSERT_EQ(CELIX_SUCCESS, status); + ASSERT_TRUE(retrievedList3 != nullptr); + EXPECT_NE(array3, retrievedList3); + EXPECT_EQ(2, celix_arrayList_size(retrievedList3)); + EXPECT_STREQ(str4, (const char*)celix_arrayList_get(retrievedList3, 0)); + EXPECT_STREQ(str5, (const char*)celix_arrayList_get(retrievedList3, 1)); + + celix_array_list* retrievedList4; + celix_autoptr(celix_array_list_t) defaultList = celix_arrayList_create(); + celix_arrayList_addString(defaultList, str1); + EXPECT_EQ(CELIX_SUCCESS, + celix_properties_getAsStringArrayList(props, "non-existing", defaultList, &retrievedList4)); + ASSERT_NE(nullptr, retrievedList4); + ASSERT_EQ(1, celix_arrayList_size(retrievedList4)); + EXPECT_STREQ(str1, (const char*)celix_arrayList_get(retrievedList4, 0)); + celix_arrayList_destroy(retrievedList4); + + auto* getList = celix_properties_getStringArrayList(props, "array2", nullptr); + EXPECT_NE(array2, getList); + getList = celix_properties_getStringArrayList(props, "array3", nullptr); + EXPECT_EQ(array3, getList); +} + +TEST_F(PropertiesTestSuite, VersionArrayListTest) { + celix_autoptr(celix_properties_t) props = celix_properties_create(); + + celix_autoptr(celix_version_t) v1 = celix_version_create(1, 2, 3, nullptr); + celix_autoptr(celix_version_t) v2 = celix_version_create(4, 5, 6, nullptr); + celix_autoptr(celix_version_t) v3 = celix_version_create(7, 8, 9, nullptr); + celix_autoptr(celix_version_t) v4 = celix_version_create(10, 11, 12, nullptr); + celix_autoptr(celix_version_t) v5 = celix_version_create(13, 14, 15, nullptr); + + const celix_version_t* array1[] = {v1, v2, v3, v4, v5}; + ASSERT_EQ(CELIX_SUCCESS, celix_properties_setVersions(props, "array1", array1, 5)); + EXPECT_EQ(1, celix_properties_size(props)); + celix_autoptr(celix_array_list_t) retrievedList1; + celix_status_t status = celix_properties_getAsVersionArrayList(props, "array1", nullptr, &retrievedList1); + ASSERT_EQ(CELIX_SUCCESS, status); + ASSERT_TRUE(retrievedList1 != nullptr); + EXPECT_EQ(5, celix_arrayList_size(retrievedList1)); + checkVersions(v1, (celix_version_t*)celix_arrayList_get(retrievedList1, 0)); + checkVersions(v2, (celix_version_t*)celix_arrayList_get(retrievedList1, 1)); + checkVersions(v3, (celix_version_t*)celix_arrayList_get(retrievedList1, 2)); + checkVersions(v4, (celix_version_t*)celix_arrayList_get(retrievedList1, 3)); + checkVersions(v5, (celix_version_t*)celix_arrayList_get(retrievedList1, 4)); + + celix_autoptr(celix_array_list_t) array2 = celix_arrayList_create(); + celix_arrayList_add(array2, v1); + celix_arrayList_add(array2, v2); + celix_arrayList_add(array2, v3); + EXPECT_EQ(CELIX_SUCCESS, celix_properties_setVersionArrayList(props, "array2", array2)); + EXPECT_EQ(2, celix_properties_size(props)); + + celix_autoptr(celix_array_list_t) retrievedList2; + status = celix_properties_getAsVersionArrayList(props, "array2", nullptr, &retrievedList2); + ASSERT_EQ(CELIX_SUCCESS, status); + ASSERT_TRUE(retrievedList2 != nullptr); + EXPECT_NE(array2, retrievedList2); + EXPECT_EQ(3, celix_arrayList_size(retrievedList2)); + checkVersions(v1, (celix_version_t*)celix_arrayList_get(retrievedList2, 0)); + checkVersions(v2, (celix_version_t*)celix_arrayList_get(retrievedList2, 1)); + checkVersions(v3, (celix_version_t*)celix_arrayList_get(retrievedList2, 2)); + + celix_array_list_t* array3 = celix_arrayList_create(); + celix_arrayList_add(array3, v4); + celix_arrayList_add(array3, v5); + EXPECT_EQ(CELIX_SUCCESS, celix_properties_assignVersionArrayList(props, "array3", array3)); + EXPECT_EQ(3, celix_properties_size(props)); + celix_autoptr(celix_array_list_t) retrievedList3; + status = celix_properties_getAsVersionArrayList(props, "array3", nullptr, &retrievedList3); + ASSERT_EQ(CELIX_SUCCESS, status); + ASSERT_TRUE(retrievedList3 != nullptr); + EXPECT_NE(array3, retrievedList3); + EXPECT_EQ(2, celix_arrayList_size(retrievedList3)); + checkVersions(v4, (celix_version_t*)celix_arrayList_get(retrievedList3, 0)); + checkVersions(v5, (celix_version_t*)celix_arrayList_get(retrievedList3, 1)); + + celix_array_list* retrievedList4; + celix_autoptr(celix_array_list_t) defaultList = celix_arrayList_create(); + celix_arrayList_add(defaultList, v1); + EXPECT_EQ(CELIX_SUCCESS, + celix_properties_getAsVersionArrayList(props, "non-existing", defaultList, &retrievedList4)); + ASSERT_NE(nullptr, retrievedList4); + ASSERT_EQ(1, celix_arrayList_size(retrievedList4)); + checkVersions(v1, (celix_version_t*)celix_arrayList_get(retrievedList4, 0)); + celix_arrayList_destroy(retrievedList4); + + auto* getList = celix_properties_getVersionArrayList(props, "array2", nullptr); + EXPECT_NE(array2, getList); + getList = celix_properties_getVersionArrayList(props, "array3", nullptr); + EXPECT_EQ(array3, getList); +} diff --git a/libs/utils/include/celix_properties.h b/libs/utils/include/celix_properties.h index fc2c33a2..900b0d3c 100644 --- a/libs/utils/include/celix_properties.h +++ b/libs/utils/include/celix_properties.h @@ -68,7 +68,11 @@ typedef enum celix_properties_value_type { CELIX_PROPERTIES_VALUE_TYPE_DOUBLE = 3, /**< Property value is a double. */ CELIX_PROPERTIES_VALUE_TYPE_BOOL = 4, /**< Property value is a boolean. */ CELIX_PROPERTIES_VALUE_TYPE_VERSION = 5, /**< Property value is a Celix version. */ - CELIX_PROPERTIES_VALUE_TYPE_LONG_ARRAY = 6 /**< Property value is an array of longs. */ + CELIX_PROPERTIES_VALUE_TYPE_STRING_ARRAY = 6, /**< Property value is an array of strings. */ + CELIX_PROPERTIES_VALUE_TYPE_LONG_ARRAY = 7, /**< Property value is an array of longs. */ + CELIX_PROPERTIES_VALUE_TYPE_DOUBLE_ARRAY = 8, /**< Property value is an array of doubles. */ + CELIX_PROPERTIES_VALUE_TYPE_BOOL_ARRAY = 9, /**< Property value is an array of booleans. */ + CELIX_PROPERTIES_VALUE_TYPE_VERSION_ARRAY = 10, /**< Property value is an array of Celix versions. */ } celix_properties_value_type_e; /** @@ -254,7 +258,14 @@ CELIX_UTILS_EXPORT celix_status_t celix_properties_assign(celix_properties_t* pr char* key, char* value); -//TODO +/** + * @Brief Get the value of a property, if the property is set and the underlying type is a long. + * @param[in] properties The property set to search. + * @param[in] key The key of the property to get. + * @param[in] defaultValue The value to return if the property is not set or the value is not a long. + * @return The value of the property, or the default value if the property is not set or the value is not of the + * requested type. + */ CELIX_UTILS_EXPORT long celix_properties_getLong(const celix_properties_t* properties, const char* key, long defaultValue); @@ -285,7 +296,14 @@ celix_properties_getAsLong(const celix_properties_t* properties, const char* key */ CELIX_UTILS_EXPORT celix_status_t celix_properties_setLong(celix_properties_t* properties, const char* key, long value); -//TODO +/** + * @Brief Get the value of a property, if the property is set and the underlying type is a boolean. + * @param[in] properties The property set to search. + * @param[in] key The key of the property to get. + * @param[in] defaultValue The value to return if the property is not set or the value is not a boolean. + * @return The value of the property, or the default value if the property is not set or the value is not of the + * requested type. + */ CELIX_UTILS_EXPORT bool celix_properties_getBool(const celix_properties_t* properties, const char* key, bool defaultValue); @@ -331,7 +349,14 @@ CELIX_UTILS_EXPORT celix_status_t celix_properties_setDouble(celix_properties_t* const char* key, double val); -//TODO +/** + * @Brief Get the value of a property, if the property is set and the underlying type is a double. + * @param[in] properties The property set to search. + * @param[in] key The key of the property to get. + * @param[in] defaultValue The value to return if the property is not set or the value is not a double. + * @return The value of the property, or the default value if the property is not set or the value is not of the + * requested type. + */ CELIX_UTILS_EXPORT double celix_properties_getDouble(const celix_properties_t* properties, const char* key, double defaultValue); @@ -386,14 +411,14 @@ CELIX_UTILS_EXPORT celix_status_t celix_properties_assignVersion(celix_propertie celix_version_t* version); /** - * @brief Peek at the Celix version value of a property without copying. + * @brief Get the Celix version value of a property without copying. * * This function provides a non-owning, read-only access to a Celix version contained in the properties. * It returns a const pointer to the Celix version value associated with the specified key. * This function does not perform any conversion from a string property value to a Celix version. * * @param[in] properties The property set to search. - * @param[in] key The key of the property to peek at. + * @param[in] key The key of the property to get. * @param[in] defaultValue The value to return if the property is not set or if the value is not a Celix version. * @return A const pointer to the Celix version if it is present and valid, or the provided default value if the * property is not set or the value is not a valid Celix version. The returned pointer should not be modified or freed. @@ -502,14 +527,14 @@ CELIX_UTILS_EXPORT celix_status_t celix_properties_getAsLongArrayList(const celi celix_array_list_t** list); /** - * @brief Peek at the property value as an array of longs without copying. + * @brief Get the property value as an array of longs without copying. * * This function provides a non-owning, read-only access to a property value interpreted as an array of longs. * It returns a const pointer to the array. If the property is not set or its value is not an array of longs, * the default value is returned. * * @param[in] properties The property set to search. - * @param[in] key The key of the property to peek at. + * @param[in] key The key of the property to get. * @param[in] defaultValue The value to return if the property is not set or its value is not an array of longs. * @return A const pointer to the property value interpreted as an array of longs, or the default value if the property * is not set or its value is not an array of longs. The returned pointer should not be modified or freed. @@ -518,6 +543,401 @@ CELIX_UTILS_EXPORT const celix_array_list_t* celix_properties_getLongArrayList(c const char* key, const celix_array_list_t* defaultValue); +/** + * @brief Set a double array value for a property. + * + * This function will make a copy of the provided celix_array_list_t object, assuming it contains double values, + * and store it in the property set. + * If an error occurs, the error status is returned and a message is logged to + * celix_err. + * + * @param[in] properties The property set to modify. + * @param[in] key The key of the property to set. + * @param[in] values An array list of double values to set for the property. Cannot be NULL. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to set the entry, + * and CELIX_ILLEGAL_ARGUMENT if the provided key or values is NULL. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_setDoubleArrayList(celix_properties_t* properties, + const char* key, + const celix_array_list_t* values); + +/** + * @brief Assign a double array value to a property, taking ownership of the array. + * + * This function stores a reference to the provided celix_array_list_t object in the property set and takes + * ownership of the array. + * If an error occurs, the error status is returned, the provided array is destroyed and a + * message is logged to celix_err. + * + * @param[in] properties The property set to modify. + * @param[in] key The key of the property to set. + * @param[in] values An array list of double values to assign to the property. Ownership of the array is transferred + * to the properties set. Cannot be NULL. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to set the entry, + * and CELIX_ILLEGAL_ARGUMENT if the provided key is NULL. On error, the values array list is destroyed. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_assignDoubleArrayList(celix_properties_t* properties, + const char* key, + celix_array_list_t* values); + +/** + * @brief Set multiple double values for a property using an array of longs. + * + * This function allows setting multiple double values for a given property key. The values are passed as an array + * of double integers. The number of values in the array should be specified by nrOfValues. + * + * If an error occurs, the error status is returned, the provided array is destroyed and a + * message is logged to celix_err. + * + * @param[in] properties The property set to modify. + * @param[in] key The key of the property to set. + * @param[in] nrOfValues The number of double values in the array. + * @param[in] values An array of double values to set for the property. Cannot be NULL. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to set the entry, + * and CELIX_ILLEGAL_ARGUMENT if the provided key is NULL or the values array is NULL. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_setDoubles(celix_properties_t* properties, + const char* key, + const double* values, + size_t nrOfValues); + +/** + * @brief Get a property value as an array of doubles, making a copy of the array. + * + * This function retrieves the value of a property, interpreting it as an array of doubles. It returns a new copy of the + * array. If the property is not set or its value is not an array of doubles, the default value is returned as a copy. + * + * @param[in] properties The property set to search. + * @param[in] key The key of the property to get. + * @param[in] defaultValue The default value to return if the property is not set or its value is not an array of + * doubles. + * @param[out] list A copy of the found list, a new array list with double values or a copy of the default value if the + * property is not set, its value is not an array doubles longs or its value cannot be converted to an + * array of doubles. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to create the + * array list. Note if the key is not found, the return status is still CELIX_SUCCESS. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_getAsDoubleArrayList(const celix_properties_t* properties, + const char* key, + const celix_array_list_t* defaultValue, + celix_array_list_t** list); + +/** + * @brief Get the property value as an array of doubles without copying. + * + * This function provides a non-owning, read-only access to a property value interpreted as an array of doubles. + * It returns a const pointer to the array. If the property is not set or its value is not an array of doubles, + * the default value is returned. + * + * @param[in] properties The property set to search. + * @param[in] key The key of the property to get. + * @param[in] defaultValue The value to return if the property is not set or its value is not an array of doubles. + * @return A const pointer to the property value interpreted as an array of doubles, or the default value if the + * property is not set or its value is not an array of doubles. The returned pointer should not be modified or freed. + */ +CELIX_UTILS_EXPORT const celix_array_list_t* celix_properties_getDoubleArrayList( + const celix_properties_t* properties, const char* key, const celix_array_list_t* defaultValue); + +/** + * @brief Set a boolean array value for a property. + * + * This function will make a copy of the provided celix_array_list_t object, assuming it contains boolean values, + * and store it in the property set. + * If an error occurs, the error status is returned and a message is logged to + * celix_err. + * + * @param[in] properties The property set to modify. + * @param[in] key The key of the property to set. + * @param[in] values An array list of boolean values to set for the property. Cannot be NULL. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to set the entry, + * and CELIX_ILLEGAL_ARGUMENT if the provided key or values is NULL. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_setBoolArrayList(celix_properties_t* properties, + const char* key, + const celix_array_list_t* values); + +/** + * @brief Assign a boolean array value to a property, taking ownership of the array. + * + * This function stores a reference to the provided celix_array_list_t object in the property set and takes + * ownership of the array. + * If an error occurs, the error status is returned, the provided array is destroyed and a + * message is logged to celix_err. + * + * @param[in] properties The property set to modify. + * @param[in] key The key of the property to set. + * @param[in] values An array list of boolean values to assign to the property. Ownership of the array is transferred + * to the properties set. Cannot be NULL. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to set the entry, + * and CELIX_ILLEGAL_ARGUMENT if the provided key is NULL. On error, the values array list is destroyed. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_assignBoolArrayList(celix_properties_t* properties, + const char* key, + celix_array_list_t* values); + +/** + * @brief Set multiple boolean values for a property using an array of longs. + * + * This function allows setting multiple boolean values for a given property key. The values are passed as an array + * of booleans. The number of values in the array should be specified by nrOfValues. + * + * If an error occurs, the error status is returned, the provided array is destroyed and a + * message is logged to celix_err. + * + * @param[in] properties The property set to modify. + * @param[in] key The key of the property to set. + * @param[in] nrOfValues The number of bool values in the array. + * @param[in] values An array of bool values to set for the property. Cannot be NULL. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to set the entry, + * and CELIX_ILLEGAL_ARGUMENT if the provided key is NULL or the values array is NULL. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_setBooleans(celix_properties_t* properties, + const char* key, + const bool* values, + size_t nrOfValues); + +/** + * @brief Get a property value as an array of booleans, making a copy of the array. + * + * This function retrieves the value of a property, interpreting it as an array of booleans. It returns a new copy of the + * array. If the property is not set or its value is not an array of booleans, the default value is returned as a copy. + * + * @param[in] properties The property set to search. + * @param[in] key The key of the property to get. + * @param[in] defaultValue The default value to return if the property is not set or its value is not an array of + * booleans. + * @param[out] list A copy of the found list, a new array list with boolean values or a copy of the default value if the + * property is not set, its value is not an array of booleans or its value cannot be converted to an + * array of booleans. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to create the + * array list. Note if the key is not found, the return status is still CELIX_SUCCESS. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_getAsBoolArrayList(const celix_properties_t* properties, + const char* key, + const celix_array_list_t* defaultValue, + celix_array_list_t** list); + +/** + * @brief Get the property value as an array of booleans without copying. + * + * This function provides a non-owning, read-only access to a property value interpreted as an array of booleans. + * It returns a const pointer to the array. If the property is not set or its value is not an array of booleans, + * the default value is returned. + * + * @param[in] properties The property set to search. + * @param[in] key The key of the property to get. + * @param[in] defaultValue The value to return if the property is not set or its value is not an array of booleans. + * @return A const pointer to the property value interpreted as an array of booleans, or the default value if the + * property is not set or its value is not an array of booleans. The returned pointer should not be modified or freed. + */ +CELIX_UTILS_EXPORT const celix_array_list_t* celix_properties_getBoolArrayList( + const celix_properties_t* properties, const char* key, const celix_array_list_t* defaultValue); + +/** + * @brief Set a string array value for a property. + * + * This function will make a copy of the provided celix_array_list_t object, assuming it contains string values, + * and store it in the property set. + * If an error occurs, the error status is returned and a message is logged to + * celix_err. + * + * @param[in] properties The property set to modify. + * @param[in] key The key of the property to set. + * @param[in] values An array list of string values to set for the property. Cannot be NULL. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to set the entry, + * and CELIX_ILLEGAL_ARGUMENT if the provided key or values is NULL. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_setStringArrayList(celix_properties_t* properties, + const char* key, + const celix_array_list_t* values); + +/** + * @brief Assign a string array value to a property, taking ownership of the array. + * + * The provided array list should be created with a remove callback so that the destruction of the array list + * will also free the strings in the array list. If this is not done, this property set will leak memory. + * + * This function stores a reference to the provided celix_array_list_t object in the property set and takes + * ownership of the array. + * If an error occurs, the error status is returned, the provided array is destroyed and a + * message is logged to celix_err. + * + * @param[in] properties The property set to modify. + * @param[in] key The key of the property to set. + * @param[in] values An array list of string values to assign to the property. Ownership of the array is transferred + * to the properties set. Cannot be NULL. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to set the entry, + * and CELIX_ILLEGAL_ARGUMENT if the provided key is NULL. On error, the values array list is destroyed. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_assignStringArrayList(celix_properties_t* properties, + const char* key, + celix_array_list_t* values); + +/** + * @brief Set multiple string values for a property using an array of longs. + * + * This function allows setting multiple string values for a given property key. The values are passed as an array + * of strings. The number of values in the array should be specified by nrOfValues. + * + * If an error occurs, the error status is returned, the provided array is destroyed and a + * message is logged to celix_err. + * + * @param[in] properties The property set to modify. + * @param[in] key The key of the property to set. + * @param[in] nrOfValues The number of string values in the array. + * @param[in] values An array of string values to set for the property. Cannot be NULL. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to set the entry, + * and CELIX_ILLEGAL_ARGUMENT if the provided key is NULL or the values array is NULL. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_setStrings(celix_properties_t* properties, + const char* key, + const char** values, + size_t nrOfValues); + +/** + * @brief Get a property value as an array of strings, making a copy of the array. + * + * This function retrieves the value of a property, interpreting it as an array of strings. It returns a new copy of the + * array. If the property is not set or its value is not an array of strings, the default value is returned as a copy. + * + * The returned array list is configured with a remove callback so that the destruction of the array list will also + * free the strings in the array list. + * + * @param[in] properties The property set to search. + * @param[in] key The key of the property to get. + * @param[in] defaultValue The default value to return if the property is not set or its value is not an array of + * strings. + * @param[out] list A copy of the found list, a new array list with string values or a copy of the default value if the + * property is not set, its value is not an array of strings or its value cannot be converted to an + * array of strings. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to create the + * array list. Note if the key is not found, the return status is still CELIX_SUCCESS. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_getAsStringArrayList(const celix_properties_t* properties, + const char* key, + const celix_array_list_t* defaultValue, + celix_array_list_t** list); + +/** + * @brief Get the property value as an array of strings without copying. + * + * This function provides a non-owning, read-only access to a property value interpreted as an array of strings. + * It returns a const pointer to the array. If the property is not set or its value is not an array of strings, + * the default value is returned. + * + * @param[in] properties The property set to search. + * @param[in] key The key of the property to get. + * @param[in] defaultValue The value to return if the property is not set or its value is not an array of strings. + * @return A const pointer to the property value interpreted as an array of strings, or the default value if the + * property is not set or its value is not an array of strings. The returned pointer should not be modified or freed. + */ +CELIX_UTILS_EXPORT const celix_array_list_t* celix_properties_getStringArrayList( + const celix_properties_t* properties, const char* key, const celix_array_list_t* defaultValue); + +/** + * @brief Set a celix_version_t array value for a property. + * + * This function will make a copy of the provided celix_array_list_t object, assuming it contains celix_version_t + * values, and store it in the property set. If an error occurs, the error status is returned and a message is logged to + * celix_err. + * + * @param[in] properties The property set to modify. + * @param[in] key The key of the property to set. + * @param[in] values An array list of celix_version_t values to set for the property. Cannot be NULL. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to set the entry, + * and CELIX_ILLEGAL_ARGUMENT if the provided key or values is NULL. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_setVersionArrayList(celix_properties_t* properties, + const char* key, + const celix_array_list_t* values); + +/** + * @brief Assign a celix_version_t array value to a property, taking ownership of the array. + * + * The provided array list should be created with a remove callback so that the destruction of the array list + * will also free the celix_version_t entries in the array list. If this is not done, this property set will leak + * memory. + * + * This function stores a reference to the provided celix_array_list_t object in the property set and takes + * ownership of the array. + * If an error occurs, the error status is returned, the provided array is destroyed and a + * message is logged to celix_err. + * + * @param[in] properties The property set to modify. + * @param[in] key The key of the property to set. + * @param[in] values An array list of celix_version_t values to assign to the property. Ownership of the array is + * transferred to the properties set. Cannot be NULL. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to set the entry, + * and CELIX_ILLEGAL_ARGUMENT if the provided key is NULL. On error, the values array list is destroyed. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_assignVersionArrayList(celix_properties_t* properties, + const char* key, + celix_array_list_t* values); + +/** + * @brief Set multiple celix_version_t values for a property using an array of longs. + * + * This function allows setting multiple celix_version_t values for a given property key. The values are passed as an + * array with celix_version_t entries. The number of values in the array should be specified by nrOfValues. + * + * If an error occurs, the error status is returned, the provided array is destroyed and a + * message is logged to celix_err. + * + * @param[in] properties The property set to modify. + * @param[in] key The key of the property to set. + * @param[in] nrOfValues The number of celix_version_t values in the array. + * @param[in] values An array of celix_version_t values to set for the property. Cannot be NULL. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to set the entry, + * and CELIX_ILLEGAL_ARGUMENT if the provided key is NULL or the values array is NULL. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_setVersions(celix_properties_t* properties, + const char* key, + const celix_version_t** values, + size_t nrOfValues); + +/** + * @brief Get a property value as an array of celix_version_t entries, making a copy of the array. + * + * This function retrieves the value of a property, interpreting it as an array of celix_version_t entries. It returns a + * new copy of the array. If the property is not set or its value is not an array of celix_version_t entries, the + * default value is returned as a copy. + * + * The returned array list is configured with a remove callback so that the destruction of the array list will also + * free the celix_version_t entries in the array list. + * + * @param[in] properties The property set to search. + * @param[in] key The key of the property to get. + * @param[in] defaultValue The default value to return if the property is not set or its value is not an array of + * celix_version_t entries. + * @param[out] list A copy of the found list, a new array list with celix_version_t values or a copy of the default + * value if the property is not set, its value is not an array of celix_version_t entries or its value cannot be + * converted to an array of celix_version_t entries. + * @return CELIX_SUCCESS if the operation was successful, CELIX_ENOMEM if there was not enough memory to create the + * array list. Note if the key is not found, the return status is still CELIX_SUCCESS. + */ +CELIX_UTILS_EXPORT celix_status_t celix_properties_getAsVersionArrayList(const celix_properties_t* properties, + const char* key, + const celix_array_list_t* defaultValue, + celix_array_list_t** list); + +/** + * @brief Get the property value as an array of celix_version_t entries without copying. + * + * This function provides a non-owning, read-only access to a property value interpreted as an array of celix_version_t + * entries. It returns a const pointer to the array. If the property is not set or its value is not an array of + * celix_version_t entries, the default value is returned. + * + * @param[in] properties The property set to search. + * @param[in] key The key of the property to get. + * @param[in] defaultValue The value to return if the property is not set or its value is not an array of + * celix_version_t entries. + * @return A const pointer to the property value interpreted as an array of celix_version_t entries, or the default + * value if the property is not set or its value is not an array of celix_version_t entries. The returned pointer should + * not be modified or freed. + */ +CELIX_UTILS_EXPORT const celix_array_list_t* celix_properties_getVersionArrayList( + const celix_properties_t* properties, const char* key, const celix_array_list_t* defaultValue); + /** * @brief Set the value of a property based on the provided property entry, maintaining underlying type. * diff --git a/libs/utils/src/properties.c b/libs/utils/src/properties.c index cafd092f..fc32350d 100644 --- a/libs/utils/src/properties.c +++ b/libs/utils/src/properties.c @@ -164,6 +164,14 @@ static celix_status_t celix_properties_fillEntry(celix_properties_t* properties, entry->value = entry->typed.boolValue ? CELIX_PROPERTIES_BOOL_TRUE_STRVAL : CELIX_PROPERTIES_BOOL_FALSE_STRVAL; } else if (prototype->valueType == CELIX_PROPERTIES_VALUE_TYPE_LONG_ARRAY) { entry->value = celix_utils_longArrayListToString(entry->typed.arrayValue); + } else if (prototype->valueType == CELIX_PROPERTIES_VALUE_TYPE_DOUBLE_ARRAY) { + entry->value = celix_utils_doubleArrayListToString(entry->typed.arrayValue); + } else if (prototype->valueType == CELIX_PROPERTIES_VALUE_TYPE_BOOL_ARRAY) { + entry->value = celix_utils_boolArrayListToString(entry->typed.arrayValue); + } else if (prototype->valueType == CELIX_PROPERTIES_VALUE_TYPE_STRING_ARRAY) { + entry->value = celix_utils_stringArrayListToString(entry->typed.arrayValue); + } else if (prototype->valueType == CELIX_PROPERTIES_VALUE_TYPE_VERSION_ARRAY) { + entry->value = celix_utils_versionArrayListToString(entry->typed.arrayValue); } else /*string value*/ { assert(prototype->valueType == CELIX_PROPERTIES_VALUE_TYPE_STRING); entry->value = celix_properties_createString(properties, prototype->typed.strValue); @@ -186,7 +194,9 @@ celix_properties_entry_t* celix_properties_allocEntry(celix_properties_t* proper } else { entry = malloc(sizeof(*entry)); } - memset(entry, 0, sizeof(*entry)); + if (entry) { + memset(entry, 0, sizeof(*entry)); + } return entry; } @@ -211,6 +221,16 @@ static void celix_properties_freeTypedEntry(const celix_properties_entry_t* entr celix_version_destroy((celix_version_t*)entry->typed.versionValue); } else if (entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_LONG_ARRAY) { celix_arrayList_destroy((celix_array_list_t*)entry->typed.arrayValue); + } else if (entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_DOUBLE_ARRAY) { + celix_arrayList_destroy((celix_array_list_t*)entry->typed.arrayValue); + } else if (entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_BOOL_ARRAY) { + celix_arrayList_destroy((celix_array_list_t*)entry->typed.arrayValue); + } else if (entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_STRING_ARRAY) { + celix_arrayList_destroy((celix_array_list_t*)entry->typed.arrayValue); + } else if (entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_VERSION_ARRAY) { + celix_arrayList_destroy((celix_array_list_t*)entry->typed.arrayValue); + } else { + // nop } } @@ -721,6 +741,14 @@ void celix_properties_unset(celix_properties_t* properties, const char* key) { } } +long celix_properties_getLong(const celix_properties_t* properties, const char* key, long defaultValue) { + celix_properties_entry_t* entry = celix_properties_getEntry(properties, key); + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_LONG) { + return entry->typed.longValue; + } + return defaultValue; +} + long celix_properties_getAsLong(const celix_properties_t* props, const char* key, long defaultValue) { celix_properties_entry_t* entry = celix_properties_getEntry(props, key); if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_LONG) { @@ -740,6 +768,14 @@ celix_status_t celix_properties_setLong(celix_properties_t* props, const char* k return celix_properties_createAndSetEntry(props, key, &prototype); } +double celix_properties_getDouble(const celix_properties_t* properties, const char* key, double defaultValue) { + celix_properties_entry_t* entry = celix_properties_getEntry(properties, key); + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_DOUBLE) { + return entry->typed.doubleValue; + } + return defaultValue; +} + double celix_properties_getAsDouble(const celix_properties_t* props, const char* key, double defaultValue) { celix_properties_entry_t* entry = celix_properties_getEntry(props, key); if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_DOUBLE) { @@ -757,6 +793,14 @@ celix_status_t celix_properties_setDouble(celix_properties_t* props, const char* return celix_properties_createAndSetEntry(props, key, &prototype); } +bool celix_properties_getBool(const celix_properties_t* properties, const char* key, bool defaultValue) { + celix_properties_entry_t* entry = celix_properties_getEntry(properties, key); + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_BOOL) { + return entry->typed.boolValue; + } + return defaultValue; +} + bool celix_properties_getAsBool(const celix_properties_t* props, const char* key, bool defaultValue) { celix_properties_entry_t* entry = celix_properties_getEntry(props, key); if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_BOOL) { @@ -839,9 +883,9 @@ celix_properties_assignVersion(celix_properties_t* properties, const char* key, } celix_status_t celix_properties_getAsLongArrayList(const celix_properties_t* properties, - const char* key, - const celix_array_list_t* defaultValue, - celix_array_list_t** list) { + const char* key, + const celix_array_list_t* defaultValue, + celix_array_list_t** list) { celix_properties_entry_t* entry = celix_properties_getEntry(properties, key); if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_LONG_ARRAY) { celix_array_list_t* copy = celix_arrayList_copy(entry->typed.arrayValue); @@ -854,7 +898,7 @@ celix_status_t celix_properties_getAsLongArrayList(const celix_properties_t* pro if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_STRING) { celix_status_t convertStatus = celix_utils_convertStringToLongArrayList(entry->value, defaultValue, list); if (convertStatus == CELIX_ILLEGAL_ARGUMENT) { - //conversion failed, but no memory error so defaultValue is copied and set + // conversion failed, but no memory error so defaultValue is copied and set return CELIX_SUCCESS; } return convertStatus; @@ -869,17 +913,38 @@ celix_status_t celix_properties_getAsLongArrayList(const celix_properties_t* pro celix_status_t celix_properties_setLongArrayList(celix_properties_t* properties, const char* key, const celix_array_list_t* values) { + assert(values != NULL); + celix_array_list_t* copy = celix_arrayList_copy(values); + if (!copy) { + return CELIX_ENOMEM; + } + celix_properties_entry_t prototype = {0}; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_LONG_ARRAY; + prototype.typed.arrayValue = copy; + return celix_properties_createAndSetEntry(properties, key, &prototype); +} + +celix_status_t +celix_properties_assignLongArrayList(celix_properties_t* properties, const char* key, celix_array_list_t* values) { + assert(values != NULL); + celix_properties_entry_t prototype = {0}; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_LONG_ARRAY; + prototype.typed.arrayValue = values; + return celix_properties_createAndSetEntry(properties, key, &prototype); +} + +celix_status_t +celix_properties_setLongs(celix_properties_t* properties, const char* key, const long* values, size_t nrOfValues) { assert(values != NULL); celix_autoptr(celix_array_list_t) copy = celix_arrayList_create(); if (!copy) { celix_err_push("Failed to create a long array"); return CELIX_ENOMEM; } - for (int i = 0; values && i < celix_arrayList_size(values); ++i) { - long val = celix_arrayList_getLong(values, i); - celix_status_t status = celix_arrayList_addLong(copy, val); + for (size_t i = 0; i < nrOfValues; ++i) { + celix_status_t status = celix_arrayList_addLong(copy, values[i]); if (status != CELIX_SUCCESS) { - celix_err_pushf("Failed to add long to array list. Got error %i", status); + celix_err_push("Failed to add long to array list"); return status; } } @@ -890,43 +955,431 @@ celix_properties_setLongArrayList(celix_properties_t* properties, const char* ke return celix_properties_createAndSetEntry(properties, key, &prototype); } +const celix_array_list_t* celix_properties_getLongArrayList(const celix_properties_t* properties, + const char* key, + const celix_array_list_t* defaultValue) { + celix_properties_entry_t* entry = celix_properties_getEntry(properties, key); + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_LONG_ARRAY) { + return entry->typed.arrayValue; + } + return defaultValue; +} + celix_status_t -celix_properties_assignLongArrayList(celix_properties_t* properties, const char* key, celix_array_list_t* values) { +celix_properties_setDoubleArrayList(celix_properties_t* properties, const char* key, const celix_array_list_t* values) { assert(values != NULL); + celix_array_list_t* copy = celix_arrayList_copy(values); + if (!copy) { + return CELIX_ENOMEM; + } celix_properties_entry_t prototype = {0}; - prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_LONG_ARRAY; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_DOUBLE_ARRAY; + prototype.typed.arrayValue = copy; + return celix_properties_createAndSetEntry(properties, key, &prototype); +} + +celix_status_t +celix_properties_assignDoubleArrayList(celix_properties_t* properties, const char* key, celix_array_list_t* values) { + assert(values != NULL); + celix_properties_entry_t prototype = {0}; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_DOUBLE_ARRAY; prototype.typed.arrayValue = values; return celix_properties_createAndSetEntry(properties, key, &prototype); } celix_status_t -celix_properties_setLongs(celix_properties_t* properties, const char* key, const long* values, size_t nrOfValues) { +celix_properties_setDoubles(celix_properties_t* properties, const char* key, const double* values, size_t nrOfValues) { assert(values != NULL); celix_autoptr(celix_array_list_t) copy = celix_arrayList_create(); if (!copy) { - celix_err_push("Failed to create a long array"); + celix_err_push("Failed to create a double array"); return CELIX_ENOMEM; } for (size_t i = 0; i < nrOfValues; ++i) { - long val = values[i]; - celix_status_t status = celix_arrayList_addLong(copy, val); + celix_status_t status = celix_arrayList_addDouble(copy, values[i]); if (status != CELIX_SUCCESS) { - celix_err_pushf("Failed to add long to array list. Got error %i", status); + celix_err_push("Failed to add double to array list"); return status; } } + celix_properties_entry_t prototype = {0}; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_DOUBLE_ARRAY; + prototype.typed.arrayValue = celix_steal_ptr(copy); + return celix_properties_createAndSetEntry(properties, key, &prototype); +} +celix_status_t celix_properties_getAsDoubleArrayList(const celix_properties_t* properties, + const char* key, + const celix_array_list_t* defaultValue, + celix_array_list_t** list) { + celix_properties_entry_t* entry = celix_properties_getEntry(properties, key); + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_DOUBLE_ARRAY) { + celix_array_list_t* copy = celix_arrayList_copy(entry->typed.arrayValue); + if (!copy) { + return CELIX_ENOMEM; + } + *list = copy; + return CELIX_SUCCESS; + } + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_STRING) { + celix_status_t convertStatus = celix_utils_convertStringToDoubleArrayList(entry->value, defaultValue, list); + if (convertStatus == CELIX_ILLEGAL_ARGUMENT) { + // conversion failed, but no memory error so defaultValue is copied and set + return CELIX_SUCCESS; + } + return convertStatus; + } + if (defaultValue) { + *list = celix_arrayList_copy(defaultValue); + return *list ? CELIX_SUCCESS : CELIX_ENOMEM; + } + *list = NULL; + return CELIX_SUCCESS; +} + +const celix_array_list_t* celix_properties_getDoubleArrayList(const celix_properties_t* properties, + const char* key, + const celix_array_list_t* defaultValue) { + celix_properties_entry_t* entry = celix_properties_getEntry(properties, key); + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_DOUBLE_ARRAY) { + return entry->typed.arrayValue; + } + return defaultValue; +} + +celix_status_t celix_properties_setBoolArrayList(celix_properties_t* properties, const char* key, const celix_array_list_t* values) { + assert(values != NULL); + celix_array_list_t* copy = celix_arrayList_copy(values); + if (!copy) { + return CELIX_ENOMEM; + } celix_properties_entry_t prototype = {0}; - prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_LONG_ARRAY; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_BOOL_ARRAY; + prototype.typed.arrayValue = copy; + return celix_properties_createAndSetEntry(properties, key, &prototype); +} + +celix_status_t +celix_properties_assignBoolArrayList(celix_properties_t* properties, const char* key, celix_array_list_t* values) { + assert(values != NULL); + celix_properties_entry_t prototype = {0}; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_BOOL_ARRAY; + prototype.typed.arrayValue = values; + return celix_properties_createAndSetEntry(properties, key, &prototype); +} + +celix_status_t +celix_properties_setBooleans(celix_properties_t* properties, const char* key, const bool* values, size_t nrOfValues) { + assert(values != NULL); + celix_autoptr(celix_array_list_t) copy = celix_arrayList_create(); + if (!copy) { + celix_err_push("Failed to create a bool array"); + return CELIX_ENOMEM; + } + for (size_t i = 0; i < nrOfValues; ++i) { + celix_status_t status = celix_arrayList_addBool(copy, values[i]); + if (status != CELIX_SUCCESS) { + celix_err_push("Failed to add bool to array list."); + return status; + } + } + celix_properties_entry_t prototype = {0}; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_BOOL_ARRAY; prototype.typed.arrayValue = celix_steal_ptr(copy); return celix_properties_createAndSetEntry(properties, key, &prototype); } -const celix_array_list_t* celix_properties_getLongArrayList(const celix_properties_t* properties, - const char* key, - const celix_array_list_t* defaultValue) { +celix_status_t celix_properties_getAsBoolArrayList(const celix_properties_t* properties, + const char* key, + const celix_array_list_t* defaultValue, + celix_array_list_t** list) { celix_properties_entry_t* entry = celix_properties_getEntry(properties, key); - if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_LONG_ARRAY) { + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_BOOL_ARRAY) { + celix_array_list_t* copy = celix_arrayList_copy(entry->typed.arrayValue); + if (!copy) { + return CELIX_ENOMEM; + } + *list = copy; + return CELIX_SUCCESS; + } + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_STRING) { + celix_status_t convertStatus = celix_utils_convertStringToBoolArrayList(entry->value, defaultValue, list); + if (convertStatus == CELIX_ILLEGAL_ARGUMENT) { + // conversion failed, but no memory error so defaultValue is copied and set + return CELIX_SUCCESS; + } + return convertStatus; + } + if (defaultValue) { + *list = celix_arrayList_copy(defaultValue); + return *list ? CELIX_SUCCESS : CELIX_ENOMEM; + } + *list = NULL; + return CELIX_SUCCESS; +} + +const celix_array_list_t* celix_properties_getBoolArrayList(const celix_properties_t* properties, + const char* key, + const celix_array_list_t* defaultValue) { + celix_properties_entry_t* entry = celix_properties_getEntry(properties, key); + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_BOOL_ARRAY) { + return entry->typed.arrayValue; + } + return defaultValue; +} + +celix_status_t celix_properties_setStringArrayList(celix_properties_t* properties, const char* key, const celix_array_list_t* values) { + assert(values != NULL); + celix_array_list_create_options_t opts = CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS; + opts.simpleRemovedCallback = free; + opts.initialCapacity = celix_arrayList_size(values); + celix_autoptr(celix_array_list_t) list = celix_arrayList_createWithOptions(&opts); + if (!list) { + celix_err_push("Failed to create a string array"); + return CELIX_ENOMEM; + } + for (int i = 0 ; i < celix_arrayList_size(values); ++i) { + const char* val = celix_arrayList_get(values, i); + char* copy = celix_utils_strdup(val); + if (!copy) { + celix_err_push("Failed to duplicate string"); + return CELIX_ENOMEM; + } + celix_status_t status = celix_arrayList_add(list, copy); + if (status != CELIX_SUCCESS) { + celix_err_push("Failed to add string to array list"); + return status; + } + } + celix_properties_entry_t prototype = {0}; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_STRING_ARRAY; + prototype.typed.arrayValue = celix_steal_ptr(list); + return celix_properties_createAndSetEntry(properties, key, &prototype); +} + +celix_status_t +celix_properties_assignStringArrayList(celix_properties_t* properties, const char* key, celix_array_list_t* values) { + assert(values != NULL); + celix_properties_entry_t prototype = {0}; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_STRING_ARRAY; + prototype.typed.arrayValue = values; + return celix_properties_createAndSetEntry(properties, key, &prototype); +} + +celix_status_t +celix_properties_setStrings(celix_properties_t* properties, const char* key, const char** values, size_t nrOfValues) { + assert(values != NULL); + celix_array_list_create_options_t opts = CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS; + opts.simpleRemovedCallback = free; + opts.initialCapacity = nrOfValues; + celix_autoptr(celix_array_list_t) list = celix_arrayList_createWithOptions(&opts); + if (!list) { + celix_err_push("Failed to create a string array"); + return CELIX_ENOMEM; + } + for (size_t i = 0; i < nrOfValues; ++i) { + char* copy = celix_utils_strdup(values[i]); + if (!copy) { + celix_err_push("Failed to duplicate string"); + return CELIX_ENOMEM; + } + celix_status_t status = celix_arrayList_addString(list, copy); + if (status != CELIX_SUCCESS) { + celix_err_push("Failed to add string to array list"); + return status; + } + } + celix_properties_entry_t prototype = {0}; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_STRING_ARRAY; + prototype.typed.arrayValue = celix_steal_ptr(list); + return celix_properties_createAndSetEntry(properties, key, &prototype); +} + +celix_array_list_t* celix_properties_deepCopyStringArrayList(const celix_array_list_t* list) { + celix_array_list_create_options_t opts = CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS; + opts.simpleRemovedCallback = free; + opts.initialCapacity = celix_arrayList_size(list); + celix_autoptr(celix_array_list_t) copy = celix_arrayList_createWithOptions(&opts); + if (!copy) { + celix_err_push("Failed to create a string array"); + return NULL; + } + for (int i = 0 ; i < celix_arrayList_size(list); ++i) { + const char* val = celix_arrayList_get(list, i); + char* copyStr = celix_utils_strdup(val); + if (!copyStr) { + celix_err_push("Failed to duplicate string"); + return NULL; + } + celix_status_t status = celix_arrayList_addString(copy, copyStr); + if (status != CELIX_SUCCESS) { + celix_err_push("Failed to add string to array list"); + return NULL; + } + } + return celix_steal_ptr(copy); +} + +celix_status_t celix_properties_getAsStringArrayList(const celix_properties_t* properties, + const char* key, + const celix_array_list_t* defaultValue, + celix_array_list_t** list) { + celix_properties_entry_t* entry = celix_properties_getEntry(properties, key); + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_STRING_ARRAY) { + *list = celix_properties_deepCopyStringArrayList(entry->typed.arrayValue); + return *list ? CELIX_SUCCESS : CELIX_ENOMEM; + } + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_STRING) { + celix_status_t convertStatus = celix_utils_convertStringToStringArrayList(entry->value, defaultValue, list); + if (convertStatus == CELIX_ILLEGAL_ARGUMENT) { + // conversion failed, but no memory error so defaultValue is copied and set + return CELIX_SUCCESS; + } + return convertStatus; + } + if (defaultValue) { + *list = celix_properties_deepCopyStringArrayList(defaultValue); + return *list ? CELIX_SUCCESS : CELIX_ENOMEM; + } + *list = NULL; + return CELIX_SUCCESS; +} + +const celix_array_list_t* celix_properties_getStringArrayList(const celix_properties_t* properties, + const char* key, + const celix_array_list_t* defaultValue) { + celix_properties_entry_t* entry = celix_properties_getEntry(properties, key); + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_STRING_ARRAY) { + return entry->typed.arrayValue; + } + return defaultValue; +} + +static void celix_properties_destroyVersionCallback(void *data) { + celix_version_destroy((celix_version_t*)data); +} + +celix_status_t celix_properties_setVersionArrayList(celix_properties_t* properties, const char* key, const celix_array_list_t* values) { + assert(values != NULL); + celix_array_list_create_options_t opts = CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS; + opts.simpleRemovedCallback = celix_properties_destroyVersionCallback; + opts.initialCapacity = celix_arrayList_size(values); + celix_autoptr(celix_array_list_t) list = celix_arrayList_createWithOptions(&opts); + if (!list) { + celix_err_push("Failed to create a version array"); + return CELIX_ENOMEM; + } + for (int i = 0 ; i < celix_arrayList_size(values); ++i) { + celix_version_t* version = celix_arrayList_get(values, i); + celix_version_t* copy = celix_version_copy(version); + if (!copy) { + celix_err_push("Failed to duplicate version"); + return CELIX_ENOMEM; + } + celix_status_t status = celix_arrayList_add(list, copy); + if (status != CELIX_SUCCESS) { + celix_err_push("Failed to add version to array list"); + return status; + } + } + celix_properties_entry_t prototype = {0}; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_VERSION_ARRAY; + prototype.typed.arrayValue = celix_steal_ptr(list); + return celix_properties_createAndSetEntry(properties, key, &prototype); +} + +celix_status_t +celix_properties_assignVersionArrayList(celix_properties_t* properties, const char* key, celix_array_list_t* values) { + assert(values != NULL); + celix_properties_entry_t prototype = {0}; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_VERSION_ARRAY; + prototype.typed.arrayValue = values; + return celix_properties_createAndSetEntry(properties, key, &prototype); +} + +celix_status_t +celix_properties_setVersions(celix_properties_t* properties, const char* key, const celix_version_t** values, size_t nrOfValues) { + assert(values != NULL); + celix_array_list_create_options_t opts = CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS; + opts.simpleRemovedCallback = free; + opts.initialCapacity = nrOfValues; + celix_autoptr(celix_array_list_t) list = celix_arrayList_createWithOptions(&opts); + if (!list) { + celix_err_push("Failed to create a version array"); + return CELIX_ENOMEM; + } + for (size_t i = 0; i < nrOfValues; ++i) { + celix_version_t* copy = celix_version_copy(values[i]); + if (!copy) { + celix_err_push("Failed to duplicate version"); + return CELIX_ENOMEM; + } + celix_status_t status = celix_arrayList_add(list, copy); + if (status != CELIX_SUCCESS) { + celix_err_push("Failed to add version to array list"); + return status; + } + } + celix_properties_entry_t prototype = {0}; + prototype.valueType = CELIX_PROPERTIES_VALUE_TYPE_VERSION_ARRAY; + prototype.typed.arrayValue = celix_steal_ptr(list); + return celix_properties_createAndSetEntry(properties, key, &prototype); +} + +static celix_array_list_t* celix_properties_deepCopyVersionArrayList(const celix_array_list_t* list) { + celix_array_list_create_options_t opts = CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS; + opts.simpleRemovedCallback = celix_properties_destroyVersionCallback; + opts.initialCapacity = celix_arrayList_size(list); + celix_autoptr(celix_array_list_t) copy = celix_arrayList_createWithOptions(&opts); + if (!copy) { + return NULL; + } + for (int i = 0; i < celix_arrayList_size(list); ++i) { + const celix_version_t* val = celix_arrayList_get(list, i); + celix_version_t* verCopy = celix_version_copy(val); + if (!verCopy) { + celix_err_push("Failed to duplicate version"); + return NULL; + } + celix_status_t status = celix_arrayList_add(copy, verCopy); + if (status != CELIX_SUCCESS) { + celix_err_push("Failed to add version to array list"); + return NULL; + } + } + return celix_steal_ptr(copy); +} + +celix_status_t celix_properties_getAsVersionArrayList(const celix_properties_t* properties, + const char* key, + const celix_array_list_t* defaultValue, + celix_array_list_t** list) { + celix_properties_entry_t* entry = celix_properties_getEntry(properties, key); + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_VERSION_ARRAY) { + *list = celix_properties_deepCopyVersionArrayList(entry->typed.arrayValue); + return *list ? CELIX_SUCCESS : CELIX_ENOMEM; + } + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_STRING) { + celix_status_t convertStatus = celix_utils_convertStringToStringArrayList(entry->value, defaultValue, list); + if (convertStatus == CELIX_ILLEGAL_ARGUMENT) { + // conversion failed, but no memory error so defaultValue is copied and set + return CELIX_SUCCESS; + } + return convertStatus; + } + if (defaultValue) { + *list = celix_properties_deepCopyVersionArrayList(defaultValue); + return *list ? CELIX_SUCCESS : CELIX_ENOMEM; + } + *list = NULL; + return CELIX_SUCCESS; +} + +const celix_array_list_t* celix_properties_getVersionArrayList(const celix_properties_t* properties, + const char* key, + const celix_array_list_t* defaultValue) { + celix_properties_entry_t* entry = celix_properties_getEntry(properties, key); + if (entry != NULL && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_VERSION_ARRAY) { return entry->typed.arrayValue; } return defaultValue;
