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 2023/11/28 21:45:17 UTC
(celix) 04/09: Refactor filter match to use property typed values
This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a commit to branch feature/674-use-properties-type-in-filter
in repository https://gitbox.apache.org/repos/asf/celix.git
commit 535dc4e89de78e3248a21c9e5e90576d82a26afb
Author: Pepijn Noltes <pn...@apache.org>
AuthorDate: Sun Nov 19 23:28:53 2023 +0100
Refactor filter match to use property typed values
---
libs/framework/src/bundle_context.c | 46 ++++---
libs/framework/src/dm_component_impl.c | 27 ++--
libs/framework/src/service_registration.c | 98 +++++++++------
libs/framework/src/service_registration_private.h | 16 +--
libs/utils/gtest/src/FilterTestSuite.cc | 27 ++++
libs/utils/src/filter.c | 145 ++++++++++++++--------
6 files changed, 231 insertions(+), 128 deletions(-)
diff --git a/libs/framework/src/bundle_context.c b/libs/framework/src/bundle_context.c
index d8b2c95c..f45d8222 100644
--- a/libs/framework/src/bundle_context.c
+++ b/libs/framework/src/bundle_context.c
@@ -43,7 +43,7 @@
#include "celix_array_list.h"
#include "celix_convert_utils.h"
-static celix_status_t bundleContext_bundleChanged(void *handle, bundle_event_t *event);
+static celix_status_t bundleContext_bundleChanged(void* listenerSvc, bundle_event_t* event);
static void bundleContext_cleanupBundleTrackers(bundle_context_t *ct);
static void bundleContext_cleanupServiceTrackers(bundle_context_t *ctx);
static void bundleContext_cleanupServiceTrackerTrackers(bundle_context_t *ctx);
@@ -147,7 +147,10 @@ celix_status_t bundleContext_installBundle(bundle_context_pt context, const char
return bundleContext_installBundle2(context, location, NULL, bundle);
}
-celix_status_t bundleContext_installBundle2(bundle_context_pt context, const char *location, const char *inputFile, bundle_pt *bundle) {
+celix_status_t bundleContext_installBundle2(bundle_context_pt context,
+ const char* location,
+ const char* inputFile __attribute__((unused)),
+ bundle_pt* bundle) {
celix_status_t status = CELIX_SUCCESS;
long id = -1L;
if (context == NULL || location == NULL || bundle == NULL) {
@@ -389,15 +392,23 @@ static long celix_bundleContext_registerServiceWithOptionsInternal(bundle_contex
}
//set properties
- celix_properties_t *props = opts->properties;
+ celix_autoptr(celix_properties_t) props = opts->properties;
if (props == NULL) {
props = celix_properties_create();
}
+
if (opts->serviceVersion != NULL && strncmp("", opts->serviceVersion, 1) != 0) {
- celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_VERSION, opts->serviceVersion);
+ celix_version_t* version = celix_version_createVersionFromString(opts->serviceVersion);
+ if (!version) {
+ celix_framework_logTssErrors(ctx->framework->logger, CELIX_LOG_LEVEL_ERROR);
+ fw_log(
+ ctx->framework->logger, CELIX_LOG_LEVEL_ERROR, "Cannot parse service version %s", opts->serviceVersion);
+ return -1;
+ }
+ celix_properties_setVersionWithoutCopy(props, CELIX_FRAMEWORK_SERVICE_VERSION, version);
}
- long svcId = -1;
+ long svcId;
if (!async && celix_framework_isCurrentThreadTheEventLoop(ctx->framework)) {
/*
* Note already on event loop, cannot register the service async, because we cannot wait a future event (the
@@ -407,20 +418,17 @@ static long celix_bundleContext_registerServiceWithOptionsInternal(bundle_contex
* registrations versions on the event loop thread
*/
- svcId = celix_framework_registerService(ctx->framework, ctx->bundle, opts->serviceName, opts->svc, opts->factory, props);
+ svcId = celix_framework_registerService(ctx->framework, ctx->bundle, opts->serviceName, opts->svc, opts->factory, celix_steal_ptr(props));
} else {
void (*asyncCallback)(void *data, long serviceId) = async ? opts->asyncCallback : NULL; //NOTE for not async call do not use the callback.
- svcId = celix_framework_registerServiceAsync(ctx->framework, ctx->bundle, opts->serviceName, opts->svc, opts->factory, props, opts->asyncData, asyncCallback, NULL, NULL);
+ svcId = celix_framework_registerServiceAsync(ctx->framework, ctx->bundle, opts->serviceName, opts->svc, opts->factory, celix_steal_ptr(props), opts->asyncData, asyncCallback, NULL, NULL);
if (!async && svcId >= 0) {
//note on event loop thread, but in a sync call, so waiting till service registration is concluded
celix_bundleContext_waitForAsyncRegistration(ctx, svcId);
}
}
-
- if (svcId < 0) {
- properties_destroy(props);
- } else {
+ if (svcId >= 0) {
celixThreadMutex_lock(&ctx->mutex);
celix_arrayList_addLong(ctx->svcRegistrations, svcId);
celixThreadMutex_unlock(&ctx->mutex);
@@ -519,19 +527,18 @@ celix_dependency_manager_t* celix_bundleContext_getDependencyManager(bundle_cont
return result;
}
-static celix_status_t bundleContext_bundleChanged(void *listenerSvc, bundle_event_t *event) {
- celix_status_t status = CELIX_SUCCESS;
- bundle_listener_t *listener = listenerSvc;
- celix_bundle_context_bundle_tracker_entry_t *tracker = listener->handle;
+static celix_status_t bundleContext_bundleChanged(void* listenerSvc, bundle_event_t* event) {
+ bundle_listener_t* listener = listenerSvc;
+ celix_bundle_context_bundle_tracker_entry_t* tracker = listener->handle;
bool handleEvent = true;
long bndId = celix_bundle_getId(event->bnd);
- if (bndId == 0 /*framework bundle*/) {
+ if (bndId == 0 /*framework bundle*/) {
handleEvent = tracker->opts.includeFrameworkBundle;
}
if (handleEvent) {
- void *callbackHandle = tracker->opts.callbackHandle;
+ void* callbackHandle = tracker->opts.callbackHandle;
if (event->type == OSGI_FRAMEWORK_BUNDLE_EVENT_INSTALLED && tracker->opts.onInstalled != NULL) {
tracker->opts.onInstalled(callbackHandle, event->bnd);
@@ -545,7 +552,7 @@ static celix_status_t bundleContext_bundleChanged(void *listenerSvc, bundle_even
tracker->opts.onBundleEvent(callbackHandle, event);
}
}
- return status;
+ return CELIX_SUCCESS;
}
void celix_bundleContext_trackBundlesWithOptionsCallback(void *data) {
@@ -571,7 +578,6 @@ static long celix_bundleContext_trackBundlesWithOptionsInternal(
bundle_context_t* ctx,
const celix_bundle_tracking_options_t *opts,
bool async) {
- long trackerId = -1;
celix_bundle_context_bundle_tracker_entry_t *entry = calloc(1, sizeof(*entry));
memcpy(&entry->opts, opts, sizeof(*opts));
entry->ctx = ctx;
@@ -582,7 +588,7 @@ static long celix_bundleContext_trackBundlesWithOptionsInternal(
celixThreadMutex_lock(&ctx->mutex);
entry->trackerId = ctx->nextTrackerId++;
hashMap_put(ctx->bundleTrackers, (void*)(entry->trackerId), entry);
- trackerId = entry->trackerId;
+ long trackerId = entry->trackerId;
celixThreadMutex_unlock(&ctx->mutex);
if (!async) { //note only using the async callback if this is a async call.
diff --git a/libs/framework/src/dm_component_impl.c b/libs/framework/src/dm_component_impl.c
index 8ba8def3..1286a1ef 100644
--- a/libs/framework/src/dm_component_impl.c
+++ b/libs/framework/src/dm_component_impl.c
@@ -445,29 +445,42 @@ celix_status_t component_addInterface(celix_dm_component_t *component, const cha
return celix_dmComponent_addInterface(component, serviceName, serviceVersion, service, properties);
}
-celix_status_t celix_dmComponent_addInterface(celix_dm_component_t *component, const char* serviceName, const char* serviceVersion, const void* service, celix_properties_t* properties) {
+celix_status_t celix_dmComponent_addInterface(celix_dm_component_t* component,
+ const char* serviceName,
+ const char* serviceVersion,
+ const void* service,
+ celix_properties_t* properties) {
if (serviceName == NULL || celix_utils_stringEquals(serviceName, "")) {
- celix_bundleContext_log(component->context, CELIX_LOG_LEVEL_ERROR, "Cannot add interface with a NULL or empty serviceName");
+ celix_bundleContext_log(
+ component->context, CELIX_LOG_LEVEL_ERROR, "Cannot add interface with a NULL or empty serviceName");
return CELIX_ILLEGAL_ARGUMENT;
}
- dm_interface_t *interface = calloc(1, sizeof(*interface));
- char *name = celix_utils_strdup(serviceName);
+ dm_interface_t* interface = calloc(1, sizeof(*interface));
+ char* name = celix_utils_strdup(serviceName);
if (properties == NULL) {
properties = celix_properties_create();
}
- if ((properties_get(properties, CELIX_FRAMEWORK_SERVICE_VERSION) == NULL) && (serviceVersion != NULL)) {
- celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, serviceVersion);
+ if (serviceVersion != NULL) {
+ celix_version_t* version = celix_version_createVersionFromString(serviceVersion);
+ if (!version) {
+ celix_bundleContext_log(
+ component->context, CELIX_LOG_LEVEL_ERROR, "Cannot add interface with an invalid serviceVersion");
+ celix_properties_destroy(properties);
+ return CELIX_ILLEGAL_ARGUMENT;
+ }
+ celix_properties_setVersionWithoutCopy(properties, CELIX_FRAMEWORK_SERVICE_VERSION, version);
}
+
celix_properties_set(properties, CELIX_DM_COMPONENT_UUID, (char*)component->uuid);
celixThreadMutex_lock(&component->mutex);
interface->serviceName = name;
interface->service = service;
interface->properties = properties;
- interface->svcId= -1L;
+ interface->svcId = -1L;
celix_arrayList_add(component->providedInterfaces, interface);
if (celix_dmComponent_currentState(component) == CELIX_DM_CMP_STATE_TRACKING_OPTIONAL) {
celix_dmComponent_registerServices(component, false);
diff --git a/libs/framework/src/service_registration.c b/libs/framework/src/service_registration.c
index 5564d331..45b89c6e 100644
--- a/libs/framework/src/service_registration.c
+++ b/libs/framework/src/service_registration.c
@@ -21,52 +21,66 @@
#include <stdio.h>
#include <string.h>
-#include "service_registration_private.h"
-#include "celix_constants.h"
#include "celix_build_assert.h"
+#include "celix_constants.h"
+#include "celix_err.h"
+#include "service_registration_private.h"
static bool serviceRegistration_destroy(struct celix_ref *);
-static celix_status_t serviceRegistration_initializeProperties(service_registration_pt registration, properties_pt properties);
-static celix_status_t serviceRegistration_createInternal(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId,
- const void * serviceObject, properties_pt dictionary, enum celix_service_type svcType, service_registration_pt *registration);
-
-service_registration_pt serviceRegistration_create(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId, const void * serviceObject, properties_pt dictionary) {
+static celix_status_t serviceRegistration_initializeProperties(service_registration_t*registration,
+ celix_properties_t* props);
+
+static celix_status_t serviceRegistration_createInternal(registry_callback_t callback,
+ celix_bundle_t* bundle,
+ const char* serviceName,
+ long serviceId,
+ const void* serviceObject,
+ celix_properties_t* dictionary,
+ enum celix_service_type svcType,
+ service_registration_t** out);
+
+service_registration_pt serviceRegistration_create(registry_callback_t callback, bundle_pt bundle, const char* serviceName, long serviceId, const void * serviceObject, properties_pt dictionary) {
service_registration_pt registration = NULL;
serviceRegistration_createInternal(callback, bundle, serviceName, serviceId, serviceObject, dictionary, CELIX_PLAIN_SERVICE, ®istration);
return registration;
}
-service_registration_pt serviceRegistration_createServiceFactory(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId, const void * serviceObject, properties_pt dictionary) {
+service_registration_pt serviceRegistration_createServiceFactory(registry_callback_t callback, bundle_pt bundle, const char* serviceName, long serviceId, const void * serviceObject, properties_pt dictionary) {
service_registration_pt registration = NULL;
serviceRegistration_createInternal(callback, bundle, serviceName, serviceId, serviceObject, dictionary, CELIX_DEPRECATED_FACTORY_SERVICE, ®istration);
return registration;
}
-static celix_status_t serviceRegistration_createInternal(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId,
- const void * serviceObject, properties_pt dictionary, enum celix_service_type svcType, service_registration_pt *out) {
-
+static celix_status_t serviceRegistration_createInternal(registry_callback_t callback,
+ celix_bundle_t* bundle,
+ const char* serviceName,
+ long serviceId,
+ const void* serviceObject,
+ celix_properties_t* dictionary,
+ enum celix_service_type svcType,
+ service_registration_t** out) {
celix_status_t status = CELIX_SUCCESS;
- service_registration_pt reg = calloc(1, sizeof(*reg));
+ service_registration_pt reg = calloc(1, sizeof(*reg));
if (reg) {
celix_ref_init(®->refCount);
reg->callback = callback;
- reg->svcType = svcType;
- reg->className = strndup(serviceName, 1024*10);
+ reg->svcType = svcType;
+ reg->className = strndup(serviceName, 1024 * 10);
reg->bundle = bundle;
- reg->serviceId = serviceId;
- reg->svcObj = serviceObject;
- reg->isUnregistering = false;
- celixThreadRwlock_create(®->lock, NULL);
- serviceRegistration_initializeProperties(reg, dictionary);
- } else {
- status = CELIX_ENOMEM;
- }
+ reg->serviceId = serviceId;
+ reg->svcObj = serviceObject;
+ reg->isUnregistering = false;
+ celixThreadRwlock_create(®->lock, NULL);
+ serviceRegistration_initializeProperties(reg, dictionary);
+ } else {
+ status = CELIX_ENOMEM;
+ }
- if (status == CELIX_SUCCESS) {
- *out = reg;
- }
+ if (status == CELIX_SUCCESS) {
+ *out = reg;
+ }
- return status;
+ return status;
}
void serviceRegistration_retain(service_registration_pt registration) {
@@ -91,24 +105,26 @@ static bool serviceRegistration_destroy(struct celix_ref *refCount) {
return true;
}
-static celix_status_t serviceRegistration_initializeProperties(service_registration_pt registration, properties_pt dictionary) {
- char sId[32];
-
- if (dictionary == NULL) {
- dictionary = properties_create();
- }
-
-
- snprintf(sId, 32, "%lu", registration->serviceId);
- properties_set(dictionary, (char *) CELIX_FRAMEWORK_SERVICE_ID, sId);
+static celix_status_t serviceRegistration_initializeProperties(service_registration_t*registration,
+ celix_properties_t* props) {
+ if (!props) {
+ props = celix_properties_create();
+ }
+ if (!props) {
+ return CELIX_ENOMEM;
+ }
- if (properties_get(dictionary, (char *) CELIX_FRAMEWORK_SERVICE_NAME) == NULL) {
- properties_set(dictionary, (char *) CELIX_FRAMEWORK_SERVICE_NAME, registration->className);
- }
+ celix_status_t status = celix_properties_setLong(props, CELIX_FRAMEWORK_SERVICE_ID, registration->serviceId);
+ CELIX_DO_IF(status, status = celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, registration->className));
- registration->properties = dictionary;
+ if (status == CELIX_SUCCESS) {
+ registration->properties = props;
+ } else {
+ celix_err_push("Cannot initialize service registration properties");
+ properties_destroy(props);
+ }
- return CELIX_SUCCESS;
+ return CELIX_SUCCESS;
}
void serviceRegistration_invalidate(service_registration_pt registration) {
diff --git a/libs/framework/src/service_registration_private.h b/libs/framework/src/service_registration_private.h
index bda962e6..0e896df2 100644
--- a/libs/framework/src/service_registration_private.h
+++ b/libs/framework/src/service_registration_private.h
@@ -35,25 +35,25 @@ struct serviceRegistration {
struct celix_ref refCount;
registry_callback_t callback; // read-only
- char * className; // read-only
- bundle_pt bundle; // read-only
- properties_pt properties; // read-only
- unsigned long serviceId; // read-only
+ char* className; // read-only
+ bundle_pt bundle; // read-only
+ properties_pt properties; // read-only
+ long serviceId; // read-only
bool isUnregistering;
enum celix_service_type svcType; // read-only
union {
- const void * svcObj;
+ const void* svcObj;
service_factory_pt deprecatedFactory;
- celix_service_factory_t *factory;
+ celix_service_factory_t* factory;
};
celix_thread_rwlock_t lock; // protects the service object
};
-service_registration_pt serviceRegistration_create(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId, const void * serviceObject, properties_pt dictionary);
-service_registration_pt serviceRegistration_createServiceFactory(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId, const void * serviceObject, properties_pt dictionary);
+service_registration_pt serviceRegistration_create(registry_callback_t callback, bundle_pt bundle, const char* serviceName, long serviceId, const void * serviceObject, properties_pt dictionary);
+service_registration_pt serviceRegistration_createServiceFactory(registry_callback_t callback, bundle_pt bundle, const char* serviceName, long serviceId, const void * serviceObject, properties_pt dictionary);
void serviceRegistration_retain(service_registration_pt registration);
void serviceRegistration_release(service_registration_pt registration);
diff --git a/libs/utils/gtest/src/FilterTestSuite.cc b/libs/utils/gtest/src/FilterTestSuite.cc
index 2dd171e2..0a493f73 100644
--- a/libs/utils/gtest/src/FilterTestSuite.cc
+++ b/libs/utils/gtest/src/FilterTestSuite.cc
@@ -435,6 +435,33 @@ TEST_F(FilterTestSuite, MissingOperandCreateTest) {
ASSERT_TRUE(filter == nullptr);
}
+TEST_F(FilterTestSuite, TypedPropertiesAndFilterTest) {
+ celix_autoptr(celix_properties_t) props = celix_properties_create();
+ celix_autoptr(celix_version_t) version = celix_version_createVersionFromString("1.2.3");
+ celix_properties_set(props, "str", "test");
+ celix_properties_setLong(props, "long", 1L);
+ celix_properties_setDouble(props, "double", 0.0);
+ celix_properties_setBool(props, "bool", true);
+ celix_properties_setVersion(props, "version", version);
+
+ celix_autoptr(celix_filter_t) filter1 =
+ celix_filter_create("(&(str=test)(long=1)(double=0.0)(bool=true)(version=1.2.3))");
+ EXPECT_TRUE(celix_filter_match(filter1, props));
+
+ celix_autoptr(celix_filter_t) filter2 =
+ celix_filter_create("(&(str>tes)(long>0)(double>-1.0)(bool>false)(version>1.0.0))");
+ EXPECT_TRUE(celix_filter_match(filter2, props));
+
+ celix_autoptr(celix_filter_t) filter3 =
+ celix_filter_create("(&(str<tesu)(long<2)(double<1.0)(bool<=true)(version<2.0.0))");
+ EXPECT_TRUE(celix_filter_match(filter3, props));
+
+ celix_autoptr(celix_filter_t) filter4 =
+ celix_filter_create("(&(str!=test)(long!=1)(double!=0.0)(bool!=true)(version!=1.2.3))");
+ EXPECT_FALSE(celix_filter_match(filter4, props));
+}
+
+
TEST_F(FilterTestSuite, SubStringTest) {
celix_autoptr(celix_properties_t) props = celix_properties_create();
celix_properties_set(props, "test", "John Bob Doe");
diff --git a/libs/utils/src/filter.c b/libs/utils/src/filter.c
index f8eced27..e1a20652 100644
--- a/libs/utils/src/filter.c
+++ b/libs/utils/src/filter.c
@@ -32,11 +32,19 @@
#include "celix_version.h"
#include "filter.h"
+//ignoring clang-tidy recursion warnings for this file, because filter uses recursion
+//NOLINTBEGIN(misc-no-recursion)
+
struct celix_filter_internal {
bool convertedToLong;
long longValue;
+
bool convertedToDouble;
double doubleValue;
+
+ bool convertedToBool;
+ bool boolValue;
+
bool convertedToVersion;
celix_version_t *versionValue;
};
@@ -51,8 +59,8 @@ static char * filter_parseAttr(char* filterString, int* pos);
static char * filter_parseValue(char* filterString, int* pos);
static celix_array_list_t* filter_parseSubstring(char* filterString, int* pos);
-static void filter_skipWhiteSpace(char * filterString, int * pos) {
- int length;
+static void filter_skipWhiteSpace(char* filterString, int* pos) {
+ size_t length;
for (length = strlen(filterString); (*pos < length) && isspace(filterString[*pos]);) {
(*pos)++;
}
@@ -111,8 +119,10 @@ static celix_filter_t * filter_parseFilterComp(char * filterString, int * pos) {
(*pos)++;
return filter_parseNot(filterString, pos);
}
+ default: {
+ return filter_parseItem(filterString, pos);
+ }
}
- return filter_parseItem(filterString, pos);
}
static celix_filter_t * filter_parseAndOrOr(char * filterString, celix_filter_operand_t andOrOr, int * pos) {
@@ -210,7 +220,6 @@ static celix_filter_t * filter_parseItem(char * filterString, int * pos) {
filter->value = filter_parseValue(filterString, pos);
return filter;
}
- break;
}
case '<': {
if (filterString[*pos + 1] == '=') {
@@ -229,7 +238,6 @@ static celix_filter_t * filter_parseItem(char * filterString, int * pos) {
filter->value = filter_parseValue(filterString, pos);
return filter;
}
- break;
}
case '=': {
celix_filter_t * filter = NULL;
@@ -280,7 +288,7 @@ static char * filter_parseAttr(char * filterString, int * pos) {
char c;
int begin = *pos;
int end = *pos;
- int length = 0;
+ int length;
filter_skipWhiteSpace(filterString, pos);
c = filterString[*pos];
@@ -443,6 +451,7 @@ static celix_status_t celix_filter_compile(celix_filter_t* filter) {
filter->internal->longValue = celix_utils_convertStringToLong(filter->value, 0, &filter->internal->convertedToLong);
filter->internal->doubleValue = celix_utils_convertStringToDouble(filter->value, 0.0, &filter->internal->convertedToDouble);
filter->internal->versionValue = celix_utils_convertStringToVersion(filter->value, NULL, &filter->internal->convertedToVersion);
+ filter->internal->boolValue = celix_utils_convertStringToBool(filter->value, false, &filter->internal->convertedToBool);
}
}
@@ -459,7 +468,7 @@ static celix_status_t celix_filter_compile(celix_filter_t* filter) {
return CELIX_SUCCESS;
}
-celix_status_t filter_match(celix_filter_t * filter, celix_properties_t *properties, bool *out) {
+celix_status_t filter_match(celix_filter_t* filter, celix_properties_t* properties, bool* out) {
bool result = celix_filter_match(filter, properties);
if (out != NULL) {
*out = result;
@@ -467,64 +476,95 @@ celix_status_t filter_match(celix_filter_t * filter, celix_properties_t *propert
return CELIX_SUCCESS;
}
-static int celix_filter_compareAttributeValue(const celix_filter_t* filter, const celix_properties_entry_t* entry) {
- const char* propertyValue = entry->value;
- if (!filter->internal->convertedToLong && !filter->internal->convertedToDouble && !filter->internal->convertedToVersion) {
- return strcmp(propertyValue, filter->value);
+static int celix_filter_cmpLong(long a, long b) {
+ if (a < b) {
+ return -1;
+ } else if (a > b) {
+ return 1;
+ } else {
+ return 0;
}
+}
- if (filter->internal->convertedToLong) {
- bool propertyValueIsLong = false;
- long value = celix_utils_convertStringToLong(propertyValue, 0, &propertyValueIsLong);
- if (propertyValueIsLong) {
- if (value < filter->internal->longValue)
- return -1;
- else if (value > filter->internal->longValue)
- return 1;
- else
- return 0;
- }
+static int celix_filter_cmpDouble(double a, double b) {
+ if (a < b) {
+ return -1;
+ } else if (a > b) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int celix_filter_cmpBool(bool a, bool b) {
+ if (a == b) {
+ return 0;
+ } else if (a) {
+ return 1;
+ } else {
+ return -1;
}
+}
- if (filter->internal->convertedToDouble) {
- bool propertyValueIsDouble = false;
- double value = celix_utils_convertStringToDouble(propertyValue, 0.0, &propertyValueIsDouble);
- if (propertyValueIsDouble) {
- if (value < filter->internal->doubleValue) {
- return -1;
- } else if (value > filter->internal->doubleValue) {
- return 1;
- } else {
- return 0;
- }
- }
+static int celix_filter_compareAttributeValue(const celix_filter_t* filter, const celix_properties_entry_t* entry) {
+ // not converted, fallback on string compare
+ if (!filter->internal->convertedToLong && !filter->internal->convertedToDouble &&
+ !filter->internal->convertedToBool && !filter->internal->convertedToVersion) {
+ return strcmp(entry->value, filter->value);
}
- if (filter->internal->convertedToVersion) {
- bool propertyValueIsVersion = false;
- celix_version_t *value = celix_utils_convertStringToVersion(propertyValue, NULL, &propertyValueIsVersion);
- if (propertyValueIsVersion) {
- int cmp = celix_version_compareTo(value, filter->internal->versionValue);
- celix_version_destroy(value);
+ //compare typed values
+ if (filter->internal->convertedToLong && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_LONG) {
+ return celix_filter_cmpLong(entry->typed.longValue, filter->internal->longValue);
+ } else if (filter->internal->convertedToDouble && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_DOUBLE) {
+ return celix_filter_cmpDouble(entry->typed.doubleValue, filter->internal->doubleValue);
+ } else if (filter->internal->convertedToBool && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_BOOL) {
+ return celix_filter_cmpBool(entry->typed.boolValue, filter->internal->boolValue);
+ } else if (filter->internal->convertedToVersion && entry->valueType == CELIX_PROPERTIES_VALUE_TYPE_VERSION) {
+ return celix_version_compareTo(entry->typed.versionValue, filter->internal->versionValue);
+ }
+
+ //check if the property string value can be converted to the filter value type
+ bool propertyConverted;
+ if (filter->internal->convertedToLong) {
+ long val = celix_utils_convertStringToLong(entry->value, 0, &propertyConverted);
+ if (propertyConverted) {
+ return celix_filter_cmpLong(val, filter->internal->longValue);
+ }
+ } else if (filter->internal->convertedToDouble) {
+ double val = celix_utils_convertStringToDouble(entry->value, 0.0, &propertyConverted);
+ if (propertyConverted) {
+ return celix_filter_cmpDouble(val, filter->internal->doubleValue);
+ }
+ } else if (filter->internal->convertedToBool) {
+ bool val = celix_utils_convertStringToBool(entry->value, false, &propertyConverted);
+ if (propertyConverted) {
+ return celix_filter_cmpBool(val, filter->internal->boolValue);
+ }
+ } else if (filter->internal->convertedToVersion) {
+ celix_version_t* val = celix_utils_convertStringToVersion(entry->value, NULL, &propertyConverted);
+ if (propertyConverted) {
+ int cmp = celix_version_compareTo(val, filter->internal->versionValue);
+ celix_version_destroy(val);
return cmp;
}
}
//fallback on string compare
- return strcmp(propertyValue, filter->value);
+ return strcmp(entry->value, filter->value);
}
static bool filter_compareSubString(const celix_filter_t* filter, const celix_properties_entry_t* entry) {
const char* propertyValue = entry->value;
- int pos = 0;
+ size_t pos = 0;
int size = celix_arrayList_size(filter->children);
- for (int i = 0; i < size; i++) {
- char * substr = (char *) celix_arrayList_get(filter->children, i);
+ for (size_t i = 0; i < size; i++) {
+ char * substr = (char *) celix_arrayList_get(filter->children, (int)i);
if (i + 1 < size) {
if (substr == NULL) {
unsigned int index;
- char * substr2 = (char *) celix_arrayList_get(filter->children, i + 1);
+ char * substr2 = (char *) celix_arrayList_get(filter->children, (int)(i + 1));
if (substr2 == NULL) {
continue;
}
@@ -551,8 +591,8 @@ static bool filter_compareSubString(const celix_filter_t* filter, const celix_pr
free(region);
}
} else {
- unsigned int len;
- int begin;
+ size_t len;
+ size_t begin;
if (substr == NULL) {
return true;
@@ -590,9 +630,10 @@ static bool celix_filter_matchPropertyEntry(const celix_filter_t* filter, const
case CELIX_FILTER_OPERAND_OR:
case CELIX_FILTER_OPERAND_PRESENT:
default:
- assert(false); //should not reach here
+ //LCOV EXCL START
+ return false; //should not happen
+ //LCOV EXCL STOP
}
- return false;
}
celix_status_t filter_getString(celix_filter_t * filter, const char **filterStr) {
@@ -615,7 +656,6 @@ celix_filter_t* celix_filter_create(const char *filterString) {
celix_autofree char* str = celix_utils_strdup(filterString);
if (!str) {
celix_err_push("Failed to create filter string");
- // TODO test error
return NULL;
}
@@ -735,8 +775,7 @@ bool celix_filter_match(const celix_filter_t* filter, const celix_properties_t*
}
// LCOV_EXCL_START
- assert(false); // should never happen
- return false;
+ return false;// should not happen
// LCOV_EXCL_STOP
}
@@ -888,3 +927,5 @@ static bool hasMandatoryNegatedPresenceAttribute(const celix_filter_t *filter, c
bool celix_filter_hasMandatoryNegatedPresenceAttribute(const celix_filter_t *filter, const char *attribute) {
return hasMandatoryNegatedPresenceAttribute(filter, attribute, false, false);
}
+
+//NOLINTEND(misc-no-recursion)