You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2024/01/07 19:43:18 UTC
(celix) 07/08: Add str, long, double, bool and version array support to properties
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 <pn...@apache.org>
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;