CELIX-237: Moved some json / argument handling from export/import_registration to json_serializer. Still need to add some tests
Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/25223306 Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/25223306 Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/25223306 Branch: refs/heads/develop Commit: 25223306e59d4fd084e94f700c419456bbf7dcda Parents: 62ede18 Author: Pepijn Noltes <[email protected]> Authored: Wed Aug 12 21:45:27 2015 +0200 Committer: Pepijn Noltes <[email protected]> Committed: Wed Aug 12 21:45:27 2015 +0200 ---------------------------------------------------------------------- .../dynamic_function_interface/dyn_function.c | 8 +- .../dynamic_function_interface/dyn_function.h | 5 +- .../json_serializer.c | 120 +++++++++++++++++++ .../json_serializer.h | 7 ++ .../tst/dyn_function_tests.cpp | 4 +- .../private/src/export_registration_dfi.c | 93 ++------------ .../private/src/import_registration_dfi.c | 52 +++----- 7 files changed, 162 insertions(+), 127 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/25223306/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 8880bc7..06f6aaa 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 @@ -116,7 +116,7 @@ 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; + int argMetaInfo = DYN_FUNCTION_ARG_META_INPUT_TYPE; char argName[32]; while (nextChar != ')' && status == 0) { ungetc(nextChar, descriptor); @@ -175,7 +175,7 @@ static void dynFunction_parseArgMeta(FILE *descriptor, int *meta) { switch (c) { case '~' : - *meta = DYN_FUNCTION_ARG_META_OUPUT_TYPE; + *meta = DYN_FUNCTION_ARG_META_OUTPUT_TYPE; break; case '^' : *meta = DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE; @@ -184,7 +184,7 @@ static void dynFunction_parseArgMeta(FILE *descriptor, int *meta) { *meta = DYN_FUNCTION_ARG_META_HANDLE_TYPE; break; default : - *meta = DYN_FUNCTION_ARG_META_STD_TYPE; + *meta = DYN_FUNCTION_ARG_META_INPUT_TYPE; ungetc(c, descriptor); break; } @@ -197,7 +197,7 @@ static int dynFunction_checkArgument(dyn_function_argument_type *argument) { if (dynType_type(argument->type) != DYN_TYPE_TYPED_POINTER) { status = ERROR; } - } else if (argument->argumentType == DYN_FUNCTION_ARG_META_OUPUT_TYPE) { + } else if (argument->argumentType == DYN_FUNCTION_ARG_META_OUTPUT_TYPE) { //expect atleast two ** if (dynType_type(argument->type) == DYN_TYPE_TYPED_POINTER) { dyn_type *subType = NULL; http://git-wip-us.apache.org/repos/asf/celix/blob/25223306/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 733c092..5cbf686 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 @@ -21,10 +21,11 @@ //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_INPUT_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_OUTPUT_TYPE 3 #define DYN_FUNCTION_ARG_META_HANDLE_TYPE 4 +//TODO input/output types? typedef struct _dyn_function_type dyn_function_type; http://git-wip-us.apache.org/repos/asf/celix/blob/25223306/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c index cf9a0ee..a2cc34e 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c @@ -414,4 +414,124 @@ static int jsonSerializer_writeComplex(dyn_type *type, void *input, json_t **out } return status; +} + +int jsonSerializer_call(dyn_function_type *func, void *handle, void (*fp)(void), json_t *arguments, json_t **out) { + int status = OK; + + int nrOfArgs = dynFunction_nrOfArguments(func); + void *args[nrOfArgs]; + + + + json_t *value = NULL; + + int i; + int index = 0; + for (i = 0; i < nrOfArgs; i += 1) { + int metaInfo = dynFunction_argumentMetaInfoForIndex(func, i); + dyn_type *argType = dynFunction_argumentTypeForIndex(func, 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_OUTPUT_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] = &handle; + } else { + printf("setting std for %i\n", i); + value = json_array_get(arguments, index++); + status = jsonSerializer_deserializeJson(argType, value, &(args[i])); + } + + if (status != OK) { + break; + } + } + + + //TODO assert return type is native int + int returnVal = 0; + dynFunction_call(func, fp, (void *)&returnVal, args); + printf("done calling\n"); + double **r = args[2]; + printf("result ptrptr is %p, result ptr %p, result is %f\n", r, *r, **r); + + for (i = 0; i < nrOfArgs; i += 1) { + int metaInfo = dynFunction_argumentMetaInfoForIndex(func, i); + dyn_type *argType = dynFunction_argumentTypeForIndex(func, i); + if (metaInfo == DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE) { + if (status == OK) { + status = jsonSerializer_serializeJson(argType, args[i], out); + } + } else if (metaInfo == DYN_FUNCTION_ARG_META_OUTPUT_TYPE) { + printf("TODO\n"); + assert(false); + } + + if (status != OK) { + break; + } + } + + //TODO free args (created by jsonSerializer and dynType_alloc) (dynType_free) + return status; +} + +int jsonSerializer_prepareArguments(dyn_function_type *func, void *args[], json_t **out) { + int status = OK; + json_t *arguments = json_array(); + + int i; + int nrOfArgs = dynFunction_nrOfArguments(func); + + for (i = 0; i < nrOfArgs; i +=1) { + if (dynFunction_argumentMetaInfoForIndex(func, i) == DYN_FUNCTION_ARG_META_INPUT_TYPE) { + json_t *val = NULL; + dyn_type *type = dynFunction_argumentTypeForIndex(func, i); + int rc = jsonSerializer_serializeJson(type, args[i], &val); + if (rc == 0) { + json_array_append_new(arguments, val); + } else { + status = ERROR; + break; + } + } else { + //skip handle / output types + } + } + + if (status == OK) { + *out = arguments; + } + + return status; +} + +int jsonSerializer_handleReply(dyn_function_type *func, void *handle, json_t *reply, void *args[]) { + int status = 0; + + int nrOfArgs = dynFunction_nrOfArguments(func); + int i; + for (i = 0; i < nrOfArgs; i += 1) { + dyn_type *argType = dynFunction_argumentTypeForIndex(func, i); + int metaInf = dynFunction_argumentMetaInfoForIndex(func, i); + if (metaInf == DYN_FUNCTION_ARG_META_PRE_ALLOCATED_OUTPUT_TYPE) { + void **tmp = NULL; + void **out = (void **)args[i]; + size_t size = dynType_size(argType); + status = jsonSerializer_deserializeJson(argType, reply, (void **)&tmp); + memcpy(*out, *tmp, size); + dynType_free(argType, tmp); + } else if (metaInf == DYN_FUNCTION_ARG_META_OUTPUT_TYPE) { + assert(false); //TODO + } else { + //skipt handle and input types + } + } + + return status; } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/25223306/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h index 9999aea..0853114 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h @@ -7,6 +7,7 @@ #include <jansson.h> #include "dfi_log_util.h" #include "dyn_type.h" +#include "dyn_function.h" //logging DFI_SETUP_LOG_HEADER(jsonSerializer); @@ -17,4 +18,10 @@ int jsonSerializer_deserializeJson(dyn_type *type, json_t *input, void **result) int jsonSerializer_serialize(dyn_type *type, void *input, char **output); int jsonSerializer_serializeJson(dyn_type *type, void *input, json_t **out); +//input should be a json array with with the std args +int jsonSerializer_call(dyn_function_type *func, void *handle, void (*fp)(void), json_t *arguments, json_t **result); + +int jsonSerializer_prepareArguments(dyn_function_type *func, void *args[], json_t **arguments); +int jsonSerializer_handleReply(dyn_function_type *func, void *handle, json_t *reply, void *args[]); + #endif http://git-wip-us.apache.org/repos/asf/celix/blob/25223306/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 ab5f33e..cb4e13b 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 @@ -174,9 +174,9 @@ extern "C" { 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_INPUT_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_OUTPUT_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); http://git-wip-us.apache.org/repos/asf/celix/blob/25223306/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 c763222..cc181b3 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 @@ -99,10 +99,13 @@ celix_status_t exportRegistration_call(export_registration_pt export, char *data printf("Parsing data: %s\n", data); json_error_t error; json_t *js_request = json_loads(data, 0, &error); + json_t *arguments = NULL; const char *sig; if (js_request) { if (json_unpack(js_request, "{s:s}", "m", &sig) != 0) { printf("RSA: Got error '%s'\n", error.text); + } else { + arguments = json_object_get(js_request, "a"); } } else { printf("RSA: got error '%s' for '%s'\n", error.text, data); @@ -110,7 +113,6 @@ celix_status_t exportRegistration_call(export_registration_pt export, char *data } printf("RSA: Looking for method %s\n", sig); - struct methods_head *methods = NULL; dynInterface_methods(export->intf, &methods); struct method_entry *entry = NULL; @@ -131,100 +133,27 @@ celix_status_t exportRegistration_call(export_registration_pt export, char *data if (method != NULL) { struct generic_service_layout *serv = export->service; + void *handle = serv->handle; + void (*fp)(void) = serv->methods[method->index]; - int nrOfArgs = dynFunction_nrOfArguments(method->dynFunc); - void *args[nrOfArgs]; - - json_t *arguments = json_object_get(js_request, "a"); - json_t *value = NULL; - - 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 { - printf("setting std for %i\n", i); - value = json_array_get(arguments, index++); - status = jsonSerializer_deserializeJson(argType, value, &(args[i])); - } - - if (status != CELIX_SUCCESS) { - break; - } - } + json_t *result = NULL; + status = jsonSerializer_call(method->dynFunc, handle, fp, arguments, &result); json_decref(js_request); - /* - //TODO assert last is output pointer (e.g. double pointer) - dyn_type *lastTypePtr = dynFunction_argumentTypeForIndex(method->dynFunc, nrOfArgs-1); - dyn_type *lastType = NULL; - dynType_typedPointer_getTypedType(lastTypePtr, &lastType); - - - void *out = NULL; - dynType_alloc(lastType, &out); //TODO, NOTE only for simple types or single pointer types.. TODO check - - //NOTE !! Need to access out, else it is a dummy pointer which will result in errors. - char b; - memcpy(&b, out, 1); - - 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; - dynFunction_call(method->dynFunc, serv->methods[method->index], (void *)&returnVal, args); - 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; - - 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); + json_object_set_new(payload, "r", result); char *response = json_dumps(payload, JSON_DECODE_ANY); - json_decref(payload); + printf("status ptr is %p. response if '%s'\n", status, response); *responseOut = response; *responseLength = -1; - } - - //TODO free args (created by jsonSerializer and dynType_alloc) (dynType_free) + json_decref(payload); + } ///TODO add more status checks } http://git-wip-us.apache.org/repos/asf/celix/blob/25223306/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c b/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c index 985d94d..20ff61d 100644 --- a/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c +++ b/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c @@ -214,36 +214,24 @@ static celix_status_t importRegistration_createProxy(import_registration_pt impo static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal) { int status = CELIX_SUCCESS; struct method_entry *entry = userData; + import_registration_pt import = *((void **)args[0]); - printf("Calling function '%s'\n", entry->id); + printf("Calling remote function '%s'\n", entry->id); json_t *invoke = json_object(); json_object_set(invoke, "m", json_string(entry->id)); - json_t *jsonArgs = json_array(); - json_object_set(invoke, "a", jsonArgs); - json_decref(jsonArgs); - - int i; - int nrOfArgs = dynFunction_nrOfArguments(entry->dynFunc); - import_registration_pt import = *((void **)args[0]); + json_t *arguments = NULL; - for (i = 1; i < nrOfArgs -1; i +=1) { //note 0 = handle, last = output - json_t *val = NULL; - dyn_type *type = dynFunction_argumentTypeForIndex(entry->dynFunc, i); - int rc = jsonSerializer_serializeJson(type, args[i], &val); - if (rc == 0) { - json_array_append_new(jsonArgs, val); - } else { - status = CELIX_ILLEGAL_ARGUMENT; - break; - } + status = jsonSerializer_prepareArguments(entry->dynFunc, args, &arguments); + if (status == CELIX_SUCCESS) { + json_object_set_new(invoke, "a", arguments); } - char *output = json_dumps(invoke, JSON_DECODE_ANY); + json_decref(invoke); + printf("Need to send following json '%s'\n", output); - printf("import is %p\n", import); if (import != NULL && import->send != NULL) { char *reply = NULL; int rc = 0; @@ -253,32 +241,22 @@ static void importRegistration_proxyFunc(void *userData, void *args[], void *ret json_t *replyJson = json_loads(reply, JSON_DECODE_ANY, NULL); //TODO check json_t *result = json_object_get(replyJson, "r"); //TODO check + status = jsonSerializer_handleReply(entry->dynFunc, NULL, result, args); + json_decref(result); + - printf("replyJson p is %p and result is %p\n", replyJson, result); - - if (rc == 0) { - dyn_type *lastPtr = dynFunction_argumentTypeForIndex(entry->dynFunc, nrOfArgs - 1); - dyn_type *lastType = NULL; - dynType_typedPointer_getTypedType(lastPtr, &lastType); - if (rc == CELIX_SUCCESS) { - void *tmp = NULL; - rc = jsonSerializer_deserializeJson(lastType, result, &tmp); - void **out = (void **)args[nrOfArgs-1]; - memcpy(*out, tmp, dynType_size(lastType)); - dynType_free(lastType, tmp); //TODO only for simple types -> eg complex type will be alloc by callee - } - json_decref(replyJson); - int *returnInt = returnVal; - *returnInt = status; + if (status == 0) { printf("done with proxy func\n"); } } else { printf("Error import of import->send is NULL\n"); } - json_decref(invoke); + //TODO assert double check if return type is native int + int *rVal = returnVal; + *rVal = status; } celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) {
