(celix) branch feature/685-properties-json-serialization updated: gh-685: Some whitespace corrections

2024-04-15 Thread pnoltes
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

2024-04-15 Thread pnoltes
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)

2024-04-15 Thread pnoltes
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

2024-04-15 Thread pnoltes
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

2024-04-15 Thread pnoltes
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;