This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a commit to branch feature/685-properties-json-serialization
in repository https://gitbox.apache.org/repos/asf/celix.git
The following commit(s) were added to
refs/heads/feature/685-properties-json-serialization by this push:
new 0e589441 gh-685: Fix several memleaks in properties encoding
0e589441 is described below
commit 0e5894419921ddbb5f4c4868cf6e7c99b463bfd2
Author: Pepijn Noltes <[email protected]>
AuthorDate: Sun Apr 14 23:03:53 2024 +0200
gh-685: Fix several memleaks in properties encoding
---
.../PropertiesEncodingErrorInjectionTestSuite.cc | 8 +-
.../utils/gtest/src/PropertiesEncodingTestSuite.cc | 107 ++++++++++++---------
libs/utils/include/celix_properties.h | 52 +++++++++-
libs/utils/src/properties_encoding.c | 23 +++--
4 files changed, 126 insertions(+), 64 deletions(-)
diff --git a/libs/utils/gtest/src/PropertiesEncodingErrorInjectionTestSuite.cc
b/libs/utils/gtest/src/PropertiesEncodingErrorInjectionTestSuite.cc
index 3bcc804e..2553e0e9 100644
--- a/libs/utils/gtest/src/PropertiesEncodingErrorInjectionTestSuite.cc
+++ b/libs/utils/gtest/src/PropertiesEncodingErrorInjectionTestSuite.cc
@@ -69,7 +69,7 @@ TEST_F(PropertiesEncodingErrorInjectionTestSuite,
SaveErrorTest) {
celix_ei_expect_open_memstream((void*)celix_properties_saveToString, 0,
nullptr);
//When I call celix_properties_saveToString
- char* out = nullptr;
+ char* out;
status = celix_properties_saveToString(props, 0, &out);
//Then I expect an error
@@ -90,7 +90,7 @@ TEST_F(PropertiesEncodingErrorInjectionTestSuite,
EncodeErrorTest) {
celix_ei_expect_celix_utils_writeOrCreateString((void*)celix_properties_saveToString,
2, nullptr);
// And I call celix_properties_saveToString using NESTED encoding
(whitebox-knowledge)
- char* out = nullptr;
+ char* out;
auto status = celix_properties_saveToString(props,
CELIX_PROPERTIES_ENCODE_NESTED_STYLE, &out);
// Then I expect an error
@@ -149,7 +149,7 @@ TEST_F(PropertiesEncodingErrorInjectionTestSuite,
EncodeArrayErrorTest) {
celix_ei_expect_json_array((void*)celix_properties_saveToString, 4,
nullptr);
// And I call celix_properties_saveToString
- char* out = nullptr;
+ char* out;
auto status = celix_properties_saveToString(props, 0, &out);
// Then I expect an error
@@ -189,7 +189,7 @@ TEST_F(PropertiesEncodingErrorInjectionTestSuite,
EncodeVersionErrorTest) {
celix_ei_expect_json_sprintf((void*)celix_properties_saveToString, 4,
nullptr);
// And I call celix_properties_saveToString
- char* out = nullptr;
+ char* out;
auto status = celix_properties_saveToString(props, 0, &out);
// Then I expect an error
diff --git a/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc
b/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc
index d4ff8e17..0771aa3c 100644
--- a/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc
+++ b/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc
@@ -93,14 +93,17 @@ TEST_F(PropertiesSerializationTestSuite,
SavePropertiesWithNaNAndInfValuesTest)
celix_autoptr(celix_properties_t) props = celix_properties_create();
celix_properties_setDouble(props, key, strtod(key, nullptr));
- //And an in-memory stream
- celix_autofree char* buf = nullptr;
- size_t bufLen = 0;
- FILE* stream = open_memstream(&buf, &bufLen);
+ // Then saving the properties to a string succeeds, but value is not
added to the JSON (because JSON does not
+ // support NAN, INF and -INF)
+ celix_autofree char* output;
+ auto status = celix_properties_saveToString(props, 0, &output);
+ ASSERT_EQ(CELIX_SUCCESS, status);
+ EXPECT_STREQ("{}", output);
- //Then saving the properties to the stream fails, because JSON does
not support NAN, INF and -INF
+ //And saving the properties to a string with the flag
CELIX_PROPERTIES_ENCODE_ERROR_ON_NAN_INF fails
celix_err_resetErrors();
- auto status = celix_properties_saveToStream(props, stream, 0);
+ char* output2;
+ status = celix_properties_saveToString(props,
CELIX_PROPERTIES_ENCODE_ERROR_ON_NAN_INF, &output2);
EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, status);
//And an error msg is added to celix_err
@@ -112,25 +115,30 @@ TEST_F(PropertiesSerializationTestSuite,
SavePropertiesWithNaNAndInfValuesTest)
TEST_F(PropertiesSerializationTestSuite, SavePropertiesWithArrayListsTest) {
// Given a properties object with array list values
celix_autoptr(celix_properties_t) props = celix_properties_create();
+
celix_array_list_t* list1 = celix_arrayList_createStringArray();
celix_arrayList_addString(list1, "value1");
celix_arrayList_addString(list1, "value2");
celix_properties_assignArrayList(props, "key1", list1);
+
celix_array_list_t* list2 = celix_arrayList_createLongArray();
celix_arrayList_addLong(list2, 1);
celix_arrayList_addLong(list2, 2);
celix_properties_assignArrayList(props, "key2", list2);
+
celix_array_list_t* list3 = celix_arrayList_createDoubleArray();
celix_arrayList_addDouble(list3, 1.0);
celix_arrayList_addDouble(list3, 2.0);
celix_properties_assignArrayList(props, "key3", list3);
+
celix_array_list_t* list4 = celix_arrayList_createBoolArray();
celix_arrayList_addBool(list4, true);
celix_arrayList_addBool(list4, false);
celix_properties_assignArrayList(props, "key4", list4);
+
celix_array_list_t* list5 = celix_arrayList_createVersionArray();
- celix_arrayList_addVersion(list5, celix_version_create(1, 2, 3,
"qualifier"));
- celix_arrayList_addVersion(list5, celix_version_create(4, 5, 6,
"qualifier"));
+ celix_arrayList_assignVersion(list5, celix_version_create(1, 2, 3,
"qualifier"));
+ celix_arrayList_assignVersion(list5, celix_version_create(4, 5, 6,
"qualifier"));
celix_properties_assignArrayList(props, "key5", list5);
// And an in-memory stream
@@ -170,17 +178,18 @@ TEST_F(PropertiesSerializationTestSuite,
SaveEmptyArrayTest) {
EXPECT_EQ(5, celix_properties_size(props));
//When saving the properties to a string
- char* output = nullptr;
- auto status = celix_properties_saveToString(props, 0, &output);
+ celix_autofree char* output1;
+ auto status = celix_properties_saveToString(props, 0, &output1);
//Then the save went ok
ASSERT_EQ(CELIX_SUCCESS, status);
//And the output contains an empty JSON object, because empty arrays are
treated as unset
- EXPECT_STREQ("{}", output);
+ EXPECT_STREQ("{}", output1);
//When saving the properties to a string with an error on empty array flag
- status = celix_properties_saveToString(props,
CELIX_PROPERTIES_ENCODE_ERROR_ON_EMPTY_ARRAYS, &output);
+ char* output2;
+ status = celix_properties_saveToString(props,
CELIX_PROPERTIES_ENCODE_ERROR_ON_EMPTY_ARRAYS, &output2);
//Then the save fails, because the empty array generates an error
ASSERT_EQ(CELIX_ILLEGAL_ARGUMENT, status);
@@ -268,7 +277,7 @@ TEST_F(PropertiesSerializationTestSuite,
SavePropertiesWithKeyNamesWithSlashesTe
//When saving the properties to a string
- char* output = nullptr;
+ celix_autofree char* output;
auto status = celix_properties_saveToString(props,
CELIX_PROPERTIES_ENCODE_NESTED_STYLE, &output);
ASSERT_EQ(CELIX_SUCCESS, status);
@@ -329,18 +338,19 @@ TEST_F(PropertiesSerializationTestSuite,
SavePropertiesWithKeyCollision) {
celix_properties_set(props, "key1/key2", "value2"); //collision with
object "key1/key2" -> overwrite
//When saving the properties to a string
- char* output = nullptr;
- auto status = celix_properties_saveToString(props,
CELIX_PROPERTIES_ENCODE_NESTED_STYLE, &output);
+ celix_autofree char* output1;
+ auto status = celix_properties_saveToString(props,
CELIX_PROPERTIES_ENCODE_NESTED_STYLE, &output1);
//Then the save succeeds
ASSERT_EQ(CELIX_SUCCESS, status);
// And both keys are serialized (one as a flat key) (flat key name is
whitebox knowledge)
- EXPECT_NE(nullptr, strstr(output, R"({"key1":{"key2":"value2"}})")) <<
"JSON: " << output;
+ EXPECT_NE(nullptr, strstr(output1, R"({"key1":{"key2":"value2"}})")) <<
"JSON: " << output1;
//When saving the properties to a string with the error on key collision
flag
+ char* output2;
status = celix_properties_saveToString(
- props, CELIX_PROPERTIES_ENCODE_NESTED_STYLE |
CELIX_PROPERTIES_ENCODE_ERROR_ON_COLLISIONS, &output);
+ props, CELIX_PROPERTIES_ENCODE_NESTED_STYLE |
CELIX_PROPERTIES_ENCODE_ERROR_ON_COLLISIONS, &output2);
//Then the save fails, because the keys collide
ASSERT_EQ(CELIX_ILLEGAL_ARGUMENT, status);
@@ -357,7 +367,7 @@ TEST_F(PropertiesSerializationTestSuite,
SavePropertiesWithAndWithoutStrictFlagT
celix_properties_assignArrayList(props, "key1", list);
//When saving the properties to a string without the strict flag
- char* output = nullptr;
+ celix_autofree char* output;
auto status = celix_properties_saveToString(props, 0, &output);
//Then the save succeeds
@@ -381,7 +391,7 @@ TEST_F(PropertiesSerializationTestSuite,
SavePropertiesWithPrettyPrintTest) {
celix_properties_set(props, "key2", "value2");
//When saving the properties to a string with pretty print
- char* output = nullptr;
+ celix_autofree char* output;
auto status = celix_properties_saveToString(props,
CELIX_PROPERTIES_ENCODE_PRETTY, &output);
//Then the save succeeds
@@ -414,17 +424,14 @@ TEST_F(PropertiesSerializationTestSuite,
SaveWithInvalidStreamTest) {
TEST_F(PropertiesSerializationTestSuite, LoadEmptyPropertiesTest) {
//Given an empty JSON object
const char* json = "{}";
- FILE* stream = fmemopen((void*)json, strlen(json), "r");
//When loading the properties from the stream
celix_autoptr(celix_properties_t) props = nullptr;
- auto status = celix_properties_loadFromStream(stream, 0, &props);
+ auto status = celix_properties_loadFromString2(json, 0, &props);
ASSERT_EQ(CELIX_SUCCESS, status);
//Then the properties object is empty
EXPECT_EQ(0, celix_properties_size(props));
-
- fclose(stream);
}
TEST_F(PropertiesSerializationTestSuite, LoadPropertiesWithSingleValuesTest) {
@@ -586,7 +593,8 @@ TEST_F(PropertiesSerializationTestSuite,
LoadPropertiesWithEmptyArrayTest) {
EXPECT_EQ(0, celix_properties_size(props));
//When loading the properties from string with a strict flag
- status = celix_properties_loadFromString2(inputJSON,
CELIX_PROPERTIES_DECODE_ERROR_ON_EMPTY_ARRAYS, &props);
+ celix_properties_t* props2;
+ status = celix_properties_loadFromString2(inputJSON,
CELIX_PROPERTIES_DECODE_ERROR_ON_EMPTY_ARRAYS, &props2);
//Then loading fails, because the empty array generates an error
ASSERT_EQ(CELIX_ILLEGAL_ARGUMENT, status);
@@ -651,7 +659,7 @@ TEST_F(PropertiesSerializationTestSuite,
LoadPropertiesWithDuplicatesTest) {
EXPECT_EQ(3, celix_properties_getLong(props, "key", 0));
// When decoding the properties from the stream using a flog that does not
allow duplicates
- celix_autoptr(celix_properties_t) props2 = nullptr;
+ celix_autoptr(celix_properties_t) props2;
status = celix_properties_loadFromString2(jsonInput,
CELIX_PROPERTIES_DECODE_ERROR_ON_DUPLICATES, &props2);
// Then loading fails, because of a duplicate key
@@ -687,7 +695,7 @@ TEST_F(PropertiesSerializationTestSuite,
LoadPropertiesEscapedSlashesTest) {
})";
// When loading the properties from a string.
- celix_autoptr(celix_properties_t) props = nullptr;
+ celix_autoptr(celix_properties_t) props;
auto status = celix_properties_loadFromString2(jsonInput, 0, &props);
// Then loading succeeds
@@ -703,7 +711,7 @@ TEST_F(PropertiesSerializationTestSuite,
LoadPropertiesEscapedSlashesTest) {
EXPECT_STREQ("value7", celix_properties_getString(props, "object3/key4"));
// When decoding the properties from a string using a flag that allows
duplicates
- celix_autoptr(celix_properties_t) props2 = nullptr;
+ celix_autoptr(celix_properties_t) props2;
status = celix_properties_loadFromString2(jsonInput,
CELIX_PROPERTIES_DECODE_ERROR_ON_DUPLICATES, &props2);
// Then loading fails, because of a duplicate key
@@ -714,7 +722,7 @@ TEST_F(PropertiesSerializationTestSuite,
LoadPropertiesEscapedSlashesTest) {
celix_err_printErrors(stderr, "Test Error: ", "\n");
// When decoding the properties from a string using a flag that allows
collisions
- celix_autoptr(celix_properties_t) props3 = nullptr;
+ celix_autoptr(celix_properties_t) props3;
status = celix_properties_loadFromString2(jsonInput,
CELIX_PROPERTIES_DECODE_ERROR_ON_COLLISIONS, &props3);
// Then loading fails, because of a collision
@@ -861,34 +869,41 @@ TEST_F(PropertiesSerializationTestSuite,
LoadWithInvalidStreamTest) {
TEST_F(PropertiesSerializationTestSuite, SaveAndLoadFlatProperties) {
// Given a properties object with all possible types (but no empty arrays)
celix_autoptr(celix_properties_t) props = celix_properties_create();
- celix_properties_set(props, "strKey", "strValue");
- celix_properties_setLong(props, "longKey", 42);
- celix_properties_setDouble(props, "doubleKey", 2.0);
- celix_properties_setBool(props, "boolKey", true);
- celix_properties_setVersion(props, "versionKey", celix_version_create(1,
2, 3, "qualifier"));
- auto* strArr = celix_arrayList_createStringArray();
+
+ celix_properties_set(props, "single/strKey", "strValue");
+ celix_properties_setLong(props, "single/longKey", 42);
+ celix_properties_setDouble(props, "single/doubleKey", 2.0);
+ celix_properties_setBool(props, "single/boolKey", true);
+ celix_properties_assignVersion(props, "single/versionKey",
celix_version_create(1, 2, 3, "qualifier"));
+
+ celix_array_list_t* strArr = celix_arrayList_createStringArray();
celix_arrayList_addString(strArr, "value1");
celix_arrayList_addString(strArr, "value2");
- auto* longArr = celix_arrayList_createLongArray();
+ celix_properties_assignArrayList(props, "array/stringArr", strArr);
+
+ celix_array_list_t* longArr = celix_arrayList_createLongArray();
celix_arrayList_addLong(longArr, 1);
celix_arrayList_addLong(longArr, 2);
- celix_properties_assignArrayList(props, "longArr", longArr);
- auto* doubleArr = celix_arrayList_createDoubleArray();
+ celix_properties_assignArrayList(props, "array/longArr", longArr);
+
+ celix_array_list_t* doubleArr = celix_arrayList_createDoubleArray();
celix_arrayList_addDouble(doubleArr, 1.0);
celix_arrayList_addDouble(doubleArr, 2.0);
- celix_properties_assignArrayList(props, "doubleArr", doubleArr);
- auto* boolArr = celix_arrayList_createBoolArray();
+ celix_properties_assignArrayList(props, "array/doubleArr", doubleArr);
+
+ celix_array_list_t* boolArr = celix_arrayList_createBoolArray();
celix_arrayList_addBool(boolArr, true);
celix_arrayList_addBool(boolArr, false);
- celix_properties_assignArrayList(props, "boolArr", boolArr);
- auto* versionArr = celix_arrayList_createVersionArray();
- celix_arrayList_addVersion(versionArr, celix_version_create(1, 2, 3,
"qualifier"));
- celix_arrayList_addVersion(versionArr, celix_version_create(4, 5, 6,
"qualifier"));
- celix_properties_assignArrayList(props, "versionArr", versionArr);
+ celix_properties_assignArrayList(props, "array/boolArr", boolArr);
+
+ celix_array_list_t* versionArr = celix_arrayList_createVersionArray();
+ celix_arrayList_assignVersion(versionArr, celix_version_create(1, 2, 3,
"qualifier"));
+ celix_arrayList_assignVersion(versionArr, celix_version_create(4, 5, 6,
"qualifier"));
+ celix_properties_assignArrayList(props, "array/versionArr", versionArr);
// When saving the properties to a properties_test.json file
const char* filename = "properties_test.json";
- auto status = celix_properties_save(props, filename, 0);
+ auto status = celix_properties_save(props, filename,
CELIX_PROPERTIES_ENCODE_PRETTY);
// Then saving succeeds
ASSERT_EQ(CELIX_SUCCESS, status);
@@ -902,4 +917,4 @@ TEST_F(PropertiesSerializationTestSuite,
SaveAndLoadFlatProperties) {
// And the loaded properties are equal to the original properties
EXPECT_TRUE(celix_properties_equals(props, loadedProps));
-}
+}
\ No newline at end of file
diff --git a/libs/utils/include/celix_properties.h
b/libs/utils/include/celix_properties.h
index a483f26a..2ac692ea 100644
--- a/libs/utils/include/celix_properties.h
+++ b/libs/utils/include/celix_properties.h
@@ -1020,6 +1020,16 @@ CELIX_UTILS_EXPORT bool
celix_propertiesIterator_equals(const celix_properties_i
*/
#define CELIX_PROPERTIES_ENCODE_ERROR_ON_EMPTY_ARRAYS 0x20
+/**
+ * @brief Flag to indicate that the encoding should fail if the JSON
representation will contain NaN or Inf values.
+ *
+ * NaN, Inf and -Inf are not valid JSON values and as such properties entries
with these values are not encoded.
+ *
+ * If this flag is set, the encoding will fail if the JSON representation will
contain NaN or Inf values and if this
+ * flag is not set, the encoding will not fail and the NaN and Inf entries
will be ignored.
+ */
+#define CELIX_PROPERTIES_ENCODE_ERROR_ON_NAN_INF 0x40
+
/**
* @brief Flag to indicate that all encode "error on" flags should be set.
*/
@@ -1031,7 +1041,26 @@ CELIX_UTILS_EXPORT bool
celix_propertiesIterator_equals(const celix_properties_i
*
* The stream is expected to be a valid stream and is not reset or closed by
this function.
*
- * TODO document the JSON format
+ * Properties are encoded as a JSON object.
+ *
+ * If no encoding style flag is set of when the
CELIX_PROPERTIES_ENCODE_FLAT_STYLE flag is set, properties
+ * entries are written as top level field entries.
+ *
+ * If the CELIX_PROPERTIES_ENCODE_NESTED_STYLE flag is set, properties entry
keys are split on '/' and nested in
+ * JSON objects. This leads to a more natural JSON representation, but if
there are colliding properties keys (e.g.
+ * `{"key": "value1", "key/with/slash": "value2"}`), not all properties
entries will be written.
+ *
+ * With all encoding styles, the empty array properties entries are ignored,
because they cannot be decoded to a valid
+ * properties array entry.
+ *
+ * Properties type entries are encoded as follows:
+ * - CELIX_PROPERTIES_TYPE_STRING: The value is encoded as a JSON string.
+ * - CELIX_PROPERTIES_TYPE_LONG: The value is encoded as a JSON number.
+ * - CELIX_PROPERTIES_TYPE_DOUBLE: The value is encoded as a JSON number.
+ * - CELIX_PROPERTIES_TYPE_BOOL: The value is encoded as a JSON boolean.
+ * - CELIX_PROPERTIES_TYPE_ARRAY: The value is encoded as a JSON array, with
each element encoded according to its type.
+ * - CELIX_PROPERTIES_TYPE_VERSION: The value is encoded as a JSON string with
a "version<" prefix and a ">" suffix
+ * (e.g. "version<1.2.3>").
*
* For a overview of the possible encode flags, see the
CELIX_PROPERTIES_ENCODE_* flags documentation.
* The default encoding style is a compact and flat JSON representation.
@@ -1168,7 +1197,26 @@ CELIX_UTILS_EXPORT celix_status_t
celix_properties_saveToString(const celix_prop
* The stream is expected to be a valid readable stream and is not reset or
closed by this function.
* The content of the stream is expected to be in the format of a JSON object.
*
- * TODO describe allowed and disallowed JSON objects.
+ * For decoding a single JSON object is decoded to a properties object.
+ *
+ * The keys of the JSON object are used as
+ * properties keys and the values of the JSON object are used as properties
values. If there are nested
+ * JSON objects, the keys are concatenated with a '/' separator (e.g. `{"key":
{"nested": "value"}}` will be
+ * decoded to a properties object with a single entry with key `key/nested`
and (string) value `value`).
+ *
+ * Because properties keys are created by concatenating the JSON keys, there
there could be collisions
+ * (e.g. `{"obj/key": "value", "obj": {"key": "value2"}}`, two entries with
the key `obj/key`. In this case
+ * the last decoded JSON entry will be used.
+ *
+ * Properties entry types are determined by the JSON value type:
+ * - JSON string values are decoded as string properties entries.
+ * - JSON number values are decoded as long or double properties entries,
depending on the value.
+ * - JSON boolean values are decoded as boolean properties entries.
+ * - jSON string values with a "version<" prefix and a ">" suffix are decoded
as version properties entries (e.g.
+ * "version<1.2.3>").
+ * - JSON array values are decoded as array properties entries. The array can
contain any of the above types, but mixed
+ * arrays are not supported.
+ * - JSON null values are ignored.
*
* For a overview of the possible decode flags, see the
CELIX_PROPERTIES_DECODE_* flags documentation.
*
diff --git a/libs/utils/src/properties_encoding.c
b/libs/utils/src/properties_encoding.c
index 2b5c693b..eba39207 100644
--- a/libs/utils/src/properties_encoding.c
+++ b/libs/utils/src/properties_encoding.c
@@ -130,8 +130,11 @@ celix_properties_entryValueToJson(const char* key, const
celix_properties_entry_
break;
case CELIX_PROPERTIES_VALUE_TYPE_DOUBLE:
if (isnan(entry->typed.doubleValue) ||
isinf(entry->typed.doubleValue)) {
- celix_err_pushf("Invalid NaN or Inf in key '%s'.", key);
- return CELIX_ILLEGAL_ARGUMENT;
+ if (flags & CELIX_PROPERTIES_ENCODE_ERROR_ON_NAN_INF) {
+ celix_err_pushf("Invalid NaN or Inf in key '%s'.", key);
+ return CELIX_ILLEGAL_ARGUMENT;
+ }
+ return CELIX_SUCCESS; // ignore NaN and Inf
}
*out = json_real(entry->typed.doubleValue);
break;
@@ -184,10 +187,8 @@ static celix_status_t
celix_properties_addPropertiesEntryFlatToJson(const celix_
int flags)
{
json_t* value;
celix_status_t status = celix_properties_entryValueToJson(key, entry,
flags, &value);
- if (status != CELIX_SUCCESS) {
- return status;
- }
- return celix_properties_addJsonValueToJson(value, key, root, flags);
+ status = CELIX_DO_IF(status, celix_properties_addJsonValueToJson(value,
key, root, flags));
+ return status;
}
static celix_status_t celix_properties_addPropertiesEntryToJson(const
celix_properties_entry_t* entry,
@@ -237,7 +238,7 @@ static celix_status_t
celix_properties_addPropertiesEntryToJson(const celix_prop
}
celix_status_t celix_properties_saveToStream(const celix_properties_t*
properties, FILE* stream, int encodeFlags) {
- json_t* root = json_object();
+ json_auto_t* root = json_object();
if (!root) {
celix_err_push("Failed to create json object");
return ENOMEM;
@@ -257,7 +258,6 @@ celix_status_t celix_properties_saveToStream(const
celix_properties_t* propertie
status = celix_properties_addPropertiesEntryToJson(&iter.entry,
iter.key, root, encodeFlags);
}
if (status != CELIX_SUCCESS) {
- json_decref(root);
return status;
}
}
@@ -268,7 +268,6 @@ celix_status_t celix_properties_saveToStream(const
celix_properties_t* propertie
}
int rc = json_dumpf(root, stream, jsonFlags);
- json_decref(root);
if (rc != 0) {
celix_err_push("Failed to dump json object to stream.");
return CELIX_FILE_IO_EXCEPTION;
@@ -432,7 +431,7 @@ celix_properties_decodeArray(celix_properties_t* props,
const char* key, const j
case CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION: {
celix_version_t* v;
status = celix_properties_parseVersion(json_string_value(value),
&v);
- status = CELIX_DO_IF(status, celix_arrayList_addVersion(array, v));
+ status = CELIX_DO_IF(status, celix_arrayList_assignVersion(array,
v));
break;
}
default:
@@ -468,7 +467,7 @@ celix_properties_decodeValue(celix_properties_t* props,
const char* key, json_t*
if (json_is_string(jsonValue) &&
celix_properties_isVersionString(json_string_value(jsonValue))) {
celix_version_t* version;
status = celix_properties_parseVersion(json_string_value(jsonValue),
&version);
- status = CELIX_DO_IF(status, celix_properties_setVersion(props, key,
version));
+ status = CELIX_DO_IF(status, celix_properties_assignVersion(props,
key, version));
} else if (json_is_string(jsonValue)) {
status = celix_properties_setString(props, key,
json_string_value(jsonValue));
} else if (json_is_integer(jsonValue)) {
@@ -549,7 +548,7 @@ celix_status_t celix_properties_loadFromStream(FILE*
stream, int decodeFlags, ce
if (decodeFlags & CELIX_PROPERTIES_DECODE_ERROR_ON_DUPLICATES) {
jsonFlags = JSON_REJECT_DUPLICATES;
}
- json_t* root = json_loadf(stream, jsonFlags, &jsonError);
+ json_auto_t* root = json_loadf(stream, jsonFlags, &jsonError);
if (!root) {
celix_err_pushf("Failed to parse json: %s.", jsonError.text);
return CELIX_ILLEGAL_ARGUMENT;