celix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pnol...@apache.org
Subject celix git commit: CELIX-237: Added support for handling reply for output pointers.
Date Mon, 07 Sep 2015 11:44:58 GMT
Repository: celix
Updated Branches:
  refs/heads/feature/CELIX-237_rsa-ffi f99de6ed1 -> 2d6ef1ba8


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/feature/CELIX-237_rsa-ffi
Commit: 2d6ef1ba83abee0a62b6aa726dbaed4cea4f1742
Parents: f99de6e
Author: Pepijn Noltes <pepijnnoltes@gmail.com>
Authored: Mon Sep 7 13:44:11 2015 +0200
Committer: Pepijn Noltes <pepijnnoltes@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) {


Mime
View raw message