(celix) branch feature/685-properties-json-serialization updated: gh-685: Some whitespace corrections
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 c46a483b gh-685: Some whitespace corrections c46a483b is described below commit c46a483bc8031edc14e11739a8bec5aa7043e4ee Author: Pepijn Noltes AuthorDate: Mon Apr 15 23:25:05 2024 +0200 gh-685: Some whitespace corrections --- conanfile.py| 2 +- libs/error_injector/jansson/src/jansson_ei.cc | 2 +- libs/utils/error_injector/celix_version/src/celix_version_ei.cc | 2 +- libs/utils/gtest/src/PropertiesEncodingTestSuite.cc | 2 +- libs/utils/include/celix_utils.h| 9 - 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/conanfile.py b/conanfile.py index d8b46d01..dbf956ba 100644 --- a/conanfile.py +++ b/conanfile.py @@ -309,7 +309,7 @@ class CelixConan(ConanFile): self.options['openssl'].shared = True if self.options.build_celix_dfi: self.options['libffi'].shared = True -if self.options.build_utils or self.options.build_celix_dfi or self.options.build_celix_etcdlib: +if self.options.build_utils or self.options.build_celix_dfi or self.options.build_celix_etcdlib: self.options['jansson'].shared = True def requirements(self): diff --git a/libs/error_injector/jansson/src/jansson_ei.cc b/libs/error_injector/jansson/src/jansson_ei.cc index 1d820629..515d4567 100644 --- a/libs/error_injector/jansson/src/jansson_ei.cc +++ b/libs/error_injector/jansson/src/jansson_ei.cc @@ -106,4 +106,4 @@ json_t* __wrap_json_sprintf(const char* fmt, ...) { return obj; } -} \ No newline at end of file +} diff --git a/libs/utils/error_injector/celix_version/src/celix_version_ei.cc b/libs/utils/error_injector/celix_version/src/celix_version_ei.cc index ddcdf9f8..b09339cd 100644 --- a/libs/utils/error_injector/celix_version/src/celix_version_ei.cc +++ b/libs/utils/error_injector/celix_version/src/celix_version_ei.cc @@ -48,4 +48,4 @@ char* __wrap_celix_version_toString(const celix_version_t* version) { return __real_celix_version_toString(version); } -} \ No newline at end of file +} diff --git a/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc b/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc index 3e03b77e..4232131b 100644 --- a/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc +++ b/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc @@ -914,4 +914,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_utils.h b/libs/utils/include/celix_utils.h index 6f58f2b7..19a4fd94 100644 --- a/libs/utils/include/celix_utils.h +++ b/libs/utils/include/celix_utils.h @@ -97,9 +97,7 @@ CELIX_UTILS_EXPORT void celix_utils_freeStringIfNotEqual(const char* buffer, cha * @brief Guard for a string created with celix_utils_writeOrCreateString, celix_utils_writeOrCreateVString. * * Can be used with celix_auto() to automatically and correctly free the string. - * If the string is pointing to the buffer, the string should be freed, otherwise the string should be freed. - * - * + * If the string is pointing to the buffer, the string should not be freed, otherwise the string should be freed. */ typedef struct celix_utils_string_guard { const char* buffer; @@ -107,7 +105,8 @@ typedef struct celix_utils_string_guard { } celix_utils_string_guard_t; /** - * @brief Initialize a guard for a string created with celix_utils_writeOrCreateString, celix_utils_writeOrCreateVString. + * @brief Initialize a guard for a string created with celix_utils_writeOrCreateString or + * celix_utils_writeOrCreateVString. * * De-initialize with celix_utils_stringGuard_deinit(). * @@ -115,7 +114,7 @@ typedef struct celix_utils_string_guard { * This is intended to be used with celix_auto(). * * * Example: -* ``` + * ``` * const char* possibleLongString = ... * char buffer[64]; * char* str = celix_utils_writeOrCreateString(buffer, sizeof(buffer), "Hello %s", possibleLongString);
(celix) 02/02: gh-685: Add properties encoding documentation
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 commit aa29987def9709f35b569280d61a2dd0aead5d12 Author: Pepijn Noltes AuthorDate: Mon Apr 15 23:17:21 2024 +0200 gh-685: Add properties encoding documentation --- documents/README.md | 1 + documents/properties_encoding.md | 333 +++ 2 files changed, 334 insertions(+) diff --git a/documents/README.md b/documents/README.md index 3930498a..c174acbe 100644 --- a/documents/README.md +++ b/documents/README.md @@ -86,6 +86,7 @@ bundles contains binaries depending on the stdlibc++ library. * [Apache Celix C Patterns](c_patterns.md) * Utils * [Apache Celix Properties & Filter](properties_and_filter.md) + * [Apache Celix Properties Encoding](properties_encoding.md) * Framework * [Apache Celix Bundles](bundles.md) * [Apache Celix Services](services.md) diff --git a/documents/properties_encoding.md b/documents/properties_encoding.md new file mode 100644 index ..c4cdb38d --- /dev/null +++ b/documents/properties_encoding.md @@ -0,0 +1,333 @@ +--- +title: Apache Celix Properties Encoding +--- + + + +# Apache Celix Properties JSON Encoding + +## Introduction + +In Apache Celix, properties represent key-value pairs, often used for configuration. While these properties are not JSON +objects inherently, they can be encoded to and decoded from JSON for interoperability or storage. This page explains how +Apache Celix properties are encoded to and decoded from JSON. + +### Encoding limitations + +Except for empty arrays and the double values NaN, Infinity, and -Infinity, all Apache Celix properties types can +be encoded to JSON. + +The reason for the empty array limitation is that for a properties array entry the array list element type is must be +known, this is not possible to infer from an empty JSON array. To ensure that everything this is encoded, can be decoded +again, a properties array entry with an empty array is not encoded to JSON. + +The reason for the double values NaN, Infinity, and -Infinity limitation is that JSON does not support these values. + +### Decoding limitations + +When decoding JSON to Apache Celix properties, the following limitations apply: + +- Mixed array types are not supported. For example, an array with both strings and longs cannot be decoded to a + properties' entry. +- null values are not supported, because properties does not support a null value type. +- Empty arrays are not supported, because the array list element type must be known, this is not possible to infer from + an empty JSON array. +- JSON keys that collide on the created properties' key level are not supported. + See [Properties Decoding](##Properties Decoding) for more information. + +## Properties Encoding + +Apache Celix properties can be encoded to JSON using the `celix_properties_save`, `celix_properties_saveToStream` +and `celix_properties_saveToString` functions. These functions take a properties object and encode it to a JSON object +string. The encoding can be controlled using flags and can be done in a flat or nested structure. + +### Properties Flat Encoding + +By default, the encoding is done in a flat structure, because a flat structure ensures that all keys of the properties +can be represented in JSON format. When properties are encoded to JSON in a flat structure, the reverse operation, +decoding JSON that has been encoded from properties, will result in the same properties (except for the previously +mentioned limitations (empty arrays and the double values NaN, Infinity, and -Infinity)). + +Flat Encoding example: + +```C +#include +#include + +int main() { +celix_autoptr(celix_properties_t) props = celix_properties_create(); + +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"); +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, "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, "array/doubleArr", doubleArr); + +
(celix) branch feature/685-properties-json-serialization updated (ae4464ca -> aa29987d)
This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a change to branch feature/685-properties-json-serialization in repository https://gitbox.apache.org/repos/asf/celix.git from ae4464ca gh-685: Fix incorrect celix_autoptr usage new a4814f3f gh-685: Fix incorrect celix_autoptr usage new aa29987d gh-685: Add properties encoding documentation The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference. Summary of changes: documents/README.md| 1 + documents/properties_encoding.md | 333 + .../utils/gtest/src/PropertiesEncodingTestSuite.cc | 23 +- 3 files changed, 344 insertions(+), 13 deletions(-) create mode 100644 documents/properties_encoding.md
(celix) 01/02: gh-685: Fix incorrect celix_autoptr usage
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 commit a4814f3f4955fe0b260e2fc416849ef1eb1d82a0 Author: Pepijn Noltes AuthorDate: Mon Apr 15 23:05:01 2024 +0200 gh-685: Fix incorrect celix_autoptr usage --- .../utils/gtest/src/PropertiesEncodingTestSuite.cc | 23 ++ 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc b/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc index 1b0035c0..3e03b77e 100644 --- a/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc +++ b/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc @@ -210,27 +210,23 @@ TEST_F(PropertiesSerializationTestSuite, SaveJPathKeysTest) { celix_properties_set(props, "object3/object4/key6", "value6"); //And an in-memory stream -celix_autofree char* buf = nullptr; -size_t bufLen = 0; -FILE* stream = open_memstream(, ); +celix_autofree char* output; //When saving the properties to the stream -auto status = celix_properties_saveToStream(props, stream, CELIX_PROPERTIES_ENCODE_NESTED_STYLE); +auto status = celix_properties_saveToString(props, CELIX_PROPERTIES_ENCODE_NESTED_STYLE, ); ASSERT_EQ(CELIX_SUCCESS, status); //Then the stream contains the JSON representation snippets of the properties -fclose(stream); -EXPECT_NE(nullptr, strstr(buf, R"("key1":"value1")")) << "JSON: " << buf; -EXPECT_NE(nullptr, strstr(buf, R"("key2":"value2")")) << "JSON: " << buf; -EXPECT_NE(nullptr, strstr(buf, R"("object1":{"key3":"value3","key4":"value4"})")) << "JSON: " << buf; -EXPECT_NE(nullptr, strstr(buf, R"("object2":{"key5":"value5"})")) << "JSON: " << buf; -EXPECT_NE(nullptr, strstr(buf, R"("object3":{"object4":{"key6":"value6"}})")) << "JSON: " << buf; +EXPECT_NE(nullptr, strstr(output, R"("key1":"value1")")) << "JSON: " << output; +EXPECT_NE(nullptr, strstr(output, R"("key2":"value2")")) << "JSON: " << output; +EXPECT_NE(nullptr, strstr(output, R"("object1":{"key3":"value3","key4":"value4"})")) << "JSON: " << output; +EXPECT_NE(nullptr, strstr(output, R"("object2":{"key5":"value5"})")) << "JSON: " << output; +EXPECT_NE(nullptr, strstr(output, R"("object3":{"object4":{"key6":"value6"}})")) << "JSON: " << output; //And the buf is a valid JSON object json_error_t error; -json_t* root = json_loads(buf, 0, ); +json_auto_t* root = json_loads(output, 0, ); EXPECT_NE(nullptr, root) << "Unexpected JSON error: " << error.text; -json_decref(root); } TEST_F(PropertiesSerializationTestSuite, SaveJPathKeysWithCollisionTest) { @@ -374,7 +370,8 @@ TEST_F(PropertiesSerializationTestSuite, SavePropertiesWithAndWithoutStrictFlagT ASSERT_EQ(CELIX_SUCCESS, status); //When saving the properties to a string with the strict flag -status = celix_properties_saveToString(props, CELIX_PROPERTIES_ENCODE_STRICT, ); +char* output2; +status = celix_properties_saveToString(props, CELIX_PROPERTIES_ENCODE_STRICT, ); //Then the save fails, because the empty array generates an error ASSERT_EQ(CELIX_ILLEGAL_ARGUMENT, status);
(celix) branch feature/685-properties-json-serialization updated: gh-685: Fix incorrect celix_autoptr usage
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 ae4464ca gh-685: Fix incorrect celix_autoptr usage ae4464ca is described below commit ae4464ca46775eb69978d8bfc0de20564b5c553a Author: Pepijn Noltes AuthorDate: Mon Apr 15 19:17:17 2024 +0200 gh-685: Fix incorrect celix_autoptr usage --- libs/utils/gtest/src/PropertiesEncodingTestSuite.cc | 6 +++--- libs/utils/src/properties_encoding.c| 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc b/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc index 0771aa3c..1b0035c0 100644 --- a/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc +++ b/libs/utils/gtest/src/PropertiesEncodingTestSuite.cc @@ -659,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; +celix_properties_t* props2; status = celix_properties_loadFromString2(jsonInput, CELIX_PROPERTIES_DECODE_ERROR_ON_DUPLICATES, ); // Then loading fails, because of a duplicate key @@ -711,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; +celix_properties_t* props2; status = celix_properties_loadFromString2(jsonInput, CELIX_PROPERTIES_DECODE_ERROR_ON_DUPLICATES, ); // Then loading fails, because of a duplicate key @@ -722,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; +celix_properties_t* props3; status = celix_properties_loadFromString2(jsonInput, CELIX_PROPERTIES_DECODE_ERROR_ON_COLLISIONS, ); // Then loading fails, because of a collision diff --git a/libs/utils/src/properties_encoding.c b/libs/utils/src/properties_encoding.c index eba39207..74103f48 100644 --- a/libs/utils/src/properties_encoding.c +++ b/libs/utils/src/properties_encoding.c @@ -519,6 +519,7 @@ celix_properties_decodeValue(celix_properties_t* props, const char* key, json_t* } static celix_status_t celix_properties_decodeFromJson(json_t* obj, int flags, celix_properties_t** out) { +*out = NULL; if (!json_is_object(obj)) { celix_err_push("Expected json object."); return CELIX_ILLEGAL_ARGUMENT;