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)