This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch feature/type_support_for_properties in repository https://gitbox.apache.org/repos/asf/celix.git
commit 4f86a3d3ac585446710fa1662c2b8665381a0063 Author: Pepijn Noltes <[email protected]> AuthorDate: Sun Jan 8 22:12:33 2023 +0100 Improve codecov and replace usage of CELIX_PROPERTIES_FOR_EACH with _ITERATE --- .../subscriber/private/src/pubsub_subscriber.c | 6 +- .../gtest/PubSubInterceptorTestSuite.cc | 5 +- .../pubsub_admin_udp_mc/src/pubsub_udpmc_admin.c | 5 +- .../src/pubsub_websocket_admin.c | 10 +- .../pubsub_discovery/src/pubsub_discovery_impl.c | 6 +- .../src/pubsub_wire_protocol_common.c | 9 +- bundles/pubsub/pubsub_spi/src/pubsub_endpoint.c | 5 +- .../src/endpoint_descriptor_writer.c | 11 +- .../src/remote_service_admin_dfi.c | 15 +-- bundles/shell/shell/src/query_command.c | 12 +-- .../include/celix/dm/DependencyManager_Impl.h | 7 +- libs/framework/src/celix_launcher.c | 30 +++--- libs/framework/src/service_reference.c | 5 +- libs/utils/gtest/src/CxxPropertiesTestSuite.cc | 7 +- libs/utils/gtest/src/CxxVersionTestSuite.cc | 2 + libs/utils/gtest/src/PropertiesTestSuite.cc | 112 +++++++++++++++++---- libs/utils/include/celix/Version.h | 3 +- libs/utils/include/celix_properties.h | 10 -- libs/utils/src/properties.c | 36 ++++--- 19 files changed, 165 insertions(+), 131 deletions(-) diff --git a/bundles/pubsub/examples/pubsub/subscriber/private/src/pubsub_subscriber.c b/bundles/pubsub/examples/pubsub/subscriber/private/src/pubsub_subscriber.c index 272ff746..c05df1ee 100644 --- a/bundles/pubsub/examples/pubsub/subscriber/private/src/pubsub_subscriber.c +++ b/bundles/pubsub/examples/pubsub/subscriber/private/src/pubsub_subscriber.c @@ -62,10 +62,8 @@ int pubsub_subscriber_recv(void* handle, const char* msgType, unsigned int msgTy if (metadata == NULL || celix_properties_size(metadata) == 0) { printf("No metadata\n"); } else { - const char *key; - CELIX_PROPERTIES_FOR_EACH(metadata, key) { - const char *val = celix_properties_get(metadata, key, "!Error!"); - printf("%s=%s\n", key, val); + CELIX_PROPERTIES_ITERATE(metadata, iter) { + printf("%s=%s\n", iter.key, iter.entry.value); } } diff --git a/bundles/pubsub/integration/gtest/PubSubInterceptorTestSuite.cc b/bundles/pubsub/integration/gtest/PubSubInterceptorTestSuite.cc index e8218ccf..0c4c7c0b 100644 --- a/bundles/pubsub/integration/gtest/PubSubInterceptorTestSuite.cc +++ b/bundles/pubsub/integration/gtest/PubSubInterceptorTestSuite.cc @@ -110,9 +110,8 @@ public: const auto *msg = static_cast<const msg_t*>(rawMsg); EXPECT_GE(msg->seqNr, 0); EXPECT_STREQ(celix_properties_get(metadata, "test", nullptr), "preSend"); - const char *key; - CELIX_PROPERTIES_FOR_EACH(metadata, key) { - printf("got property %s=%s\n", key, celix_properties_get(metadata, key, nullptr)); + CELIX_PROPERTIES_ITERATE(metadata, iter) { + printf("got property %s=%s\n", iter.key, iter.entry.value); } fprintf(stdout, "Got message in postSend interceptor %s/%s for type %s and ser %s with seq nr %i\n", intProps->scope, intProps->topic, intProps->psaType, intProps->serializationType, msg->seqNr); diff --git a/bundles/pubsub/pubsub_admin_udp_mc/src/pubsub_udpmc_admin.c b/bundles/pubsub/pubsub_admin_udp_mc/src/pubsub_udpmc_admin.c index 9257ac87..91ec6b1b 100644 --- a/bundles/pubsub/pubsub_admin_udp_mc/src/pubsub_udpmc_admin.c +++ b/bundles/pubsub/pubsub_admin_udp_mc/src/pubsub_udpmc_admin.c @@ -455,9 +455,8 @@ static celix_status_t pubsub_udpmcAdmin_connectEndpointToReceiver(pubsub_udpmc_a if (sockAddress == NULL || sockPort < 0) { L_WARN("[PSA UPDMC] Error got endpoint without udpmc socket address/port or endpoint type. Properties:"); - const char *key = NULL; - CELIX_PROPERTIES_FOR_EACH(endpoint, key) { - L_WARN("[PSA UPDMC] |- %s=%s\n", key, celix_properties_get(endpoint, key, NULL)); + CELIX_PROPERTIES_ITERATE(endpoint, iter) { + L_WARN("[PSA UPDMC] |- %s=%s\n", iter.key, iter.entry.value); } status = CELIX_BUNDLE_EXCEPTION; } else { diff --git a/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.c b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.c index 2a103eec..765e416d 100644 --- a/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.c +++ b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.c @@ -379,9 +379,8 @@ static celix_status_t pubsub_websocketAdmin_connectEndpointToReceiver(pubsub_web if (publisher && (sockAddress == NULL || sockPort < 0)) { L_WARN("[PSA WEBSOCKET] Error got endpoint without websocket address/port or endpoint type. Properties:"); - const char *key = NULL; - CELIX_PROPERTIES_FOR_EACH(endpoint, key) { - L_WARN("[PSA WEBSOCKET] |- %s=%s\n", key, celix_properties_get(endpoint, key, NULL)); + CELIX_PROPERTIES_ITERATE(endpoint, iter) { + L_WARN("[PSA WEBSOCKET] |- %s=%s\n", iter.key, iter.entry.value); } status = CELIX_BUNDLE_EXCEPTION; } else { @@ -436,9 +435,8 @@ static celix_status_t pubsub_websocketAdmin_disconnectEndpointFromReceiver(pubsu if (publisher && (sockAddress == NULL || sockPort < 0)) { L_WARN("[PSA WEBSOCKET] Error got endpoint without websocket address/port or endpoint type. Properties:"); - const char *key = NULL; - CELIX_PROPERTIES_FOR_EACH(endpoint, key) { - L_WARN("[PSA WEBSOCKET] |- %s=%s\n", key, celix_properties_get(endpoint, key, NULL)); + CELIX_PROPERTIES_ITERATE(endpoint, iter) { + L_WARN("[PSA WEBSOCKET] |- %s=%s\n", iter.key, iter.entry.value); } status = CELIX_BUNDLE_EXCEPTION; } else if (eTopic != NULL && strncmp(eTopic, topic, 1024 * 1024) == 0) { diff --git a/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c b/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c index 4815bd92..d7c2501d 100644 --- a/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c +++ b/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c @@ -557,10 +557,8 @@ static char* pubsub_discovery_createJsonEndpoint(const celix_properties_t *props //note props is already check for validity (pubsubEndpoint_isValid) json_t *jsEndpoint = json_object(); - const char* propKey = NULL; - CELIX_PROPERTIES_FOR_EACH(props, propKey) { - const char* val = celix_properties_get(props, propKey, NULL); - json_object_set_new(jsEndpoint, propKey, json_string(val)); + CELIX_PROPERTIES_ITERATE(props, iter) { + json_object_set_new(jsEndpoint, iter.key, json_string(iter.entry.value)); } char* str = json_dumps(jsEndpoint, JSON_COMPACT); json_decref(jsEndpoint); diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/src/pubsub_wire_protocol_common.c b/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/src/pubsub_wire_protocol_common.c index 1d123d7b..390b43e4 100644 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/src/pubsub_wire_protocol_common.c +++ b/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/src/pubsub_wire_protocol_common.c @@ -199,16 +199,13 @@ celix_status_t pubsubProtocol_encodeMetadata(pubsub_protocol_message_t *message, size_t len = 0; if (message->metadata.metadata != NULL && celix_properties_size(message->metadata.metadata) > 0) { - const char *key; char *keyNetString = NULL; int netStringMemoryLength = 0; - CELIX_PROPERTIES_FOR_EACH(message->metadata.metadata, key) { - const char *val = celix_properties_get(message->metadata.metadata, key, "!Error!"); - + CELIX_PROPERTIES_ITERATE(message->metadata.metadata, iter) { //refactoring these two copies to a function leads to a slow down of about 2x int strlenKeyNetString = 0; - status = pubsubProtocol_createNetstring(key, &keyNetString, &strlenKeyNetString, &netStringMemoryLength); + status = pubsubProtocol_createNetstring(iter.key, &keyNetString, &strlenKeyNetString, &netStringMemoryLength); if (status != CELIX_SUCCESS) { break; } @@ -227,7 +224,7 @@ celix_status_t pubsubProtocol_encodeMetadata(pubsub_protocol_message_t *message, memcpy(line + idx, keyNetString, strlenKeyNetString); idx += strlenKeyNetString; - status = pubsubProtocol_createNetstring(val, &keyNetString, &strlenKeyNetString, &netStringMemoryLength); + status = pubsubProtocol_createNetstring(iter.entry.value, &keyNetString, &strlenKeyNetString, &netStringMemoryLength); if (status != CELIX_SUCCESS) { break; } diff --git a/bundles/pubsub/pubsub_spi/src/pubsub_endpoint.c b/bundles/pubsub/pubsub_spi/src/pubsub_endpoint.c index 9d1ffe9e..25f133e1 100644 --- a/bundles/pubsub/pubsub_spi/src/pubsub_endpoint.c +++ b/bundles/pubsub/pubsub_spi/src/pubsub_endpoint.c @@ -46,9 +46,8 @@ static void pubsubEndpoint_setFields(celix_properties_t *ep, const char* fwUUID, //copy topic properties if (topic_props != NULL) { - const char *key = NULL; - CELIX_PROPERTIES_FOR_EACH((celix_properties_t *) topic_props, key) { - celix_properties_set(ep, key, celix_properties_get(topic_props, key, NULL)); + CELIX_PROPERTIES_ITERATE((celix_properties_t *) topic_props, iter) { + celix_properties_set(ep, iter.key, iter.entry.value); } } diff --git a/bundles/remote_services/discovery_common/src/endpoint_descriptor_writer.c b/bundles/remote_services/discovery_common/src/endpoint_descriptor_writer.c index 66580b5a..5c4b585c 100644 --- a/bundles/remote_services/discovery_common/src/endpoint_descriptor_writer.c +++ b/bundles/remote_services/discovery_common/src/endpoint_descriptor_writer.c @@ -139,16 +139,15 @@ static celix_status_t endpointDescriptorWriter_writeEndpoint(endpoint_descriptor } else { xmlTextWriterStartElement(writer->writer, ENDPOINT_DESCRIPTION); - const char* propertyName; - CELIX_PROPERTIES_FOR_EACH(endpoint->properties, propertyName) { - const xmlChar* propertyValue = (const xmlChar*) celix_properties_get(endpoint->properties, propertyName, ""); + CELIX_PROPERTIES_ITERATE(endpoint->properties, iter) { + const xmlChar* propertyValue = (const xmlChar*) celix_properties_get(endpoint->properties, iter.key, ""); xmlTextWriterStartElement(writer->writer, PROPERTY); - xmlTextWriterWriteAttribute(writer->writer, NAME, (const xmlChar*)propertyName); + xmlTextWriterWriteAttribute(writer->writer, NAME, (const xmlChar*)iter.key); - if (strcmp(OSGI_FRAMEWORK_OBJECTCLASS, (char*) propertyName) == 0) { + if (strcmp(OSGI_FRAMEWORK_OBJECTCLASS, (char*) iter.key) == 0) { // objectClass *must* be represented as array of string values... endpointDescriptorWriter_writeArrayValue(writer->writer, propertyValue); - } else if (strcmp(OSGI_RSA_ENDPOINT_SERVICE_ID, (char*) propertyName) == 0) { + } else if (strcmp(OSGI_RSA_ENDPOINT_SERVICE_ID, (char*) iter.key) == 0) { // endpoint.service.id *must* be represented as long value... endpointDescriptorWriter_writeTypedValue(writer->writer, VALUE_TYPE_LONG, propertyValue); } else { diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c index 656b3773..2b5fc335 100644 --- a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c +++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c @@ -747,9 +747,8 @@ static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_servic celix_properties_set(endpointProperties, RSA_DFI_ENDPOINT_URL, url); if (props != NULL) { - const char* key; - CELIX_PROPERTIES_FOR_EACH(props, key) { - celix_properties_set(endpointProperties, key, celix_properties_get(props, key, "")); + CELIX_PROPERTIES_ITERATE(props, iter) { + celix_properties_set(endpointProperties, iter.key, iter.entry.value); } } @@ -947,14 +946,10 @@ static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description } else { struct curl_slist *metadataHeader = NULL; if (metadata != NULL && celix_properties_size(metadata) > 0) { - const char *key = NULL; - CELIX_PROPERTIES_FOR_EACH(metadata, key) { - const char *val = celix_properties_get(metadata, key, ""); - size_t length = strlen(key) + strlen(val) + 18; // "X-RSA-Metadata-key: val\0" - + CELIX_PROPERTIES_ITERATE(metadata, iter) { + size_t length = strlen(iter.key) + strlen(iter.entry.value) + 18; // "X-RSA-Metadata-key: val\0" char header[length]; - - snprintf(header, length, "X-RSA-Metadata-%s: %s", key, val); + snprintf(header, length, "X-RSA-Metadata-%s: %s", iter.key, iter.entry.value); metadataHeader = curl_slist_append(metadataHeader, header); } diff --git a/bundles/shell/shell/src/query_command.c b/bundles/shell/shell/src/query_command.c index 739d3450..93cf69cb 100644 --- a/bundles/shell/shell/src/query_command.c +++ b/bundles/shell/shell/src/query_command.c @@ -95,18 +95,10 @@ static void queryCommand_callback(void *handle, const celix_bundle_t *bnd) { queryCommand_printBundleHeader(data->sout, bnd, &printBundleCalled); fprintf(data->sout, "|- Provided service '%s' [id = %li]\n", entry->serviceName, entry->serviceId); if (data->opts->verbose) { - const char *cmpUUID = celix_properties_get(entry->serviceProperties, "component.uuid", NULL); - if (cmpUUID != NULL) { - //TODO add context to opts - //TODO add celix_dependencyManager_createInfoForUUID() } - //TODO print component name - } fprintf(data->sout, " |- Is factory: %s\n", entry->factory ? "true" : "false"); fprintf(data->sout, " |- Properties:\n"); - const char *key; - CELIX_PROPERTIES_FOR_EACH(entry->serviceProperties, key) { - const char *val = celix_properties_get(entry->serviceProperties, key, "!ERROR!"); - fprintf(data->sout, " |- %20s = %s\n", key, val); + CELIX_PROPERTIES_ITERATE(entry->serviceProperties, iter) { + fprintf(data->sout, " |- %20s = %s\n", iter.key, iter.entry.value); } } } diff --git a/libs/framework/include/celix/dm/DependencyManager_Impl.h b/libs/framework/include/celix/dm/DependencyManager_Impl.h index f3e9f075..05e262d9 100644 --- a/libs/framework/include/celix/dm/DependencyManager_Impl.h +++ b/libs/framework/include/celix/dm/DependencyManager_Impl.h @@ -174,10 +174,8 @@ static celix::dm::DependencyManagerInfo createDepManInfoFromC(celix_dependency_m auto* cIntInfo = static_cast<dm_interface_info_t*>(celix_arrayList_get(cCmpInfo->interfaces, k)); celix::dm::InterfaceInfo intInfo{}; intInfo.serviceName = std::string{cIntInfo->name}; - const char* key; - CELIX_PROPERTIES_FOR_EACH(cIntInfo->properties, key) { - const char* val =celix_properties_get(cIntInfo->properties, key, nullptr); - intInfo.properties[std::string{key}] = std::string{val}; + CELIX_PROPERTIES_ITERATE(cIntInfo->properties, iter) { + intInfo.properties[std::string{iter.key}] = std::string{iter.entry.value}; } cmpInfo.interfacesInfo.emplace_back(std::move(intInfo)); } @@ -206,7 +204,6 @@ inline celix::dm::DependencyManagerInfo DependencyManager::getInfo() const { return result; } - inline std::vector<celix::dm::DependencyManagerInfo> DependencyManager::getInfos() const { std::vector<celix::dm::DependencyManagerInfo> result{}; auto* cInfos = celix_dependencyManager_createInfos(cDependencyManager()); diff --git a/libs/framework/src/celix_launcher.c b/libs/framework/src/celix_launcher.c index 60b0c8ec..394e0a15 100644 --- a/libs/framework/src/celix_launcher.c +++ b/libs/framework/src/celix_launcher.c @@ -188,17 +188,15 @@ void celixLauncher_stop(celix_framework_t* framework) { } static void show_properties(celix_properties_t *embeddedProps, const char *configFile) { - const char *key = NULL; celix_properties_t *keys = celix_properties_create(); //only to store the keys printf("Embedded properties:\n"); if (embeddedProps == NULL || celix_properties_size(embeddedProps) == 0) { printf("|- Empty!\n"); } else { - CELIX_PROPERTIES_FOR_EACH(embeddedProps, key) { - const char *val = celix_properties_get(embeddedProps, key, "!Error!"); - printf("|- %s=%s\n", key, val); - celix_properties_set(keys, key, NULL); + CELIX_PROPERTIES_ITERATE(embeddedProps, iter) { + printf("|- %s=%s\n", iter.key, iter.entry.value); + celix_properties_set(keys, iter.key, NULL); } } printf("\n"); @@ -211,10 +209,9 @@ static void show_properties(celix_properties_t *embeddedProps, const char *confi if (runtimeProps == NULL || celix_properties_size(runtimeProps) == 0) { printf("|- Empty!\n"); } else { - CELIX_PROPERTIES_FOR_EACH(runtimeProps, key) { - const char *val = celix_properties_get(runtimeProps, key, "!Error!"); - printf("|- %s=%s\n", key, val); - celix_properties_set(keys, key, NULL); + CELIX_PROPERTIES_ITERATE(runtimeProps, iter) { + printf("|- %s=%s\n", iter.key, iter.entry.value); + celix_properties_set(keys, iter.key, NULL); } } printf("\n"); @@ -225,13 +222,13 @@ static void show_properties(celix_properties_t *embeddedProps, const char *confi if (celix_properties_size(keys) == 0) { printf("|- Empty!\n"); } else { - CELIX_PROPERTIES_FOR_EACH(keys, key) { - const char *valEm = celix_properties_get(embeddedProps, key, NULL); - const char *valRt = celix_properties_get(runtimeProps, key, NULL); - const char *envVal = getenv(key); + CELIX_PROPERTIES_ITERATE(keys, iter) { + const char *valEm = celix_properties_get(embeddedProps, iter.key, NULL); + const char *valRt = celix_properties_get(runtimeProps, iter.key, NULL); + const char *envVal = getenv(iter.key); const char *val = envVal != NULL ? envVal : valRt != NULL ? valRt : valEm; const char *source = envVal != NULL ? "environment" : valRt != NULL ? "runtime" : "embedded"; - printf("|- %s=%s (source %s)\n", key, val, source); + printf("|- %s=%s (source %s)\n", iter.key, val, source); } } printf("\n"); @@ -258,9 +255,8 @@ static void printEmbeddedBundles() { static void combine_properties(celix_properties_t *original, const celix_properties_t *append) { if (original != NULL && append != NULL) { - const char *key = NULL; - CELIX_PROPERTIES_FOR_EACH(append, key) { - celix_properties_set(original, key, celix_properties_get(append, key, NULL)); + CELIX_PROPERTIES_ITERATE(append, iter) { + celix_properties_set(original, iter.key, iter.entry.value); } } } diff --git a/libs/framework/src/service_reference.c b/libs/framework/src/service_reference.c index a7faebd7..0160ae8e 100644 --- a/libs/framework/src/service_reference.c +++ b/libs/framework/src/service_reference.c @@ -204,9 +204,8 @@ FRAMEWORK_EXPORT celix_status_t serviceReference_getPropertyKeys(service_referen int vsize = celix_properties_size(props); *size = (unsigned int)vsize; *keys = malloc(vsize * sizeof(**keys)); - const char* key; - CELIX_PROPERTIES_FOR_EACH(props, key) { - (*keys)[i++] = (char*)key; + CELIX_PROPERTIES_ITERATE(props, iter) { + (*keys)[i++] = (char*)iter.key; } return status; } diff --git a/libs/utils/gtest/src/CxxPropertiesTestSuite.cc b/libs/utils/gtest/src/CxxPropertiesTestSuite.cc index b2f39192..7d4f3532 100644 --- a/libs/utils/gtest/src/CxxPropertiesTestSuite.cc +++ b/libs/utils/gtest/src/CxxPropertiesTestSuite.cc @@ -176,7 +176,12 @@ TEST_F(CxxPropertiesTestSuite, StoreAndLoadTest) { EXPECT_NO_THROW(loadedProps = celix::Properties::load(path)); EXPECT_EQ(props.size(), loadedProps.size()); - EXPECT_THROW(loadedProps = celix::Properties::load("non-existence"), celix::IOException); + try { + loadedProps = celix::Properties::load("non-existence"); + FAIL() << "Expected exception not thrown"; + } catch (const celix::IOException& e) { + EXPECT_TRUE(strstr(e.what(), "Cannot load celix::Properties")); + } } #if __cplusplus >= 201703L //C++17 or higher diff --git a/libs/utils/gtest/src/CxxVersionTestSuite.cc b/libs/utils/gtest/src/CxxVersionTestSuite.cc index 0055d5c4..ac7266c3 100644 --- a/libs/utils/gtest/src/CxxVersionTestSuite.cc +++ b/libs/utils/gtest/src/CxxVersionTestSuite.cc @@ -18,6 +18,8 @@ */ #include <gtest/gtest.h> +#include <unordered_map> +#include <map> #include "celix/Version.h" diff --git a/libs/utils/gtest/src/PropertiesTestSuite.cc b/libs/utils/gtest/src/PropertiesTestSuite.cc index f21b4049..6904652e 100644 --- a/libs/utils/gtest/src/PropertiesTestSuite.cc +++ b/libs/utils/gtest/src/PropertiesTestSuite.cc @@ -21,6 +21,7 @@ #include "celix_properties.h" #include "celix_utils.h" +#include "properties.h" using ::testing::MatchesRegex; @@ -56,6 +57,16 @@ TEST_F(PropertiesTestSuite, LoadTest) { celix_properties_destroy(properties); } +TEST_F(PropertiesTestSuite, LoadFromStringTest) { + const char* string = "key1=value1\nkey2=value2"; + auto* props = celix_properties_loadFromString(string); + EXPECT_EQ(2, celix_properties_size(props)); + EXPECT_STREQ("value1", celix_properties_get(props, "key1", "")); + EXPECT_STREQ("value2", celix_properties_get(props, "key2", "")); + celix_properties_destroy(props); +} + + TEST_F(PropertiesTestSuite, StoreTest) { const char* propertiesFile = "resources-test/properties_out.txt"; auto* properties = celix_properties_create(); @@ -99,23 +110,6 @@ TEST_F(PropertiesTestSuite, GetAsLongTest) { celix_properties_destroy(props); } -TEST_F(PropertiesTestSuite, CopyTest) { - char propertiesFile[] = "resources-test/properties.txt"; - auto* properties = celix_properties_load(propertiesFile); - EXPECT_EQ(4, celix_properties_size(properties)); - - celix_properties_t *copy = celix_properties_copy(properties); - - char keyA[] = "a"; - const char *valueA = celix_properties_get(copy, keyA, nullptr); - EXPECT_STREQ("b", valueA); - const char keyB[] = "b"; - EXPECT_STREQ("c \t d", celix_properties_get(copy, keyB, nullptr)); - - celix_properties_destroy(properties); - celix_properties_destroy(copy); -} - TEST_F(PropertiesTestSuite, GetSetTest) { auto* properties = celix_properties_create(); char keyA[] = "x"; @@ -169,6 +163,13 @@ TEST_F(PropertiesTestSuite, SetUnsetTest) { celix_properties_unset(properties, keyD); EXPECT_EQ(nullptr, celix_properties_get(properties, keyA, nullptr)); EXPECT_EQ(nullptr, celix_properties_get(properties, "a", nullptr)); + EXPECT_EQ(0, celix_properties_size(properties)); + + celix_properties_set(properties, keyA, nullptr); + EXPECT_EQ(1, celix_properties_size(properties)); + celix_properties_unset(properties, keyA); + EXPECT_EQ(0, celix_properties_size(properties)); + celix_properties_destroy(properties); } @@ -202,6 +203,35 @@ TEST_F(PropertiesTestSuite, GetLongTest) { celix_properties_destroy(properties); } +TEST_F(PropertiesTestSuite, GetAsDoubleTest) { + auto* properties = celix_properties_create(); + + celix_properties_set(properties, "a", "2"); + celix_properties_set(properties, "b", "-10032L"); + celix_properties_set(properties, "c", "1.2"); + celix_properties_setDouble(properties, "d", 1.4); + celix_properties_set(properties, "e", ""); + celix_properties_set(properties, "f", "garbage"); + + double a = celix_properties_getAsDouble(properties, "a", -1); + double b = celix_properties_getAsDouble(properties, "b", -1); + double c = celix_properties_getAsDouble(properties, "c", -1); + double d = celix_properties_getAsDouble(properties, "d", -1); + double e = celix_properties_getAsDouble(properties, "e", -1); + double f = celix_properties_getAsDouble(properties, "f", -1); + double g = celix_properties_getAsDouble(properties, "g", -1); //does not exist + + EXPECT_EQ(2, a); + EXPECT_EQ(-10032L, b); + EXPECT_EQ(1.2, c); + EXPECT_EQ(1.4, d); + EXPECT_EQ(-1L, e); + EXPECT_EQ(-1L, f); + EXPECT_EQ(-1L, g); + + celix_properties_destroy(properties); +} + TEST_F(PropertiesTestSuite, GetBoolTest) { auto* properties = celix_properties_create(); @@ -295,7 +325,7 @@ TEST_F(PropertiesTestSuite, SizeAndIteratorTest) { celix_properties_destroy(props); } -TEST_F(PropertiesTestSuite, GetTypeTest) { +TEST_F(PropertiesTestSuite, GetTypeAndCopyTest) { auto* props = celix_properties_create(); celix_properties_set(props, "string", "value"); celix_properties_setLong(props, "long", 123); @@ -304,6 +334,7 @@ TEST_F(PropertiesTestSuite, GetTypeTest) { auto* version = celix_version_createVersion(1, 2, 3, nullptr); celix_properties_setVersion(props, "version", version); + EXPECT_EQ(5, celix_properties_size(props)); EXPECT_EQ(CELIX_PROPERTIES_VALUE_TYPE_STRING, celix_properties_getType(props, "string")); EXPECT_EQ(CELIX_PROPERTIES_VALUE_TYPE_LONG, celix_properties_getType(props, "long")); EXPECT_EQ(CELIX_PROPERTIES_VALUE_TYPE_DOUBLE, celix_properties_getType(props, "double")); @@ -311,8 +342,17 @@ TEST_F(PropertiesTestSuite, GetTypeTest) { EXPECT_EQ(CELIX_PROPERTIES_VALUE_TYPE_VERSION, celix_properties_getType(props, "version")); EXPECT_EQ(CELIX_PROPERTIES_VALUE_TYPE_UNSET, celix_properties_getType(props, "missing")); + auto* copy = celix_properties_copy(props); + EXPECT_EQ(5, celix_properties_size(copy)); + EXPECT_EQ(CELIX_PROPERTIES_VALUE_TYPE_STRING, celix_properties_getType(copy, "string")); + EXPECT_EQ(CELIX_PROPERTIES_VALUE_TYPE_LONG, celix_properties_getType(copy, "long")); + EXPECT_EQ(CELIX_PROPERTIES_VALUE_TYPE_DOUBLE, celix_properties_getType(copy, "double")); + EXPECT_EQ(CELIX_PROPERTIES_VALUE_TYPE_BOOL, celix_properties_getType(copy, "bool")); + EXPECT_EQ(CELIX_PROPERTIES_VALUE_TYPE_VERSION, celix_properties_getType(copy, "version")); + celix_version_destroy(version); celix_properties_destroy(props); + celix_properties_destroy(copy); } TEST_F(PropertiesTestSuite, GetEntryTest) { @@ -509,4 +549,38 @@ TEST_F(PropertiesTestSuite, EndOfEmptyPropertiesTest) { celix_properties_destroy(props); } -//TODO test replace and replace WithCopy \ No newline at end of file +TEST_F(PropertiesTestSuite, SetWithCopyTest) { + auto* props = celix_properties_create(); + celix_properties_setWithoutCopy(props, celix_utils_strdup("key"), celix_utils_strdup("value2")); + //replace, should free old value and provided key + celix_properties_setWithoutCopy(props, celix_utils_strdup("key"), celix_utils_strdup("value2")); + EXPECT_EQ(1, celix_properties_size(props)); + celix_properties_destroy(props); +} + +TEST_F(PropertiesTestSuite, DeprecatedApiTest) { + //Check if the deprecated api can still be used + auto* props = properties_create(); + properties_set(props, "key", "value"); + EXPECT_EQ(1, celix_properties_size(props)); + EXPECT_STREQ("value", properties_get(props, "key")); + EXPECT_STREQ("notfound", properties_getWithDefault(props, "non-existing", "notfound")); + properties_unset(props, "key"); + EXPECT_EQ(0, celix_properties_size(props)); + celix_properties_t * copy = nullptr; + EXPECT_EQ(CELIX_SUCCESS, properties_copy(props, ©)); + properties_destroy(copy); + + + properties_store(props, "deprecated-api-stored.properties", ""); + auto* loaded = properties_load("deprecated-api-stored.properties"); + EXPECT_NE(nullptr, loaded); + properties_destroy(loaded); + + loaded = properties_loadFromString("key=value"); + EXPECT_EQ(1, celix_properties_size(loaded)); + properties_destroy(loaded); + + + properties_destroy(props); +} diff --git a/libs/utils/include/celix/Version.h b/libs/utils/include/celix/Version.h index 556f4e92..c019d14a 100644 --- a/libs/utils/include/celix/Version.h +++ b/libs/utils/include/celix/Version.h @@ -45,8 +45,6 @@ namespace celix { cVersion{createVersion(celix_version_createEmptyVersion())}, qualifier{celix_version_getQualifier(cVersion.get())} {} -#if __cplusplus >= 201703L //C++17 or higher - /** * @brief Constructs a new version with the given components and qualifier. * @param major The major component of the version. @@ -54,6 +52,7 @@ namespace celix { * @param micro The micro component of the version. * @param qualifier The qualifier string of the version. */ +#if __cplusplus >= 201703L //C++17 or higher Version(int major, int minor, int micro, std::string_view qualifier = {}) : cVersion{createVersion(celix_version_create(major, minor, micro, qualifier.empty() ? "" : qualifier.data()))}, qualifier{celix_version_getQualifier(cVersion.get())} {} diff --git a/libs/utils/include/celix_properties.h b/libs/utils/include/celix_properties.h index 71bc0f53..45bbef17 100644 --- a/libs/utils/include/celix_properties.h +++ b/libs/utils/include/celix_properties.h @@ -405,14 +405,6 @@ void celix_propertiesIterator_next(celix_properties_iterator_t* iter); */ bool celix_propertiesIterator_isEnd(const celix_properties_iterator_t* iter); -/** - * @brief Get the property set being iterated over. - * - * @param[in] iter The iterator to get the property set from. - * @return The property set being iterated over. - */ -celix_properties_t* celix_propertiesIterator_properties(const celix_properties_iterator_t *iter); - /** * @brief Determine whether two iterators are equal. * @@ -517,8 +509,6 @@ const char* celix_propertiesIterator_nextKey(celix_properties_iterator_t* iter) for(celix_properties_iterator_t iter_##key = celix_propertiesIterator_construct(properties); \ celix_propertiesIterator_hasNext(&iter_##key), (key) = celix_propertiesIterator_nextKey(&iter_##key);) - - #ifdef __cplusplus } #endif diff --git a/libs/utils/src/properties.c b/libs/utils/src/properties.c index dbbc2048..cf9df264 100644 --- a/libs/utils/src/properties.c +++ b/libs/utils/src/properties.c @@ -141,7 +141,10 @@ static void updateBuffers(char **key, char ** value, char **output, int outputPo * optimization string buffer. */ static char* celix_properties_createString(celix_properties_t* properties, const char* str) { - size_t len = str == NULL ? 0 : strnlen(str, CELIX_UTILS_MAX_STRLEN) + 1; + if (str == NULL) { + return NULL; + } + size_t len = strnlen(str, CELIX_UTILS_MAX_STRLEN) + 1; size_t left = CELIX_SHORT_PROPERTIES_OPTIMIZATION_STRING_BUFFER_SIZE - properties->currentStringBufferIndex; char* result; if (len < left) { @@ -160,7 +163,7 @@ static char* celix_properties_createString(celix_properties_t* properties, const static celix_status_t celix_properties_fillEntry( celix_properties_t *properties, celix_properties_entry_t* entry, - const char *strValue, + const char** strValue, const long* longValue, const double* doubleValue, const bool* boolValue, @@ -168,7 +171,7 @@ static celix_status_t celix_properties_fillEntry( char convertedValueBuffer[32]; if (strValue != NULL) { entry->valueType = CELIX_PROPERTIES_VALUE_TYPE_STRING; - entry->value = celix_properties_createString(properties, strValue); + entry->value = celix_properties_createString(properties, *strValue); entry->typed.strValue = entry->value; } else if (longValue != NULL) { entry->valueType = CELIX_PROPERTIES_VALUE_TYPE_LONG; @@ -250,7 +253,7 @@ static celix_properties_entry_t* celix_properties_createEntryWithNoCopy(celix_pr static celix_properties_entry_t* celix_properties_createEntry( celix_properties_t *properties, const char *key, - const char *strValue, + const char** strValue, const long* longValue, const double* doubleValue, const bool* boolValue, @@ -276,7 +279,7 @@ static celix_properties_entry_t* celix_properties_createEntry( static void celix_properties_createAndSetEntry( celix_properties_t *properties, const char *key, - const char *strValue, + const char** strValue, const long* longValue, const double* doubleValue, const bool* boolValue, @@ -348,13 +351,13 @@ celix_properties_t* celix_properties_create(void) { void celix_properties_destroy(celix_properties_t *props) { if (props != NULL) { //TODO measure print nr of entries and total size of the string keys and values -// fprintf(stdout, "Properties size; %d", celix_properties_size(props)); -// size_t size = 0; -// CELIX_PROPERTIES_ITERATE(props, iter) { -// size += strlen(iter.entry.key) + 1; -// size += strlen(iter.entry.value) + 1; -// } -// fprintf(stdout, "Properties string size: %zu", size); + fprintf(stdout, "Properties entries size: %d\n", celix_properties_size(props)); + size_t size = 0; + CELIX_PROPERTIES_ITERATE(props, iter) { + size += strlen(iter.key) + 1; + size += strlen(iter.entry.value) + 1; + } + fprintf(stdout, "Properties total string size: %zu\n\n", size); celix_stringHashMap_destroy(props->map); free(props); @@ -628,8 +631,8 @@ celix_properties_entry_t* celix_properties_getEntry(const celix_properties_t* pr } void celix_properties_set(celix_properties_t *properties, const char *key, const char *value) { - if (properties != NULL && key != NULL && value != NULL) { - celix_properties_createAndSetEntry(properties, key, value, NULL, NULL, NULL, NULL); + if (properties != NULL && key != NULL) { + celix_properties_createAndSetEntry(properties, key, &value, NULL, NULL, NULL, NULL); } } @@ -863,8 +866,3 @@ bool celix_propertiesIterator_equals(const celix_properties_iterator_t* a, const return celix_stringHashMapIterator_equals(&internalIterA.mapIter, &internalIterB.mapIter); } -celix_properties_t* celix_propertiesIterator_properties(const celix_properties_iterator_t *iter) { - celix_properties_iterator_internal_t internalIter; - memcpy(&internalIter, iter, sizeof(internalIter)); - return (celix_properties_t*)internalIter.props; -}
