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 2015/10/13 12:21:43 UTC
[15/50] [abbrv] celix git commit: CELIX-237: Added support for
argument meta info (output types) and added use of this info in the
export_registration
CELIX-237: Added support for argument meta info (output types) and added use of this info in the export_registration
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/62ede189
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/62ede189
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/62ede189
Branch: refs/heads/develop
Commit: 62ede189c0e5cbc32b1a29256f3c109e8acef02c
Parents: 4c4a5e9
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Wed Aug 12 18:16:08 2015 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Wed Aug 12 18:16:08 2015 +0200
----------------------------------------------------------------------
...apache.celix.calc.api.Calculator2.descriptor | 6 +-
.../dynamic_function_interface/dyn_function.c | 114 +++++++++++++++++--
.../dynamic_function_interface/dyn_function.h | 15 ++-
.../dynamic_function_interface/dyn_type.c | 13 ++-
.../tst/dyn_function_tests.cpp | 55 ++++++++-
.../private/src/export_registration_dfi.c | 81 ++++++++-----
6 files changed, 238 insertions(+), 46 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/62ede189/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor b/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
index 711df0b..52e3322 100644
--- a/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
+++ b/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
@@ -6,6 +6,6 @@ version=1.0.0
classname=org.example.Calculator
:types
:methods
-add(DD)D=add(PDD*D)N
-sub(DD)D=sub(PDD*D)N
-sqrt(D)D=sqrt(PD*D)N
+add(DD)D=add(#PDD^*D)N
+sub(DD)D=sub(#PDD^*D)N
+sqrt(D)D=sqrt(#PD^*D)N
http://git-wip-us.apache.org/repos/asf/celix/blob/62ede189/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c
index 0e12791..8880bc7 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c
@@ -27,6 +27,7 @@ typedef struct _dyn_function_argument_type dyn_function_argument_type;
struct _dyn_function_argument_type {
int index;
char *name;
+ int argumentType;
dyn_type *type;
TAILQ_ENTRY(_dyn_function_argument_type) entries;
};
@@ -40,7 +41,11 @@ DFI_SETUP_LOG(dynFunction)
static int dynFunction_initCif(dyn_function_type *dynFunc);
static int dynFunction_parseDescriptor(dyn_function_type *dynFunc, FILE *descriptor);
-static void dynFunction_ffiBind(ffi_cif *cif, void *ret, void *args[], void *userData);
+static void dynFunction_ffiBind(ffi_cif *cif, void *ret, void *args[], void *userData);
+
+static int dynFunction_checkArgument(dyn_function_argument_type *argument);
+
+static void dynFunction_parseArgMeta(FILE *descriptor, int *meta);
int dynFunction_parse(FILE *descriptor, struct types_head *refTypes, dyn_function_type **out) {
int status = OK;
@@ -67,7 +72,12 @@ int dynFunction_parse(FILE *descriptor, struct types_head *refTypes, dyn_functio
if (status == 0) {
*out = dynFunc;
- }
+ } else {
+ if (dynFunc != NULL) {
+ dynFunction_destroy(dynFunc);
+ }
+
+ }
return status;
}
@@ -106,22 +116,50 @@ static int dynFunction_parseDescriptor(dyn_function_type *dynFunc, FILE *descrip
int nextChar = fgetc(descriptor);
int index = 0;
dyn_type *type = NULL;
+ int argMetaInfo = DYN_FUNCTION_ARG_META_STD_TYPE;
+ char argName[32];
while (nextChar != ')' && status == 0) {
- type = NULL;
ungetc(nextChar, descriptor);
- status = dynType_parse(descriptor, NULL, dynFunc->refTypes, &type);
+ type = NULL;
+
+ dynFunction_parseArgMeta(descriptor, &argMetaInfo);
+ dyn_function_argument_type *arg = NULL;
+
+ status = dynType_parse(descriptor, NULL, dynFunc->refTypes, &type);
if (status == 0) {
- dyn_function_argument_type *arg = calloc(1, sizeof(*arg));
- arg->index = index++;
- arg->type = type;
- arg->name = NULL; //TODO
+ arg = calloc(1, sizeof(*arg));
if (arg != NULL) {
- TAILQ_INSERT_TAIL(&dynFunc->arguments, arg, entries);
+ arg->index = index;
+ arg->type = type;
+ arg->argumentType = argMetaInfo;
+
+ snprintf(argName, 32, "arg%04i", index);
+ arg->name = strdup(argName);
+
+ index += 1;
} else {
LOG_ERROR("Error allocating memory");
status = MEM_ERROR;
}
- }
+ }
+
+ if (status == 0) {
+ status = dynFunction_checkArgument(arg);
+ }
+
+ if (status == 0) {
+ TAILQ_INSERT_TAIL(&dynFunc->arguments, arg, entries);
+ } else {
+ if (arg != NULL) {
+ if (arg->name != NULL) {
+ free(arg->name);
+ }
+ if (arg->type != NULL) {
+ dynType_destroy(arg->type);
+ }
+ free(arg);
+ }
+ }
nextChar = fgetc(descriptor);
}
@@ -132,6 +170,48 @@ static int dynFunction_parseDescriptor(dyn_function_type *dynFunc, FILE *descrip
return status;
}
+static void dynFunction_parseArgMeta(FILE *descriptor, int *meta) {
+ int c = fgetc(descriptor);
+
+ switch (c) {
+ case '~' :
+ *meta = DYN_FUNCTION_ARG_META_OUPUT_TYPE;
+ break;
+ case '^' :
+ *meta = DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE;
+ break;
+ case '#' :
+ *meta = DYN_FUNCTION_ARG_META_HANDLE_TYPE;
+ break;
+ default :
+ *meta = DYN_FUNCTION_ARG_META_STD_TYPE;
+ ungetc(c, descriptor);
+ break;
+ }
+}
+
+static int dynFunction_checkArgument(dyn_function_argument_type *argument) {
+ int status = 0;
+ if (argument->argumentType == DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE) {
+ //expect atleast one *
+ if (dynType_type(argument->type) != DYN_TYPE_TYPED_POINTER) {
+ status = ERROR;
+ }
+ } else if (argument->argumentType == DYN_FUNCTION_ARG_META_OUPUT_TYPE) {
+ //expect atleast two **
+ if (dynType_type(argument->type) == DYN_TYPE_TYPED_POINTER) {
+ dyn_type *subType = NULL;
+ status = dynType_typedPointer_getTypedType(argument->type, &subType);
+ if (status == OK && dynType_type(subType) != DYN_TYPE_TYPED_POINTER) {
+ status = ERROR;
+ }
+ } else {
+ status = ERROR;
+ }
+ }
+ return status;
+}
+
static int dynFunction_initCif(dyn_function_type *dynFunc) {
int status = 0;
@@ -261,4 +341,18 @@ dyn_type * dynFunction_returnType(dyn_function_type *dynFunction) {
return dynFunction->funcReturn;
}
+int dynFunction_argumentMetaInfoForIndex(dyn_function_type *dynFunc, int argumentNr) {
+ int argType = DYN_FUNCTION_ARG_META_UNKNOWN_TYPE;
+ int index = 0;
+ dyn_function_argument_type *entry = NULL;
+ TAILQ_FOREACH(entry, &dynFunc->arguments, entries) {
+ if (index == argumentNr) {
+ argType = entry->argumentType;
+ break;
+ }
+ index +=1;
+ }
+ return argType;
+}
+
http://git-wip-us.apache.org/repos/asf/celix/blob/62ede189/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h
index b1abfb6..733c092 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h
@@ -10,10 +10,22 @@
/**
* Uses the following schema
- * (Name)([Type]*)Type
+ * (Name)([ArgType]*)Type
+ *
+ * ArgType = (Type|PreAllocatedOutputType|OutputType)
+ * PreAllocatedOutputType = ^(Type) #Note must be *(Type)
+ * OutputType = ~(Type) #Note must be **(Type)
* e.g add(DD)D or sum({[D[D setA setB})D
*/
+//TODO maybe refactor to meta info flags (e.g context/handler, output, etc with a start/stop -> M(MetaType);
+
+#define DYN_FUNCTION_ARG_META_UNKNOWN_TYPE 0
+#define DYN_FUNCTION_ARG_META_STD_TYPE 1
+#define DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE 2
+#define DYN_FUNCTION_ARG_META_OUPUT_TYPE 3
+#define DYN_FUNCTION_ARG_META_HANDLE_TYPE 4
+
typedef struct _dyn_function_type dyn_function_type;
DFI_SETUP_LOG_HEADER(dynFunction);
@@ -24,6 +36,7 @@ int dynFunction_parseWithStr(const char *descriptor, struct types_head *refTypes
int dynFunction_nrOfArguments(dyn_function_type *dynFunc);
dyn_type *dynFunction_argumentTypeForIndex(dyn_function_type *dynFunc, int argumentNr);
dyn_type * dynFunction_returnType(dyn_function_type *dynFunction);
+int dynFunction_argumentMetaInfoForIndex(dyn_function_type *dynFunc, int argumentNr);
void dynFunction_destroy(dyn_function_type *dynFunc);
int dynFunction_call(dyn_function_type *dynFunc, void(*fn)(void), void *returnValue, void **argValues);
http://git-wip-us.apache.org/repos/asf/celix/blob/62ede189/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c
index e47fe6d..6396d1c 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c
@@ -503,6 +503,17 @@ int dynType_alloc(dyn_type *type, void **bufLoc) {
void *inst = calloc(1, type->ffiType->size);
if (inst != NULL) {
+ if (type->type == DYN_TYPE_TYPED_POINTER) {
+ void *ptr = NULL;
+ dyn_type *sub = NULL;
+ status = dynType_typedPointer_getTypedType(type, &sub);
+ if (status == OK) {
+ status = dynType_alloc(sub, &ptr);
+ if (status == OK) {
+ *(void **)inst = ptr;
+ }
+ }
+ }
*bufLoc = inst;
} else {
status = MEM_ERROR;
@@ -913,7 +924,7 @@ static void dynType_printComplex(char *name, dyn_type *type, int depth, FILE *st
}
dynType_printDepth(depth, stream);
- printf("}\n");
+ fprintf(stream, "}\n");
} else {
dynType_printDepth(depth, stream);
fprintf(stream, "%s: complex type ('%s'), size is %zu, alignment is %i, descriptor is '%c'.\n", name, type->name, type->ffiType->size, type->ffiType->alignment, type->descriptor);
http://git-wip-us.apache.org/repos/asf/celix/blob/62ede189/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp
index 006897c..ab5f33e 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp
@@ -133,6 +133,7 @@ extern "C" {
static void test_example3(void) {
dyn_function_type *dynFunc = NULL;
+ void (*fp)(void) = (void(*)(void)) testExample3;
int rc;
rc = dynFunction_parseWithStr(EXAMPLE3_DESCRIPTOR, NULL, &dynFunc);
@@ -145,15 +146,60 @@ extern "C" {
args[0] = &ptr;
args[1] = &a;
args[2] = &input;
- void (*fp)(void) = (void(*)(void)) testExample3;
-
int rVal;
rc = dynFunction_call(dynFunc, fp, &rVal, args);
+ CHECK_EQUAL(0, rc);
+ CHECK_EQUAL(4.0, result);
+
+ double *inMemResult = (double *)calloc(1, sizeof(double));
+ a = 2.0;
+ ptr = &a;
+ args[0] = &ptr;
+ args[1] = &a;
+ args[2] = &inMemResult;
+ rVal;
+ rc = dynFunction_call(dynFunc, fp, &rVal, args);
CHECK_EQUAL(0, rc);
CHECK_EQUAL(4.0, result);
+ free(inMemResult);
+
+ dynFunction_destroy(dynFunc);
}
+ void test_meta(void) {
+ int rc;
+ dyn_function_type *func = NULL;
+
+ const char *descriptor1 = "sqrt(D^*D~**D#P)V";
+ rc = dynFunction_parseWithStr(descriptor1, NULL, &func);
+ CHECK_EQUAL(0, rc);
+ CHECK_EQUAL(DYN_FUNCTION_ARG_META_STD_TYPE, dynFunction_argumentMetaInfoForIndex(func, 0));
+ CHECK_EQUAL(DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE, dynFunction_argumentMetaInfoForIndex(func, 1));
+ CHECK_EQUAL(DYN_FUNCTION_ARG_META_OUPUT_TYPE, dynFunction_argumentMetaInfoForIndex(func, 2));
+ CHECK_EQUAL(DYN_FUNCTION_ARG_META_HANDLE_TYPE, dynFunction_argumentMetaInfoForIndex(func, 3));
+ CHECK_EQUAL(DYN_FUNCTION_ARG_META_UNKNOWN_TYPE, dynFunction_argumentMetaInfoForIndex(func, 4));
+ dynFunction_destroy(func);
+
+ const char *descriptor2 = "sqrt(D~*D)V";
+ rc = dynFunction_parseWithStr(descriptor2, NULL, &func);
+ CHECK(rc != 0);
+
+ const char *descriptor3 = "sqrt(D~***D)V";
+ rc = dynFunction_parseWithStr(descriptor3, NULL, &func);
+ CHECK_EQUAL(0, rc);
+ dynFunction_destroy(func);
+
+
+ const char *descriptor4 = "sqrt(D^D)V";
+ rc = dynFunction_parseWithStr(descriptor4, NULL, &func);
+ CHECK(rc != 0);
+
+ const char *descriptor5 = "sqrt(D^***D)V";
+ rc = dynFunction_parseWithStr(descriptor5, NULL, &func);
+ CHECK_EQUAL(0, rc);
+ dynFunction_destroy(func);
+ }
}
TEST_GROUP(DynFunctionTests) {
@@ -176,7 +222,10 @@ TEST(DynFunctionTests, DynFuncAccTest) {
test_access_functions();
}
-
TEST(DynFunctionTests, DynFuncTest3) {
test_example3();
+}
+
+TEST(DynFunctionTests, DynFuncTestMeta) {
+ test_meta();
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/62ede189/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c b/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c
index 74512d3..c763222 100644
--- a/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c
+++ b/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c
@@ -5,6 +5,7 @@
#include <dyn_interface.h>
#include <json_serializer.h>
#include <remote_constants.h>
+#include <assert.h>
#include "export_registration.h"
#include "export_registration_dfi.h"
@@ -129,31 +130,43 @@ celix_status_t exportRegistration_call(export_registration_pt export, char *data
if (method != NULL) {
+ struct generic_service_layout *serv = export->service;
+
int nrOfArgs = dynFunction_nrOfArguments(method->dynFunc);
- void *args[nrOfArgs]; //arg 0 is handle
+ void *args[nrOfArgs];
json_t *arguments = json_object_get(js_request, "a");
json_t *value = NULL;
- int index = -1;
- json_array_foreach(arguments, index, value) {
- int argNr = index + 1;
- if (argNr < nrOfArgs -1 ) { //note skip last argument. this is the output
- dyn_type *argType = dynFunction_argumentTypeForIndex(method->dynFunc, argNr);
- status = jsonSerializer_deserializeJson(argType, value, &(args[argNr]));
+
+ int i;
+ int index = 0;
+ for (i = 0; i < nrOfArgs; i += 1) {
+ int metaInfo = dynFunction_argumentMetaInfoForIndex(method->dynFunc, i);
+ dyn_type *argType = dynFunction_argumentTypeForIndex(method->dynFunc, i);
+ if (metaInfo == DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE) {
+ printf("setting pre alloc output for %i\n", i);
+ dynType_alloc(argType, &args[i]);
+
+ } else if ( metaInfo == DYN_FUNCTION_ARG_META_OUPUT_TYPE) {
+ printf("setting output for %i\n", i);
+ args[i] = NULL;
+ } else if (metaInfo == DYN_FUNCTION_ARG_META_HANDLE_TYPE) {
+ printf("setting handle for %i\n", i);
+ args[i] = &serv->handle;
} else {
- status = CELIX_ILLEGAL_ARGUMENT;
+ printf("setting std for %i\n", i);
+ value = json_array_get(arguments, index++);
+ status = jsonSerializer_deserializeJson(argType, value, &(args[i]));
}
- if (status != 0) {
+
+ if (status != CELIX_SUCCESS) {
break;
}
}
json_decref(js_request);
-
- struct generic_service_layout *serv = export->service;
- args[0] = &serv->handle;
-
+ /*
//TODO assert last is output pointer (e.g. double pointer)
dyn_type *lastTypePtr = dynFunction_argumentTypeForIndex(method->dynFunc, nrOfArgs-1);
dyn_type *lastType = NULL;
@@ -170,34 +183,46 @@ celix_status_t exportRegistration_call(export_registration_pt export, char *data
dynType_alloc(lastType, &out); //TODO, NOTE only for simple types or single pointer types.. TODO check
printf("out ptr is %p value is %f\n", out, *(double *)out);
args[nrOfArgs-1] = &out; //NOTE for simple type no double
+ */
printf("args is %p %p %p\n", args[0] , args[1], args[2]);
printf("args derefs is %p %p %p\n", *(void **)args[0], *(void **)args[1], *(void **)args[2]);
//TODO assert return type is native int
int returnVal = 0;
- //printf("calling function '%s', with index %i, nrOfArgs %i and at loc %p\n", method->id, method->index, nrOfArgs, serv->methods[method->index]);
dynFunction_call(method->dynFunc, serv->methods[method->index], (void *)&returnVal, args);
- //printf("done calling\n");
- //printf("args is %p %p %p\n", args[0] , args[1], args[2]);
- //printf("args derefs is %p %p %p\n", *(void **)args[0], *(void **)args[1], *(void **)args[2]);
- //printf("out is %p and val is %f\n", out, *(double *)out);
+ printf("done calling\n");
+ double **r = args[2];
+ printf("result ptrptr is %p, result ptr %p, result is %f\n", r, *r, **r);
json_t *responseJson = NULL;
- //double r = 2.0;
- //status = jsonSerializer_serializeJson(lastOutputType, &r /*out*/, &responseJson);
- printf("out ptr is %p, value is %f\n", out, *(double *)out);
- status = jsonSerializer_serializeJson(lastType, out, &responseJson);
- json_t *payload = json_object();
- json_object_set_new(payload, "r", responseJson);
+ for (i = 0; i < nrOfArgs; i += 1) {
+ int metaInfo = dynFunction_argumentMetaInfoForIndex(method->dynFunc, i);
+ dyn_type *argType = dynFunction_argumentTypeForIndex(method->dynFunc, i);
+ if (metaInfo == DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE) {
+ if (status == CELIX_SUCCESS) {
+ status = jsonSerializer_serializeJson(argType, args[i], &responseJson);
+ }
+ break;
+ } else if (metaInfo == DYN_FUNCTION_ARG_META_OUPUT_TYPE) {
+ printf("TODO\n");
+ assert(false);
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ printf("creating payload\n");
+ json_t *payload = json_object();
+ json_object_set_new(payload, "r", responseJson);
- char *response = json_dumps(payload, JSON_DECODE_ANY);
- json_decref(payload);
+ char *response = json_dumps(payload, JSON_DECODE_ANY);
+ json_decref(payload);
+ *responseOut = response;
+ *responseLength = -1;
+ }
- *responseOut = response;
- *responseLength = -1;
//TODO free args (created by jsonSerializer and dynType_alloc) (dynType_free)