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:59 UTC
[31/50] [abbrv] celix git commit: CELIX-237: Added support for
handling reply for output pointers.
CELIX-237: Added support for handling reply for output pointers.
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/2d6ef1ba
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/2d6ef1ba
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/2d6ef1ba
Branch: refs/heads/develop
Commit: 2d6ef1ba83abee0a62b6aa726dbaed4cea4f1742
Parents: f99de6e
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Sep 7 13:44:11 2015 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Sep 7 13:44:11 2015 +0200
----------------------------------------------------------------------
.../dynamic_function_interface/dyn_function.c | 37 ++++++++-
.../dynamic_function_interface/dyn_function.h | 8 ++
.../dynamic_function_interface/dyn_interface.c | 12 +++
.../dynamic_function_interface/dyn_type.c | 1 -
.../dynamic_function_interface/json_rpc.c | 87 ++++++++++++--------
.../json_rpc_tests.cpp | 49 ++++++++++-
6 files changed, 154 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/2d6ef1ba/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 e059078..7a6a24d 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,7 +27,7 @@ typedef struct _dyn_function_argument_type dyn_function_argument_type;
struct _dyn_function_argument_type {
int index;
char *name;
- int argumentType;
+ enum dyn_function_argument_meta argumentMeta;
dyn_type *type;
TAILQ_ENTRY(_dyn_function_argument_type) entries;
};
@@ -65,8 +65,27 @@ int dynFunction_parse(FILE *descriptor, struct types_head *refTypes, dyn_functio
LOG_ERROR("Error allocationg memory for dyn functipn\n");
status = MEM_ERROR;
}
+
+ if (status == OK) {
+ dyn_function_argument_type *arg = NULL;
+ TAILQ_FOREACH(arg, &dynFunc->arguments, entries) {
+ const char *meta = dynType_getMetaInfo(arg->type, "am");
+ if (meta == NULL) {
+ arg->argumentMeta = DYN_FUNCTION_ARGUMENT_META__STD;
+ } else if (strcmp(meta, "handle") == 0) {
+ arg->argumentMeta = DYN_FUNCTION_ARGUMENT_META__HANDLE;
+ } else if (strcmp(meta, "pre") == 0) {
+ arg->argumentMeta = DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT;
+ } else if (strcmp(meta, "out") == 0) {
+ arg->argumentMeta = DYN_FUNCTION_ARGUMENT_META__OUTPUT;
+ } else {
+ LOG_WARNING("unknown argument meta '%s' encountered", meta);
+ arg->argumentMeta = DYN_FUNCTION_ARGUMENT_META__STD;
+ }
+ }
+ }
- if (status == 0) {
+ if (status == OK) {
*out = dynFunc;
} else {
if (dynFunc != NULL) {
@@ -156,6 +175,20 @@ static int dynFunction_parseDescriptor(dyn_function_type *dynFunc, FILE *descrip
return status;
}
+enum dyn_function_argument_meta dynFunction_argumentMetaForIndex(dyn_function_type *dynFunc, int argumentNr) {
+ enum dyn_function_argument_meta result = 0;
+ dyn_function_argument_type *arg = NULL;
+ int index = 0;
+ TAILQ_FOREACH(arg, &dynFunc->arguments, entries) {
+ if (index == argumentNr) {
+ result = arg->argumentMeta;
+ break;
+ }
+ index += 1;
+ }
+ return result;
+}
+
static int dynFunction_initCif(dyn_function_type *dynFunc) {
int status = 0;
http://git-wip-us.apache.org/repos/asf/celix/blob/2d6ef1ba/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 de8853c..b756e76 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
@@ -22,11 +22,19 @@ typedef struct _dyn_function_type dyn_function_type;
DFI_SETUP_LOG_HEADER(dynFunction);
+enum dyn_function_argument_meta {
+ DYN_FUNCTION_ARGUMENT_META__STD = 0,
+ DYN_FUNCTION_ARGUMENT_META__HANDLE = 1,
+ DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT = 2,
+ DYN_FUNCTION_ARGUMENT_META__OUTPUT = 3
+};
+
int dynFunction_parse(FILE *descriptorStream, struct types_head *refTypes, dyn_function_type **dynFunc);
int dynFunction_parseWithStr(const char *descriptor, struct types_head *refTypes, dyn_function_type **dynFunc);
int dynFunction_nrOfArguments(dyn_function_type *dynFunc);
dyn_type *dynFunction_argumentTypeForIndex(dyn_function_type *dynFunc, int argumentNr);
+enum dyn_function_argument_meta dynFunction_argumentMetaForIndex(dyn_function_type *dynFunc, int argumentNr);
dyn_type * dynFunction_returnType(dyn_function_type *dynFunction);
void dynFunction_destroy(dyn_function_type *dynFunc);
http://git-wip-us.apache.org/repos/asf/celix/blob/2d6ef1ba/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.c
index 5cd7104..ab436b7 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.c
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.c
@@ -279,6 +279,18 @@ static int dynInterface_parseMethods(dyn_interface_type *intf, FILE *stream) {
entry->index = index++;
entry->id = id;
entry->dynFunc = func;
+ entry->name = strndup(id, 1024);
+ if (entry->name != NULL) {
+ int i;
+ for (i = 0; i < 1024; i += 1) {
+ if (entry->name[i] == '\0') {
+ break;
+ } else if (entry->name[i] == '(') {
+ entry->name[i] = '\0';
+ break;
+ }
+ }
+ }
TAILQ_INSERT_TAIL(&intf->methods, entry, entries);
} else {
status = ERROR;
http://git-wip-us.apache.org/repos/asf/celix/blob/2d6ef1ba/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 70f6a7b..3967e15 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
@@ -452,7 +452,6 @@ static int dynType_parseSequence(FILE *stream, dyn_type *type) {
if (status == OK) {
type->ffiType = &type->sequence.seqType;
dynType_prepCif(&type->sequence.seqType);
- LOG_DEBUG("seq size is %zu\n", type->ffiType->size);
}
return status;
http://git-wip-us.apache.org/repos/asf/celix/blob/2d6ef1ba/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_rpc.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_rpc.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_rpc.c
index 9acd3fb..56c237c 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_rpc.c
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_rpc.c
@@ -87,16 +87,16 @@ int jsonRpc_call(dyn_interface_type *intf, void *service, const char *request, c
for (i = 0; i < nrOfArgs; i += 1) {
dyn_type *argType = dynFunction_argumentTypeForIndex(func, i);
- const char *argMeta = dynType_getMetaInfo(argType, "am");
- if (argMeta == NULL) {
+ enum dyn_function_argument_meta meta = dynFunction_argumentMetaForIndex(func, i);
+ if (meta == DYN_FUNCTION_ARGUMENT_META__STD) {
value = json_array_get(arguments, index++);
status = jsonSerializer_deserializeJson(argType, value, &(args[i]));
- } else if (strcmp(argMeta, "pre") == 0) {
+ } else if (meta == DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT) {
dynType_alloc(argType, &args[i]);
- } else if (strcmp(argMeta, "out") == 0) {
+ } else if (meta == DYN_FUNCTION_ARGUMENT_META__OUTPUT) {
void *inMemPtr = calloc(1, sizeof(void *));
args[i] = &inMemPtr;
- } else if (strcmp(argMeta, "handle") == 0) {
+ } else if (meta == DYN_FUNCTION_ARGUMENT_META__HANDLE) {
args[i] = &handle;
}
@@ -127,15 +127,15 @@ int jsonRpc_call(dyn_interface_type *intf, void *service, const char *request, c
if (funcCallStatus == 0 && status == OK) {
for (i = 0; i < nrOfArgs; i += 1) {
dyn_type *argType = dynFunction_argumentTypeForIndex(func, i);
- const char *argMeta = dynType_getMetaInfo(argType, "am");
- if (argMeta == NULL) {
+ enum dyn_function_argument_meta meta = dynFunction_argumentMetaForIndex(func, i);
+ if (meta == DYN_FUNCTION_ARGUMENT_META__STD) {
dynType_free(argType, args[i]);
- } else if (strcmp(argMeta, "pre") == 0) {
+ } else if (meta == DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT) {
if (status == OK) {
status = jsonSerializer_serializeJson(argType, args[i], &jsonResult);
}
dynType_free(argType, args[i]);
- } else if (strcmp(argMeta, "out") == 0) {
+ } else if (meta == DYN_FUNCTION_ARGUMENT_META__OUTPUT) {
void ***out = args[i];
if (out != NULL && *out != NULL && **out != NULL) {
status = jsonSerializer_serializeJson(argType, out, &jsonResult);
@@ -179,7 +179,6 @@ int jsonRpc_call(dyn_interface_type *intf, void *service, const char *request, c
free(response);
}
- //TODO free args (created by jsonSerializer and dynType_alloc) (dynType_free)
return status;
}
@@ -198,8 +197,8 @@ int jsonRpc_prepareInvokeRequest(dyn_function_type *func, const char *id, void *
int nrOfArgs = dynFunction_nrOfArguments(func);
for (i = 0; i < nrOfArgs; i +=1) {
dyn_type *type = dynFunction_argumentTypeForIndex(func, i);
- const char *argMeta = dynType_getMetaInfo(type, "am");
- if (argMeta == NULL) {
+ enum dyn_function_argument_meta meta = dynFunction_argumentMetaForIndex(func, i);
+ if (meta == DYN_FUNCTION_ARGUMENT_META__STD) {
json_t *val = NULL;
int rc = jsonSerializer_serializeJson(type, args[i], &val);
@@ -225,31 +224,51 @@ int jsonRpc_prepareInvokeRequest(dyn_function_type *func, const char *id, void *
}
int jsonRpc_handleReply(dyn_function_type *func, const char *reply, void *args[]) {
- int status = 0;
+ int status = OK;
- json_t *replyJson = json_loads(reply, JSON_DECODE_ANY, NULL); //TODO check
- json_t *result = json_object_get(replyJson, "r"); //TODO check
+ json_error_t error;
+ json_t *replyJson = json_loads(reply, JSON_DECODE_ANY, &error);
+ if (replyJson == NULL) {
+ status = ERROR;
+ LOG_ERROR("Error parsing json '%s', got error '%s'", reply, error.text);
+ }
- LOG_DEBUG("replyJson ptr is %p and result ptr is %p\n", replyJson, result);
+ json_t *result = NULL;
+ if (status == OK) {
+ result = json_object_get(replyJson, "r"); //TODO check
+ if (result == NULL) {
+ status = ERROR;
+ LOG_ERROR("Cannot find r entry in json reply '%s'", reply);
+ }
+ }
- int nrOfArgs = dynFunction_nrOfArguments(func);
- int i;
- for (i = 0; i < nrOfArgs; i += 1) {
- dyn_type *argType = dynFunction_argumentTypeForIndex(func, i);
- const char *argMeta = dynType_getMetaInfo(argType, "am");
- if (argMeta == NULL) {
- //skip
- } else if (strcmp(argMeta, "pre") == 0) {
- dyn_type *subType = NULL;
- dynType_typedPointer_getTypedType(argType, &subType);
- void *tmp = NULL;
- size_t size = dynType_size(subType);
- status = jsonSerializer_deserializeJson(subType, result, &tmp);
- void **out = (void **)args[i];
- memcpy(*out, tmp, size);
- dynType_free(subType, tmp);
- } else if (strcmp(argMeta, "out") == 0) {
- assert(false); //TODO
+ if (status == OK) {
+ int nrOfArgs = dynFunction_nrOfArguments(func);
+ int i;
+ for (i = 0; i < nrOfArgs; i += 1) {
+ dyn_type *argType = dynFunction_argumentTypeForIndex(func, i);
+ enum dyn_function_argument_meta meta = dynFunction_argumentMetaForIndex(func, i);
+ if (meta == DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT) {
+ //FIXME need a tmp because deserialize does always does a create (add option?)
+ dyn_type *subType = NULL;
+ dynType_typedPointer_getTypedType(argType, &subType);
+ void *tmp = NULL;
+ size_t size = dynType_size(subType);
+ status = jsonSerializer_deserializeJson(subType, result, &tmp);
+ void **out = (void **)args[i];
+ memcpy(*out, tmp, size);
+ dynType_free(subType, tmp);
+ } else if (meta == DYN_FUNCTION_ARGUMENT_META__OUTPUT) {
+ dyn_type *subType = NULL;
+ dynType_typedPointer_getTypedType(argType, &subType);
+ dyn_type *subSubType = NULL;
+ dynType_typedPointer_getTypedType(subType, &subSubType);
+ void ***out = (void **)args[i];
+ //status = jsonSerializer_deserializeJson(subType, result, *out);
+ status = jsonSerializer_deserializeJson(subSubType, result, *out);
+ } else {
+ //skip
+ }
}
}
http://git-wip-us.apache.org/repos/asf/celix/blob/2d6ef1ba/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/json_rpc_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/json_rpc_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/json_rpc_tests.cpp
index 5e116a5..6ebf1c3 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/json_rpc_tests.cpp
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface_tst/json_rpc_tests.cpp
@@ -59,7 +59,7 @@ static void stdLog(void *handle, int level, const char *file, int line, const ch
dynFunction_destroy(dynFunc);
}
- void handleTest(void) {
+ void handleTestPre(void) {
dyn_function_type *dynFunc = NULL;
int rc = dynFunction_parseWithStr("add(#am=handle;PDD#am=pre;*D)N", NULL, &dynFunc);
CHECK_EQUAL(0, rc);
@@ -182,6 +182,45 @@ static void stdLog(void *handle, int level, const char *file, int line, const ch
dynInterface_destroy(intf);
}
+ void handleTestOut(void) {
+ dyn_interface_type *intf = NULL;
+ FILE *desc = fopen("descriptors/example1.descriptor", "r");
+ CHECK(desc != NULL);
+ int rc = dynInterface_parse(desc, &intf);
+ CHECK_EQUAL(0, rc);
+
+ struct methods_head *head;
+ dynInterface_methods(intf, &head);
+ dyn_function_type *func = NULL;
+ struct method_entry *entry = NULL;
+ TAILQ_FOREACH(entry, head, entries) {
+ if (strcmp(entry->name, "stats") == 0) {
+ func = entry->dynFunc;
+ break;
+ }
+ }
+ CHECK(func != NULL);
+
+ const char *reply = "{\"r\":{\"input\":[1.0,2.0],\"max\":2.0,\"average\":1.5,\"min\":1.0}}";
+
+ void *args[3];
+ args[0] = NULL;
+ args[1] = NULL;
+ args[2] = NULL;
+
+ struct tst_StatsResult *result = NULL;
+ void *out = &result;
+ args[2] = &out;
+
+ rc = jsonRpc_handleReply(func, reply, args);
+ CHECK_EQUAL(0, rc);
+ CHECK_EQUAL(1.5, result->average);
+
+ free(result->input.buf);
+ free(result);
+ dynInterface_destroy(intf);
+ }
+
}
TEST_GROUP(JsonRpcTests) {
@@ -202,8 +241,12 @@ TEST(JsonRpcTests, prepareTest) {
prepareTest();
}
-TEST(JsonRpcTests, handleTest) {
- handleTest();
+TEST(JsonRpcTests, handleTestPre) {
+ handleTestPre();
+}
+
+TEST(JsonRpcTests, handleTestOut) {
+ handleTestOut();
}
TEST(JsonRpcTests, callPre) {