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 2018/05/14 19:17:57 UTC
[06/12] celix git commit: CELIX-446: Adds
celix_bundleContext_findService(s) implementation. Also adds support
setting/getting different primitive types for the celix array list.
CELIX-446: Adds celix_bundleContext_findService(s) implementation. Also adds support setting/getting different primitive types for the celix array list.
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/48aada3a
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/48aada3a
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/48aada3a
Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: 48aada3abace985b22adbe082f9e754028d6362c
Parents: ae09682
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri May 11 14:58:13 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri May 11 14:58:13 2018 +0200
----------------------------------------------------------------------
.../src/dynamic_consumer_example.c | 9 +-
.../src/dynamic_provider_example.c | 7 +-
framework/include/bundle_context.h | 93 +++++++++---
framework/private/mock/bundle_context_mock.c | 30 ++++
framework/src/bundle_context.c | 94 ++++++++----
framework/src/service_tracker.c | 32 ++--
framework/tst/bundle_context_services_test.cpp | 35 ++++-
utils/include/array_list.h | 43 +++++-
utils/src/array_list.c | 152 +++++++++++++------
utils/src/array_list_private.h | 2 +-
10 files changed, 370 insertions(+), 127 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c b/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
index 5a676d6..7a7f177 100644
--- a/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
+++ b/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
@@ -112,8 +112,8 @@ void * run(void *handle) {
activator_data_t *data = handle;
printf("starting consumer thread\n");
- celix_service_tracking_options_t opts;
- opts.serviceName = EXAMPLE_CALC_NAME;
+ celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
+ opts.filter.serviceName = EXAMPLE_CALC_NAME;
opts.callbackHandle = data;
opts.addWithProperties = (void*)addSvc;
opts.removeWithProperties = (void*)removeSvc;
@@ -128,10 +128,9 @@ void * run(void *handle) {
gccExample(data); //gcc trampolines example (nested functions)
- celix_service_use_options_t opts;
- memset(&opts, 0, sizeof(opts));
+ celix_service_use_options_t opts = CELIX_EMPTY_SERVICE_USE_OPTIONS;
- opts.serviceName = EXAMPLE_CALC_NAME;
+ opts.filter.serviceName = EXAMPLE_CALC_NAME;
opts.callbackHandle = data;
opts.useWithProperties = (void*)useHighest;
celix_bundleContext_useServiceWithOptions(data->ctx, &opts);
http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/dynamic_provider_example.c b/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
index f322303..4127c4b 100644
--- a/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
+++ b/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
@@ -67,7 +67,8 @@ void * run(void *handle) {
celix_properties_setLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, rand());
data->svcIds[i++] = celix_bundleContext_registerService(data->ctx, EXAMPLE_CALC_NAME, &data->svc, NULL, props);
} else { //down
- celix_bundleContext_unregisterService(data->ctx, data->svcIds[i--]);
+ celix_bundleContext_unregisterService(data->ctx, data->svcIds[i]);
+ data->svcIds[--i] = -1L;
}
if (i == 99) {
up = false;
@@ -79,9 +80,7 @@ void * run(void *handle) {
for (int i = 0; i < 100; ++i) {
long id = data->svcIds[i];
- if (id >=0 ) {
- celix_bundleContext_unregisterService(data->ctx, id);
- }
+ celix_bundleContext_unregisterService(data->ctx, id);
}
printf("exiting service register thread\n");
http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/framework/include/bundle_context.h
----------------------------------------------------------------------
diff --git a/framework/include/bundle_context.h b/framework/include/bundle_context.h
index 44cca39..5daaff9 100644
--- a/framework/include/bundle_context.h
+++ b/framework/include/bundle_context.h
@@ -272,13 +272,51 @@ long celix_bundleContext_registerServiceFactorForLang(celix_bundle_context_t *ct
void celix_bundleContext_unregisterService(celix_bundle_context_t *ctx, long serviceId);
-//TODO
-//typedef struct celix_service_find_filter_options {
-// servicname, versionrange, filter, lang
-//} celix_service_find_filter_options_t;
-//celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName);
-//celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName);
-//alts WithOptions
+typedef struct celix_service_filter_options {
+ const char* serviceName; //REQUIRED
+ const char* versionRange;
+ const char* filter;
+ const char* lang; //NULL -> 'CELIX_LANG_C'
+} celix_service_filter_options_t;
+
+#define CELIX_EMPTY_SERVICE_FILTER_OPTIONS {.serviceName = NULL, .versionRange = NULL, .filter = NULL, .lang = NULL}
+
+
+/**
+ * Finds the highest ranking service and returns the service id.
+ *
+ * @param ctx The bundle context
+ * @param serviceName The required service name
+ * @return If found a valid service id (>= 0) if not found -1.
+ */
+long celix_bundleContext_findService(celix_bundle_context_t *ctx, const char *serviceName);
+
+/**
+ * Finds the highest ranking service and returns the service id.
+ *
+ * @param ctx The bundle context
+ * @param opts The pointer to the filter options.
+ * @return If found a valid service id (>= 0) if not found -1.
+ */
+long celix_bundleContext_findServiceWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts);
+
+/**
+ * Finds the services with the provided service name and returns a list of the found service ids.
+ *
+ * @param ctx The bundle context
+ * @param serviceName The required service name
+ * @return A array list with as value a long int.
+ */
+celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName);
+
+/**
+ * Finds the services conform the provider filter options and returns a list of the found service ids.
+ *
+ * @param ctx The bundle context
+ * @param opts The pointer to the filter options.
+ * @return A array list with as value a long int.
+ */
+celix_array_list_t* celix_bundleContext_findServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts);
/**
@@ -323,11 +361,7 @@ long celix_bundleContext_trackServices(
);
typedef struct celix_service_tracker_options {
- //service filter options
- const char* serviceName;
- const char* versionRange;
- const char* filter;
- const char* lang; //NULL -> 'CELIX_LANG_C'
+ celix_service_filter_options_t filter;
//callback options
void* callbackHandle;
@@ -335,19 +369,31 @@ typedef struct celix_service_tracker_options {
void (*set)(void *handle, void *svc); //highest ranking
void (*add)(void *handle, void *svc);
void (*remove)(void *handle, void *svc);
- void (*modified)(void *handle, void *svc);
void (*setWithProperties)(void *handle, void *svc, const celix_properties_t *props); //highest ranking
void (*addWithProperties)(void *handle, void *svc, const celix_properties_t *props);
void (*removeWithProperties)(void *handle, void *svc, const celix_properties_t *props);
- void (*modifiedWithProperties)(void *handle, void *svc, const celix_properties_t *props);
void (*setWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner); //highest ranking
void (*addWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
void (*removeWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
- void (*modifiedWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
} celix_service_tracking_options_t;
+#define CELIX_EMPTY_SERVICE_TRACKING_OPTIONS { .filter.serviceName = NULL, \
+ .filter.versionRange = NULL, \
+ .filter.filter = NULL, \
+ .filter.lang = NULL, \
+ .callbackHandle = NULL, \
+ .set = NULL, \
+ .add = NULL, \
+ .remove = NULL, \
+ .setWithProperties = NULL, \
+ .addWithProperties = NULL, \
+ .removeWithProperties = NULL, \
+ .setWithOwner = NULL, \
+ .addWithOwner = NULL, \
+ .removeWithOwner = NULL}
+
/**
* Tracks services using the provided tracker options.
* The tracker options are only using during this call and can safely be freed/reused after this call returns.
@@ -431,13 +477,7 @@ void celix_bundleContext_useServices(
typedef struct celix_service_use_options {
- /**
- * service filter options. Note the serviceName is required.
- */
- const char *serviceName; //REQUIRED
- const char *versionRange; //default will be empty
- const char *filter; //default will be empty
- const char *lang; //default will be LANG_C
+ celix_service_filter_options_t filter;
/**
* Callback info
@@ -449,6 +489,15 @@ typedef struct celix_service_use_options {
void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
} celix_service_use_options_t;
+#define CELIX_EMPTY_SERVICE_USE_OPTIONS {.filter.serviceName = NULL, \
+ .filter.versionRange = NULL, \
+ .filter.filter = NULL, \
+ .filter.lang = NULL, \
+ .callbackHandle = NULL, \
+ .use = NULL, \
+ .useWithProperties = NULL, \
+ .useWithOwner = NULL}
+
/**
* Get and lock the current highest ranking service conform the service filter info from the provided options.
*
http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/framework/private/mock/bundle_context_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/bundle_context_mock.c b/framework/private/mock/bundle_context_mock.c
index 749e3ca..b763b5a 100644
--- a/framework/private/mock/bundle_context_mock.c
+++ b/framework/private/mock/bundle_context_mock.c
@@ -346,4 +346,34 @@ long celix_bundleContext_registerServiceFactorForLang(celix_bundle_context_t *ct
->withStringParameters("lang", lang)
->withPointerParameters("props", props);
return mock_c()->returnValue().value.longIntValue;
+}
+
+long celix_bundleContext_findService(celix_bundle_context_t *ctx, const char *serviceName) {
+ mock_c()->actualCall("celix_bundleContext_findService")
+ ->withPointerParameters("ctx", ctx)
+ ->withStringParameters("serviceName", serviceName);
+ return mock_c()->returnValue().value.longIntValue;
+}
+
+
+long celix_bundleContext_findServiceWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts) {
+ mock_c()->actualCall("celix_bundleContext_findServiceWithOptions")
+ ->withPointerParameters("ctx", ctx)
+ ->withConstPointerParameters("opts", opts);
+ return mock_c()->returnValue().value.longIntValue;
+}
+
+
+celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName) {
+ mock_c()->actualCall("celix_bundleContext_findServices")
+ ->withPointerParameters("ctx", ctx)
+ ->withStringParameters("serviceName", serviceName);
+ return mock_c()->returnValue().value.pointerValue;
+}
+
+celix_array_list_t* celix_bundleContext_findServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts) {
+ mock_c()->actualCall("celix_bundleContext_findServicesWithOptions")
+ ->withPointerParameters("ctx", ctx)
+ ->withConstPointerParameters("opts", opts);
+ return mock_c()->returnValue().value.pointerValue;
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/framework/src/bundle_context.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle_context.c b/framework/src/bundle_context.c
index 7d5dea9..ffb1704 100644
--- a/framework/src/bundle_context.c
+++ b/framework/src/bundle_context.c
@@ -672,14 +672,13 @@ bool celix_bundleContext_useServiceWithId(
const char *serviceName,
void *callbackHandle,
void (*use)(void *handle, void *svc)) {
- celix_service_use_options_t opts;
- memset(&opts, 0, sizeof(opts));
+ celix_service_use_options_t opts = CELIX_EMPTY_SERVICE_USE_OPTIONS;
char filter[64];
snprintf(filter, 64, "(%s=%li)", OSGI_FRAMEWORK_SERVICE_ID, serviceId);
- opts.serviceName = serviceName;
- opts.filter = filter;
+ opts.filter.serviceName = serviceName;
+ opts.filter.filter = filter;
opts.callbackHandle = callbackHandle;
opts.use = use;
return celix_bundleContext_useServiceWithOptions(ctx, &opts);
@@ -690,9 +689,8 @@ bool celix_bundleContext_useService(
const char* serviceName,
void *callbackHandle,
void (*use)(void *handle, void *svc)) {
- celix_service_use_options_t opts;
- memset(&opts, 0, sizeof(opts));
- opts.serviceName = serviceName;
+ celix_service_use_options_t opts = CELIX_EMPTY_SERVICE_USE_OPTIONS;
+ opts.filter.serviceName = serviceName;
opts.callbackHandle = callbackHandle;
opts.use = use;
return celix_bundleContext_useServiceWithOptions(ctx, &opts);
@@ -704,9 +702,8 @@ void celix_bundleContext_useServices(
const char* serviceName,
void *callbackHandle,
void (*use)(void *handle, void *svc)) {
- celix_service_use_options_t opts;
- memset(&opts, 0, sizeof(opts));
- opts.serviceName = serviceName;
+ celix_service_use_options_t opts = CELIX_EMPTY_SERVICE_USE_OPTIONS;
+ opts.filter.serviceName = serviceName;
opts.callbackHandle = callbackHandle;
opts.use = use;
celix_bundleContext_useServicesWithOptions(ctx, &opts);
@@ -721,10 +718,10 @@ bool celix_bundleContext_useServiceWithOptions(
memset(&trkOpts, 0, sizeof(trkOpts));
if (opts != NULL) {
- trkOpts.serviceName = opts->serviceName;
+ trkOpts.filter.serviceName = opts->filter.serviceName;
trkOpts.filter = opts->filter;
- trkOpts.versionRange = opts->versionRange;
- trkOpts.lang = opts->lang;
+ trkOpts.filter.versionRange = opts->filter.versionRange;
+ trkOpts.filter.lang = opts->filter.lang;
service_tracker_t *trk = celix_serviceTracker_createWithOptions(ctx, &trkOpts);
if (trk != NULL) {
@@ -737,7 +734,7 @@ bool celix_bundleContext_useServiceWithOptions(
if (opts->useWithOwner != NULL) {
}
- called = celix_serviceTracker_useHighestRankingService(trk, opts->serviceName, opts->callbackHandle, opts->use, opts->useWithProperties, opts->useWithOwner);
+ called = celix_serviceTracker_useHighestRankingService(trk, opts->filter.serviceName, opts->callbackHandle, opts->use, opts->useWithProperties, opts->useWithOwner);
celix_serviceTracker_destroy(trk);
}
}
@@ -749,18 +746,17 @@ bool celix_bundleContext_useServiceWithOptions(
void celix_bundleContext_useServicesWithOptions(
celix_bundle_context_t *ctx,
const celix_service_use_options_t *opts) {
- celix_service_tracking_options_t trkOpts;
- memset(&trkOpts, 0, sizeof(trkOpts));
+ celix_service_tracking_options_t trkOpts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
if (opts != NULL) {
- trkOpts.serviceName = opts->serviceName;
- trkOpts.filter = opts->filter;
- trkOpts.versionRange = opts->versionRange;
- trkOpts.lang = opts->lang;
+ trkOpts.filter.serviceName = opts->filter.serviceName;
+ trkOpts.filter.filter = opts->filter.filter;
+ trkOpts.filter.versionRange = opts->filter.versionRange;
+ trkOpts.filter.lang = opts->filter.lang;
service_tracker_t *trk = celix_serviceTracker_createWithOptions(ctx, &trkOpts);
if (trk != NULL) {
- celix_serviceTracker_useServices(trk, opts->serviceName, opts->callbackHandle, opts->use, opts->useWithProperties, opts->useWithOwner);
+ celix_serviceTracker_useServices(trk, opts->filter.serviceName, opts->callbackHandle, opts->use, opts->useWithProperties, opts->useWithOwner);
celix_serviceTracker_destroy(trk);
}
}
@@ -772,9 +768,8 @@ long celix_bundleContext_trackService(
const char* serviceName,
void* callbackHandle,
void (*set)(void* handle, void* svc)) {
- celix_service_tracking_options_t opts;
- memset(&opts, 0, sizeof(opts));
- opts.serviceName = serviceName;
+ celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
+ opts.filter.serviceName = serviceName;
opts.callbackHandle = callbackHandle;
opts.set = set;
return celix_bundleContext_trackServicesWithOptions(ctx, &opts);
@@ -787,9 +782,8 @@ long celix_bundleContext_trackServices(
void* callbackHandle,
void (*add)(void* handle, void* svc),
void (*remove)(void* handle, void* svc)) {
- celix_service_tracking_options_t opts;
- memset(&opts, 0, sizeof(opts));
- opts.serviceName = serviceName;
+ celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
+ opts.filter.serviceName = serviceName;
opts.callbackHandle = callbackHandle;
opts.add = add;
opts.remove = remove;
@@ -831,4 +825,50 @@ long celix_bundleContext_registerServiceFactorForLang(celix_bundle_context_t *ct
celixThreadMutex_unlock(&ctx->mutex);
}
return facId;
+}
+
+long celix_bundleContext_findService(celix_bundle_context_t *ctx, const char *serviceName) {
+ celix_service_filter_options_t opts = CELIX_EMPTY_SERVICE_FILTER_OPTIONS;
+ opts.serviceName = serviceName;
+ return celix_bundleContext_findServiceWithOptions(ctx, &opts);
+}
+
+static void bundleContext_retrieveSvcId(void *handle, void *svc __attribute__((unused)), const celix_properties_t *props) {
+ long *svcId = handle;
+ *svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
+}
+
+long celix_bundleContext_findServiceWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts) {
+ long svcId = -1L;
+ celix_service_use_options_t useOpts = CELIX_EMPTY_SERVICE_USE_OPTIONS;
+ memcpy(&useOpts.filter, opts, sizeof(useOpts.filter));
+ useOpts.callbackHandle = &svcId;
+ useOpts.useWithProperties = bundleContext_retrieveSvcId;
+ celix_bundleContext_useServiceWithOptions(ctx, &useOpts);
+ return svcId;
+}
+
+
+celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName) {
+ celix_service_filter_options_t opts = CELIX_EMPTY_SERVICE_FILTER_OPTIONS;
+ opts.serviceName = serviceName;
+ return celix_bundleContext_findServicesWithOptions(ctx, &opts);
+}
+
+static void bundleContext_retrieveSvcIds(void *handle, void *svc __attribute__((unused)), const celix_properties_t *props) {
+ celix_array_list_t *list = handle;
+ if (list != NULL) {
+ long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
+ celix_arrayList_addLong(list, svcId);
+ }
+}
+
+celix_array_list_t* celix_bundleContext_findServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts) {
+ celix_array_list_t* list = celix_arrayList_create();
+ celix_service_use_options_t useOpts = CELIX_EMPTY_SERVICE_USE_OPTIONS;
+ memcpy(&useOpts.filter, opts, sizeof(useOpts.filter));
+ useOpts.callbackHandle = list;
+ useOpts.useWithProperties = bundleContext_retrieveSvcIds;
+ celix_bundleContext_useServicesWithOptions(ctx, &useOpts);
+ return list;
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/framework/src/service_tracker.c
----------------------------------------------------------------------
diff --git a/framework/src/service_tracker.c b/framework/src/service_tracker.c
index c92efa3..56ad199 100644
--- a/framework/src/service_tracker.c
+++ b/framework/src/service_tracker.c
@@ -560,11 +560,10 @@ celix_service_tracker_t* celix_serviceTracker_create(
const char *serviceName,
const char *versionRange,
const char *filter) {
- celix_service_tracking_options_t opts;
- memset(&opts, 0, sizeof(opts));
- opts.serviceName = serviceName;
- opts.filter = filter;
- opts.versionRange = versionRange;
+ celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
+ opts.filter.serviceName = serviceName;
+ opts.filter.filter = filter;
+ opts.filter.versionRange = versionRange;
return celix_serviceTracker_createWithOptions(ctx, &opts);
}
@@ -573,7 +572,7 @@ celix_service_tracker_t* celix_serviceTracker_createWithOptions(
const celix_service_tracking_options_t *opts
) {
celix_service_tracker_t *tracker = NULL;
- if (ctx != NULL && opts != NULL && opts->serviceName != NULL) {
+ if (ctx != NULL && opts != NULL && opts->filter.serviceName != NULL) {
tracker = calloc(1, sizeof(*tracker));
if (tracker != NULL) {
tracker->context = ctx;
@@ -586,44 +585,41 @@ celix_service_tracker_t* celix_serviceTracker_createWithOptions(
tracker->set = opts->set;
tracker->add = opts->add;
tracker->remove = opts->remove;
- tracker->modified = opts->modified;
tracker->setWithProperties = opts->setWithProperties;
tracker->addWithProperties = opts->addWithProperties;
tracker->removeWithProperties = opts->removeWithProperties;
- tracker->modifiedWithProperties = opts->modifiedWithProperties;
tracker->setWithOwner = opts->setWithOwner;
tracker->addWithOwner = opts->addWithOwner;
tracker->removeWithOwner = opts->removeWithOwner;
- tracker->modifiedWithOwner = opts->modifiedWithOwner;
//highest service state
celixThreadMutex_create(&tracker->mutex, NULL);
tracker->currentHighestServiceId = -1;
//setting lang
- const char *lang = opts->lang;
+ const char *lang = opts->filter.lang;
if (lang == NULL || strncmp("", lang, 1) == 0) {
lang = CELIX_FRAMEWORK_SERVICE_C_LANGUAGE;
}
//setting filter
- if (opts->filter != NULL && opts->versionRange != NULL) {
+ if (opts->filter.filter != NULL && opts->filter.versionRange != NULL) {
//TODO version range
- asprintf(&tracker->filter, "&((%s=%s)(%s=%s)%s)", OSGI_FRAMEWORK_OBJECTCLASS, opts->serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang, opts->filter);
- } else if (opts->versionRange != NULL) {
+ asprintf(&tracker->filter, "&((%s=%s)(%s=%s)%s)", OSGI_FRAMEWORK_OBJECTCLASS, opts->filter.serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang, opts->filter.filter);
+ } else if (opts->filter.versionRange != NULL) {
//TODO version range
- asprintf(&tracker->filter, "&((%s=%s)(%s=%s))", OSGI_FRAMEWORK_OBJECTCLASS, opts->serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang);
- } else if (opts->filter != NULL) {
- asprintf(&tracker->filter, "(&(%s=%s)(%s=%s)%s)", OSGI_FRAMEWORK_OBJECTCLASS, opts->serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang, opts->filter);
+ asprintf(&tracker->filter, "&((%s=%s)(%s=%s))", OSGI_FRAMEWORK_OBJECTCLASS, opts->filter.serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang);
+ } else if (opts->filter.filter != NULL) {
+ asprintf(&tracker->filter, "(&(%s=%s)(%s=%s)%s)", OSGI_FRAMEWORK_OBJECTCLASS, opts->filter.serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang, opts->filter.filter);
} else {
- asprintf(&tracker->filter, "(&(%s=%s)(%s=%s))", OSGI_FRAMEWORK_OBJECTCLASS, opts->serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang);
+ asprintf(&tracker->filter, "(&(%s=%s)(%s=%s))", OSGI_FRAMEWORK_OBJECTCLASS, opts->filter.serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang);
}
//TODO open on other thread?
serviceTracker_open(tracker);
}
} else {
- if (opts != NULL && opts->serviceName == NULL) {
+ if (opts != NULL && opts->filter.serviceName == NULL) {
framework_log(logger, OSGI_FRAMEWORK_LOG_ERROR, __FUNCTION__, __BASE_FILE__, __LINE__,
"Error incorrect arguments. Missing service name.");
} else {
http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/framework/tst/bundle_context_services_test.cpp
----------------------------------------------------------------------
diff --git a/framework/tst/bundle_context_services_test.cpp b/framework/tst/bundle_context_services_test.cpp
index 2597ece..6fa1204 100644
--- a/framework/tst/bundle_context_services_test.cpp
+++ b/framework/tst/bundle_context_services_test.cpp
@@ -297,7 +297,7 @@ TEST(CelixBundleContextServicesTests, servicesTrackerInvalidArgsTest) {
memset(&opts, 0, sizeof(opts));
trackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
CHECK(trackerId < 0); //required opts->serviceName missing
- opts.serviceName = "calc";
+ opts.filter.serviceName = "calc";
trackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
CHECK(trackerId >= 0); //valid
celix_bundleContext_stopTracker(ctx, trackerId);
@@ -361,7 +361,7 @@ TEST(CelixBundleContextServicesTests, servicesTrackerTestWithProperties) {
celix_service_tracking_options_t opts;
memset(&opts, 0, sizeof(opts));
- opts.serviceName = "calc";
+ opts.filter.serviceName = "calc";
opts.callbackHandle = &count;
opts.addWithProperties = add;
opts.removeWithProperties = remove;
@@ -401,7 +401,7 @@ TEST(CelixBundleContextServicesTests, servicesTrackerTestWithOwner) {
celix_service_tracking_options_t opts;
memset(&opts, 0, sizeof(opts));
- opts.serviceName = "calc";
+ opts.filter.serviceName = "calc";
opts.callbackHandle = &count;
opts.addWithOwner = add;
opts.removeWithOwner = remove;
@@ -557,7 +557,7 @@ TEST(CelixBundleContextServicesTests, servicesTrackerSetTest) {
celix_service_tracking_options_t opts;
memset(&opts, 0, sizeof(opts));
opts.callbackHandle = (void*)&count;
- opts.serviceName = "NA";
+ opts.filter.serviceName = "NA";
opts.set = set;
long trackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
CHECK(trackerId > 0);
@@ -628,3 +628,30 @@ TEST(CelixBundleContextServicesTests, serviceFactoryTest) {
celix_bundleContext_unregisterService(ctx, facId);
}
+TEST(CelixBundleContextServicesTests, findServicesTest) {
+ long svcId1 = celix_bundleContext_registerService(ctx, "example", (void*)0x100, NULL, NULL);
+ long svcId2 = celix_bundleContext_registerService(ctx, "example", (void*)0x100, NULL, NULL);
+
+ long foundId = celix_bundleContext_findService(ctx, "non existing service name");
+ CHECK_EQUAL(-1L, foundId);
+
+ foundId = celix_bundleContext_findService(ctx, "example");
+ CHECK_EQUAL(foundId, svcId1); //oldest should have highest ranking
+
+ array_list_t *list = celix_bundleContext_findServices(ctx, "non existintg service name");
+ CHECK_EQUAL(0, celix_arrayList_size(list));
+ arrayList_destroy(list);
+
+ list = celix_bundleContext_findServices(ctx, "example");
+ CHECK_EQUAL(2, celix_arrayList_size(list));
+ arrayList_destroy(list);
+
+ celix_bundleContext_unregisterService(ctx, svcId1);
+
+ celix_service_filter_options_t opts = CELIX_EMPTY_SERVICE_FILTER_OPTIONS;
+ opts.serviceName = "example";
+ foundId = celix_bundleContext_findServiceWithOptions(ctx, &opts);
+ CHECK_EQUAL(foundId, svcId2); //only one left
+
+ celix_bundleContext_unregisterService(ctx, svcId2);
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/utils/include/array_list.h
----------------------------------------------------------------------
diff --git a/utils/include/array_list.h b/utils/include/array_list.h
index 46a0697..fa8602b 100644
--- a/utils/include/array_list.h
+++ b/utils/include/array_list.h
@@ -30,11 +30,24 @@
#include "celixbool.h"
#include "exports.h"
#include "celix_errno.h"
+#include "stdbool.h"
#ifdef __cplusplus
extern "C" {
#endif
+typedef union celix_array_list_entry {
+ void *voidPtrVal;
+ int intVal;
+ long int longVal;
+ unsigned int uintVal;
+ unsigned long ulongVal;
+ double doubleVal;
+ float floatVal;
+ bool boolVal;
+ size_t sizeVal;
+} celix_array_list_entry_t;
+
typedef struct celix_arrayList celix_array_list_t;
typedef struct celix_arrayList *array_list_pt;
@@ -45,7 +58,7 @@ typedef struct arrayListIterator array_list_iterator_t;
typedef celix_status_t (*array_list_element_equals_pt)(const void *, const void *, bool *equals);
-typedef bool (*celix_arrayList_equals_fp)(const void *, const void *);
+typedef bool (*celix_arrayList_equals_fp)(celix_array_list_entry_t, celix_array_list_entry_t);
UTILS_EXPORT celix_status_t arrayList_create(array_list_pt *list);
@@ -107,6 +120,7 @@ UTILS_EXPORT void arrayListIterator_remove(array_list_iterator_pt iterator);
**********************************************************************************************************************
**********************************************************************************************************************/
+
celix_array_list_t* celix_arrayList_create();
celix_array_list_t* celix_arrayList_createWithEquals(celix_arrayList_equals_fp equals);
@@ -117,8 +131,31 @@ size_t celix_arrayList_size(const celix_array_list_t *list);
void* celix_arrayList_get(const celix_array_list_t *list, int index);
-//TODO rest
-
+//more of the same for the different entry types
+int celix_arrayList_getInt(const celix_array_list_t *list, int index);
+long int celix_arrayList_getLong(const celix_array_list_t *list, int index);
+unsigned int celix_arrayList_getUInt(const celix_array_list_t *list, int index);
+unsigned long int celix_arrayList_getULong(const celix_array_list_t *list, int index);
+float celix_arrayList_getFloat(const celix_array_list_t *list, int index);
+double celix_arrayList_getDouble(const celix_array_list_t *list, int index);
+bool celix_arrayList_getBool(const celix_array_list_t *list, int index);
+size_t celix_arrayList_getSize(const celix_array_list_t *list, int index);
+
+void celix_arrayList_add(celix_array_list_t *list, void* val);
+
+//more of the same for the different entry types
+void celix_arrayList_addInt(celix_array_list_t *list, int val);
+void celix_arrayList_addLong(celix_array_list_t *list, long val);
+void celix_arrayList_addUInt(celix_array_list_t *list, unsigned int val);
+void celix_arrayList_addULong(celix_array_list_t *list, unsigned long val);
+void celix_arrayList_addFloat(celix_array_list_t *list, float val);
+void celix_arrayList_addDouble(celix_array_list_t *list, double val);
+void celix_arrayList_addBool(celix_array_list_t *list, bool val);
+void celix_arrayList_addSize(celix_array_list_t *list, size_t val);
+
+int celix_arrayList_indexOf(celix_array_list_t *list, celix_array_list_entry_t entry);
+void celix_arrayList_remove(celix_array_list_t *list, int index);
+void celix_arrayList_removeEntry(celix_array_list_t *list, celix_array_list_entry_t entry);
#ifdef __cplusplus
}
http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/utils/src/array_list.c
----------------------------------------------------------------------
diff --git a/utils/src/array_list.c b/utils/src/array_list.c
index 751712e..ca12798 100644
--- a/utils/src/array_list.c
+++ b/utils/src/array_list.c
@@ -31,8 +31,8 @@
#include "array_list_private.h"
static celix_status_t arrayList_elementEquals(const void *a, const void *b, bool *equals);
-static bool celix_arrayList_defaultEquals(const void *a, const void *b);
-static bool celix_arrayList_equalsForElement(celix_array_list_t *list, void *a, void *b);
+static bool celix_arrayList_defaultEquals(const celix_array_list_entry_t a, const celix_array_list_entry_t b);
+static bool celix_arrayList_equalsForElement(celix_array_list_t *list, celix_array_list_entry_t a, celix_array_list_entry_t b);
celix_status_t arrayList_create(array_list_pt *list) {
@@ -57,15 +57,15 @@ static celix_status_t arrayList_elementEquals(const void *a, const void *b, bool
return CELIX_SUCCESS;
}
-static bool celix_arrayList_defaultEquals(const void *a, const void *b) {
- return a == b;
+static bool celix_arrayList_defaultEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+ return a.longVal == b.longVal; //just compare as long int
}
-static bool celix_arrayList_equalsForElement(celix_array_list_t *list, void *a, void *b) {
+static bool celix_arrayList_equalsForElement(celix_array_list_t *list, celix_array_list_entry_t a, celix_array_list_entry_t b) {
bool equals = false;
if (list != NULL) {
if (list->equalsDeprecated != NULL) {
- list->equalsDeprecated(a, b, &equals);
+ list->equalsDeprecated(a.voidPtrVal, b.voidPtrVal, &equals);
} else if (list->equals != NULL) {
equals = list->equals(a, b);
}
@@ -74,34 +74,32 @@ static bool celix_arrayList_equalsForElement(celix_array_list_t *list, void *a,
}
void arrayList_trimToSize(array_list_pt list) {
- unsigned int oldCapacity;
list->modCount++;
- oldCapacity = list->capacity;
+ size_t oldCapacity = list->capacity;
if (list->size < oldCapacity) {
- void ** newList = (void **) realloc(list->elementData, sizeof(void *) * list->size);
+ celix_array_list_entry_t * newList = realloc(list->elementData, sizeof(void *) * list->size);
list->capacity = list->size;
list->elementData = newList;
}
}
void arrayList_ensureCapacity(array_list_pt list, int capacity) {
- void ** newList;
- unsigned int oldCapacity;
+ celix_array_list_entry_t *newList;
list->modCount++;
- oldCapacity = list->capacity;
+ size_t oldCapacity = list->capacity;
if (capacity > oldCapacity) {
- unsigned int newCapacity = (oldCapacity * 3) / 2 + 1;
+ size_t newCapacity = (oldCapacity * 3) / 2 + 1;
if (newCapacity < capacity) {
newCapacity = capacity;
}
- newList = (void **) realloc(list->elementData, sizeof(void *) * newCapacity);
+ newList = realloc(list->elementData, sizeof(void *) * newCapacity);
list->capacity = newCapacity;
list->elementData = newList;
}
}
unsigned int arrayList_size(array_list_pt list) {
- return list->size;
+ return (int)list->size;
}
bool arrayList_isEmpty(array_list_pt list) {
@@ -117,14 +115,15 @@ int arrayList_indexOf(array_list_pt list, void * element) {
if (element == NULL) {
unsigned int i = 0;
for (i = 0; i < list->size; i++) {
- if (list->elementData[i] == NULL) {
+ if (list->elementData[i].voidPtrVal == NULL) {
return i;
}
}
} else {
unsigned int i = 0;
for (i = 0; i < list->size; i++) {
- bool equals = celix_arrayList_equalsForElement(list, element, list->elementData[i]);
+ celix_array_list_entry_t entry = { .voidPtrVal = element };
+ bool equals = celix_arrayList_equalsForElement(list, entry, list->elementData[i]);
if (equals) {
return i;
}
@@ -136,17 +135,21 @@ int arrayList_indexOf(array_list_pt list, void * element) {
int arrayList_lastIndexOf(array_list_pt list, void * element) {
if (element == NULL) {
int i = 0;
- for (i = list->size - 1; i >= 0; i--) {
- if (list->elementData[i] == NULL) {
- return i;
+ int size = (int)list->size;
+ for (i = size - 1; i >= 0; i--) {
+ if (list->elementData[i].voidPtrVal == NULL) {
+ return (int)i;
}
}
} else {
int i = 0;
- for (i = list->size - 1; i >= 0; i--) {
- bool equals = celix_arrayList_equalsForElement(list, element, list->elementData[i]);
+ int size = (int)list->size;
+ for (i = size - 1; i >= 0; i--) {
+ celix_array_list_entry_t entry = { .voidPtrVal = element };
+
+ bool equals = celix_arrayList_equalsForElement(list, entry, list->elementData[i]);
if (equals) {
- return i;
+ return (int)i;
}
}
}
@@ -158,7 +161,7 @@ void * arrayList_get(array_list_pt list, unsigned int index) {
return NULL;
}
- return list->elementData[index];
+ return list->elementData[index].voidPtrVal;
}
void * arrayList_set(array_list_pt list, unsigned int index, void * element) {
@@ -167,61 +170,63 @@ void * arrayList_set(array_list_pt list, unsigned int index, void * element) {
return NULL;
}
- oldElement = list->elementData[index];
- list->elementData[index] = element;
+ oldElement = list->elementData[index].voidPtrVal;
+ memset(&list->elementData[index], 0, sizeof(celix_array_list_entry_t));
+ list->elementData[index].voidPtrVal = element;
return oldElement;
}
bool arrayList_add(array_list_pt list, void * element) {
- arrayList_ensureCapacity(list, list->size + 1);
- list->elementData[list->size++] = element;
+ arrayList_ensureCapacity(list, (int)list->size + 1);
+ memset(&list->elementData[list->size], 0, sizeof(celix_array_list_entry_t));
+ list->elementData[list->size++].voidPtrVal = element;
return true;
}
int arrayList_addIndex(array_list_pt list, unsigned int index, void * element) {
- unsigned int numMoved;
+ size_t numMoved;
if (index > list->size) {
return -1;
}
- arrayList_ensureCapacity(list, list->size+1);
+ arrayList_ensureCapacity(list, (int)list->size+1);
numMoved = list->size - index;
memmove(list->elementData+(index+1), list->elementData+index, sizeof(void *) * numMoved);
- list->elementData[index] = element;
+ list->elementData[index].voidPtrVal = element;
list->size++;
return 0;
}
void * arrayList_remove(array_list_pt list, unsigned int index) {
void * oldElement;
- unsigned int numMoved;
+ size_t numMoved;
if (index >= list->size) {
return NULL;
}
list->modCount++;
- oldElement = list->elementData[index];
+ oldElement = list->elementData[index].voidPtrVal;
numMoved = list->size - index - 1;
memmove(list->elementData+index, list->elementData+index+1, sizeof(void *) * numMoved);
- list->elementData[--list->size] = NULL;
+ memset(&list->elementData[--list->size], 0, sizeof(celix_array_list_entry_t));
return oldElement;
}
void arrayList_fastRemove(array_list_pt list, unsigned int index) {
- unsigned int numMoved;
+ size_t numMoved;
list->modCount++;
numMoved = list->size - index - 1;
memmove(list->elementData+index, list->elementData+index+1, sizeof(void *) * numMoved);
- list->elementData[--list->size] = NULL;
+ memset(&list->elementData[--list->size], 0, sizeof(celix_array_list_entry_t));
}
bool arrayList_removeElement(array_list_pt list, void * element) {
if (element == NULL) {
unsigned int i = 0;
for (i = 0; i < list->size; i++) {
- if (list->elementData[i] == NULL) {
+ if (list->elementData[i].voidPtrVal == NULL) {
arrayList_fastRemove(list, i);
return true;
}
@@ -229,7 +234,9 @@ bool arrayList_removeElement(array_list_pt list, void * element) {
} else {
unsigned int i = 0;
for (i = 0; i < list->size; i++) {
- bool equals = celix_arrayList_equalsForElement(list, element, list->elementData[i]);
+ celix_array_list_entry_t entry;
+ entry.voidPtrVal = element;
+ bool equals = celix_arrayList_equalsForElement(list, entry, list->elementData[i]);
if (equals) {
arrayList_fastRemove(list, i);
return true;
@@ -245,7 +252,7 @@ void arrayList_clear(array_list_pt list) {
for (i = 0; i < list->size; i++) {
// free(list->elementData[i]);
- list->elementData[i] = NULL;
+ memset(&list->elementData[i], 0, sizeof(celix_array_list_entry_t));
}
list->size = 0;
}
@@ -375,15 +382,74 @@ size_t celix_arrayList_size(const celix_array_list_t *list) {
return list->size;
}
-void* celix_arrayList_get(const celix_array_list_t *list, int index) {
- void *el = NULL;
+static celix_array_list_entry_t arrayList_getEntry(const celix_array_list_t *list, int index) {
+ celix_array_list_entry_t entry;
+ memset(&entry, 0, sizeof(entry));
if (index < list->size) {
- el = list->elementData[index];
+ entry = list->elementData[index];
}
- return el;
+ return entry;
+}
+
+void* celix_arrayList_get(const celix_array_list_t *list, int index) {
+ return arrayList_getEntry(list, index).voidPtrVal;
+}
+
+int celix_arrayList_getInt(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).intVal; }
+long int celix_arrayList_getLong(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).longVal; }
+unsigned int celix_arrayList_getUInt(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).uintVal; }
+unsigned long int celix_arrayList_getULong(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).ulongVal; }
+float celix_arrayList_getFloat(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).floatVal; }
+double celix_arrayList_getDouble(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).doubleVal; }
+bool celix_arrayList_getBool(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).boolVal; }
+size_t celix_arrayList_getSize(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).sizeVal; }
+
+static void arrayList_addEntry(celix_array_list_t *list, celix_array_list_entry_t entry) {
+ arrayList_ensureCapacity(list, (int)list->size + 1);
+ memset(&list->elementData[list->size], 0, sizeof(entry));
+ list->elementData[list->size++] = entry;
+}
+
+void celix_arrayList_add(celix_array_list_t *list, void * element) {
+ celix_array_list_entry_t entry = { .voidPtrVal = element };
+ arrayList_addEntry(list, entry);
}
+void celix_arrayList_addInt(celix_array_list_t *list, int val) { celix_array_list_entry_t entry = { .intVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addLong(celix_array_list_t *list, long val) { celix_array_list_entry_t entry = { .longVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addUInt(celix_array_list_t *list, unsigned int val) { celix_array_list_entry_t entry = { .uintVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addULong(celix_array_list_t *list, unsigned long val) { celix_array_list_entry_t entry = { .ulongVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addFloat(celix_array_list_t *list, float val) { celix_array_list_entry_t entry = { .floatVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addDouble(celix_array_list_t *list, double val) { celix_array_list_entry_t entry = { .doubleVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addBool(celix_array_list_t *list, bool val) { celix_array_list_entry_t entry = { .boolVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addSize(celix_array_list_t *list, size_t val) { celix_array_list_entry_t entry = { .sizeVal = val }; arrayList_addEntry(list, entry);}
+
+int celix_arrayList_indexOf(celix_array_list_t *list, celix_array_list_entry_t entry) {
+ size_t size = celix_arrayList_size(list);
+ int i;
+ int index = -1;
+ for (i = 0 ; i < size ; ++i) {
+ bool eq = celix_arrayList_equalsForElement(list, entry, list->elementData[i]);
+ if (eq) {
+ index = i;
+ break;
+ }
+ }
+ return index;
+}
+void celix_arrayList_remove(celix_array_list_t *list, int index) {
+ if (index >= 0 && index < list->size) {
+ list->modCount++;
+ size_t numMoved = list->size - index - 1;
+ memmove(list->elementData+index, list->elementData+index+1, sizeof(void *) * numMoved);
+ memset(&list->elementData[--list->size], 0, sizeof(celix_array_list_entry_t));
+ }
+}
+void celix_arrayList_removeEntry(celix_array_list_t *list, celix_array_list_entry_t entry) {
+ int index = celix_arrayList_indexOf(list, entry);
+ celix_arrayList_remove(list, index);
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/utils/src/array_list_private.h
----------------------------------------------------------------------
diff --git a/utils/src/array_list_private.h b/utils/src/array_list_private.h
index e5394cd..5f83605 100644
--- a/utils/src/array_list_private.h
+++ b/utils/src/array_list_private.h
@@ -30,7 +30,7 @@
#include "array_list.h"
struct celix_arrayList {
- void ** elementData;
+ celix_array_list_entry_t* elementData;
size_t size;
size_t capacity;