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/07/31 22:57:30 UTC
[01/10] celix git commit: CELIX-237: Added extra test
Repository: celix
Updated Branches:
refs/heads/feature/CELIX-237_rsa-ffi f9ed9b33b -> 481e5c861
CELIX-237: Added extra test
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/a2b09e22
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/a2b09e22
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/a2b09e22
Branch: refs/heads/feature/CELIX-237_rsa-ffi
Commit: a2b09e223114b509a01209d418cd479bb09e4b7c
Parents: f9ed9b3
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri Jul 31 15:57:42 2015 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri Jul 31 15:57:42 2015 +0200
----------------------------------------------------------------------
.../dynamic_function_interface/dyn_type.c | 4 ++--
.../dynamic_function_interface/dyn_type.h | 2 ++
.../tst/dyn_type_tests.cpp | 15 +++++++++++++++
3 files changed, 19 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/a2b09e22/remote_services/dynamic_function_interface/dyn_type.c
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/dyn_type.c b/remote_services/dynamic_function_interface/dyn_type.c
index af98fe9..2946607 100644
--- a/remote_services/dynamic_function_interface/dyn_type.c
+++ b/remote_services/dynamic_function_interface/dyn_type.c
@@ -595,7 +595,7 @@ void dynType_free(dyn_type *type, void *loc) {
void dynType_deepFree(dyn_type *type, void *loc, bool alsoDeleteSelf) {
if (loc != NULL) {
dyn_type *subType = NULL;
- const char *text = NULL;
+ char *text = NULL;
switch (type->type) {
case DYN_TYPE_COMPLEX :
dynType_freeComplexType(type, loc);
@@ -608,7 +608,7 @@ void dynType_deepFree(dyn_type *type, void *loc, bool alsoDeleteSelf) {
dynType_deepFree(subType, *(void **)loc, true);
break;
case DYN_TYPE_TEXT :
- text = *(const char **)loc;
+ text = *(char **)loc;
free(text);
break;
}
http://git-wip-us.apache.org/repos/asf/celix/blob/a2b09e22/remote_services/dynamic_function_interface/dyn_type.h
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/dyn_type.h b/remote_services/dynamic_function_interface/dyn_type.h
index c4f33a2..9fdbff2 100644
--- a/remote_services/dynamic_function_interface/dyn_type.h
+++ b/remote_services/dynamic_function_interface/dyn_type.h
@@ -128,8 +128,10 @@ int dynType_sequence_increaseLengthAndReturnLastLoc(dyn_type *type, void *seqLoc
dyn_type * dynType_sequence_itemType(dyn_type *type);
uint32_t dynType_sequence_length(void *seqLoc);
+//typed pointer
int dynType_typedPointer_getTypedType(dyn_type *type, dyn_type **typedType);
+//text
int dynType_text_allocAndInit(dyn_type *type, void *textLoc, const char *value);
//simple
http://git-wip-us.apache.org/repos/asf/celix/blob/a2b09e22/remote_services/dynamic_function_interface/tst/dyn_type_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/tst/dyn_type_tests.cpp b/remote_services/dynamic_function_interface/tst/dyn_type_tests.cpp
index daee4cf..96f64fa 100644
--- a/remote_services/dynamic_function_interface/tst/dyn_type_tests.cpp
+++ b/remote_services/dynamic_function_interface/tst/dyn_type_tests.cpp
@@ -173,3 +173,18 @@ TEST(DynTypeTests, AssignTest2) {
dynType_destroy(type);
}
+
+TEST(DynTypeTests, AssignTest3) {
+ int simple = 1;
+ dyn_type *type = NULL;
+ int rc = dynType_parseWithStr("N", NULL, NULL, &type);
+ CHECK_EQUAL(0, rc);
+
+ int newValue = 42;
+ void *loc = &simple;
+ void *input = &newValue;
+ dynType_simple_setValue(type, loc, input);
+ CHECK_EQUAL(42, simple);
+ dynType_destroy(type);
+}
+
[09/10] celix git commit: CELIX-237: initial setup for rsa dfi testing
Posted by pn...@apache.org.
CELIX-237: initial setup for rsa dfi testing
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/1e618fb1
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/1e618fb1
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/1e618fb1
Branch: refs/heads/feature/CELIX-237_rsa-ffi
Commit: 1e618fb14061a04d43174291dde729c928e76a3f
Parents: 2f56576
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri Jul 31 21:45:10 2015 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri Jul 31 21:45:10 2015 +0200
----------------------------------------------------------------------
launcher/private/src/launcher.c | 19 +++++++++++-----
launcher/private/src/main.c | 1 +
launcher/public/include/launcher.h | 3 +++
.../remote_service_admin_dfi/tst/CMakeLists.txt | 23 ++++++++++++++++++++
.../tst/config.properties.in | 1 +
.../remote_service_admin_dfi/tst/run_tests.cpp | 18 +++++++++++++++
6 files changed, 60 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/1e618fb1/launcher/private/src/launcher.c
----------------------------------------------------------------------
diff --git a/launcher/private/src/launcher.c b/launcher/private/src/launcher.c
index 6d09fc4..9292ffb 100644
--- a/launcher/private/src/launcher.c
+++ b/launcher/private/src/launcher.c
@@ -40,6 +40,8 @@
static void launcher_shutdown(int signal);
static struct framework * framework;
+static properties_pt config;
+
#ifdef WITH_APR
static apr_pool_t *memoryPool;
#endif
@@ -60,7 +62,7 @@ int celixLauncher_launch(const char *configFile) {
int celixLauncher_launchWithStream(FILE *stream) {
int status = 0;
- properties_pt config = properties_loadWithStream(stream);
+ config = properties_loadWithStream(stream);
fclose(stream);
// Make sure we've read it and that nothing went wrong with the file access...
if (config == NULL) {
@@ -154,10 +156,6 @@ int celixLauncher_launchWithStream(FILE *stream) {
}
arrayList_destroy(installed);
-
- framework_waitForStop(framework);
- framework_destroy(framework);
- properties_destroy(config);
}
}
@@ -179,6 +177,17 @@ int celixLauncher_launchWithStream(FILE *stream) {
return status;
}
+void celixLauncher_waitForShutdown(void) {
+ framework_waitForStop(framework);
+ framework_destroy(framework);
+ properties_destroy(config);
+}
+
+
+struct framework *celixLauncher_getFramework(void) {
+ return framework;
+}
+
static void launcher_shutdown(int signal) {
bundle_pt fwBundle = NULL;
framework_getFrameworkBundle(framework, &fwBundle);
http://git-wip-us.apache.org/repos/asf/celix/blob/1e618fb1/launcher/private/src/main.c
----------------------------------------------------------------------
diff --git a/launcher/private/src/main.c b/launcher/private/src/main.c
index 0a59bc4..b6d3033 100644
--- a/launcher/private/src/main.c
+++ b/launcher/private/src/main.c
@@ -55,6 +55,7 @@ int main(int argc, char *argv[]) {
}
celixLauncher_launch(config_file);
+ celixLauncher_waitForShutdown();
}
static void show_usage(char* prog_name) {
http://git-wip-us.apache.org/repos/asf/celix/blob/1e618fb1/launcher/public/include/launcher.h
----------------------------------------------------------------------
diff --git a/launcher/public/include/launcher.h b/launcher/public/include/launcher.h
index 296df7c..f95e160 100644
--- a/launcher/public/include/launcher.h
+++ b/launcher/public/include/launcher.h
@@ -28,8 +28,11 @@
#define CELIX_LAUNCHER_H
#include <stdio.h>
+#include "framework.h"
int celixLauncher_launch(const char *configFile);
int celixLauncher_launchWithStream(FILE *config);
+void celixLauncher_waitForShutdown(void);
+struct framework *celixLauncher_getFramework(void);
#endif //CELIX_LAUNCHER_H
http://git-wip-us.apache.org/repos/asf/celix/blob/1e618fb1/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt b/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt
new file mode 100644
index 0000000..fb1834a
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt
@@ -0,0 +1,23 @@
+#
+# Licensed under Apache License v2. See LICENSE for more information.
+#
+
+include_directories(
+ ${PROJECT_SOURCE_DIR}/launcher/public
+ ${CPPUTEST_INCLUDE_DIR}
+)
+
+
+#if (FRAMEWORK_TESTS) TODO
+ add_executable(rsa_dfi_tests
+ ${PROJECT_SOURCE_DIR}/launcher/private/src/launcher
+ tst/run_tests.cpp
+ )
+ target_link_libraries(rsa_dfi_tests ${CPPUTEST_LIBRARY}) #TODO add celix/launcer etc
+
+ get_property(rsa_bundle_file TARGET remote_service_admin_dfi PROPERTY BUNDLE)
+ configure_file(config.properties.in config-rsa.properties @ONLY)
+
+ add_test(NAME run_rsa_dfi_tests COMMAND rsa_dfi_tests)
+ SETUP_TARGET_FOR_COVERAGE(rsa_dfi_tests_cov rsa_dfi_tests ${CMAKE_BINARY_DIR}/coverage/rsa_dfi)
+#endif()
http://git-wip-us.apache.org/repos/asf/celix/blob/1e618fb1/remote_services/remote_service_admin_dfi/tst/config.properties.in
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/tst/config.properties.in b/remote_services/remote_service_admin_dfi/tst/config.properties.in
new file mode 100644
index 0000000..b926f36
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/tst/config.properties.in
@@ -0,0 +1 @@
+cosgi.auto.start.1=@rsa_bundle_file@
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/1e618fb1/remote_services/remote_service_admin_dfi/tst/run_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/tst/run_tests.cpp b/remote_services/remote_service_admin_dfi/tst/run_tests.cpp
new file mode 100644
index 0000000..b5f29e7
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/tst/run_tests.cpp
@@ -0,0 +1,18 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"
+
+#include <stdio.h>
+
+#include "launcher.h"
+
+
+int main(int argc, char** argv) {
+ celixLauncher_launch("config.properties");
+ int rc = RUN_ALL_TESTS(argc, argv);
+ framework_stop((celixLauncher_getFramework()));
+ celixLauncher_waitForShutdown();
+ return rc;
+}
\ No newline at end of file
[02/10] celix git commit: CELIX-237: Moved dynamic function interface
under remote_service_admin_dfi
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/open_memstream.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/open_memstream.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/open_memstream.h
new file mode 100644
index 0000000..e87bb0a
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/open_memstream.h
@@ -0,0 +1,15 @@
+#ifndef OPEN_MEMSTREAM_H_
+#define OPEN_MEMSTREAM_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+FILE *open_memstream(char **cp, size_t *lenp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef FMEMOPEN_H_
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/complex.avdl
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/complex.avdl b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/complex.avdl
new file mode 100644
index 0000000..0490dcd
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/complex.avdl
@@ -0,0 +1,11 @@
+protocol Complex {
+
+ record StatResult {
+ double sum;
+ double min;
+ double max;
+ array<double> input;
+ }
+
+ StatResult stats(array<double> input);
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/complex.avpr
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/complex.avpr b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/complex.avpr
new file mode 100644
index 0000000..0577397
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/complex.avpr
@@ -0,0 +1,36 @@
+{
+ "protocol" : "Complex",
+ "namespace" : null,
+ "types" : [ {
+ "type" : "record",
+ "name" : "StatResult",
+ "fields" : [ {
+ "name" : "sum",
+ "type" : "double"
+ }, {
+ "name" : "min",
+ "type" : "double"
+ }, {
+ "name" : "max",
+ "type" : "double"
+ }, {
+ "name" : "input",
+ "type" : {
+ "type" : "array",
+ "items" : "double"
+ }
+ } ]
+ } ],
+ "messages" : {
+ "stats" : {
+ "request" : [ {
+ "name" : "input",
+ "type" : {
+ "type" : "array",
+ "items" : "double"
+ }
+ } ],
+ "response" : "StatResult"
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/invalid1.avpr
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/invalid1.avpr b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/invalid1.avpr
new file mode 100644
index 0000000..c968c61
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/invalid1.avpr
@@ -0,0 +1,29 @@
+{
+ "protocol" : "Complex",
+ "namespace" : null,
+ "types" : [ {
+ "type" : "record",
+ "name" : "StatResult",
+ "fields" : [ {
+ "name" : "sum",
+ "type" : "double"
+ }, {
+ "name" : "min",
+ "type" : "double"
+ }, {
+ "name" : "max",
+ "type" : "double"
+ }, {
+ "name" : "input",
+ "type" : {
+ "type" : "array",
+ "items" : "double"
+ }
+ } ]
+ } ],
+ "messages" : {
+ "stats" : {
+ "response" : "StatResult"
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/invalid2.avpr
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/invalid2.avpr b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/invalid2.avpr
new file mode 100644
index 0000000..fc48ca9
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/invalid2.avpr
@@ -0,0 +1,31 @@
+{
+ "protocol" : "Simple",
+ "types" : [ ],
+ "messages" : {
+ "sum" : {
+ "request" : [ {
+ "name" : "a"
+ }, {
+ "name" : "b",
+ "type" : "double"
+ } ],
+ "response" : "double"
+ },
+ "sub" : {
+ "request" : [ {
+ "name" : "a",
+ "type" : "double"
+ }, {
+ "name" : "b",
+ "type" : "double"
+ } ],
+ "response" : "double"
+ },
+ "sqrt" : {
+ "request" : [ {
+ "name" : "a"
+ } ],
+ "response" : "double"
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/simple.avdl
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/simple.avdl b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/simple.avdl
new file mode 100644
index 0000000..cd5cafe
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/simple.avdl
@@ -0,0 +1,6 @@
+@namespace("org.apache.avro.test")
+protocol Simple {
+ double sum(double a, double b);
+ double sub(double a, double b);
+ double sqrt(double a);
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/simple.avpr
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/simple.avpr b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/simple.avpr
new file mode 100644
index 0000000..8a90bb2
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/simple.avpr
@@ -0,0 +1,33 @@
+{
+ "protocol" : "Simple",
+ "types" : [ ],
+ "messages" : {
+ "sum" : {
+ "request" : [ {
+ "name" : "a",
+ "type" : "double"
+ }, {
+ "name" : "b",
+ "type" : "double"
+ } ],
+ "response" : "double"
+ },
+ "sub" : {
+ "request" : [ {
+ "name" : "a",
+ "type" : "double"
+ }, {
+ "name" : "b",
+ "type" : "double"
+ } ],
+ "response" : "double"
+ },
+ "sqrt" : {
+ "request" : [ {
+ "name" : "a",
+ "type" : "double"
+ } ],
+ "response" : "double"
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/simple_min.avpr
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/simple_min.avpr b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/simple_min.avpr
new file mode 100644
index 0000000..c2bce19
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/schemas/simple_min.avpr
@@ -0,0 +1 @@
+{"protocol":"Simple","types":[],"messages":{"sum":{"request":[{"name":"a","type":"double"},{"name":"b","type":"double"}],"response":"double"},"sub":{"request":[{"name":"a","type":"double"},{"name":"b","type":"double"}],"response":"double"},"sqrt":{"request":[{"name":"a","type":"double"}],"response":"double"}}}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/avro_descriptor_translator_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/avro_descriptor_translator_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/avro_descriptor_translator_tests.cpp
new file mode 100644
index 0000000..63401e5
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/avro_descriptor_translator_tests.cpp
@@ -0,0 +1,164 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"
+
+extern "C" {
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+#include "dyn_common.h"
+#include "descriptor_translator.h"
+
+#if defined(BSD) || defined(__APPLE__)
+#include "open_memstream.h"
+#include "fmemopen.h"
+#endif
+
+ static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
+ va_list ap;
+ const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
+ fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ fprintf(stderr, "\n");
+ }
+
+
+ static char *readSchema(const char *file) {
+ size_t size = 0;
+ char *ptr = NULL;
+
+ FILE *schema = fopen(file, "r");
+ FILE *stream = open_memstream(&ptr, &size);
+
+ assert(schema != NULL);
+ assert(stream != NULL);
+
+ int c = fgetc(schema);
+ while (c != EOF ) {
+ fputc(c, stream);
+ c = fgetc(schema);
+ }
+ fclose(schema);
+ fclose(stream);
+
+ assert(ptr != NULL);
+ return ptr;
+ }
+
+ static dyn_interface_type *createInterfaceInfo(const char *schemaFile) {
+ char *schema = readSchema(schemaFile);
+ dyn_interface_type *ift= NULL;
+
+ int status = descriptorTranslator_translate(schema, &ift);
+ CHECK_EQUAL(0, status);
+
+ free(schema);
+ return ift;
+ }
+
+ static int countMethodInfos(dyn_interface_type *info) {
+ int count = 0;
+ method_info_type *mInfo = NULL;
+ TAILQ_FOREACH(mInfo, &info->methodInfos, entries) {
+ count +=1;
+ }
+ return count;
+ }
+
+ static int countTypeInfos(dyn_interface_type *info) {
+ int count = 0;
+ type_info_type *tInfo = NULL;
+ TAILQ_FOREACH(tInfo, &info->typeInfos, entries) {
+ count +=1;
+ }
+ return count;
+ }
+
+ static void simple(void) {
+ //first argument void *handle, last argument output pointer for result and return int with status for exception handling
+ //sum(DD)D -> sum(PDD*D)N
+ //sub(DD)D -> sub(PDD*D)N
+ //sqrt(D)D -> sqrt(PD*D)N
+
+ dyn_interface_type *intf = createInterfaceInfo("schemas/simple.avpr");
+
+ int count = countMethodInfos(intf);
+ CHECK_EQUAL(3, count);
+
+ count = countTypeInfos(intf);
+ CHECK_EQUAL(0, count);
+
+ method_info_type *mInfo = NULL;
+ TAILQ_FOREACH(mInfo, &intf->methodInfos, entries) {
+ if (strcmp("sum", mInfo->name) == 0) {
+ STRCMP_EQUAL("sum(PDD*D)N", mInfo->descriptor);
+ } else if (strcmp("add", mInfo->name) == 0) {
+ STRCMP_EQUAL("add(PDD*D)N", mInfo->descriptor);
+ } else if (strcmp("sqrt", mInfo->name) == 0) {
+ STRCMP_EQUAL("sqrt(PD*D)N", mInfo->descriptor);
+ }
+ }
+
+ dynInterface_destroy(intf);
+ }
+
+ static void complex(void) {
+ dyn_interface_type *intf = createInterfaceInfo("schemas/complex.avpr");
+
+ int count = countMethodInfos(intf);
+ CHECK_EQUAL(1, count);
+
+ method_info_type *mInfo = TAILQ_FIRST(&intf->methodInfos);
+ STRCMP_EQUAL("stats", mInfo->name);
+ STRCMP_EQUAL("stats(P[D*LStatResult;)N", mInfo->descriptor);
+
+ count = countTypeInfos(intf);
+ CHECK_EQUAL(1, count);
+
+ type_info_type *tInfo = TAILQ_FIRST(&intf->typeInfos);
+ STRCMP_EQUAL("StatResult", tInfo->name);
+ STRCMP_EQUAL("{DDD[D sum min max input}", tInfo->descriptor);
+
+ dynInterface_destroy(intf);
+ }
+
+ static void invalid(const char *file) {
+ char *schema = readSchema(file);
+ dyn_interface_type *ift= NULL;
+
+ int status = descriptorTranslator_translate(schema, &ift);
+ CHECK(status != 0);
+
+ free(schema);
+ }
+}
+
+TEST_GROUP(AvroDescTranslatorTest) {
+ void setup() {
+ descriptorTranslator_logSetup(stdLog, NULL, 3);
+ dynInterface_logSetup(stdLog, NULL, 3);
+ dynType_logSetup(stdLog, NULL, 3);
+ dynCommon_logSetup(stdLog, NULL, 3);
+ }
+};
+
+TEST(AvroDescTranslatorTest, simple) {
+ simple();
+}
+
+TEST(AvroDescTranslatorTest, complex) {
+ complex();
+}
+
+TEST(AvroDescTranslatorTest, invalid1) {
+ invalid("schemas/invalid1.avpr");
+}
+
+TEST(AvroDescTranslatorTest, invalid2) {
+ invalid("schemas/invalid2.avpr");
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_closure_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_closure_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_closure_tests.cpp
new file mode 100644
index 0000000..b2b11d7
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_closure_tests.cpp
@@ -0,0 +1,146 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"
+
+extern "C" {
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "dyn_common.h"
+#include "dyn_function.h"
+
+static int g_count;
+
+static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
+ va_list ap;
+ const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
+ fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ fprintf(stderr, "\n");
+}
+
+#define EXAMPLE1_DESCRIPTOR "example(III)I"
+static void example1_binding(void *userData, void* args[], void *out) {
+ int32_t a = *((int32_t *)args[0]);
+ int32_t b = *((int32_t *)args[1]);
+ int32_t c = *((int32_t *)args[2]);
+ int32_t *ret = (int32_t *)out;
+ *ret = a + b + c;
+ g_count += 1;
+}
+
+#define EXAMPLE2_DESCRIPTOR "example(I{DDD val1 val2 val3}I)D"
+struct example2_arg2 {
+ double val1;
+ double val2;
+ double val3;
+};
+void example2_binding(void *userData, void* args[], void *out) {
+ int32_t a = *((int32_t *)args[0]);
+ struct example2_arg2 b = *((struct example2_arg2 *)args[1]);
+ int32_t c = *((int32_t *)args[2]);
+ double *ret = (double *)out;
+ *ret = a + b.val1 + b.val2 + b.val3 + c;
+ g_count += 1;
+}
+
+
+#define EXAMPLE3_DESCRIPTOR "example(III){III sum max min}"
+struct example3_ret {
+ int32_t sum;
+ int32_t max;
+ int32_t min;
+};
+
+static void example3_binding(void *userData, void* args[], void *out) {
+ int32_t a = *((int32_t *)args[0]);
+ int32_t b = *((int32_t *)args[1]);
+ int32_t c = *((int32_t *)args[2]);
+ struct example3_ret *result = (struct example3_ret *)calloc(1,sizeof(struct example3_ret));
+ result->sum = a + b + c;
+ result->min = a <= b ? a : b;
+ result->max = a >= b ? a : b;
+ result->min = result->min <= c ? result->min : c;
+ result->max = result->max >= c ? result->max : c;
+
+ struct example3_ret **ret = (struct example3_ret **)out;
+ (*ret) = result;
+ g_count += 1;
+}
+
+static void tests() {
+ dyn_function_type *dynFunction = NULL;
+ int rc = 0;
+
+ {
+ int32_t (*func)(int32_t a, int32_t b, int32_t c) = NULL;
+ rc = dynFunction_parseWithStr(EXAMPLE1_DESCRIPTOR, NULL, &dynFunction);
+ CHECK_EQUAL(0, rc);
+ rc = dynFunction_createClosure(dynFunction, example1_binding, NULL, (void(**)(void))&func);
+ CHECK_EQUAL(0, rc);
+ int32_t ret = func(2,3,4);
+ CHECK_EQUAL(1, g_count);
+ CHECK_EQUAL(9, ret);
+ dynFunction_destroy(dynFunction);
+ }
+
+ {
+ double (*func)(int32_t a, struct example2_arg2 b, int32_t c) = NULL;
+ double (*func2)(int32_t a, struct example2_arg2 b, int32_t c) = NULL;
+ dynFunction = NULL;
+ rc = dynFunction_parseWithStr(EXAMPLE2_DESCRIPTOR, NULL, &dynFunction);
+ CHECK_EQUAL(0, rc);
+ rc = dynFunction_createClosure(dynFunction, example2_binding, NULL, (void(**)(void))&func);
+ CHECK_EQUAL(0, rc);
+ rc = dynFunction_getFnPointer(dynFunction, (void(**)(void))&func2);
+ CHECK_EQUAL(0, rc);
+ CHECK(func == func2);
+ struct example2_arg2 b;
+ b.val1 = 1.0;
+ b.val2 = 1.5;
+ b.val3 = 2.0;
+ double ret = func(2,b,4);
+ CHECK_EQUAL(2, g_count);
+ CHECK_EQUAL(10.5, ret);
+ dynFunction_destroy(dynFunction);
+ }
+
+ {
+ struct example3_ret * (*func)(int32_t a, int32_t b, int32_t c) = NULL;
+ dynFunction = NULL;
+ rc = dynFunction_parseWithStr(EXAMPLE3_DESCRIPTOR, NULL, &dynFunction);
+ CHECK_EQUAL(0, rc);
+ rc = dynFunction_createClosure(dynFunction, example3_binding, NULL, (void(**)(void))&func);
+ CHECK_EQUAL(0, rc);
+ struct example3_ret *ret = func(2,8,4);
+ CHECK_EQUAL(3, g_count);
+ CHECK_EQUAL(14, ret->sum);
+ dynFunction_destroy(dynFunction);
+ free(ret);
+ }
+}
+
+}
+
+
+TEST_GROUP(DynClosureTests) {
+ void setup() {
+ dynFunction_logSetup(stdLog, NULL, 3);
+ dynType_logSetup(stdLog, NULL, 3);
+ //TODO dynType_logSetup(stdLog, NULL, 4);
+ dynCommon_logSetup(stdLog, NULL, 3);
+ g_count = 0;
+ }
+};
+
+TEST(DynClosureTests, DynCLosureTest1) {
+ //TODO split up
+ tests();
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/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
new file mode 100644
index 0000000..410b3ec
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp
@@ -0,0 +1,115 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"
+
+extern "C" {
+ #include <stdio.h>
+ #include <stdint.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <ctype.h>
+
+
+ #include "dyn_common.h"
+ #include "dyn_function.h"
+
+ static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
+ va_list ap;
+ const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
+ fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ fprintf(stderr, "\n");
+ }
+
+ #define EXAMPLE1_DESCRIPTOR "example(III)I"
+ int32_t example1(int32_t a, int32_t b, int32_t c) {
+ CHECK_EQUAL(2, a);
+ CHECK_EQUAL(4, b);
+ CHECK_EQUAL(8, c);
+ return 1;
+ }
+
+ void test_example1(void) {
+ dyn_function_type *dynFunc = NULL;
+ int rc;
+ void (*fp)(void) = (void (*)(void)) example1;
+
+ rc = dynFunction_parseWithStr(EXAMPLE1_DESCRIPTOR, NULL, &dynFunc);
+ CHECK_EQUAL(0, rc);
+
+ int32_t a = 2;
+ int32_t b = 4;
+ int32_t c = 8;
+ void *values[3];
+ int32_t rVal = 0;
+ values[0] = &a;
+ values[1] = &b;
+ values[2] = &c;
+
+ rc = dynFunction_call(dynFunc, fp, &rVal, values);
+ CHECK_EQUAL(0, rc);
+ CHECK_EQUAL(1, rVal);
+ dynFunction_destroy(dynFunc);
+ }
+
+ #define EXAMPLE2_DESCRIPTOR "example(I{IID val1 val2 val3}D)D"
+ struct example2_arg {
+ int32_t val1;
+ int32_t val2;
+ double val3;
+ };
+
+ double example2(int32_t arg1, struct example2_arg arg2, double arg3) {
+ CHECK_EQUAL(2, arg1);
+ CHECK_EQUAL(2, arg2.val1);
+ CHECK_EQUAL(3, arg2.val2);
+ CHECK_EQUAL(4.1, arg2.val3);
+ CHECK_EQUAL(8.1, arg3);
+ return 2.2;
+ }
+
+ void test_example2(void) {
+ dyn_function_type *dynFunc = NULL;
+ int rc;
+ void (*fp)(void) = (void (*)(void)) example2;
+
+ rc = dynFunction_parseWithStr(EXAMPLE2_DESCRIPTOR, NULL, &dynFunc);
+ CHECK_EQUAL(0, rc);
+
+ int32_t arg1 = 2;
+ struct example2_arg arg2;
+ arg2.val1 = 2;
+ arg2.val2 = 3;
+ arg2.val3 = 4.1;
+ double arg3 = 8.1;
+ double returnVal = 0;
+ void *values[3];
+ values[0] = &arg1;
+ values[1] = &arg2;
+ values[2] = &arg3;
+
+ rc = dynFunction_call(dynFunc, fp, &returnVal, values);
+ CHECK_EQUAL(0, rc);
+ CHECK_EQUAL(2.2, returnVal);
+ dynFunction_destroy(dynFunc);
+ }
+}
+
+TEST_GROUP(DynFunctionTests) {
+ void setup() {
+ dynFunction_logSetup(stdLog, NULL, 3);
+ dynType_logSetup(stdLog, NULL, 3);
+ dynCommon_logSetup(stdLog, NULL, 3);
+ }
+};
+
+TEST(DynFunctionTests, DynFuncTest1) {
+ test_example1();
+}
+
+TEST(DynFunctionTests, DynFuncTest2) {
+ test_example2();
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_interface_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_interface_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_interface_tests.cpp
new file mode 100644
index 0000000..6453afd
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_interface_tests.cpp
@@ -0,0 +1,79 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"
+extern "C" {
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "dyn_common.h"
+#include "dyn_interface.h"
+
+#if defined(BSD) || defined(__APPLE__)
+#include "open_memstream.h"
+#include "fmemopen.h"
+#endif
+
+ static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
+ va_list ap;
+ const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
+ fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ fprintf(stderr, "\n");
+ }
+
+ static void test1(void) {
+ int status = 0;
+ dyn_interface_type *dynIntf = NULL;
+ FILE *desc = fopen("descriptors/example1.descriptor", "r");
+ assert(desc != NULL);
+ status = dynInterface_parse(desc, &dynIntf);
+ CHECK_EQUAL(0, status);
+ fclose(desc);
+
+ char *name = NULL;
+ status = dynInterface_getName(dynIntf, &name);
+ CHECK_EQUAL(0, status);
+ STRCMP_EQUAL("calculator", name);
+
+ char *version = NULL;
+ status = dynInterface_getVersion(dynIntf, &version);
+ CHECK_EQUAL(0, status);
+ STRCMP_EQUAL("1.0.0", version);
+
+ char *annVal = NULL;
+ status = dynInterface_getAnnotationEntry(dynIntf, "classname", &annVal);
+ CHECK_EQUAL(0, status);
+ STRCMP_EQUAL("org.example.Calculator", annVal);
+
+ char *nonExist = NULL;
+ status = dynInterface_getHeaderEntry(dynIntf, "nonExisting", &nonExist);
+ CHECK(status != 0);
+ CHECK(nonExist == NULL);
+
+ dynInterface_destroy(dynIntf);
+ }
+
+}
+
+
+TEST_GROUP(DynInterfaceTests) {
+ void setup() {
+ int level = 1;
+ dynCommon_logSetup(stdLog, NULL, level);
+ dynType_logSetup(stdLog, NULL, level);
+ dynFunction_logSetup(stdLog, NULL, level);
+ dynInterface_logSetup(stdLog, NULL, level);
+ }
+};
+
+TEST(DynInterfaceTests, test1) {
+ test1();
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_type_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_type_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_type_tests.cpp
new file mode 100644
index 0000000..96f64fa
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_type_tests.cpp
@@ -0,0 +1,190 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"
+
+extern "C" {
+ #include <string.h>
+ #include <stdarg.h>
+
+ #include "dyn_common.h"
+ #include "dyn_type.h"
+
+ static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
+ va_list ap;
+ const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
+ fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ fprintf(stderr, "\n");
+ }
+
+ static void runTest(const char *descriptorStr, const char *exName) {
+ dyn_type *type;
+ int i;
+ type = NULL;
+ //printf("\n-- example %s with descriptor string '%s' --\n", exName, descriptorStr);
+ int status = dynType_parseWithStr(descriptorStr, exName, NULL, &type);
+ CHECK_EQUAL(0, status);
+
+ FILE *stream = fopen("/dev/null", "w");
+ dynType_print(type, stream);
+ fclose(stream);
+ dynType_destroy(type);
+ //printf("--\n\n");
+ }
+}
+
+TEST_GROUP(DynTypeTests) {
+ void setup() {
+ dynType_logSetup(stdLog, NULL, 0);
+ }
+};
+
+#define EX1 "{BbJjIiSsDFNN arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12}"
+#define EX2 "{D{DD b_1 b_2}I a b c}"
+#define EX3 "Tsub={DD b_1 b_2};{DLsub;I a b c}"
+#define EX4 "{[I numbers}"
+#define EX5 "[[{DD{iii val3_1 val3_2 val3_3} val1 val2 val3}"
+#define EX6 "Tsample={DD vala valb};Lsample;"
+#define EX7 "Tsample={DD vala valb};[Lsample;"
+#define EX8 "[Tsample={DD a b};Lsample;"
+#define EX9 "*D"
+#define EX10 "Tsample={DD a b};******Lsample;"
+#define EX11 "Tsample=D;Lsample;"
+#define EX12 "Tnode={Lnode;Lnode; left right};{Lnode; head}" //note recursive example
+#define EX13 "Ttype={DDDDD a b c d e};{ltype;Ltype;ltype;Ltype; byVal1 byRef1 byVal2 ByRef2}"
+#define EX14 "{DD{FF{JJ}{II*{ss}}}}" //unnamed fields
+
+#define CREATE_EXAMPLES_TEST(DESC) \
+ TEST(DynTypeTests, ParseTestExample ## DESC) { \
+ runTest(DESC, #DESC); \
+ }
+
+CREATE_EXAMPLES_TEST(EX1)
+CREATE_EXAMPLES_TEST(EX2)
+CREATE_EXAMPLES_TEST(EX3)
+CREATE_EXAMPLES_TEST(EX4)
+CREATE_EXAMPLES_TEST(EX5)
+CREATE_EXAMPLES_TEST(EX6)
+CREATE_EXAMPLES_TEST(EX7)
+CREATE_EXAMPLES_TEST(EX8)
+CREATE_EXAMPLES_TEST(EX9)
+CREATE_EXAMPLES_TEST(EX10)
+CREATE_EXAMPLES_TEST(EX11)
+CREATE_EXAMPLES_TEST(EX12)
+CREATE_EXAMPLES_TEST(EX13)
+CREATE_EXAMPLES_TEST(EX14)
+
+TEST(DynTypeTests, ParseRandomGarbageTest) {
+ /*
+ unsigned int seed = 4148;
+ char *testRandom = getenv("DYN_TYPE_TEST_RANDOM");
+ if (testRandom != NULL && strcmp("true", testRandom) == 0) {
+ seed = (unsigned int) time(NULL);
+ }
+ srandom(seed);
+ size_t nrOfTests = 100;
+
+ printf("\nStarting test with random seed %i and nrOfTests %zu.\n", seed, nrOfTests);
+
+ int i;
+ int k;
+ int c;
+ int sucesses = 0;
+ char descriptorStr[32];
+ descriptorStr[31] = '\0';
+ for(i = 0; i < nrOfTests; i += 1) {
+ for(k = 0; k < 31; k += 1) {
+ do {
+ c = (char) (((random() * 128) / RAND_MAX) - 1);
+ } while (!isprint(c));
+ descriptorStr[k] = c;
+ if (c == '\0') {
+ break;
+ }
+ }
+
+ //printf("ParseRandomGarbageTest iteration %i with descriptor string '%s'\n", k, descriptorStr);
+ dyn_type *type = NULL;
+ int status = dynType_parseWithStr(descriptorStr, NULL, NULL, &type);
+ if (status == 0) {
+ dynType_destroy(type);
+ }
+ }
+ */
+}
+
+TEST(DynTypeTests, AssignTest1) {
+ struct ex1 {
+ int32_t a;
+ int32_t b;
+ int32_t c;
+ };
+ struct ex1 inst;
+ const char *desc = "{III a b c}";
+ dyn_type *type = NULL;
+ int status = dynType_parseWithStr(desc, NULL, NULL, &type);
+ CHECK_EQUAL(0, status);
+ int32_t val1 = 2;
+ int32_t val2 = 4;
+ int32_t val3 = 8;
+ dynType_complex_setValueAt(type, 0, &inst, &val1);
+ CHECK_EQUAL(2, inst.a);
+ dynType_complex_setValueAt(type, 1, &inst, &val2);
+ CHECK_EQUAL(4, inst.b);
+ dynType_complex_setValueAt(type, 2, &inst, &val3);
+ CHECK_EQUAL(8, inst.c);
+
+ dynType_destroy(type);
+}
+
+TEST(DynTypeTests, AssignTest2) {
+ struct ex {
+ int32_t a;
+ struct {
+ double a;
+ double b;
+ } b;
+ };
+ struct ex inst;
+ const char *desc = "{I{DD a b} a b}";
+ dyn_type *type = NULL;
+ int status = dynType_parseWithStr(desc, NULL, NULL, &type);
+ CHECK_EQUAL(0, status);
+ int32_t a = 2;
+ double b_a = 1.1;
+ double b_b = 1.2;
+
+ dynType_complex_setValueAt(type, 0, &inst, &a);
+ CHECK_EQUAL(2, inst.a);
+
+ void *loc = NULL;
+ dyn_type *subType = NULL;
+ dynType_complex_valLocAt(type, 1, (void *)&inst, &loc);
+ dynType_complex_dynTypeAt(type, 1, &subType);
+
+ dynType_complex_setValueAt(subType, 0, &inst.b, &b_a);
+ CHECK_EQUAL(1.1, inst.b.a);
+
+ dynType_complex_setValueAt(subType, 1, &inst.b, &b_b);
+ CHECK_EQUAL(1.2, inst.b.b);
+
+ dynType_destroy(type);
+}
+
+TEST(DynTypeTests, AssignTest3) {
+ int simple = 1;
+ dyn_type *type = NULL;
+ int rc = dynType_parseWithStr("N", NULL, NULL, &type);
+ CHECK_EQUAL(0, rc);
+
+ int newValue = 42;
+ void *loc = &simple;
+ void *input = &newValue;
+ dynType_simple_setValue(type, loc, input);
+ CHECK_EQUAL(42, simple);
+ dynType_destroy(type);
+}
+
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/json_serializer_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/json_serializer_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/json_serializer_tests.cpp
new file mode 100644
index 0000000..c21d594
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/json_serializer_tests.cpp
@@ -0,0 +1,398 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"
+
+extern "C" {
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <ffi.h>
+
+#include "dyn_common.h"
+#include "dyn_type.h"
+#include "json_serializer.h"
+
+static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
+ va_list ap;
+ const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
+ fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ fprintf(stderr, "\n");
+}
+
+/*********** example 1 ************************/
+/** struct type ******************************/
+const char *example1_descriptor = "{DJISF a b c d e}";
+
+const char *example1_input = "{ \
+ \"a\" : 1.0, \
+ \"b\" : 22, \
+ \"c\" : 32, \
+ \"d\" : 42, \
+ \"e\" : 4.4 \
+}";
+
+struct example1 {
+ double a; //0
+ int64_t b; //1
+ int32_t c; //2
+ int16_t d; //3
+ float e; //4
+};
+
+static void check_example1(void *data) {
+ struct example1 *ex = (struct example1 *)data;
+ CHECK_EQUAL(1.0, ex->a);
+ CHECK_EQUAL(22, ex->b);
+ CHECK_EQUAL(32, ex->c);
+ CHECK_EQUAL(42, ex->d);
+ CHECK_EQUAL(4.4f, ex->e);
+}
+
+/*********** example 2 ************************/
+const char *example2_descriptor = "{BJJDFD byte long1 long2 double1 float1 double2}";
+
+const char *example2_input = "{ \
+ \"byte\" : 42, \
+ \"long1\" : 232, \
+ \"long2\" : 242, \
+ \"double1\" : 4.2, \
+ \"float1\" : 3.2, \
+ \"double2\" : 4.4 \
+}";
+
+struct example2 {
+ char byte; //0
+ int64_t long1; //1
+ int64_t long2; //2
+ double double1; //3
+ float float1; //4
+ double double2; //5
+};
+
+static void check_example2(void *data) {
+ struct example2 *ex = (struct example2 *)data;
+ CHECK_EQUAL(42, ex->byte);
+ CHECK_EQUAL(232, ex->long1);
+ CHECK_EQUAL(242, ex->long2);
+ CHECK_EQUAL(4.2, ex->double1);
+ CHECK_EQUAL(3.2f, ex->float1);
+ CHECK_EQUAL(4.4, ex->double2);
+}
+
+
+/*********** example 3 ************************/
+/** sequence with a simple type **************/
+const char *example3_descriptor = "{[I numbers}";
+
+const char *example3_input = "{ \
+ \"numbers\" : [22,32,42] \
+}";
+
+struct example3 {
+ struct {
+ uint32_t cap;
+ uint32_t len;
+ int32_t *buf;
+ } numbers;
+};
+
+static void check_example3(void *data) {
+ struct example3 *ex = (struct example3 *)data;
+ CHECK_EQUAL(3, ex->numbers.len);
+ CHECK_EQUAL(22, ex->numbers.buf[0]);
+ CHECK_EQUAL(32, ex->numbers.buf[1]);
+ CHECK_EQUAL(42, ex->numbers.buf[2]);
+}
+
+/*********** example 4 ************************/
+/** structs within a struct (by reference)*******/
+const char *example4_descriptor = "{{IDD index val1 val2}{IDD index val1 val2} left right}";
+
+static const char *example4_input = "{ \
+ \"left\" : {\"index\":1, \"val1\":1.0, \"val2\":2.0 }, \
+ \"right\" : {\"index\":2, \"val1\":5.0, \"val2\":4.0 } \
+}";
+
+struct ex4_leaf {
+ int32_t index;
+ double val1;
+ double val2;
+};
+
+struct example4 {
+ struct ex4_leaf left;
+ struct ex4_leaf right;
+};
+
+static void check_example4(void *data) {
+ struct example4 *ex = (struct example4 *)data;
+ CHECK_EQUAL(1, ex->left.index);
+ CHECK_EQUAL(1.0, ex->left.val1);
+ CHECK_EQUAL(2.0, ex->left.val2);
+ CHECK_EQUAL(2, ex->right.index);
+ CHECK_EQUAL(5.0, ex->right.val1);
+ CHECK_EQUAL(4.0, ex->right.val2);
+}
+
+
+/*********** example 4 ************************/
+/** structs within a struct (by reference)*******/
+const char *example5_descriptor = "Tleaf={ts name age};Tnode={Lnode;Lnode;Lleaf; left right value};{Lnode; head}";
+
+static const char *example5_input = "{ \
+ \"head\" : {\
+ \"left\" : {\
+ \"value\" : {\
+ \"name\" : \"John\",\
+ \"age\" : 44 \
+ }\
+ },\
+ \"right\" : {\
+ \"value\" : {\
+ \"name\" : \"Peter\", \
+ \"age\" : 55 \
+ }\
+ }\
+ }\
+}";
+
+struct leaf {
+ const char *name;
+ uint16_t age;
+};
+
+struct node {
+ struct node *left;
+ struct node *right;
+ struct leaf *value;
+};
+
+struct example5 {
+ struct node *head;
+};
+
+static void check_example5(void *data) {
+ struct example5 *ex = (struct example5 *)data;
+ CHECK_TRUE(ex->head != NULL);
+
+ CHECK(ex->head->left != NULL);
+ CHECK(ex->head->left->value != NULL);
+ STRCMP_EQUAL("John", ex->head->left->value->name);
+ CHECK_EQUAL(44, ex->head->left->value->age);
+ CHECK(ex->head->left->left == NULL);
+ CHECK(ex->head->left->right == NULL);
+
+ CHECK(ex->head->right != NULL);
+ CHECK(ex->head->right->value != NULL);
+ STRCMP_EQUAL("Peter", ex->head->right->value->name);
+ CHECK_EQUAL(55, ex->head->right->value->age);
+ CHECK(ex->head->right->left == NULL);
+ CHECK(ex->head->right->right == NULL);
+}
+
+static void parseTests(void) {
+ dyn_type *type;
+ void *inst;
+ int rc;
+
+ type = NULL;
+ inst = NULL;
+ rc = dynType_parseWithStr(example1_descriptor, NULL, NULL, &type);
+ CHECK_EQUAL(0, rc);
+ rc = jsonSerializer_deserialize(type, example1_input, &inst);
+ CHECK_EQUAL(0, rc);
+ check_example1(inst);
+ dynType_free(type, inst);
+ dynType_destroy(type);
+
+ type = NULL;
+ inst = NULL;
+ rc = dynType_parseWithStr(example2_descriptor, NULL, NULL, &type);
+ CHECK_EQUAL(0, rc);
+ rc = jsonSerializer_deserialize(type, example2_input, &inst);
+ CHECK_EQUAL(0, rc);
+ check_example2(inst);
+ dynType_free(type, inst);
+ dynType_destroy(type);
+
+ type = NULL;
+ inst = NULL;
+ rc = dynType_parseWithStr(example3_descriptor, NULL, NULL, &type);
+ CHECK_EQUAL(0, rc);
+ rc = jsonSerializer_deserialize(type, example3_input, &inst);
+ CHECK_EQUAL(0, rc);
+ check_example3(inst);
+ dynType_free(type, inst);
+ dynType_destroy(type);
+
+ type = NULL;
+ inst = NULL;
+ rc = dynType_parseWithStr(example4_descriptor, NULL, NULL, &type);
+ CHECK_EQUAL(0, rc);
+ rc = jsonSerializer_deserialize(type, example4_input, &inst);
+ CHECK_EQUAL(0, rc);
+ check_example4(inst);
+ dynType_free(type, inst);
+ dynType_destroy(type);
+
+ type = NULL;
+ inst = NULL;
+ rc = dynType_parseWithStr(example5_descriptor, NULL, NULL, &type);
+ CHECK_EQUAL(0, rc);
+ rc = jsonSerializer_deserialize(type, example5_input, &inst);
+ CHECK_EQUAL(0, rc);
+ check_example5(inst);
+ dynType_free(type, inst);
+ dynType_destroy(type);
+}
+
+const char *write_example1_descriptor = "{BSIJsijFDN a b c d e f g h i j}";
+
+struct write_example1 {
+ char a;
+ int16_t b;
+ int32_t c;
+ int64_t d;
+ uint16_t e;
+ uint32_t f;
+ uint64_t g;
+ float h;
+ double i;
+ int j;
+};
+
+void writeTest1(void) {
+ struct write_example1 ex1 = {.a=1, .b=2, .c=3, .d=4, .e=5, .f=6, .g=7, .h=8.8f, .i=9.9, .j=10};
+ dyn_type *type = NULL;
+ char *result = NULL;
+ int rc = dynType_parseWithStr(write_example1_descriptor, "ex1", NULL, &type);
+ CHECK_EQUAL(0, rc);
+ rc = jsonSerializer_serialize(type, &ex1, &result);
+ CHECK_EQUAL(0, rc);
+ STRCMP_CONTAINS("\"a\":1", result);
+ STRCMP_CONTAINS("\"b\":2", result);
+ STRCMP_CONTAINS("\"c\":3", result);
+ STRCMP_CONTAINS("\"d\":4", result);
+ STRCMP_CONTAINS("\"e\":5", result);
+ STRCMP_CONTAINS("\"f\":6", result);
+ STRCMP_CONTAINS("\"g\":7", result);
+ STRCMP_CONTAINS("\"h\":8.8", result);
+ STRCMP_CONTAINS("\"i\":9.9", result);
+ STRCMP_CONTAINS("\"j\":10", result);
+ //printf("example 1 result: '%s'\n", result);
+ dynType_destroy(type);
+ free(result);
+}
+
+const char *write_example2_descriptor = "{*{JJ a b}{SS c d} sub1 sub2}";
+
+struct write_example2_sub {
+ int64_t a;
+ int64_t b;
+};
+
+struct write_example2 {
+ struct write_example2_sub *sub1;
+ struct {
+ int16_t c;
+ int16_t d;
+ } sub2;
+};
+
+void writeTest2(void) {
+ struct write_example2_sub sub1 = { .a = 1, .b = 2 };
+ struct write_example2 ex = { .sub1 = &sub1 };
+ ex.sub2.c = 3;
+ ex.sub2.d = 4;
+
+ dyn_type *type = NULL;
+ char *result = NULL;
+ int rc = dynType_parseWithStr(write_example2_descriptor, "ex2", NULL, &type);
+ CHECK_EQUAL(0, rc);
+ rc = jsonSerializer_serialize(type, &ex, &result);
+ CHECK_EQUAL(0, rc);
+ STRCMP_CONTAINS("\"a\":1", result);
+ STRCMP_CONTAINS("\"b\":2", result);
+ STRCMP_CONTAINS("\"c\":3", result);
+ STRCMP_CONTAINS("\"d\":4", result);
+ //printf("example 2 result: '%s'\n", result);
+ dynType_destroy(type);
+ free(result);
+}
+
+const char *write_example3_descriptor = "Tperson={ti name age};[Lperson;";
+
+struct write_example3_person {
+ const char *name;
+ uint32_t age;
+};
+
+struct write_example3 {
+ uint32_t cap;
+ uint32_t len;
+ struct write_example3_person **buf;
+};
+
+void writeTest3(void) {
+ struct write_example3_person p1 = {.name = "John", .age = 33};
+ struct write_example3_person p2 = {.name = "Peter", .age = 44};
+ struct write_example3_person p3 = {.name = "Carol", .age = 55};
+ struct write_example3_person p4 = {.name = "Elton", .age = 66};
+ struct write_example3 seq;
+ seq.buf = (struct write_example3_person **) calloc(4, sizeof(void *));
+ seq.len = seq.cap = 4;
+ seq.buf[0] = &p1;
+ seq.buf[1] = &p2;
+ seq.buf[2] = &p3;
+ seq.buf[3] = &p4;
+
+ dyn_type *type = NULL;
+ char *result = NULL;
+ int rc = dynType_parseWithStr(write_example3_descriptor, "ex3", NULL, &type);
+ CHECK_EQUAL(0, rc);
+ rc = jsonSerializer_serialize(type, &seq, &result);
+ CHECK_EQUAL(0, rc);
+ STRCMP_CONTAINS("\"age\":33", result);
+ STRCMP_CONTAINS("\"age\":44", result);
+ STRCMP_CONTAINS("\"age\":55", result);
+ STRCMP_CONTAINS("\"age\":66", result);
+ //printf("example 3 result: '%s'\n", result);
+ free(seq.buf);
+ dynType_destroy(type);
+ free(result);
+}
+
+}
+
+TEST_GROUP(JsonSerializerTests) {
+ void setup() {
+ int lvl = 1;
+ dynCommon_logSetup(stdLog, NULL, lvl);
+ dynType_logSetup(stdLog, NULL,lvl);
+ jsonSerializer_logSetup(stdLog, NULL, lvl);
+ }
+};
+
+TEST(JsonSerializerTests, ParseTests) {
+ //TODO split up
+ parseTests();
+}
+
+TEST(JsonSerializerTests, WriteTest1) {
+ writeTest1();
+}
+
+TEST(JsonSerializerTests, WriteTest2) {
+ writeTest2();
+}
+
+TEST(JsonSerializerTests, WriteTest3) {
+ writeTest3();
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/run_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/run_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/run_tests.cpp
new file mode 100644
index 0000000..f405c9f
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/run_tests.cpp
@@ -0,0 +1,9 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"
+
+int main(int argc, char** argv) {
+ return RUN_ALL_TESTS(argc, argv);
+}
[10/10] celix git commit: CELIX-237: Finished ccputest setup for
testing the rsa dfi bundle. Cpputest uses the launcher to launch an embedded
celix
Posted by pn...@apache.org.
CELIX-237: Finished ccputest setup for testing the rsa dfi bundle. Cpputest uses the launcher to launch an embedded celix
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/481e5c86
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/481e5c86
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/481e5c86
Branch: refs/heads/feature/CELIX-237_rsa-ffi
Commit: 481e5c86114ecdd2bef5b2f5f6afdb32a6a6a537
Parents: 1e618fb
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri Jul 31 22:56:02 2015 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri Jul 31 22:56:02 2015 +0200
----------------------------------------------------------------------
launcher/private/src/launcher.c | 9 +++--
launcher/public/include/launcher.h | 1 +
.../remote_service_admin_dfi/CMakeLists.txt | 4 ++-
.../remote_service_admin_dfi/tst/CMakeLists.txt | 18 ++++++----
.../remote_service_admin_dfi/tst/rsa_tests.cpp | 36 ++++++++++++++++++++
.../remote_service_admin_dfi/tst/run_tests.cpp | 21 +++++++++---
6 files changed, 74 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/481e5c86/launcher/private/src/launcher.c
----------------------------------------------------------------------
diff --git a/launcher/private/src/launcher.c b/launcher/private/src/launcher.c
index 9292ffb..4f0f3de 100644
--- a/launcher/private/src/launcher.c
+++ b/launcher/private/src/launcher.c
@@ -183,15 +183,18 @@ void celixLauncher_waitForShutdown(void) {
properties_destroy(config);
}
+void celixLauncher_stop(void) {
+ bundle_pt fwBundle = NULL;
+ framework_getFrameworkBundle(framework, &fwBundle);
+ bundle_stop(fwBundle);
+}
struct framework *celixLauncher_getFramework(void) {
return framework;
}
static void launcher_shutdown(int signal) {
- bundle_pt fwBundle = NULL;
- framework_getFrameworkBundle(framework, &fwBundle);
- bundle_stop(fwBundle);
+ celixLauncher_stop();
// if (framework_waitForStop(framework) != CELIX_SUCCESS) {
// celix_log("Error waiting for stop.");
// }
http://git-wip-us.apache.org/repos/asf/celix/blob/481e5c86/launcher/public/include/launcher.h
----------------------------------------------------------------------
diff --git a/launcher/public/include/launcher.h b/launcher/public/include/launcher.h
index f95e160..6ee8357 100644
--- a/launcher/public/include/launcher.h
+++ b/launcher/public/include/launcher.h
@@ -32,6 +32,7 @@
int celixLauncher_launch(const char *configFile);
int celixLauncher_launchWithStream(FILE *config);
+void celixLauncher_stop(void);
void celixLauncher_waitForShutdown(void);
struct framework *celixLauncher_getFramework(void);
http://git-wip-us.apache.org/repos/asf/celix/blob/481e5c86/remote_services/remote_service_admin_dfi/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/CMakeLists.txt b/remote_services/remote_service_admin_dfi/CMakeLists.txt
index 500e40e..3937605 100644
--- a/remote_services/remote_service_admin_dfi/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/CMakeLists.txt
@@ -46,7 +46,9 @@ if (RSA_REMOTE_SERVICE_ADMIN_DFI)
${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
)
- target_link_libraries(remote_service_admin_dfi celix_framework ${CURL_LIBRARIES} ${JANSSON_LIBRARIES} ${FFI_LIBRARIES} dfi)
+ target_link_libraries(remote_service_admin_dfi celix_framework celix_utils ${CURL_LIBRARIES} ${JANSSON_LIBRARIES} ${FFI_LIBRARIES} dfi)
install_bundle(remote_service_admin_dfi)
+
+ add_subdirectory(tst)
endif (RSA_REMOTE_SERVICE_ADMIN_DFI)
http://git-wip-us.apache.org/repos/asf/celix/blob/481e5c86/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt b/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt
index fb1834a..d71186e 100644
--- a/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt
@@ -3,20 +3,26 @@
#
include_directories(
- ${PROJECT_SOURCE_DIR}/launcher/public
+ ${PROJECT_SOURCE_DIR}/launcher/public/include
${CPPUTEST_INCLUDE_DIR}
+ ${PROJECT_SOURCE_DIR}/framework/public/include
+ ${PROJECT_SOURCE_DIR}/utils/public/include
)
-
#if (FRAMEWORK_TESTS) TODO
+ SET(CMAKE_SKIP_BUILD_RPATH FALSE) #TODO needed?
+ SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) #TODO needed?
+ SET(CMAKE_INSTALL_RPATH "${PROJECT_BINARY_DIR}/framework:${PROJECT_BINARY_DIR}/utils")
+
add_executable(rsa_dfi_tests
- ${PROJECT_SOURCE_DIR}/launcher/private/src/launcher
- tst/run_tests.cpp
+ ${PROJECT_SOURCE_DIR}/launcher/private/src/launcher.c
+ run_tests.cpp
+ rsa_tests.cpp
)
- target_link_libraries(rsa_dfi_tests ${CPPUTEST_LIBRARY}) #TODO add celix/launcer etc
+ target_link_libraries(rsa_dfi_tests ${CPPUTEST_LIBRARY} celix_framework celix_utils ${CURL_LIBRARIES})
get_property(rsa_bundle_file TARGET remote_service_admin_dfi PROPERTY BUNDLE)
- configure_file(config.properties.in config-rsa.properties @ONLY)
+ configure_file(config.properties.in config.properties @ONLY)
add_test(NAME run_rsa_dfi_tests COMMAND rsa_dfi_tests)
SETUP_TARGET_FOR_COVERAGE(rsa_dfi_tests_cov rsa_dfi_tests ${CMAKE_BINARY_DIR}/coverage/rsa_dfi)
http://git-wip-us.apache.org/repos/asf/celix/blob/481e5c86/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp b/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp
new file mode 100644
index 0000000..b9206da
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp
@@ -0,0 +1,36 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"
+
+extern "C" {
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "launcher.h"
+#include "framework.h"
+
+
+static void testFindRsaService(void) {
+ struct framework *fm = celixLauncher_getFramework();
+ CHECK(fm != NULL);
+
+ //TODO get framework bundle context. lookup service -> test service
+}
+
+}
+
+
+TEST_GROUP(RsaDfiTests) {
+ void setup() {
+ }
+};
+
+TEST(RsaDfiTests, FindRsaService) {
+ testFindRsaService();
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/481e5c86/remote_services/remote_service_admin_dfi/tst/run_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/tst/run_tests.cpp b/remote_services/remote_service_admin_dfi/tst/run_tests.cpp
index b5f29e7..dedb70a 100644
--- a/remote_services/remote_service_admin_dfi/tst/run_tests.cpp
+++ b/remote_services/remote_service_admin_dfi/tst/run_tests.cpp
@@ -4,15 +4,26 @@
#include <CppUTest/TestHarness.h>
#include "CppUTest/CommandLineTestRunner.h"
-#include <stdio.h>
-#include "launcher.h"
+extern "C" {
+ #include <stdio.h>
+ #include "launcher.h"
+ #include "framework.h"
+
+ static int startCelix(void) {
+ celixLauncher_launch("config.properties");
+ }
+
+ static int stopCelix(void) {
+ celixLauncher_stop();
+ celixLauncher_waitForShutdown();
+ }
+}
int main(int argc, char** argv) {
- celixLauncher_launch("config.properties");
+ startCelix();
int rc = RUN_ALL_TESTS(argc, argv);
- framework_stop((celixLauncher_getFramework()));
- celixLauncher_waitForShutdown();
+ stopCelix();
return rc;
}
\ No newline at end of file
[08/10] celix git commit: CELIX-237: Split launcher in a main.c and
launcher.c/.h. Trying to reuse the launcher for cpputests
Posted by pn...@apache.org.
CELIX-237: Split launcher in a main.c and launcher.c/.h. Trying to reuse the launcher for cpputests
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/2f56576a
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/2f56576a
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/2f56576a
Branch: refs/heads/feature/CELIX-237_rsa-ffi
Commit: 2f56576ae7f4bb006b8c22a776812dd0907abe6f
Parents: 3d7f764
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri Jul 31 16:57:09 2015 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri Jul 31 16:57:09 2015 +0200
----------------------------------------------------------------------
framework/private/src/properties.c | 13 +-
framework/public/include/properties.h | 3 +
launcher/CMakeLists.txt | 6 +-
launcher/private/src/launcher.c | 225 ++++++++++++++---------------
launcher/private/src/main.c | 62 ++++++++
launcher/public/include/launcher.h | 35 +++++
6 files changed, 220 insertions(+), 124 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/2f56576a/framework/private/src/properties.c
----------------------------------------------------------------------
diff --git a/framework/private/src/properties.c b/framework/private/src/properties.c
index 38ed214..14455c4 100644
--- a/framework/private/src/properties.c
+++ b/framework/private/src/properties.c
@@ -47,9 +47,14 @@ void properties_destroy(properties_pt properties) {
}
properties_pt properties_load(char *filename) {
- properties_pt props = NULL;
- FILE *file = fopen ( filename, "r" );
+ FILE *file = fopen(filename, "r");
+ properties_pt props = properties_loadWithStream(file);
+ fclose(file);
+ return props;
+}
+FRAMEWORK_EXPORT properties_pt properties_loadWithStream(FILE *file) {
+ properties_pt props = NULL;
char line[1024];
char key[1024];
char value[1024];
@@ -110,7 +115,7 @@ properties_pt properties_load(char *filename) {
}
} else if (line[linePos] == '\\') {
if (precedingCharIsBackslash) { //double backslash -> backslash
- output[outputPos++] = '\\';
+ output[outputPos++] = '\\';
}
precedingCharIsBackslash = true;
} else { //normal character
@@ -128,8 +133,6 @@ properties_pt properties_load(char *filename) {
hashMap_put(props, strdup(utils_stringTrim(key)), strdup(utils_stringTrim(value)));
}
}
-
- fclose(file);
}
return props;
http://git-wip-us.apache.org/repos/asf/celix/blob/2f56576a/framework/public/include/properties.h
----------------------------------------------------------------------
diff --git a/framework/public/include/properties.h b/framework/public/include/properties.h
index 36297a5..c4803cb 100644
--- a/framework/public/include/properties.h
+++ b/framework/public/include/properties.h
@@ -27,6 +27,8 @@
#ifndef PROPERTIES_H_
#define PROPERTIES_H_
+#include <stdio.h>
+
#include "hash_map.h"
#include "framework_exports.h"
@@ -35,6 +37,7 @@ typedef hash_map_pt properties_pt;
FRAMEWORK_EXPORT properties_pt properties_create(void);
FRAMEWORK_EXPORT void properties_destroy(properties_pt properties);
FRAMEWORK_EXPORT properties_pt properties_load(char * filename);
+FRAMEWORK_EXPORT properties_pt properties_loadWithStream(FILE *stream);
FRAMEWORK_EXPORT void properties_store(properties_pt properties, char * file, char * header);
FRAMEWORK_EXPORT char * properties_get(properties_pt properties, char * key);
http://git-wip-us.apache.org/repos/asf/celix/blob/2f56576a/launcher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 27d1682..6001eaf 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -17,8 +17,12 @@
celix_subproject(LAUNCHER "Option to build the launcher" "ON" DEPS UTILS FRAMEWORK)
if (LAUNCHER)
find_package(CURL REQUIRED)
+
+ include_directories(public/include)
- add_executable(celix private/src/launcher)
+ add_executable(celix
+ private/src/main
+ private/src/launcher)
target_link_libraries(celix celix_framework ${CURL_LIBRARIES})
include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
http://git-wip-us.apache.org/repos/asf/celix/blob/2f56576a/launcher/private/src/launcher.c
----------------------------------------------------------------------
diff --git a/launcher/private/src/launcher.c b/launcher/private/src/launcher.c
index f334057..6d09fc4 100644
--- a/launcher/private/src/launcher.c
+++ b/launcher/private/src/launcher.c
@@ -23,6 +23,9 @@
* \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
* \copyright Apache License, Version 2.0
*/
+
+#include "launcher.h"
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -34,33 +37,48 @@
#include "framework.h"
#include "linked_list_iterator.h"
-#define DEFAULT_CONFIG_FILE "config.properties"
-
-void launcher_shutdown(int signal);
+static void launcher_shutdown(int signal);
-int running = 0;
-
-struct framework * framework;
+static struct framework * framework;
#ifdef WITH_APR
-apr_pool_t *memoryPool;
+static apr_pool_t *memoryPool;
#endif
-void show_usage(char* prog_name);
+int celixLauncher_launch(const char *configFile) {
+ int status = 0;
+ FILE *config = fopen(configFile, "r");
+ if (config != NULL) {
+ status = celixLauncher_launchWithStream(config);
+ } else {
+ fprintf(stderr, "Error: invalid or non-existing configuration file: '%s'.", configFile);
+ perror("");
+ status = 1;
+ }
+ return status;
+}
+
+int celixLauncher_launchWithStream(FILE *stream) {
+ int status = 0;
+
+ properties_pt config = properties_loadWithStream(stream);
+ fclose(stream);
+ // Make sure we've read it and that nothing went wrong with the file access...
+ if (config == NULL) {
+ fprintf(stderr, "Error: invalid configuration file");
+ perror(NULL);
+ status = 1;
+ }
-int main(int argc, char *argv[]) {
- // Set signal handler
+ // Set signal handler
#ifdef WITH_APR
apr_status_t rv;
apr_status_t s;
#endif
- properties_pt config = NULL;
- char *autoStart = NULL;
- bundle_pt fwBundle = NULL;
- (void) signal(SIGINT, launcher_shutdown);
+ (void) signal(SIGINT, launcher_shutdown);
- // Before doing anything else, let's setup Curl
- curl_global_init(CURL_GLOBAL_NOTHING);
+ // Before doing anything else, let's setup Curl
+ curl_global_init(CURL_GLOBAL_NOTHING);
#ifdef WITH_APR
rv = apr_initialize();
@@ -74,128 +92,99 @@ int main(int argc, char *argv[]) {
}
#endif
- // Perform some minimal command-line option parsing...
- char* opt = NULL;
- if (argc > 1) {
- opt = argv[1];
- }
-
- char* config_file = NULL;
-
- if (opt) {
- // Check whether the user wants some help...
- if (strcmp("-h", opt) == 0 || strcmp("-help", opt) == 0) {
- show_usage(argv[0]);
- return 0;
- } else {
- config_file = opt;
- }
- } else {
- config_file = DEFAULT_CONFIG_FILE;
- }
-
- config = properties_load(config_file);
- // Make sure we've read it and that nothing went wrong with the file access...
- if (config == NULL) {
- printf("Error: invalid or non-existing configuration file: \"%s\"!\n", config_file);
- perror(NULL);
- show_usage(argv[0]);
- return CELIX_START_ERROR;
- }
-
- autoStart = properties_get(config, "cosgi.auto.start.1");
- framework = NULL;
- celix_status_t status;
+
+ if (status == 0) {
+ char *autoStart = properties_get(config, "cosgi.auto.start.1");
+ framework = NULL;
+ celix_status_t status;
#ifdef WITH_APR
- status = framework_create(&framework, memoryPool, config);
+ status = framework_create(&framework, memoryPool, config);
#else
- status = framework_create(&framework, config);
+ status = framework_create(&framework, config);
#endif
- if (status == CELIX_SUCCESS) {
- status = fw_init(framework);
- if (status == CELIX_SUCCESS) {
- // Start the system bundle
- framework_getFrameworkBundle(framework, &fwBundle);
- bundle_start(fwBundle);
-
- char delims[] = " ";
- char *result = NULL;
- char *save_ptr = NULL;
- linked_list_pt bundles;
- array_list_pt installed = NULL;
- bundle_pt bundle = NULL;
- bundle_context_pt context = NULL;
- linked_list_iterator_pt iter = NULL;
- unsigned int i;
-
- linkedList_create(&bundles);
- result = strtok_r(autoStart, delims, &save_ptr);
- while (result != NULL) {
- char * location = strdup(result);
- linkedList_addElement(bundles, location);
- result = strtok_r(NULL, delims, &save_ptr);
- }
- // First install all bundles
- // Afterwards start them
- arrayList_create(&installed);
- framework_getFrameworkBundle(framework, &bundle);
- bundle_getContext(bundle, &context);
- iter = linkedListIterator_create(bundles, 0);
- while (linkedListIterator_hasNext(iter)) {
- bundle_pt current = NULL;
- char * location = (char *) linkedListIterator_next(iter);
- if (bundleContext_installBundle(context, location, ¤t) == CELIX_SUCCESS) {
- // Only add bundle if it is installed correctly
- arrayList_add(installed, current);
- } else {
- printf("Could not install bundle from %s\n", location);
+ bundle_pt fwBundle = NULL;
+ if (status == CELIX_SUCCESS) {
+ status = fw_init(framework);
+ if (status == CELIX_SUCCESS) {
+ // Start the system bundle
+ framework_getFrameworkBundle(framework, &fwBundle);
+ bundle_start(fwBundle);
+
+ char delims[] = " ";
+ char *result = NULL;
+ char *save_ptr = NULL;
+ linked_list_pt bundles;
+ array_list_pt installed = NULL;
+ bundle_pt bundle = NULL;
+ bundle_context_pt context = NULL;
+ linked_list_iterator_pt iter = NULL;
+ unsigned int i;
+
+ linkedList_create(&bundles);
+ result = strtok_r(autoStart, delims, &save_ptr);
+ while (result != NULL) {
+ char *location = strdup(result);
+ linkedList_addElement(bundles, location);
+ result = strtok_r(NULL, delims, &save_ptr);
}
- linkedListIterator_remove(iter);
- free(location);
- }
- linkedListIterator_destroy(iter);
- linkedList_destroy(bundles);
+ // First install all bundles
+ // Afterwards start them
+ arrayList_create(&installed);
+ framework_getFrameworkBundle(framework, &bundle);
+ bundle_getContext(bundle, &context);
+ iter = linkedListIterator_create(bundles, 0);
+ while (linkedListIterator_hasNext(iter)) {
+ bundle_pt current = NULL;
+ char *location = (char *) linkedListIterator_next(iter);
+ if (bundleContext_installBundle(context, location, ¤t) == CELIX_SUCCESS) {
+ // Only add bundle if it is installed correctly
+ arrayList_add(installed, current);
+ } else {
+ printf("Could not install bundle from %s\n", location);
+ }
+ linkedListIterator_remove(iter);
+ free(location);
+ }
+ linkedListIterator_destroy(iter);
+ linkedList_destroy(bundles);
- for (i = 0; i < arrayList_size(installed); i++) {
- bundle_pt installedBundle = (bundle_pt) arrayList_get(installed, i);
- bundle_startWithOptions(installedBundle, 0);
- }
+ for (i = 0; i < arrayList_size(installed); i++) {
+ bundle_pt installedBundle = (bundle_pt) arrayList_get(installed, i);
+ bundle_startWithOptions(installedBundle, 0);
+ }
- arrayList_destroy(installed);
+ arrayList_destroy(installed);
- framework_waitForStop(framework);
- framework_destroy(framework);
- properties_destroy(config);
- }
- }
+ framework_waitForStop(framework);
+ framework_destroy(framework);
+ properties_destroy(config);
+ }
+ }
- if (status != CELIX_SUCCESS) {
- printf("Problem creating framework\n");
- }
+ if (status != CELIX_SUCCESS) {
+ printf("Problem creating framework\n");
+ }
#ifdef WITH_APR
apr_pool_destroy(memoryPool);
apr_terminate();
#endif
- // Cleanup Curl
- curl_global_cleanup();
+ // Cleanup Curl
+ curl_global_cleanup();
- printf("Launcher: Exit\n");
+ printf("Launcher: Exit\n");
+ }
- return 0;
+ return status;
}
-void launcher_shutdown(int signal) {
- bundle_pt fwBundle = NULL;
- framework_getFrameworkBundle(framework, &fwBundle);
- bundle_stop(fwBundle);
+static void launcher_shutdown(int signal) {
+ bundle_pt fwBundle = NULL;
+ framework_getFrameworkBundle(framework, &fwBundle);
+ bundle_stop(fwBundle);
// if (framework_waitForStop(framework) != CELIX_SUCCESS) {
// celix_log("Error waiting for stop.");
// }
// framework_destroy(framework);
}
-
-void show_usage(char* prog_name) {
- printf("Usage:\n %s [path/to/config.properties]\n\n", basename(prog_name));
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2f56576a/launcher/private/src/main.c
----------------------------------------------------------------------
diff --git a/launcher/private/src/main.c b/launcher/private/src/main.c
new file mode 100644
index 0000000..0a59bc4
--- /dev/null
+++ b/launcher/private/src/main.c
@@ -0,0 +1,62 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * main.c
+ *
+ * \date Jul 30, 2015
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include <string.h>
+#include <curl/curl.h>
+#include <signal.h>
+#include "launcher.h"
+
+static void show_usage(char* prog_name);
+
+#define DEFAULT_CONFIG_FILE "config.properties"
+
+int main(int argc, char *argv[]) {
+ // Perform some minimal command-line option parsing...
+ char *opt = NULL;
+ if (argc > 1) {
+ opt = argv[1];
+ }
+
+ char *config_file = NULL;
+
+ if (opt) {
+ // Check whether the user wants some help...
+ if (strcmp("-h", opt) == 0 || strcmp("-help", opt) == 0) {
+ show_usage(argv[0]);
+ return 0;
+ } else {
+ config_file = opt;
+ }
+ } else {
+ config_file = DEFAULT_CONFIG_FILE;
+ }
+
+ celixLauncher_launch(config_file);
+}
+
+static void show_usage(char* prog_name) {
+ printf("Usage:\n %s [path/to/config.properties]\n\n", basename(prog_name));
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2f56576a/launcher/public/include/launcher.h
----------------------------------------------------------------------
diff --git a/launcher/public/include/launcher.h b/launcher/public/include/launcher.h
new file mode 100644
index 0000000..296df7c
--- /dev/null
+++ b/launcher/public/include/launcher.h
@@ -0,0 +1,35 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * launcher.h
+ *
+ * \date Jul 30, 2015
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef CELIX_LAUNCHER_H
+#define CELIX_LAUNCHER_H
+
+#include <stdio.h>
+
+int celixLauncher_launch(const char *configFile);
+int celixLauncher_launchWithStream(FILE *config);
+
+#endif //CELIX_LAUNCHER_H
[06/10] celix git commit: CELIX-237: moved rsa_http_ffi source to
rsa_dfi
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_impl.c b/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_impl.c
deleted file mode 100644
index ac54e8d..0000000
--- a/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_impl.c
+++ /dev/null
@@ -1,1085 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin_impl.c
- *
- * \date May 21, 2015
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <ifaddrs.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <uuid/uuid.h>
-
-#include <curl/curl.h>
-
-#include <ffi.h>
-#include <jansson.h>
-
-#include "export_registration_impl.h"
-#include "import_registration_impl.h"
-#include "remote_service_admin_impl.h"
-#include "remote_constants.h"
-#include "constants.h"
-#include "utils.h"
-#include "bundle_context.h"
-#include "bundle.h"
-#include "service_reference.h"
-#include "service_registration.h"
-#include "log_helper.h"
-#include "log_service.h"
-#include "celix_threads.h"
-#include "civetweb.h"
-#include "log_helper.h"
-#include "endpoint_description.h"
-
-// defines how often the webserver is restarted (with an increased port number)
-#define MAX_NUMBER_OF_RESTARTS 5
-
-typedef void (*GEN_FUNC_TYPE)(void);
-
-struct generic_service_layout {
- void *handle;
- GEN_FUNC_TYPE functions[];
-};
-
-struct proxy {
- remote_service_admin_pt admin;
- char *sig;
- int index;
- ffi_cif cif;
- ffi_closure *closure;
- endpoint_description_pt endpointDescription
-};
-
-
-
-
-
-struct remote_service_admin {
- bundle_context_pt context;
- log_helper_pt loghelper;
-
- celix_thread_mutex_t exportedServicesLock;
- hash_map_pt exportedServices;
-
- celix_thread_mutex_t importedServicesLock;
- hash_map_pt importedServices;
-
- char *port;
- char *ip;
-
- struct mg_context *ctx;
-};
-
-struct post {
- const char *readptr;
- int size;
-};
-
-struct get {
- char *writeptr;
- int size;
-};
-
-static const char *data_response_headers =
- "HTTP/1.1 200 OK\r\n"
- "Cache: no-cache\r\n"
- "Content-Type: application/json\r\n"
- "\r\n";
-
-static const char *no_content_response_headers =
- "HTTP/1.1 204 OK\r\n";
-
-// TODO do we need to specify a non-Amdatu specific configuration type?!
-static const char * const CONFIGURATION_TYPE = "org.amdatu.remote.admin.http";
-static const char * const ENDPOINT_URL = "org.amdatu.remote.admin.http.url";
-
-static const char *DEFAULT_PORT = "8888";
-static const char *DEFAULT_IP = "127.0.0.1";
-
-static const unsigned int DEFAULT_TIMEOUT = 0;
-
-static int remoteServiceAdmin_callback(struct mg_connection *conn);
-
-static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, char *interface, endpoint_description_pt *description);
-
-static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip);
-
-static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp);
-static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp);
-
-celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin) {
- celix_status_t status = CELIX_SUCCESS;
-
- *admin = calloc(1, sizeof(**admin));
-
- if (!*admin) {
- status = CELIX_ENOMEM;
- } else {
- unsigned int port_counter = 0;
- char *port = NULL;
- char *ip = NULL;
- char *detectedIp = NULL;
- (*admin)->context = context;
- (*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL);
- (*admin)->importedServices = hashMap_create(NULL, NULL, NULL, NULL);
-
- celixThreadMutex_create(&(*admin)->exportedServicesLock, NULL);
- celixThreadMutex_create(&(*admin)->importedServicesLock, NULL);
-
- if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
- logHelper_start((*admin)->loghelper);
- }
-
- bundleContext_getProperty(context, "RSA_PORT", &port);
- if (port == NULL) {
- port = (char *)DEFAULT_PORT;
- }
-
- bundleContext_getProperty(context, "RSA_IP", &ip);
- if (ip == NULL) {
- char *interface = NULL;
-
- bundleContext_getProperty(context, "RSA_INTERFACE", &interface);
- if ((interface != NULL) && (remoteServiceAdmin_getIpAdress(interface, &detectedIp) != CELIX_SUCCESS)) {
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: Could not retrieve IP adress for interface %s", interface);
- }
-
- if (ip == NULL) {
- remoteServiceAdmin_getIpAdress(NULL, &detectedIp);
- }
-
- ip = detectedIp;
- }
-
- if (ip != NULL) {
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Using %s for service annunciation", ip);
- (*admin)->ip = strdup(ip);
- }
- else {
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No IP address for service annunciation set. Using %s", DEFAULT_IP);
- (*admin)->ip = (char*) DEFAULT_IP;
- }
-
- if (detectedIp != NULL) {
- free(detectedIp);
- }
-
- // Prepare callbacks structure. We have only one callback, the rest are NULL.
- struct mg_callbacks callbacks;
- memset(&callbacks, 0, sizeof(callbacks));
- callbacks.begin_request = remoteServiceAdmin_callback;
-
- do {
- char newPort[10];
- const char *options[] = { "listening_ports", port, NULL};
-
- (*admin)->ctx = mg_start(&callbacks, (*admin), options);
-
- if ((*admin)->ctx != NULL) {
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Start webserver: %s", port);
- (*admin)->port = strdup(port);
-
- }
- else {
- char* endptr = port;
- int currentPort = strtol(port, &endptr, 10);
-
- errno = 0;
-
- if (*endptr || errno != 0) {
- currentPort = strtol(DEFAULT_PORT, NULL, 10);
- }
-
- port_counter++;
- snprintf(&newPort[0], 6, "%d", (currentPort+1));
-
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting rsa server on port %s - retrying on port %s...", port, newPort);
- port = newPort;
- }
- } while(((*admin)->ctx == NULL) && (port_counter < MAX_NUMBER_OF_RESTARTS));
-
- }
- return status;
-}
-
-
-celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin)
-{
- celix_status_t status = CELIX_SUCCESS;
-
- free((*admin)->ip);
- free((*admin)->port);
- free(*admin);
-
- *admin = NULL;
-
- return status;
-}
-
-celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin) {
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&admin->exportedServicesLock);
-
- hash_map_iterator_pt iter = hashMapIterator_create(admin->exportedServices);
- while (hashMapIterator_hasNext(iter)) {
- array_list_pt exports = hashMapIterator_nextValue(iter);
- int i;
- for (i = 0; i < arrayList_size(exports); i++) {
- export_registration_pt export = arrayList_get(exports, i);
- exportRegistration_stopTracking(export);
- }
- }
- hashMapIterator_destroy(iter);
- celixThreadMutex_unlock(&admin->exportedServicesLock);
-
- celixThreadMutex_lock(&admin->importedServicesLock);
-
- iter = hashMapIterator_create(admin->importedServices);
- while (hashMapIterator_hasNext(iter))
- {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-
- import_registration_factory_pt importFactory = hashMapEntry_getValue(entry);
-
- if (importFactory != NULL) {
- int i;
- for (i = 0; i < arrayList_size(importFactory->registrations); i++)
- {
- import_registration_pt importRegistration = arrayList_get(importFactory->registrations, i);
-
- if (importFactory->trackedFactory != NULL)
- {
- importFactory->trackedFactory->unregisterProxyService(importFactory->trackedFactory->factory, importRegistration->endpointDescription);
- }
- }
-
- serviceTracker_close(importFactory->proxyFactoryTracker);
- importRegistrationFactory_close(importFactory);
-
- hashMapIterator_remove(iter);
- importRegistrationFactory_destroy(&importFactory);
- }
- }
- hashMapIterator_destroy(iter);
- celixThreadMutex_unlock(&admin->importedServicesLock);
-
- if (admin->ctx != NULL) {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Stopping webserver...");
- mg_stop(admin->ctx);
- admin->ctx = NULL;
- }
-
- hashMap_destroy(admin->exportedServices, false, false);
- hashMap_destroy(admin->importedServices, false, false);
-
- logHelper_stop(admin->loghelper);
- logHelper_destroy(&admin->loghelper);
-
- return status;
-}
-
-/**
- * Request: http://host:port/services/{service}/{request}
- */
-//void *remoteServiceAdmin_callback(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info) {
-
-static int remoteServiceAdmin_callback(struct mg_connection *conn) {
- int result = 0; // zero means: let civetweb handle it further, any non-zero value means it is handled by us...
-
- const struct mg_request_info *request_info = mg_get_request_info(conn);
- if (request_info->uri != NULL) {
- remote_service_admin_pt rsa = request_info->user_data;
-
-
- if (strncmp(request_info->uri, "/service/", 9) == 0 && strcmp("POST", request_info->request_method) == 0) {
-
- // uri = /services/myservice/call
- const char *uri = request_info->uri;
- // rest = myservice/call
-
- const char *rest = uri+9;
- char *interfaceStart = strchr(rest, '/');
- int pos = interfaceStart - rest;
- char service[pos+1];
- strncpy(service, rest, pos);
- service[pos] = '\0';
- long serviceId = atol(service);
-
- celixThreadMutex_lock(&rsa->exportedServicesLock);
-
- //find endpoint
- export_registration_pt export = NULL;
- hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- array_list_pt exports = hashMapEntry_getValue(entry);
- int expIt = 0;
- for (expIt = 0; expIt < arrayList_size(exports); expIt++) {
- export_registration_pt check = arrayList_get(exports, expIt);
- if (serviceId == check->endpointDescription->serviceId) {
- export = check;
- break;
- }
- }
- }
- hashMapIterator_destroy(iter);
-
- if (export != NULL) {
- uint64_t datalength = request_info->content_length;
- char* data = malloc(datalength + 1);
- mg_read(conn, data, datalength);
- data[datalength] = '\0';
-
- char *response = NULL;
-
- //FIXME assuming add signature (add(double, double) : double)
- /*TODO
- export->endpoint->handleRequest(export->endpoint->endpoint, data, &response);
- */
-
-
- //retreive schema.
- char *schema = NULL;
- schema = properties_get(export->endpointDescription->properties, "protocol.schema");
- printf("RSA: got schema %s\n", schema);
-
-
- printf("Parsing data: %s\n", data);
- json_error_t error;
- json_t *js_request = json_loads(data, 0, &error);
- 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 {
- printf("RSA: got error '%s' for '%s'\n", error.text, data);
- return 0;
- }
-
- printf("RSA: Looking for method %s\n", sig);
-
- json_t *js_schema = json_loads(schema, 0, &error);
- int methodIndex = -1;
- if (js_schema) {
- //TODO parse schema and create cif
- size_t index;
- json_t *value;
- json_array_foreach(js_schema, index, value) {
- if (strcmp(sig, json_string_value(value)) == 0) {
- //found match
- methodIndex = index;
- break;
- }
- }
- } else {
- printf("RSA: got error '%s' for '%s'\n", error.text, schema);
- return 0;
- }
-
- if (methodIndex < 0) {
- printf("RSA: cannot find method '%s'\n", sig);
- return 1;
- }
-
- size_t sigLength = strlen(sig);
- char provArgs[sigLength];
- bool startFound = false;
- int i = 0;
- int argIndex = 0;
- for (; i < sigLength; i += 1) {
- if (!startFound) {
- if (sig[i] == '(') {
- startFound = true;
- }
- } else {
- if (sig[i] != ')') {
- provArgs[argIndex++] = sig[i];
- }
- }
- }
- provArgs[argIndex] = '\0';
- size_t provArgsLength = strlen(provArgs) -1;
- printf("method index is %i and args are '%s'\n", methodIndex, provArgs);
-
-
- //FFI part
- ffi_cif cif;
- ffi_type *argTypes[provArgsLength + 2]; //e.g. void *handle (extra), double a, double b, double *result (extra)
- void *valuePointers[provArgsLength + 2];
- //note assuming doubles!!
- double values[provArgsLength];
- double result = 0.0;
- double *resultPointer = &result;
- int rvalue = 0;
-
- argTypes[0] = &ffi_type_pointer;
- argTypes[provArgsLength +1] = &ffi_type_pointer; //last argument is return value, handled as a pointer
- for (i = 0; i < provArgsLength; i += 1) {
- //FIXME for now assuming double as arguments
- argTypes[i+1] = &ffi_type_double;
- }
-
- valuePointers[0] = NULL;
- valuePointers[provArgsLength+1] = &resultPointer;
- for (i = 0; i < provArgsLength; i += 1) {
- values[i] = 0.0;
- valuePointers[i+1] = &(values[i]);
- }
-
- json_t *arguments = json_object_get(js_request, "a");
- json_t *value;
- size_t index;
- json_array_foreach(arguments, index, value) {
- values[index] = json_real_value(value); //setting values, again assuming double
- }
-
- json_decref(js_schema);
- json_decref(js_request);
-
- if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, provArgsLength + 2,
- &ffi_type_sint, argTypes) == FFI_OK)
- {
- printf("RSA: FFI PREP OK\n");
-
- //TRYING TO CALL Calculate service
- void *service = NULL;
- bundleContext_getService(rsa->context, export->reference, &service);
- if (service == NULL) {
- printf("RSA: Ouch service is NULL\n");
- return 0;
- } else {
- printf("RSA: service ok\n");
- }
-
- struct generic_service_layout *serv = service;
-
- printf("RSA:Trying to call service using ffi\n");
- valuePointers[0] = serv->handle;
- ffi_call(&cif, serv->functions[methodIndex], &rvalue, valuePointers);
- printf("RSA: Done calling service through ffi, got value %f\n", result);
-
- json_t *resultRoot;
- resultRoot = json_pack("{s:f}", "r", result);
- response = json_dumps(resultRoot, 0);
- json_decref(resultRoot);
- }
-
- if (response != NULL) {
- mg_write(conn, data_response_headers, strlen(data_response_headers));
-// mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
- mg_write(conn, response, strlen(response));
-// mg_send_data(conn, response, strlen(response));
-// mg_write_data(conn, response, strlen(response));
-
- free(response);
- } else {
- mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
- }
- result = 0;
-
- free(data);
- } else {
- //TODO log warning
- }
-
- celixThreadMutex_unlock(&rsa->exportedServicesLock);
-
- }
- }
-
- return 1;
-}
-
-celix_status_t remoteServiceAdmin_handleRequest(remote_service_admin_pt rsa, char *service, char *data, char **reply) {
- celixThreadMutex_lock(&rsa->exportedServicesLock);
-
- hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- array_list_pt exports = hashMapEntry_getValue(entry);
- int expIt = 0;
- for (expIt = 0; expIt < arrayList_size(exports); expIt++) {
- export_registration_pt export = arrayList_get(exports, expIt);
- if (strcmp(service, export->endpointDescription->service) == 0) {
- export->endpoint->handleRequest(export->endpoint->endpoint, data, reply);
- }
- }
- }
- hashMapIterator_destroy(iter);
-
- celixThreadMutex_unlock(&rsa->exportedServicesLock);
-
- return CELIX_SUCCESS;
-}
-
-celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations) {
- celix_status_t status = CELIX_SUCCESS;
- arrayList_create(registrations);
- array_list_pt references = NULL;
- service_reference_pt reference = NULL;
- char filter [256];
-
- snprintf(filter, 256, "(%s=%s)", (char *)OSGI_FRAMEWORK_SERVICE_ID, serviceId);
-
- bundleContext_getServiceReferences(admin->context, NULL, filter, &references); //FIXME not safe
-
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: exportService called for serviceId %s", serviceId);
-
- if (arrayList_size(references) >= 1) {
- reference = arrayList_get(references, 0);
- }
-
- if(references!=NULL){
- arrayList_destroy(references);
- }
-
- if (reference == NULL) {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "ERROR: expected a reference for service id %s.", serviceId);
- return CELIX_ILLEGAL_STATE;
- }
-
- char *exports = NULL;
- char *provided = NULL;
- char *schema = NULL;
- serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports);
- serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_OBJECTCLASS, &provided);
- serviceReference_getProperty(reference, (char *) "protocol.schema", &schema);
-
- if (exports == NULL || provided == NULL) {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No Services to export.");
- status = CELIX_ILLEGAL_STATE;
- } else {
- if (schema == NULL) {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: no protocol.schema found.");
- status = CELIX_ILLEGAL_STATE;
- } else {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Export service (%s)", provided);
-
- char *interface = provided;
- endpoint_description_pt endpoint = NULL;
- export_registration_pt registration = NULL;
-
- remoteServiceAdmin_createEndpointDescription(admin, reference, interface, &endpoint);
- printf("RSA: Creating export registration with endpoint pointer %p\n", endpoint);
- exportRegistration_create(admin->loghelper, reference, endpoint, admin, admin->context, ®istration);
- arrayList_add(*registrations, registration);
-
- exportRegistration_open(registration);
- exportRegistration_startTracking(registration);
-
- celixThreadMutex_lock(&admin->exportedServicesLock);
- hashMap_put(admin->exportedServices, reference, *registrations);
- celixThreadMutex_unlock(&admin->exportedServicesLock);
- }
- }
- return status;
-}
-
-celix_status_t remoteServiceAdmin_removeExportedService(export_registration_pt registration) {
- celix_status_t status = CELIX_SUCCESS;
- remote_service_admin_pt admin = registration->rsa;
-
- celixThreadMutex_lock(&admin->exportedServicesLock);
-
- hashMap_remove(admin->exportedServices, registration->reference);
-
- celixThreadMutex_unlock(&admin->exportedServicesLock);
-
- return status;
-}
-
-static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, char *interface, endpoint_description_pt *endpoint) {
- celix_status_t status = CELIX_SUCCESS;
- properties_pt endpointProperties = properties_create();
-
-
- unsigned int size = 0;
- char **keys;
-
- serviceReference_getPropertyKeys(reference, &keys, &size);
- for (int i = 0; i < size; i++) {
- char *key = keys[i];
- char *value = NULL;
-
- if (serviceReference_getProperty(reference, key, &value) == CELIX_SUCCESS
- && strcmp(key, (char*) OSGI_RSA_SERVICE_EXPORTED_INTERFACES) != 0
- && strcmp(key, (char*) OSGI_FRAMEWORK_OBJECTCLASS) != 0) {
- properties_set(endpointProperties, key, value);
- printf("Added property '%s' with value '%s'\n", key, value);
- }
- }
-
- hash_map_entry_pt entry = hashMap_getEntry(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
-
- char* key = hashMapEntry_getKey(entry);
- char *serviceId = (char *) hashMap_remove(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
- char *uuid = NULL;
-
- char buf[512];
- snprintf(buf, 512, "/service/%s/%s", serviceId, interface);
-
- char url[1024];
- snprintf(url, 1024, "http://%s:%s%s", admin->ip, admin->port, buf);
-
- uuid_t endpoint_uid;
- uuid_generate(endpoint_uid);
- char endpoint_uuid[37];
- uuid_unparse_lower(endpoint_uid, endpoint_uuid);
-
- bundleContext_getProperty(admin->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
- properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
- properties_set(endpointProperties, (char*) OSGI_FRAMEWORK_OBJECTCLASS, interface);
- properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_SERVICE_ID, serviceId);
- properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID, endpoint_uuid);
- properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED, "true");
- properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED_CONFIGS, (char*) CONFIGURATION_TYPE);
- properties_set(endpointProperties, (char*) ENDPOINT_URL, url);
-
-
-
- *endpoint = calloc(1, sizeof(**endpoint));
- if (!*endpoint) {
- status = CELIX_ENOMEM;
- } else {
- (*endpoint)->id = properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID);
- char *serviceId = NULL;
- serviceReference_getProperty(reference, (char*) OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
- (*endpoint)->serviceId = strtoull(serviceId, NULL, 0);
- (*endpoint)->frameworkUUID = properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
- (*endpoint)->service = interface;
- (*endpoint)->properties = endpointProperties;
- }
-
- free(key);
- free(serviceId);
- free(keys);
-
- return status;
-}
-
-static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip) {
- celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
- struct ifaddrs *ifaddr, *ifa;
- char host[NI_MAXHOST];
-
- if (getifaddrs(&ifaddr) != -1)
- {
- for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
- {
- if (ifa->ifa_addr == NULL)
- continue;
-
- if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
- if (interface == NULL) {
- *ip = strdup(host);
- status = CELIX_SUCCESS;
- }
- else if (strcmp(ifa->ifa_name, interface) == 0) {
- *ip = strdup(host);
- status = CELIX_SUCCESS;
- }
- }
- }
-
- freeifaddrs(ifaddr);
- }
-
- return status;
-}
-
-
-celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description)
-{
- celix_status_t status = CELIX_SUCCESS;
-
- properties_destroy((*description)->properties);
- free(*description);
-
- return status;
-}
-
-
-celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services) {
- celix_status_t status = CELIX_SUCCESS;
- return status;
-}
-
-celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services) {
- celix_status_t status = CELIX_SUCCESS;
- return status;
-}
-
-
-static int remoteServiceAdmin_remoteFunctionProxy(ffi_cif *cif, int *ret, void* args[], void *userData); //TODO MOVE
-static int remoteServiceAdmin_remoteFunctionProxy(ffi_cif *cif, int *ret, void* args[], void *userData) {
- void **handle = args[0];
- remote_service_admin_pt admin = (*handle);
-
- struct proxy *proxy = userData;
-
- printf("ffi closure got called for method sig %s with index %i\n", proxy->sig, proxy->index);
-
- json_t *root = json_object();
- json_t *sig = json_string(proxy->sig);
- json_object_set(root, "m", sig);
-
- json_t *arguments = json_array();
- int i;
- for (i = 1; i < proxy->cif.nargs -1; i += 1) {
- //NOTE assuming double
- double *dval = args[i];
- json_t *value = json_real(*dval);
- json_array_append(arguments, value);
- }
- json_object_set(root, "a", arguments);
-
- char *data = json_dumps(root, 0);
- char *reply = NULL;
- int replyStatus;
-
- remoteServiceAdmin_send(proxy->admin, proxy->endpointDescription, data, &reply, &replyStatus);
- (*ret) = replyStatus;
- printf("got reply from server '%s'\n", reply);
-
- json_error_t error;
- json_t *js_reply = json_loads(reply, JSON_DECODE_ANY, &error);
- if (js_reply) {
- //note assuming double
- double **result = args[proxy->cif.nargs - 1];
- json_unpack(js_reply, "{s:f}", "r", *result);
- json_decref(js_reply);
- } else {
- printf("PROXY: got error '%s' for '%s'\n", error.text, reply);
- }
-
- json_decref(root);
-
- free(data);
- free(reply);
-
- return 0;
-}
-
-
-celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpointDescription, import_registration_pt *registration) {
- celix_status_t status = CELIX_SUCCESS;
-
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Import service %s", endpointDescription->service);
-
- char *schema = properties_get(endpointDescription->properties, "protocol.schema");
- if (schema == NULL) {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: protocol schema not found for endpoint\n");
- return CELIX_SUCCESS;
- }
-
- printf("protocol.schema is '%s'\n", schema);
- json_error_t error;
- json_t *js_schema = json_loads(schema, 0, &error);
- if (js_schema) {
- //TODO parse schema and create cif
- size_t numOfMethods = json_array_size(js_schema);
- printf("RSA: num of method for proxy is %i\n", (int) numOfMethods);
-
- struct generic_service_layout *service = calloc(1, sizeof(*service) + (numOfMethods-1) * sizeof(GEN_FUNC_TYPE));
- service->handle = admin;
-
- //struct generic_service_layout {
- // void *handle;
- // GEN_FUNC_TYPE functions[];
- //};
-
- size_t index;
- json_t *value;
- json_array_foreach(js_schema, index, value) {
- //create closure
-
- char *sig = json_string_value(value);
- size_t sigLength = strlen(sig);
- char provArgs[sigLength];
- bool startFound = false;
- int i = 0;
- int argIndex = 0;
- for (; i < sigLength; i += 1) {
- if (!startFound) {
- if (sig[i] == '(') {
- startFound = true;
- }
- } else {
- if (sig[i] != ')') {
- provArgs[argIndex++] = sig[i];
- }
- }
- }
- provArgs[argIndex] = '\0';
- printf("method index is %i and args are '%s'\n", index, provArgs);
-
- int provArgLength = strlen(provArgs) -1;
-
- struct proxy *proxy = malloc(sizeof(*proxy));
- proxy->admin = admin;
- proxy->sig = strdup(sig);
- proxy->index = index;
- proxy->endpointDescription = endpointDescription;
-
- ffi_type **args = calloc(provArgLength +2, sizeof(ffi_type)); //TODO test if this can be on the stack
-
- void (*function)(void);
- proxy->closure = ffi_closure_alloc(sizeof(ffi_closure), &function);
- service->functions[index] = function;
-
- /* Initialize the argument info vectors */
- args[0] = &ffi_type_pointer;
- args[provArgLength + 1] = &ffi_type_pointer;
- for (i = 0; i < provArgLength; i += 1) {
- args[i+1] = &ffi_type_double;
- }
-
- if (proxy->closure) {
- if (ffi_prep_cif(&proxy->cif, FFI_DEFAULT_ABI, provArgLength + 2, &ffi_type_sint, args) == FFI_OK) {
- if (ffi_prep_closure_loc(proxy->closure, &proxy->cif, remoteServiceAdmin_remoteFunctionProxy, proxy, function) == FFI_OK) {
- printf("RSA: created closure for method '%s'\n", sig);
- }
- }
- }
- }
-
- //TODO register with imported properties
- char *objectClass = properties_get(endpointDescription->properties, "objectClass");
- service_registration_pt reg = NULL;
- bundleContext_registerService(admin->context, objectClass, service, NULL, ®);
- printf("registered proxy service with objectclass '%s'\n", objectClass);
-
- } else {
- printf("RSA: got error '%s' for '%s'\n", error.text, schema);
- return CELIX_ILLEGAL_STATE;
- }
-
-
- //celixThreadMutex_lock(&admin->importedServicesLock);
- //celixThreadMutex_unlock(&admin->importedServicesLock);
-
-
- return status;
- /*
-
- celixThreadMutex_lock(&admin->importedServicesLock);
-
- import_registration_factory_pt registration_factory = (import_registration_factory_pt) hashMap_get(admin->importedServices, endpointDescription->service);
-
- // check whether we already have a registration_factory registered in the hashmap
- if (registration_factory == NULL)
- {
- status = importRegistrationFactory_install(admin->loghelper, endpointDescription->service, admin->context, ®istration_factory);
- if (status == CELIX_SUCCESS) {
- hashMap_put(admin->importedServices, endpointDescription->service, registration_factory);
- }
- }
-
- // factory available
- if (status != CELIX_SUCCESS || (registration_factory->trackedFactory == NULL))
- {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: no proxyFactory available.");
- if (status == CELIX_SUCCESS) {
- status = CELIX_SERVICE_EXCEPTION;
- }
- }
- else
- {
- // we create an importRegistration per imported service
- importRegistration_create(endpointDescription, admin, (sendToHandle) &remoteServiceAdmin_send, admin->context, registration);
- registration_factory->trackedFactory->registerProxyService(registration_factory->trackedFactory->factory, endpointDescription, admin, (sendToHandle) &remoteServiceAdmin_send);
-
- arrayList_add(registration_factory->registrations, *registration);
- }
-
- celixThreadMutex_unlock(&admin->importedServicesLock);
-
-
- return status;
- */
-}
-
-
-celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration) {
- celix_status_t status = CELIX_SUCCESS;
- return status;
- /*
-
- endpoint_description_pt endpointDescription = (endpoint_description_pt) registration->endpointDescription;
- import_registration_factory_pt registration_factory = NULL;
-
- celixThreadMutex_lock(&admin->importedServicesLock);
-
- registration_factory = (import_registration_factory_pt) hashMap_get(admin->importedServices, endpointDescription->service);
-
- // factory available
- if ((registration_factory == NULL) || (registration_factory->trackedFactory == NULL))
- {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: Error while retrieving registration factory for imported service %s", endpointDescription->service);
- }
- else
- {
- registration_factory->trackedFactory->unregisterProxyService(registration_factory->trackedFactory->factory, endpointDescription);
- arrayList_removeElement(registration_factory->registrations, registration);
- importRegistration_destroy(registration);
-
- if (arrayList_isEmpty(registration_factory->registrations))
- {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: closing proxy.");
-
- serviceTracker_close(registration_factory->proxyFactoryTracker);
- importRegistrationFactory_close(registration_factory);
-
- hashMap_remove(admin->importedServices, endpointDescription->service);
-
- importRegistrationFactory_destroy(®istration_factory);
- }
- }
-
- celixThreadMutex_unlock(&admin->importedServicesLock);
-
- return status;
- */
-}
-
-
-celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) {
-
- struct post post;
- post.readptr = request;
- post.size = strlen(request);
-
- struct get get;
- get.size = 0;
- get.writeptr = malloc(1);
-
- char *serviceUrl = properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
- char url[256];
- snprintf(url, 256, "%s", serviceUrl);
-
- // assume the default timeout
- int timeout = DEFAULT_TIMEOUT;
-
- char *timeoutStr = NULL;
- // Check if the endpoint has a timeout, if so, use it.
- timeoutStr = properties_get(endpointDescription->properties, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT);
- if (timeoutStr == NULL) {
- // If not, get the global variable and use that one.
- bundleContext_getProperty(rsa->context, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr);
- }
-
- // Update timeout if a property is used to set it.
- if (timeoutStr != NULL) {
- timeout = atoi(timeoutStr);
- }
-
- celix_status_t status = CELIX_SUCCESS;
- CURL *curl;
- CURLcode res;
-
- curl = curl_easy_init();
- if(!curl) {
- status = CELIX_ILLEGAL_STATE;
- } else {
- curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
- curl_easy_setopt(curl, CURLOPT_URL, &url[0]);
- curl_easy_setopt(curl, CURLOPT_POST, 1L);
- curl_easy_setopt(curl, CURLOPT_READFUNCTION, remoteServiceAdmin_readCallback);
- curl_easy_setopt(curl, CURLOPT_READDATA, &post);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&get);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)post.size);
- res = curl_easy_perform(curl);
- curl_easy_cleanup(curl);
-
- *reply = get.writeptr;
- *replyStatus = res;
- }
-
- return status;
-}
-
-static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp) {
- struct post *post = userp;
-
- if (post->size) {
- *(char *) ptr = post->readptr[0];
- post->readptr++;
- post->size--;
- return 1;
- }
-
- return 0;
-}
-
-static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp) {
- size_t realsize = size * nmemb;
- struct get *mem = (struct get *)userp;
-
- mem->writeptr = realloc(mem->writeptr, mem->size + realsize + 1);
- if (mem->writeptr == NULL) {
- /* out of memory! */
- printf("not enough memory (realloc returned NULL)");
- exit(EXIT_FAILURE);
- }
-
- memcpy(&(mem->writeptr[mem->size]), contents, realsize);
- mem->size += realsize;
- mem->writeptr[mem->size] = 0;
-
- return realsize;
-}
-
-
-celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
- celix_status_t status = CELIX_SUCCESS;
-
- *endpoint = reference->endpoint;
-
- return status;
-}
-
-celix_status_t exportReference_getExportedService(export_reference_pt reference) {
- celix_status_t status = CELIX_SUCCESS;
- return status;
-}
-
-celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
- celix_status_t status = CELIX_SUCCESS;
- return status;
-}
-
-celix_status_t importReference_getImportedService(import_reference_pt reference) {
- celix_status_t status = CELIX_SUCCESS;
- return status;
-}
[04/10] celix git commit: CELIX-237: Moved dynamic function interface
under remote_service_admin_dfi
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/json_serializer.c
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/json_serializer.c b/remote_services/dynamic_function_interface/json_serializer.c
deleted file mode 100644
index 614e948..0000000
--- a/remote_services/dynamic_function_interface/json_serializer.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#include "json_serializer.h"
-#include "dyn_type.h"
-
-#include <jansson.h>
-#include <assert.h>
-#include <stdint.h>
-#include <string.h>
-
-static int jsonSerializer_createObject(dyn_type *type, json_t *object, void **result);
-static int jsonSerializer_parseObject(dyn_type *type, json_t *object, void *inst);
-static int jsonSerializer_parseObjectMember(dyn_type *type, const char *name, json_t *val, void *inst);
-static int jsonSerializer_parseSequence(dyn_type *seq, json_t *array, void *seqLoc);
-static int jsonSerializer_parseAny(dyn_type *type, void *input, json_t *val);
-
-static int jsonSerializer_writeAny(dyn_type *type, void *input, json_t **val);
-
-static int jsonSerializer_writeComplex(dyn_type *type, void *input, json_t **val);
-
-static int jsonSerializer_writeSequence(dyn_type *type, void *input, json_t **out);
-
-static int OK = 0;
-static int ERROR = 1;
-
-DFI_SETUP_LOG(jsonSerializer);
-
-int jsonSerializer_deserialize(dyn_type *type, const char *input, void **result) {
- assert(dynType_type(type) == DYN_TYPE_COMPLEX);
- int status = 0;
-
- json_error_t error;
- json_t *root = json_loads(input, JSON_DECODE_ANY, &error);
-
- if (root != NULL) {
- if (json_is_object(root)) {
- status = jsonSerializer_createObject(type, root, result);
- } else {
- status = ERROR;
- LOG_ERROR("Error expected root element to be an object");
- }
- json_decref(root);
- } else {
- status = ERROR;
- LOG_ERROR("Error parsing json input '%s'. Error is %s\n", input, error.text);
- }
-
- return status;
-}
-
-static int jsonSerializer_createObject(dyn_type *type, json_t *object, void **result) {
- assert(object != NULL);
- int status = OK;
-
- void *inst = NULL;
- status = dynType_alloc(type, &inst);
-
- if (status == OK) {
- assert(inst != NULL);
- status = jsonSerializer_parseObject(type, object, inst);
-
- if (status != OK) {
- dynType_free(type, inst);
- }
- }
-
- if (status == OK) {
- *result = inst;
- }
-
- return status;
-}
-
-static int jsonSerializer_parseObject(dyn_type *type, json_t *object, void *inst) {
- assert(object != NULL);
- int status = 0;
- json_t *value;
- const char *key;
-
- json_object_foreach(object, key, value) {
- status = jsonSerializer_parseObjectMember(type, key, value, inst);
- if (status != OK) {
- break;
- }
- }
-
- return status;
-}
-
-static int jsonSerializer_parseObjectMember(dyn_type *type, const char *name, json_t *val, void *inst) {
- int status = OK;
- int index = dynType_complex_indexForName(type, name);
- void *valp = NULL;
- dyn_type *valType = NULL;
-
- status = dynType_complex_valLocAt(type, index, inst, &valp);
-
- if (status == OK ) {
- status = dynType_complex_dynTypeAt(type, index, &valType);
- }
-
- if (status == OK) {
- status = jsonSerializer_parseAny(valType, valp, val);
- }
-
- return status;
-}
-
-static int jsonSerializer_parseAny(dyn_type *type, void *loc, json_t *val) {
- int status = OK;
-
- dyn_type *subType = NULL;
- char c = dynType_descriptorType(type);
-
- float *f; //F
- double *d; //D
- char *b; //B
- int *n; //N
- int16_t *s; //S
- int32_t *i; //I
- int64_t *l; //J
- uint16_t *us; //s
- uint32_t *ui; //i
- uint64_t *ul; //j
-
- switch (c) {
- case 'F' :
- f = loc;
- *f = (float) json_real_value(val);
- break;
- case 'D' :
- d = loc;
- *d = json_real_value(val);
- break;
- case 'N' :
- n = loc;
- *n = (int) json_real_value(val);
- break;
- case 'B' :
- b = loc;
- *b = (char) json_integer_value(val);
- break;
- case 'S' :
- s = loc;
- *s = (int16_t) json_integer_value(val);
- break;
- case 'I' :
- i = loc;
- *i = (int32_t) json_integer_value(val);
- break;
- case 'J' :
- l = loc;
- *l = (int64_t) json_integer_value(val);
- break;
- case 's' :
- us = loc;
- *us = (uint16_t) json_integer_value(val);
- break;
- case 'i' :
- ui = loc;
- *ui = (uint32_t) json_integer_value(val);
- break;
- case 'j' :
- ul = loc;
- *ul = (uint64_t) json_integer_value(val);
- break;
- case 't' :
- if (json_is_string(val)) {
- dynType_text_allocAndInit(type, loc, json_string_value(val));
- } else {
- status = ERROR;
- LOG_ERROR("Expected json string type got %i", json_typeof(val));
- }
- break;
- case '[' :
- if (json_is_array(val)) {
- status = jsonSerializer_parseSequence(type, val, loc);
- } else {
- status = ERROR;
- LOG_ERROR("Expected json array type got '%i'", json_typeof(val));
- }
- break;
- case '{' :
- if (status == OK) {
- status = jsonSerializer_parseObject(type, val, loc);
- }
- break;
- case '*' :
- status = dynType_typedPointer_getTypedType(type, &subType);
- if (status == OK) {
- status = jsonSerializer_createObject(subType, val, (void **)loc);
- }
- break;
- case 'P' :
- status = ERROR;
- LOG_WARNING("Untyped pointer are not supported for serialization");
- break;
- default :
- status = ERROR;
- LOG_ERROR("Error provided type '%c' not supported for JSON\n", dynType_descriptorType(type));
- break;
- }
-
- return status;
-}
-
-static int jsonSerializer_parseSequence(dyn_type *seq, json_t *array, void *seqLoc) {
- assert(dynType_type(seq) == DYN_TYPE_SEQUENCE);
- int status = OK;
-
- size_t size = json_array_size(array);
- LOG_DEBUG("Allocating sequence with capacity %zu", size);
- status = dynType_sequence_alloc(seq, seqLoc, (int) size);
-
- if (status == OK) {
- dyn_type *itemType = dynType_sequence_itemType(seq);
- size_t index;
- json_t *val;
- json_array_foreach(array, index, val) {
- void *valLoc = NULL;
- status = dynType_sequence_increaseLengthAndReturnLastLoc(seq, seqLoc, &valLoc);
- LOG_DEBUG("Got sequence loc %p", valLoc);
-
- if (status == OK) {
- status = jsonSerializer_parseAny(itemType, valLoc, val);
- if (status != OK) {
- break;
- }
- }
- }
- }
-
- return status;
-}
-
-int jsonSerializer_serialize(dyn_type *type, void *input, char **output) {
- int status = OK;
-
- json_t *root = NULL;
- status = jsonSerializer_writeAny(type, input, &root);
-
- if (status == OK) {
- *output = json_dumps(root, JSON_COMPACT);
- json_decref(root);
- }
-
- return status;
-}
-
-static int jsonSerializer_writeAny(dyn_type *type, void *input, json_t **out) {
- int status = OK;
-
- int descriptor = dynType_descriptorType(type);
- json_t *val = NULL;
- dyn_type *subType = NULL;
-
- float *f; //F
- double *d; //D
- char *b; //B
- int *n; //N
- int16_t *s; //S
- int32_t *i; //I
- int64_t *l; //J
- uint16_t *us; //s
- uint32_t *ui; //i
- uint64_t *ul; //j
-
- switch (descriptor) {
- case 'B' :
- b = input;
- val = json_integer((json_int_t)*b);
- break;
- case 'S' :
- s = input;
- val = json_integer((json_int_t)*s);
- break;
- case 'I' :
- i = input;
- val = json_integer((json_int_t)*i);
- break;
- case 'J' :
- l = input;
- val = json_integer((json_int_t)*l);
- break;
- case 's' :
- us = input;
- val = json_integer((json_int_t)*us);
- break;
- case 'i' :
- ui = input;
- val = json_integer((json_int_t)*ui);
- break;
- case 'j' :
- ul = input;
- val = json_integer((json_int_t)*ul);
- break;
- case 'N' :
- n = input;
- val = json_integer((json_int_t)*n);
- break;
- case 'F' :
- f = input;
- val = json_real((double) *f);
- break;
- case 'D' :
- d = input;
- val = json_real(*d);
- break;
- case 't' :
- val = json_string(*(const char **) input);
- break;
- case '*' :
- status = dynType_typedPointer_getTypedType(type, &subType);
- if (status == OK) {
- status = jsonSerializer_writeAny(subType, *(void **)input, &val);
- }
- break;
- case '{' :
- status = jsonSerializer_writeComplex(type, input, &val);
- break;
- case '[' :
- status = jsonSerializer_writeSequence(type, input, &val);
- break;
- case 'P' :
- LOG_WARNING("Untyped pointer not supported for serialization. ignoring");
- break;
- default :
- LOG_ERROR("Unsupported descriptor '%c'", descriptor);
- status = ERROR;
- break;
- }
-
- if (status == OK && val != NULL) {
- *out = val;
- }
-
- return status;
-}
-
-static int jsonSerializer_writeSequence(dyn_type *type, void *input, json_t **out) {
- assert(dynType_type(type) == DYN_TYPE_SEQUENCE);
- int status = OK;
-
- json_t *array = json_array();
- dyn_type *itemType = dynType_sequence_itemType(type);
- uint32_t len = dynType_sequence_length(input);
-
- int i = 0;
- void *itemLoc = NULL;
- json_t *item = NULL;
- for (i = 0; i < len; i += 1) {
- item = NULL;
- status = dynType_sequence_locForIndex(type, input, i, &itemLoc);
- if (status == OK) {
- status = jsonSerializer_writeAny(itemType, itemLoc, &item);
- if (status == OK) {
- json_array_append(array, item);
- json_decref(item);
- }
- }
-
- if (status != OK) {
- break;
- }
- }
-
- if (status == OK && array != NULL) {
- *out = array;
- }
-
- return status;
-}
-
-static int jsonSerializer_writeComplex(dyn_type *type, void *input, json_t **out) {
- assert(dynType_type(type) == DYN_TYPE_COMPLEX);
- int status = OK;
-
- json_t *val = json_object();
- struct complex_type_entry *entry = NULL;
- struct complex_type_entries_head *entries = NULL;
- int index = -1;
-
- status = dynType_complex_entries(type, &entries);
- if (status == OK) {
- TAILQ_FOREACH(entry, entries, entries) {
- void *subLoc = NULL;
- json_t *subVal = NULL;
- dyn_type *subType = NULL;
- index = dynType_complex_indexForName(type, entry->name);
- status = dynType_complex_valLocAt(type, index, input, &subLoc);
- if (status == OK ) {
- status = dynType_complex_dynTypeAt(type, index, &subType);
- }
- if (status == OK) {
- status = jsonSerializer_writeAny(subType, subLoc, &subVal);
- }
- if (status == OK) {
- json_object_set(val, entry->name, subVal);
- json_decref(subVal);
- }
-
- if (status != OK) {
- break;
- }
- }
- }
-
- if (status == OK && val != NULL) {
- *out = val;
- }
-
- return status;
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/json_serializer.h
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/json_serializer.h b/remote_services/dynamic_function_interface/json_serializer.h
deleted file mode 100644
index eb2e629..0000000
--- a/remote_services/dynamic_function_interface/json_serializer.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#ifndef __JSON_SERIALIZER_H_
-#define __JSON_SERIALIZER_H_
-
-#include "dfi_log_util.h"
-#include "dyn_type.h"
-
-//logging
-DFI_SETUP_LOG_HEADER(jsonSerializer);
-
-int jsonSerializer_deserialize(dyn_type *type, const char *input, void **result);
-int jsonSerializer_serialize(dyn_type *type, void *input, char **output);
-
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/memstream/README.md
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/memstream/README.md b/remote_services/dynamic_function_interface/memstream/README.md
deleted file mode 100644
index 476810e..0000000
--- a/remote_services/dynamic_function_interface/memstream/README.md
+++ /dev/null
@@ -1,49 +0,0 @@
-fmemopen for Mac OS and iOS
-===========================
-
-Originally ported from [ingenuitas python-tesseract](https://github.com/ingenuitas/python-tesseract/blob/master/fmemopen.c). Ported by Jeff Verkoeyen under the Apache 2.0 License.
-
-From the fmemopen man page:
-
-> FILE *fmemopen(void *buf, size_t size, const char *mode);
->
-> The fmemopen() function opens a stream that permits the access specified by mode. The stream
-> allows I/O to be performed on the string or memory buffer pointed to by buf. This buffer must be
-> at least size bytes long.
-
-Alas, this method does not exist on BSD operating systems (specifically Mac OS X and iOS). It is
-possible to recreate this functionality using a BSD-specific method called `funopen`.
-
-From the funopen man page:
-
-> FILE * funopen(const void *cookie, int (*readfn)(void *, char *, int),
-> int (*writefn)(void *, const char *, int), fpos_t (*seekfn)(void *, fpos_t, int),
-> int (*closefn)(void *));
->
-> The funopen() function associates a stream with up to four ``I/O functions''. Either readfn or
-> writefn must be specified; the others can be given as an appropriately-typed NULL pointer. These
-> I/O functions will be used to read, write, seek and close the new stream.
-
-fmemopen.c provides a simple implementation of fmemopen using funopen so that you can create FILE
-pointers to blocks of memory.
-
-Adding it to your Project
-=========================
-
-Drag fmemopen.h and fmemopen.c to your project and add them to your target. `#include "fmemopen.h"`
-wherever you need to use `fmemopen`.
-
-Examples
-========
-
-```obj-c
-#import "fmemopen.h"
-
-NSString* string = @"fmemopen in Objective-C";
-const char* cstr = [string UTF8String];
-FILE* file = fmemopen((void *)cstr, sizeof(char) * (string.length + 1), "r");
-
-// fread on file will now read the contents of the NSString
-
-fclose(file);
-```
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/memstream/fmemopen.c
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/memstream/fmemopen.c b/remote_services/dynamic_function_interface/memstream/fmemopen.c
deleted file mode 100644
index 926ce36..0000000
--- a/remote_services/dynamic_function_interface/memstream/fmemopen.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * fmem.c : fmemopen() on top of BSD's funopen()
- * 20081017 AF
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef linux
-struct fmem {
- size_t pos;
- size_t size;
- char *buffer;
-};
-typedef struct fmem fmem_t;
-
-static int readfn(void *handler, char *buf, int size)
-{
- int count = 0;
- fmem_t *mem = handler;
- size_t available = mem->size - mem->pos;
-
- if(size > available) size = available;
- for(count=0; count < size; mem->pos++, count++)
- buf[count] = mem->buffer[mem->pos];
-
- return count;
-}
-
-static int writefn(void *handler, const char *buf, int size)
-{
- int count = 0;
- fmem_t *mem = handler;
- size_t available = mem->size - mem->pos;
-
- if(size > available) size = available;
- for(count=0; count < size; mem->pos++, count++)
- mem->buffer[mem->pos] = buf[count];
-
- return count; // ? count : size;
-}
-
-static fpos_t seekfn(void *handler, fpos_t offset, int whence)
-{
- size_t pos;
- fmem_t *mem = handler;
-
- switch(whence) {
- case SEEK_SET: pos = offset; break;
- case SEEK_CUR: pos = mem->pos + offset; break;
- case SEEK_END: pos = mem->size + offset; break;
- default: return -1;
- }
-
- if(pos < 0 || pos > mem->size) return -1;
-
- mem->pos = pos;
- return (fpos_t) pos;
-}
-
-static int closefn(void *handler)
-{
- free(handler);
- return 0;
-}
-
-/* simple, but portable version of fmemopen for OS X / BSD */
-FILE *fmemopen(void *buf, size_t size, const char *mode)
-{
- fmem_t *mem = (fmem_t *) malloc(sizeof(fmem_t));
-
- memset(mem, 0, sizeof(fmem_t));
- mem->size = size, mem->buffer = buf;
- return funopen(mem, readfn, writefn, seekfn, closefn);
-}
-#endif
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/memstream/fmemopen.h
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/memstream/fmemopen.h b/remote_services/dynamic_function_interface/memstream/fmemopen.h
deleted file mode 100644
index 3d06b20..0000000
--- a/remote_services/dynamic_function_interface/memstream/fmemopen.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright 2012 Jeff Verkoeyen
-// Originally ported from https://github.com/ingenuitas/python-tesseract/blob/master/fmemopen.c
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef FMEMOPEN_H_
-#define FMEMOPEN_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * A BSD port of the fmemopen Linux method using funopen.
- *
- * man docs for fmemopen:
- * http://linux.die.net/man/3/fmemopen
- *
- * man docs for funopen:
- * https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/funopen.3.html
- *
- * This method is ported from ingenuitas' python-tesseract project.
- *
- * You must call fclose on the returned file pointer or memory will be leaked.
- *
- * @param buf The data that will be used to back the FILE* methods. Must be at least
- * @c size bytes.
- * @param size The size of the @c buf data.
- * @param mode The permitted stream operation modes.
- * @returns A pointer that can be used in the fread/fwrite/fseek/fclose family of methods.
- * If a failure occurred NULL will be returned.
- */
-FILE *fmemopen(void *buf, size_t size, const char *mode);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // #ifndef FMEMOPEN_H_
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/memstream/open_memstream.c
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/memstream/open_memstream.c b/remote_services/dynamic_function_interface/memstream/open_memstream.c
deleted file mode 100644
index 6bc4f01..0000000
--- a/remote_services/dynamic_function_interface/memstream/open_memstream.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/* Use funopen(3) to provide open_memstream(3) like functionality. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-struct memstream {
- char **cp;
- size_t *lenp;
- size_t offset;
-};
-
-static void
-memstream_grow(struct memstream *ms, size_t newsize)
-{
- char *buf;
-
- if (newsize > *ms->lenp) {
- buf = realloc(*ms->cp, newsize + 1);
- if (buf != NULL) {
-#ifdef DEBUG
- fprintf(stderr, "MS: %p growing from %zd to %zd\n",
- ms, *ms->lenp, newsize);
-#endif
- memset(buf + *ms->lenp + 1, 0, newsize - *ms->lenp);
- *ms->cp = buf;
- *ms->lenp = newsize;
- }
- }
-}
-
-static int
-memstream_read(void *cookie, char *buf, int len)
-{
- struct memstream *ms;
- int tocopy;
-
- ms = cookie;
- memstream_grow(ms, ms->offset + len);
- tocopy = *ms->lenp - ms->offset;
- if (len < tocopy)
- tocopy = len;
- memcpy(buf, *ms->cp + ms->offset, tocopy);
- ms->offset += tocopy;
-#ifdef DEBUG
- fprintf(stderr, "MS: read(%p, %d) = %d\n", ms, len, tocopy);
-#endif
- return (tocopy);
-}
-
-static int
-memstream_write(void *cookie, const char *buf, int len)
-{
- struct memstream *ms;
- int tocopy;
-
- ms = cookie;
- memstream_grow(ms, ms->offset + len);
- tocopy = *ms->lenp - ms->offset;
- if (len < tocopy)
- tocopy = len;
- memcpy(*ms->cp + ms->offset, buf, tocopy);
- ms->offset += tocopy;
-#ifdef DEBUG
- fprintf(stderr, "MS: write(%p, %d) = %d\n", ms, len, tocopy);
-#endif
- return (tocopy);
-}
-
-static fpos_t
-memstream_seek(void *cookie, fpos_t pos, int whence)
-{
- struct memstream *ms;
-#ifdef DEBUG
- size_t old;
-#endif
-
- ms = cookie;
-#ifdef DEBUG
- old = ms->offset;
-#endif
- switch (whence) {
- case SEEK_SET:
- ms->offset = pos;
- break;
- case SEEK_CUR:
- ms->offset += pos;
- break;
- case SEEK_END:
- ms->offset = *ms->lenp + pos;
- break;
- }
-#ifdef DEBUG
- fprintf(stderr, "MS: seek(%p, %zd, %d) %zd -> %zd\n", ms, pos, whence,
- old, ms->offset);
-#endif
- return (ms->offset);
-}
-
-static int
-memstream_close(void *cookie)
-{
-
- free(cookie);
- return (0);
-}
-
-FILE *
-open_memstream(char **cp, size_t *lenp)
-{
- struct memstream *ms;
- int save_errno;
- FILE *fp;
-
- *cp = NULL;
- *lenp = 0;
- ms = malloc(sizeof(*ms));
- ms->cp = cp;
- ms->lenp = lenp;
- ms->offset = 0;
- fp = funopen(ms, memstream_read, memstream_write, memstream_seek,
- memstream_close);
- if (fp == NULL) {
- save_errno = errno;
- free(ms);
- errno = save_errno;
- }
- return (fp);
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/memstream/open_memstream.h
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/memstream/open_memstream.h b/remote_services/dynamic_function_interface/memstream/open_memstream.h
deleted file mode 100644
index e87bb0a..0000000
--- a/remote_services/dynamic_function_interface/memstream/open_memstream.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef OPEN_MEMSTREAM_H_
-#define OPEN_MEMSTREAM_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-FILE *open_memstream(char **cp, size_t *lenp);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // #ifndef FMEMOPEN_H_
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/schemas/complex.avdl
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/schemas/complex.avdl b/remote_services/dynamic_function_interface/schemas/complex.avdl
deleted file mode 100644
index 0490dcd..0000000
--- a/remote_services/dynamic_function_interface/schemas/complex.avdl
+++ /dev/null
@@ -1,11 +0,0 @@
-protocol Complex {
-
- record StatResult {
- double sum;
- double min;
- double max;
- array<double> input;
- }
-
- StatResult stats(array<double> input);
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/schemas/complex.avpr
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/schemas/complex.avpr b/remote_services/dynamic_function_interface/schemas/complex.avpr
deleted file mode 100644
index 0577397..0000000
--- a/remote_services/dynamic_function_interface/schemas/complex.avpr
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "protocol" : "Complex",
- "namespace" : null,
- "types" : [ {
- "type" : "record",
- "name" : "StatResult",
- "fields" : [ {
- "name" : "sum",
- "type" : "double"
- }, {
- "name" : "min",
- "type" : "double"
- }, {
- "name" : "max",
- "type" : "double"
- }, {
- "name" : "input",
- "type" : {
- "type" : "array",
- "items" : "double"
- }
- } ]
- } ],
- "messages" : {
- "stats" : {
- "request" : [ {
- "name" : "input",
- "type" : {
- "type" : "array",
- "items" : "double"
- }
- } ],
- "response" : "StatResult"
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/schemas/invalid1.avpr
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/schemas/invalid1.avpr b/remote_services/dynamic_function_interface/schemas/invalid1.avpr
deleted file mode 100644
index c968c61..0000000
--- a/remote_services/dynamic_function_interface/schemas/invalid1.avpr
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "protocol" : "Complex",
- "namespace" : null,
- "types" : [ {
- "type" : "record",
- "name" : "StatResult",
- "fields" : [ {
- "name" : "sum",
- "type" : "double"
- }, {
- "name" : "min",
- "type" : "double"
- }, {
- "name" : "max",
- "type" : "double"
- }, {
- "name" : "input",
- "type" : {
- "type" : "array",
- "items" : "double"
- }
- } ]
- } ],
- "messages" : {
- "stats" : {
- "response" : "StatResult"
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/schemas/invalid2.avpr
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/schemas/invalid2.avpr b/remote_services/dynamic_function_interface/schemas/invalid2.avpr
deleted file mode 100644
index fc48ca9..0000000
--- a/remote_services/dynamic_function_interface/schemas/invalid2.avpr
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "protocol" : "Simple",
- "types" : [ ],
- "messages" : {
- "sum" : {
- "request" : [ {
- "name" : "a"
- }, {
- "name" : "b",
- "type" : "double"
- } ],
- "response" : "double"
- },
- "sub" : {
- "request" : [ {
- "name" : "a",
- "type" : "double"
- }, {
- "name" : "b",
- "type" : "double"
- } ],
- "response" : "double"
- },
- "sqrt" : {
- "request" : [ {
- "name" : "a"
- } ],
- "response" : "double"
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/schemas/simple.avdl
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/schemas/simple.avdl b/remote_services/dynamic_function_interface/schemas/simple.avdl
deleted file mode 100644
index cd5cafe..0000000
--- a/remote_services/dynamic_function_interface/schemas/simple.avdl
+++ /dev/null
@@ -1,6 +0,0 @@
-@namespace("org.apache.avro.test")
-protocol Simple {
- double sum(double a, double b);
- double sub(double a, double b);
- double sqrt(double a);
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/schemas/simple.avpr
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/schemas/simple.avpr b/remote_services/dynamic_function_interface/schemas/simple.avpr
deleted file mode 100644
index 8a90bb2..0000000
--- a/remote_services/dynamic_function_interface/schemas/simple.avpr
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "protocol" : "Simple",
- "types" : [ ],
- "messages" : {
- "sum" : {
- "request" : [ {
- "name" : "a",
- "type" : "double"
- }, {
- "name" : "b",
- "type" : "double"
- } ],
- "response" : "double"
- },
- "sub" : {
- "request" : [ {
- "name" : "a",
- "type" : "double"
- }, {
- "name" : "b",
- "type" : "double"
- } ],
- "response" : "double"
- },
- "sqrt" : {
- "request" : [ {
- "name" : "a",
- "type" : "double"
- } ],
- "response" : "double"
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/schemas/simple_min.avpr
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/schemas/simple_min.avpr b/remote_services/dynamic_function_interface/schemas/simple_min.avpr
deleted file mode 100644
index c2bce19..0000000
--- a/remote_services/dynamic_function_interface/schemas/simple_min.avpr
+++ /dev/null
@@ -1 +0,0 @@
-{"protocol":"Simple","types":[],"messages":{"sum":{"request":[{"name":"a","type":"double"},{"name":"b","type":"double"}],"response":"double"},"sub":{"request":[{"name":"a","type":"double"},{"name":"b","type":"double"}],"response":"double"},"sqrt":{"request":[{"name":"a","type":"double"}],"response":"double"}}}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/tst/avro_descriptor_translator_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/tst/avro_descriptor_translator_tests.cpp b/remote_services/dynamic_function_interface/tst/avro_descriptor_translator_tests.cpp
deleted file mode 100644
index 63401e5..0000000
--- a/remote_services/dynamic_function_interface/tst/avro_descriptor_translator_tests.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#include <CppUTest/TestHarness.h>
-#include "CppUTest/CommandLineTestRunner.h"
-
-extern "C" {
-
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-
-#include "dyn_common.h"
-#include "descriptor_translator.h"
-
-#if defined(BSD) || defined(__APPLE__)
-#include "open_memstream.h"
-#include "fmemopen.h"
-#endif
-
- static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
- va_list ap;
- const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
- fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
- va_start(ap, msg);
- vfprintf(stderr, msg, ap);
- fprintf(stderr, "\n");
- }
-
-
- static char *readSchema(const char *file) {
- size_t size = 0;
- char *ptr = NULL;
-
- FILE *schema = fopen(file, "r");
- FILE *stream = open_memstream(&ptr, &size);
-
- assert(schema != NULL);
- assert(stream != NULL);
-
- int c = fgetc(schema);
- while (c != EOF ) {
- fputc(c, stream);
- c = fgetc(schema);
- }
- fclose(schema);
- fclose(stream);
-
- assert(ptr != NULL);
- return ptr;
- }
-
- static dyn_interface_type *createInterfaceInfo(const char *schemaFile) {
- char *schema = readSchema(schemaFile);
- dyn_interface_type *ift= NULL;
-
- int status = descriptorTranslator_translate(schema, &ift);
- CHECK_EQUAL(0, status);
-
- free(schema);
- return ift;
- }
-
- static int countMethodInfos(dyn_interface_type *info) {
- int count = 0;
- method_info_type *mInfo = NULL;
- TAILQ_FOREACH(mInfo, &info->methodInfos, entries) {
- count +=1;
- }
- return count;
- }
-
- static int countTypeInfos(dyn_interface_type *info) {
- int count = 0;
- type_info_type *tInfo = NULL;
- TAILQ_FOREACH(tInfo, &info->typeInfos, entries) {
- count +=1;
- }
- return count;
- }
-
- static void simple(void) {
- //first argument void *handle, last argument output pointer for result and return int with status for exception handling
- //sum(DD)D -> sum(PDD*D)N
- //sub(DD)D -> sub(PDD*D)N
- //sqrt(D)D -> sqrt(PD*D)N
-
- dyn_interface_type *intf = createInterfaceInfo("schemas/simple.avpr");
-
- int count = countMethodInfos(intf);
- CHECK_EQUAL(3, count);
-
- count = countTypeInfos(intf);
- CHECK_EQUAL(0, count);
-
- method_info_type *mInfo = NULL;
- TAILQ_FOREACH(mInfo, &intf->methodInfos, entries) {
- if (strcmp("sum", mInfo->name) == 0) {
- STRCMP_EQUAL("sum(PDD*D)N", mInfo->descriptor);
- } else if (strcmp("add", mInfo->name) == 0) {
- STRCMP_EQUAL("add(PDD*D)N", mInfo->descriptor);
- } else if (strcmp("sqrt", mInfo->name) == 0) {
- STRCMP_EQUAL("sqrt(PD*D)N", mInfo->descriptor);
- }
- }
-
- dynInterface_destroy(intf);
- }
-
- static void complex(void) {
- dyn_interface_type *intf = createInterfaceInfo("schemas/complex.avpr");
-
- int count = countMethodInfos(intf);
- CHECK_EQUAL(1, count);
-
- method_info_type *mInfo = TAILQ_FIRST(&intf->methodInfos);
- STRCMP_EQUAL("stats", mInfo->name);
- STRCMP_EQUAL("stats(P[D*LStatResult;)N", mInfo->descriptor);
-
- count = countTypeInfos(intf);
- CHECK_EQUAL(1, count);
-
- type_info_type *tInfo = TAILQ_FIRST(&intf->typeInfos);
- STRCMP_EQUAL("StatResult", tInfo->name);
- STRCMP_EQUAL("{DDD[D sum min max input}", tInfo->descriptor);
-
- dynInterface_destroy(intf);
- }
-
- static void invalid(const char *file) {
- char *schema = readSchema(file);
- dyn_interface_type *ift= NULL;
-
- int status = descriptorTranslator_translate(schema, &ift);
- CHECK(status != 0);
-
- free(schema);
- }
-}
-
-TEST_GROUP(AvroDescTranslatorTest) {
- void setup() {
- descriptorTranslator_logSetup(stdLog, NULL, 3);
- dynInterface_logSetup(stdLog, NULL, 3);
- dynType_logSetup(stdLog, NULL, 3);
- dynCommon_logSetup(stdLog, NULL, 3);
- }
-};
-
-TEST(AvroDescTranslatorTest, simple) {
- simple();
-}
-
-TEST(AvroDescTranslatorTest, complex) {
- complex();
-}
-
-TEST(AvroDescTranslatorTest, invalid1) {
- invalid("schemas/invalid1.avpr");
-}
-
-TEST(AvroDescTranslatorTest, invalid2) {
- invalid("schemas/invalid2.avpr");
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/tst/dyn_closure_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/tst/dyn_closure_tests.cpp b/remote_services/dynamic_function_interface/tst/dyn_closure_tests.cpp
deleted file mode 100644
index b2b11d7..0000000
--- a/remote_services/dynamic_function_interface/tst/dyn_closure_tests.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#include <CppUTest/TestHarness.h>
-#include "CppUTest/CommandLineTestRunner.h"
-
-extern "C" {
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "dyn_common.h"
-#include "dyn_function.h"
-
-static int g_count;
-
-static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
- va_list ap;
- const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
- fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
- va_start(ap, msg);
- vfprintf(stderr, msg, ap);
- fprintf(stderr, "\n");
-}
-
-#define EXAMPLE1_DESCRIPTOR "example(III)I"
-static void example1_binding(void *userData, void* args[], void *out) {
- int32_t a = *((int32_t *)args[0]);
- int32_t b = *((int32_t *)args[1]);
- int32_t c = *((int32_t *)args[2]);
- int32_t *ret = (int32_t *)out;
- *ret = a + b + c;
- g_count += 1;
-}
-
-#define EXAMPLE2_DESCRIPTOR "example(I{DDD val1 val2 val3}I)D"
-struct example2_arg2 {
- double val1;
- double val2;
- double val3;
-};
-void example2_binding(void *userData, void* args[], void *out) {
- int32_t a = *((int32_t *)args[0]);
- struct example2_arg2 b = *((struct example2_arg2 *)args[1]);
- int32_t c = *((int32_t *)args[2]);
- double *ret = (double *)out;
- *ret = a + b.val1 + b.val2 + b.val3 + c;
- g_count += 1;
-}
-
-
-#define EXAMPLE3_DESCRIPTOR "example(III){III sum max min}"
-struct example3_ret {
- int32_t sum;
- int32_t max;
- int32_t min;
-};
-
-static void example3_binding(void *userData, void* args[], void *out) {
- int32_t a = *((int32_t *)args[0]);
- int32_t b = *((int32_t *)args[1]);
- int32_t c = *((int32_t *)args[2]);
- struct example3_ret *result = (struct example3_ret *)calloc(1,sizeof(struct example3_ret));
- result->sum = a + b + c;
- result->min = a <= b ? a : b;
- result->max = a >= b ? a : b;
- result->min = result->min <= c ? result->min : c;
- result->max = result->max >= c ? result->max : c;
-
- struct example3_ret **ret = (struct example3_ret **)out;
- (*ret) = result;
- g_count += 1;
-}
-
-static void tests() {
- dyn_function_type *dynFunction = NULL;
- int rc = 0;
-
- {
- int32_t (*func)(int32_t a, int32_t b, int32_t c) = NULL;
- rc = dynFunction_parseWithStr(EXAMPLE1_DESCRIPTOR, NULL, &dynFunction);
- CHECK_EQUAL(0, rc);
- rc = dynFunction_createClosure(dynFunction, example1_binding, NULL, (void(**)(void))&func);
- CHECK_EQUAL(0, rc);
- int32_t ret = func(2,3,4);
- CHECK_EQUAL(1, g_count);
- CHECK_EQUAL(9, ret);
- dynFunction_destroy(dynFunction);
- }
-
- {
- double (*func)(int32_t a, struct example2_arg2 b, int32_t c) = NULL;
- double (*func2)(int32_t a, struct example2_arg2 b, int32_t c) = NULL;
- dynFunction = NULL;
- rc = dynFunction_parseWithStr(EXAMPLE2_DESCRIPTOR, NULL, &dynFunction);
- CHECK_EQUAL(0, rc);
- rc = dynFunction_createClosure(dynFunction, example2_binding, NULL, (void(**)(void))&func);
- CHECK_EQUAL(0, rc);
- rc = dynFunction_getFnPointer(dynFunction, (void(**)(void))&func2);
- CHECK_EQUAL(0, rc);
- CHECK(func == func2);
- struct example2_arg2 b;
- b.val1 = 1.0;
- b.val2 = 1.5;
- b.val3 = 2.0;
- double ret = func(2,b,4);
- CHECK_EQUAL(2, g_count);
- CHECK_EQUAL(10.5, ret);
- dynFunction_destroy(dynFunction);
- }
-
- {
- struct example3_ret * (*func)(int32_t a, int32_t b, int32_t c) = NULL;
- dynFunction = NULL;
- rc = dynFunction_parseWithStr(EXAMPLE3_DESCRIPTOR, NULL, &dynFunction);
- CHECK_EQUAL(0, rc);
- rc = dynFunction_createClosure(dynFunction, example3_binding, NULL, (void(**)(void))&func);
- CHECK_EQUAL(0, rc);
- struct example3_ret *ret = func(2,8,4);
- CHECK_EQUAL(3, g_count);
- CHECK_EQUAL(14, ret->sum);
- dynFunction_destroy(dynFunction);
- free(ret);
- }
-}
-
-}
-
-
-TEST_GROUP(DynClosureTests) {
- void setup() {
- dynFunction_logSetup(stdLog, NULL, 3);
- dynType_logSetup(stdLog, NULL, 3);
- //TODO dynType_logSetup(stdLog, NULL, 4);
- dynCommon_logSetup(stdLog, NULL, 3);
- g_count = 0;
- }
-};
-
-TEST(DynClosureTests, DynCLosureTest1) {
- //TODO split up
- tests();
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/tst/dyn_function_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/tst/dyn_function_tests.cpp b/remote_services/dynamic_function_interface/tst/dyn_function_tests.cpp
deleted file mode 100644
index 410b3ec..0000000
--- a/remote_services/dynamic_function_interface/tst/dyn_function_tests.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#include <CppUTest/TestHarness.h>
-#include "CppUTest/CommandLineTestRunner.h"
-
-extern "C" {
- #include <stdio.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
-
- #include "dyn_common.h"
- #include "dyn_function.h"
-
- static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
- va_list ap;
- const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
- fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
- va_start(ap, msg);
- vfprintf(stderr, msg, ap);
- fprintf(stderr, "\n");
- }
-
- #define EXAMPLE1_DESCRIPTOR "example(III)I"
- int32_t example1(int32_t a, int32_t b, int32_t c) {
- CHECK_EQUAL(2, a);
- CHECK_EQUAL(4, b);
- CHECK_EQUAL(8, c);
- return 1;
- }
-
- void test_example1(void) {
- dyn_function_type *dynFunc = NULL;
- int rc;
- void (*fp)(void) = (void (*)(void)) example1;
-
- rc = dynFunction_parseWithStr(EXAMPLE1_DESCRIPTOR, NULL, &dynFunc);
- CHECK_EQUAL(0, rc);
-
- int32_t a = 2;
- int32_t b = 4;
- int32_t c = 8;
- void *values[3];
- int32_t rVal = 0;
- values[0] = &a;
- values[1] = &b;
- values[2] = &c;
-
- rc = dynFunction_call(dynFunc, fp, &rVal, values);
- CHECK_EQUAL(0, rc);
- CHECK_EQUAL(1, rVal);
- dynFunction_destroy(dynFunc);
- }
-
- #define EXAMPLE2_DESCRIPTOR "example(I{IID val1 val2 val3}D)D"
- struct example2_arg {
- int32_t val1;
- int32_t val2;
- double val3;
- };
-
- double example2(int32_t arg1, struct example2_arg arg2, double arg3) {
- CHECK_EQUAL(2, arg1);
- CHECK_EQUAL(2, arg2.val1);
- CHECK_EQUAL(3, arg2.val2);
- CHECK_EQUAL(4.1, arg2.val3);
- CHECK_EQUAL(8.1, arg3);
- return 2.2;
- }
-
- void test_example2(void) {
- dyn_function_type *dynFunc = NULL;
- int rc;
- void (*fp)(void) = (void (*)(void)) example2;
-
- rc = dynFunction_parseWithStr(EXAMPLE2_DESCRIPTOR, NULL, &dynFunc);
- CHECK_EQUAL(0, rc);
-
- int32_t arg1 = 2;
- struct example2_arg arg2;
- arg2.val1 = 2;
- arg2.val2 = 3;
- arg2.val3 = 4.1;
- double arg3 = 8.1;
- double returnVal = 0;
- void *values[3];
- values[0] = &arg1;
- values[1] = &arg2;
- values[2] = &arg3;
-
- rc = dynFunction_call(dynFunc, fp, &returnVal, values);
- CHECK_EQUAL(0, rc);
- CHECK_EQUAL(2.2, returnVal);
- dynFunction_destroy(dynFunc);
- }
-}
-
-TEST_GROUP(DynFunctionTests) {
- void setup() {
- dynFunction_logSetup(stdLog, NULL, 3);
- dynType_logSetup(stdLog, NULL, 3);
- dynCommon_logSetup(stdLog, NULL, 3);
- }
-};
-
-TEST(DynFunctionTests, DynFuncTest1) {
- test_example1();
-}
-
-TEST(DynFunctionTests, DynFuncTest2) {
- test_example2();
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/tst/dyn_interface_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/tst/dyn_interface_tests.cpp b/remote_services/dynamic_function_interface/tst/dyn_interface_tests.cpp
deleted file mode 100644
index 6453afd..0000000
--- a/remote_services/dynamic_function_interface/tst/dyn_interface_tests.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#include <CppUTest/TestHarness.h>
-#include "CppUTest/CommandLineTestRunner.h"
-extern "C" {
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-
-#include "dyn_common.h"
-#include "dyn_interface.h"
-
-#if defined(BSD) || defined(__APPLE__)
-#include "open_memstream.h"
-#include "fmemopen.h"
-#endif
-
- static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
- va_list ap;
- const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
- fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
- va_start(ap, msg);
- vfprintf(stderr, msg, ap);
- fprintf(stderr, "\n");
- }
-
- static void test1(void) {
- int status = 0;
- dyn_interface_type *dynIntf = NULL;
- FILE *desc = fopen("descriptors/example1.descriptor", "r");
- assert(desc != NULL);
- status = dynInterface_parse(desc, &dynIntf);
- CHECK_EQUAL(0, status);
- fclose(desc);
-
- char *name = NULL;
- status = dynInterface_getName(dynIntf, &name);
- CHECK_EQUAL(0, status);
- STRCMP_EQUAL("calculator", name);
-
- char *version = NULL;
- status = dynInterface_getVersion(dynIntf, &version);
- CHECK_EQUAL(0, status);
- STRCMP_EQUAL("1.0.0", version);
-
- char *annVal = NULL;
- status = dynInterface_getAnnotationEntry(dynIntf, "classname", &annVal);
- CHECK_EQUAL(0, status);
- STRCMP_EQUAL("org.example.Calculator", annVal);
-
- char *nonExist = NULL;
- status = dynInterface_getHeaderEntry(dynIntf, "nonExisting", &nonExist);
- CHECK(status != 0);
- CHECK(nonExist == NULL);
-
- dynInterface_destroy(dynIntf);
- }
-
-}
-
-
-TEST_GROUP(DynInterfaceTests) {
- void setup() {
- int level = 1;
- dynCommon_logSetup(stdLog, NULL, level);
- dynType_logSetup(stdLog, NULL, level);
- dynFunction_logSetup(stdLog, NULL, level);
- dynInterface_logSetup(stdLog, NULL, level);
- }
-};
-
-TEST(DynInterfaceTests, test1) {
- test1();
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/tst/dyn_type_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/tst/dyn_type_tests.cpp b/remote_services/dynamic_function_interface/tst/dyn_type_tests.cpp
deleted file mode 100644
index 96f64fa..0000000
--- a/remote_services/dynamic_function_interface/tst/dyn_type_tests.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#include <CppUTest/TestHarness.h>
-#include "CppUTest/CommandLineTestRunner.h"
-
-extern "C" {
- #include <string.h>
- #include <stdarg.h>
-
- #include "dyn_common.h"
- #include "dyn_type.h"
-
- static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
- va_list ap;
- const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
- fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
- va_start(ap, msg);
- vfprintf(stderr, msg, ap);
- fprintf(stderr, "\n");
- }
-
- static void runTest(const char *descriptorStr, const char *exName) {
- dyn_type *type;
- int i;
- type = NULL;
- //printf("\n-- example %s with descriptor string '%s' --\n", exName, descriptorStr);
- int status = dynType_parseWithStr(descriptorStr, exName, NULL, &type);
- CHECK_EQUAL(0, status);
-
- FILE *stream = fopen("/dev/null", "w");
- dynType_print(type, stream);
- fclose(stream);
- dynType_destroy(type);
- //printf("--\n\n");
- }
-}
-
-TEST_GROUP(DynTypeTests) {
- void setup() {
- dynType_logSetup(stdLog, NULL, 0);
- }
-};
-
-#define EX1 "{BbJjIiSsDFNN arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12}"
-#define EX2 "{D{DD b_1 b_2}I a b c}"
-#define EX3 "Tsub={DD b_1 b_2};{DLsub;I a b c}"
-#define EX4 "{[I numbers}"
-#define EX5 "[[{DD{iii val3_1 val3_2 val3_3} val1 val2 val3}"
-#define EX6 "Tsample={DD vala valb};Lsample;"
-#define EX7 "Tsample={DD vala valb};[Lsample;"
-#define EX8 "[Tsample={DD a b};Lsample;"
-#define EX9 "*D"
-#define EX10 "Tsample={DD a b};******Lsample;"
-#define EX11 "Tsample=D;Lsample;"
-#define EX12 "Tnode={Lnode;Lnode; left right};{Lnode; head}" //note recursive example
-#define EX13 "Ttype={DDDDD a b c d e};{ltype;Ltype;ltype;Ltype; byVal1 byRef1 byVal2 ByRef2}"
-#define EX14 "{DD{FF{JJ}{II*{ss}}}}" //unnamed fields
-
-#define CREATE_EXAMPLES_TEST(DESC) \
- TEST(DynTypeTests, ParseTestExample ## DESC) { \
- runTest(DESC, #DESC); \
- }
-
-CREATE_EXAMPLES_TEST(EX1)
-CREATE_EXAMPLES_TEST(EX2)
-CREATE_EXAMPLES_TEST(EX3)
-CREATE_EXAMPLES_TEST(EX4)
-CREATE_EXAMPLES_TEST(EX5)
-CREATE_EXAMPLES_TEST(EX6)
-CREATE_EXAMPLES_TEST(EX7)
-CREATE_EXAMPLES_TEST(EX8)
-CREATE_EXAMPLES_TEST(EX9)
-CREATE_EXAMPLES_TEST(EX10)
-CREATE_EXAMPLES_TEST(EX11)
-CREATE_EXAMPLES_TEST(EX12)
-CREATE_EXAMPLES_TEST(EX13)
-CREATE_EXAMPLES_TEST(EX14)
-
-TEST(DynTypeTests, ParseRandomGarbageTest) {
- /*
- unsigned int seed = 4148;
- char *testRandom = getenv("DYN_TYPE_TEST_RANDOM");
- if (testRandom != NULL && strcmp("true", testRandom) == 0) {
- seed = (unsigned int) time(NULL);
- }
- srandom(seed);
- size_t nrOfTests = 100;
-
- printf("\nStarting test with random seed %i and nrOfTests %zu.\n", seed, nrOfTests);
-
- int i;
- int k;
- int c;
- int sucesses = 0;
- char descriptorStr[32];
- descriptorStr[31] = '\0';
- for(i = 0; i < nrOfTests; i += 1) {
- for(k = 0; k < 31; k += 1) {
- do {
- c = (char) (((random() * 128) / RAND_MAX) - 1);
- } while (!isprint(c));
- descriptorStr[k] = c;
- if (c == '\0') {
- break;
- }
- }
-
- //printf("ParseRandomGarbageTest iteration %i with descriptor string '%s'\n", k, descriptorStr);
- dyn_type *type = NULL;
- int status = dynType_parseWithStr(descriptorStr, NULL, NULL, &type);
- if (status == 0) {
- dynType_destroy(type);
- }
- }
- */
-}
-
-TEST(DynTypeTests, AssignTest1) {
- struct ex1 {
- int32_t a;
- int32_t b;
- int32_t c;
- };
- struct ex1 inst;
- const char *desc = "{III a b c}";
- dyn_type *type = NULL;
- int status = dynType_parseWithStr(desc, NULL, NULL, &type);
- CHECK_EQUAL(0, status);
- int32_t val1 = 2;
- int32_t val2 = 4;
- int32_t val3 = 8;
- dynType_complex_setValueAt(type, 0, &inst, &val1);
- CHECK_EQUAL(2, inst.a);
- dynType_complex_setValueAt(type, 1, &inst, &val2);
- CHECK_EQUAL(4, inst.b);
- dynType_complex_setValueAt(type, 2, &inst, &val3);
- CHECK_EQUAL(8, inst.c);
-
- dynType_destroy(type);
-}
-
-TEST(DynTypeTests, AssignTest2) {
- struct ex {
- int32_t a;
- struct {
- double a;
- double b;
- } b;
- };
- struct ex inst;
- const char *desc = "{I{DD a b} a b}";
- dyn_type *type = NULL;
- int status = dynType_parseWithStr(desc, NULL, NULL, &type);
- CHECK_EQUAL(0, status);
- int32_t a = 2;
- double b_a = 1.1;
- double b_b = 1.2;
-
- dynType_complex_setValueAt(type, 0, &inst, &a);
- CHECK_EQUAL(2, inst.a);
-
- void *loc = NULL;
- dyn_type *subType = NULL;
- dynType_complex_valLocAt(type, 1, (void *)&inst, &loc);
- dynType_complex_dynTypeAt(type, 1, &subType);
-
- dynType_complex_setValueAt(subType, 0, &inst.b, &b_a);
- CHECK_EQUAL(1.1, inst.b.a);
-
- dynType_complex_setValueAt(subType, 1, &inst.b, &b_b);
- CHECK_EQUAL(1.2, inst.b.b);
-
- dynType_destroy(type);
-}
-
-TEST(DynTypeTests, AssignTest3) {
- int simple = 1;
- dyn_type *type = NULL;
- int rc = dynType_parseWithStr("N", NULL, NULL, &type);
- CHECK_EQUAL(0, rc);
-
- int newValue = 42;
- void *loc = &simple;
- void *input = &newValue;
- dynType_simple_setValue(type, loc, input);
- CHECK_EQUAL(42, simple);
- dynType_destroy(type);
-}
-
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/tst/json_serializer_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/tst/json_serializer_tests.cpp b/remote_services/dynamic_function_interface/tst/json_serializer_tests.cpp
deleted file mode 100644
index c21d594..0000000
--- a/remote_services/dynamic_function_interface/tst/json_serializer_tests.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-/**
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#include <CppUTest/TestHarness.h>
-#include "CppUTest/CommandLineTestRunner.h"
-
-extern "C" {
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <ffi.h>
-
-#include "dyn_common.h"
-#include "dyn_type.h"
-#include "json_serializer.h"
-
-static void stdLog(void *handle, int level, const char *file, int line, const char *msg, ...) {
- va_list ap;
- const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"};
- fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line);
- va_start(ap, msg);
- vfprintf(stderr, msg, ap);
- fprintf(stderr, "\n");
-}
-
-/*********** example 1 ************************/
-/** struct type ******************************/
-const char *example1_descriptor = "{DJISF a b c d e}";
-
-const char *example1_input = "{ \
- \"a\" : 1.0, \
- \"b\" : 22, \
- \"c\" : 32, \
- \"d\" : 42, \
- \"e\" : 4.4 \
-}";
-
-struct example1 {
- double a; //0
- int64_t b; //1
- int32_t c; //2
- int16_t d; //3
- float e; //4
-};
-
-static void check_example1(void *data) {
- struct example1 *ex = (struct example1 *)data;
- CHECK_EQUAL(1.0, ex->a);
- CHECK_EQUAL(22, ex->b);
- CHECK_EQUAL(32, ex->c);
- CHECK_EQUAL(42, ex->d);
- CHECK_EQUAL(4.4f, ex->e);
-}
-
-/*********** example 2 ************************/
-const char *example2_descriptor = "{BJJDFD byte long1 long2 double1 float1 double2}";
-
-const char *example2_input = "{ \
- \"byte\" : 42, \
- \"long1\" : 232, \
- \"long2\" : 242, \
- \"double1\" : 4.2, \
- \"float1\" : 3.2, \
- \"double2\" : 4.4 \
-}";
-
-struct example2 {
- char byte; //0
- int64_t long1; //1
- int64_t long2; //2
- double double1; //3
- float float1; //4
- double double2; //5
-};
-
-static void check_example2(void *data) {
- struct example2 *ex = (struct example2 *)data;
- CHECK_EQUAL(42, ex->byte);
- CHECK_EQUAL(232, ex->long1);
- CHECK_EQUAL(242, ex->long2);
- CHECK_EQUAL(4.2, ex->double1);
- CHECK_EQUAL(3.2f, ex->float1);
- CHECK_EQUAL(4.4, ex->double2);
-}
-
-
-/*********** example 3 ************************/
-/** sequence with a simple type **************/
-const char *example3_descriptor = "{[I numbers}";
-
-const char *example3_input = "{ \
- \"numbers\" : [22,32,42] \
-}";
-
-struct example3 {
- struct {
- uint32_t cap;
- uint32_t len;
- int32_t *buf;
- } numbers;
-};
-
-static void check_example3(void *data) {
- struct example3 *ex = (struct example3 *)data;
- CHECK_EQUAL(3, ex->numbers.len);
- CHECK_EQUAL(22, ex->numbers.buf[0]);
- CHECK_EQUAL(32, ex->numbers.buf[1]);
- CHECK_EQUAL(42, ex->numbers.buf[2]);
-}
-
-/*********** example 4 ************************/
-/** structs within a struct (by reference)*******/
-const char *example4_descriptor = "{{IDD index val1 val2}{IDD index val1 val2} left right}";
-
-static const char *example4_input = "{ \
- \"left\" : {\"index\":1, \"val1\":1.0, \"val2\":2.0 }, \
- \"right\" : {\"index\":2, \"val1\":5.0, \"val2\":4.0 } \
-}";
-
-struct ex4_leaf {
- int32_t index;
- double val1;
- double val2;
-};
-
-struct example4 {
- struct ex4_leaf left;
- struct ex4_leaf right;
-};
-
-static void check_example4(void *data) {
- struct example4 *ex = (struct example4 *)data;
- CHECK_EQUAL(1, ex->left.index);
- CHECK_EQUAL(1.0, ex->left.val1);
- CHECK_EQUAL(2.0, ex->left.val2);
- CHECK_EQUAL(2, ex->right.index);
- CHECK_EQUAL(5.0, ex->right.val1);
- CHECK_EQUAL(4.0, ex->right.val2);
-}
-
-
-/*********** example 4 ************************/
-/** structs within a struct (by reference)*******/
-const char *example5_descriptor = "Tleaf={ts name age};Tnode={Lnode;Lnode;Lleaf; left right value};{Lnode; head}";
-
-static const char *example5_input = "{ \
- \"head\" : {\
- \"left\" : {\
- \"value\" : {\
- \"name\" : \"John\",\
- \"age\" : 44 \
- }\
- },\
- \"right\" : {\
- \"value\" : {\
- \"name\" : \"Peter\", \
- \"age\" : 55 \
- }\
- }\
- }\
-}";
-
-struct leaf {
- const char *name;
- uint16_t age;
-};
-
-struct node {
- struct node *left;
- struct node *right;
- struct leaf *value;
-};
-
-struct example5 {
- struct node *head;
-};
-
-static void check_example5(void *data) {
- struct example5 *ex = (struct example5 *)data;
- CHECK_TRUE(ex->head != NULL);
-
- CHECK(ex->head->left != NULL);
- CHECK(ex->head->left->value != NULL);
- STRCMP_EQUAL("John", ex->head->left->value->name);
- CHECK_EQUAL(44, ex->head->left->value->age);
- CHECK(ex->head->left->left == NULL);
- CHECK(ex->head->left->right == NULL);
-
- CHECK(ex->head->right != NULL);
- CHECK(ex->head->right->value != NULL);
- STRCMP_EQUAL("Peter", ex->head->right->value->name);
- CHECK_EQUAL(55, ex->head->right->value->age);
- CHECK(ex->head->right->left == NULL);
- CHECK(ex->head->right->right == NULL);
-}
-
-static void parseTests(void) {
- dyn_type *type;
- void *inst;
- int rc;
-
- type = NULL;
- inst = NULL;
- rc = dynType_parseWithStr(example1_descriptor, NULL, NULL, &type);
- CHECK_EQUAL(0, rc);
- rc = jsonSerializer_deserialize(type, example1_input, &inst);
- CHECK_EQUAL(0, rc);
- check_example1(inst);
- dynType_free(type, inst);
- dynType_destroy(type);
-
- type = NULL;
- inst = NULL;
- rc = dynType_parseWithStr(example2_descriptor, NULL, NULL, &type);
- CHECK_EQUAL(0, rc);
- rc = jsonSerializer_deserialize(type, example2_input, &inst);
- CHECK_EQUAL(0, rc);
- check_example2(inst);
- dynType_free(type, inst);
- dynType_destroy(type);
-
- type = NULL;
- inst = NULL;
- rc = dynType_parseWithStr(example3_descriptor, NULL, NULL, &type);
- CHECK_EQUAL(0, rc);
- rc = jsonSerializer_deserialize(type, example3_input, &inst);
- CHECK_EQUAL(0, rc);
- check_example3(inst);
- dynType_free(type, inst);
- dynType_destroy(type);
-
- type = NULL;
- inst = NULL;
- rc = dynType_parseWithStr(example4_descriptor, NULL, NULL, &type);
- CHECK_EQUAL(0, rc);
- rc = jsonSerializer_deserialize(type, example4_input, &inst);
- CHECK_EQUAL(0, rc);
- check_example4(inst);
- dynType_free(type, inst);
- dynType_destroy(type);
-
- type = NULL;
- inst = NULL;
- rc = dynType_parseWithStr(example5_descriptor, NULL, NULL, &type);
- CHECK_EQUAL(0, rc);
- rc = jsonSerializer_deserialize(type, example5_input, &inst);
- CHECK_EQUAL(0, rc);
- check_example5(inst);
- dynType_free(type, inst);
- dynType_destroy(type);
-}
-
-const char *write_example1_descriptor = "{BSIJsijFDN a b c d e f g h i j}";
-
-struct write_example1 {
- char a;
- int16_t b;
- int32_t c;
- int64_t d;
- uint16_t e;
- uint32_t f;
- uint64_t g;
- float h;
- double i;
- int j;
-};
-
-void writeTest1(void) {
- struct write_example1 ex1 = {.a=1, .b=2, .c=3, .d=4, .e=5, .f=6, .g=7, .h=8.8f, .i=9.9, .j=10};
- dyn_type *type = NULL;
- char *result = NULL;
- int rc = dynType_parseWithStr(write_example1_descriptor, "ex1", NULL, &type);
- CHECK_EQUAL(0, rc);
- rc = jsonSerializer_serialize(type, &ex1, &result);
- CHECK_EQUAL(0, rc);
- STRCMP_CONTAINS("\"a\":1", result);
- STRCMP_CONTAINS("\"b\":2", result);
- STRCMP_CONTAINS("\"c\":3", result);
- STRCMP_CONTAINS("\"d\":4", result);
- STRCMP_CONTAINS("\"e\":5", result);
- STRCMP_CONTAINS("\"f\":6", result);
- STRCMP_CONTAINS("\"g\":7", result);
- STRCMP_CONTAINS("\"h\":8.8", result);
- STRCMP_CONTAINS("\"i\":9.9", result);
- STRCMP_CONTAINS("\"j\":10", result);
- //printf("example 1 result: '%s'\n", result);
- dynType_destroy(type);
- free(result);
-}
-
-const char *write_example2_descriptor = "{*{JJ a b}{SS c d} sub1 sub2}";
-
-struct write_example2_sub {
- int64_t a;
- int64_t b;
-};
-
-struct write_example2 {
- struct write_example2_sub *sub1;
- struct {
- int16_t c;
- int16_t d;
- } sub2;
-};
-
-void writeTest2(void) {
- struct write_example2_sub sub1 = { .a = 1, .b = 2 };
- struct write_example2 ex = { .sub1 = &sub1 };
- ex.sub2.c = 3;
- ex.sub2.d = 4;
-
- dyn_type *type = NULL;
- char *result = NULL;
- int rc = dynType_parseWithStr(write_example2_descriptor, "ex2", NULL, &type);
- CHECK_EQUAL(0, rc);
- rc = jsonSerializer_serialize(type, &ex, &result);
- CHECK_EQUAL(0, rc);
- STRCMP_CONTAINS("\"a\":1", result);
- STRCMP_CONTAINS("\"b\":2", result);
- STRCMP_CONTAINS("\"c\":3", result);
- STRCMP_CONTAINS("\"d\":4", result);
- //printf("example 2 result: '%s'\n", result);
- dynType_destroy(type);
- free(result);
-}
-
-const char *write_example3_descriptor = "Tperson={ti name age};[Lperson;";
-
-struct write_example3_person {
- const char *name;
- uint32_t age;
-};
-
-struct write_example3 {
- uint32_t cap;
- uint32_t len;
- struct write_example3_person **buf;
-};
-
-void writeTest3(void) {
- struct write_example3_person p1 = {.name = "John", .age = 33};
- struct write_example3_person p2 = {.name = "Peter", .age = 44};
- struct write_example3_person p3 = {.name = "Carol", .age = 55};
- struct write_example3_person p4 = {.name = "Elton", .age = 66};
- struct write_example3 seq;
- seq.buf = (struct write_example3_person **) calloc(4, sizeof(void *));
- seq.len = seq.cap = 4;
- seq.buf[0] = &p1;
- seq.buf[1] = &p2;
- seq.buf[2] = &p3;
- seq.buf[3] = &p4;
-
- dyn_type *type = NULL;
- char *result = NULL;
- int rc = dynType_parseWithStr(write_example3_descriptor, "ex3", NULL, &type);
- CHECK_EQUAL(0, rc);
- rc = jsonSerializer_serialize(type, &seq, &result);
- CHECK_EQUAL(0, rc);
- STRCMP_CONTAINS("\"age\":33", result);
- STRCMP_CONTAINS("\"age\":44", result);
- STRCMP_CONTAINS("\"age\":55", result);
- STRCMP_CONTAINS("\"age\":66", result);
- //printf("example 3 result: '%s'\n", result);
- free(seq.buf);
- dynType_destroy(type);
- free(result);
-}
-
-}
-
-TEST_GROUP(JsonSerializerTests) {
- void setup() {
- int lvl = 1;
- dynCommon_logSetup(stdLog, NULL, lvl);
- dynType_logSetup(stdLog, NULL,lvl);
- jsonSerializer_logSetup(stdLog, NULL, lvl);
- }
-};
-
-TEST(JsonSerializerTests, ParseTests) {
- //TODO split up
- parseTests();
-}
-
-TEST(JsonSerializerTests, WriteTest1) {
- writeTest1();
-}
-
-TEST(JsonSerializerTests, WriteTest2) {
- writeTest2();
-}
-
-TEST(JsonSerializerTests, WriteTest3) {
- writeTest3();
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/tst/run_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/tst/run_tests.cpp b/remote_services/dynamic_function_interface/tst/run_tests.cpp
deleted file mode 100644
index f405c9f..0000000
--- a/remote_services/dynamic_function_interface/tst/run_tests.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#include <CppUTest/TestHarness.h>
-#include "CppUTest/CommandLineTestRunner.h"
-
-int main(int argc, char** argv) {
- return RUN_ALL_TESTS(argc, argv);
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/CMakeLists.txt b/remote_services/remote_service_admin_dfi/CMakeLists.txt
new file mode 100644
index 0000000..f74cac1
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/CMakeLists.txt
@@ -0,0 +1,52 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+celix_subproject(RSA_REMOTE_SERVICE_ADMIN_DFI "Option to enable building the Remote Service Admin Service DFI" OFF)
+if (RSA_REMOTE_SERVICE_ADMIN_DFI)
+ find_package(CURL REQUIRED)
+ find_package(Jansson REQUIRED)
+ find_package(FFI REQUIRED)
+
+ add_subdirectory(dynamic_function_interface)
+
+ include_directories(${FFI_INCLUDE_DIRS})
+ include_directories(${CURL_INCLUDE_DIRS})
+ include_directories(${JANSSON_INCLUDE_DIRS})
+ include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+ include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
+ include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/private/include")
+ include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
+ include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
+ include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/include")
+ include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_http/private/include")
+ include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
+
+ #SET_HEADER(BUNDLE_SYMBOLICNAME "apache_celix_remote_service_admin_dfi")
+ #SET(BUNDLE_VERSION "0.0.1")
+ #SET_HEADERS("Bundle-Name: Apache Celix Remote Service Admin HTTP for dynamic function interface")
+
+ #bundle(remote_service_admin_dfi SOURCES
+ # private/src/remote_service_admin_impl
+ # private/src/remote_service_admin_activator
+ # ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/export_registration_impl
+ # ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/import_registration_impl
+ # ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
+ # ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
+ #)
+ #target_link_libraries(remote_service_admin_dfi celix_framework ${CURL_LIBRARIES} ${JANSSON_LIBRARIES} ${FFI_LIBRARIES})
+
+ #install_bundle(remote_service_admin_dfi)
+endif (RSA_REMOTE_SERVICE_ADMIN_DFI)
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt b/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
new file mode 100644
index 0000000..309176f
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
@@ -0,0 +1,53 @@
+#
+# Licensed under Apache License v2. See LICENSE for more information.
+#
+find_package(Jansson REQUIRED)
+find_package(CppUTest REQUIRED)
+find_package(FFI REQUIRED)
+
+include_directories(
+ ${CPPUTEST_INCLUDE_DIR}
+ ${JANSSON_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_LIST_DIR}
+ ${FFI_INCLUDE_DIRS}
+ memstream
+)
+
+set(MEMSTREAM_SOURCES "")
+if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
+ set(MEMSTREAM_SOURCES memstream/open_memstream.c memstream/fmemopen.c)
+endif()
+
+add_library(dfi
+ dyn_common.c
+ dyn_type.c
+ dyn_function.c
+ dyn_interface.c
+ json_serializer.c
+# avro_descriptor_translator.c
+ ${MEMSTREAM_SOURCES}
+)
+target_link_libraries(dfi ${FFI_LIBRARIES} ${JANSSON_LIBRARY})
+
+
+#if (FRAMEWORK_TESTS)
+ add_executable(dfi_tests
+ tst/dyn_type_tests.cpp
+ tst/dyn_function_tests.cpp
+ tst/dyn_closure_tests.cpp
+ tst/dyn_interface_tests.cpp
+ tst/json_serializer_tests.cpp
+# tst/avro_descriptor_translator_tests.cpp
+ tst/run_tests.cpp
+ )
+ target_link_libraries(dfi_tests dfi ${FFI_LIBRARIES} ${CPPUTEST_LIBRARY} ${JANSSON_LIBRARY})
+
+ add_custom_target(copy-input
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/schemas schemas
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/descriptors descriptors
+ )
+ add_dependencies(dfi_tests copy-input)
+
+ add_test(NAME run_dfi_tests COMMAND dfi_tests)
+ SETUP_TARGET_FOR_COVERAGE(dfi_tests_cov dfi_tests ${CMAKE_BINARY_DIR}/coverage/dfi)
+#endif()
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/avro_descriptor_translator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/avro_descriptor_translator.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/avro_descriptor_translator.c
new file mode 100644
index 0000000..a9fea1d
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/avro_descriptor_translator.c
@@ -0,0 +1,319 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include "descriptor_translator.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <jansson.h>
+
+#if defined(BSD) || defined(__APPLE__)
+#include "open_memstream.h"
+#include "fmemopen.h"
+#endif
+
+DFI_SETUP_LOG(descriptorTranslator)
+
+static const int OK = 0;
+static const int MEM_ERROR = 1;
+static const int PARSE_ERROR = 2;
+static const int INV_ARG_ERROR = 2;
+
+static int descriptorTranslator_createMethodInfo(dyn_interface_type *intf, json_t *schema, const char *name, int index, json_t *message);
+static int descriptorTranslator_parseType(dyn_interface_type *intf, json_t *type);
+static int descriptorTranslator_parseMessage(json_t *schema, const char *name, json_t *message, bool asJavaSignature, char **descriptor);
+static int descriptorTranslator_parseArgument(FILE *stream, json_t *type);
+
+int descriptorTranslator_translate(const char *schemaStr, dyn_interface_type **out) {
+ LOG_DEBUG("translating descriptor for schema '%s'\n", schemaStr);
+ int status = OK;
+
+ dyn_interface_type *intf = NULL;
+ status = dynInterface_create("TODO", &intf); //TODO parse json first retreive 'Protocol' string value
+ if (status == 0) {
+ json_error_t error;
+ json_t *schema = json_loads(schemaStr, JSON_DECODE_ANY, &error);
+
+ if (schema != NULL) {
+ json_t *types = json_object_get(schema, "types");
+ if (types != NULL) {
+ json_t *type = NULL;
+ int index = 0;
+ json_array_foreach(types, index, type) {
+ status = descriptorTranslator_parseType(intf, type);
+ if (status != OK) {
+ break;
+ }
+ }
+ }
+ json_t *messages = json_object_get(schema, "messages");
+ if (status == OK && messages != NULL) {
+ const char *name;
+ json_t *message;
+ int index = 0;
+ json_object_foreach(messages, name, message) {
+ status = descriptorTranslator_createMethodInfo(intf, schema, name, index++, message);
+ if (status != OK) {
+ break;
+ }
+ }
+ }
+ json_decref(schema);
+ } else {
+ status = PARSE_ERROR;
+ printf("AVRO_DESCRIPTOR_TRANSLATOR: error parsing json input '%s'. Error is %s\n", schemaStr, error.text);
+ }
+ } else {
+ status = MEM_ERROR;
+ }
+
+
+ if (status == OK) {
+ *out = intf;
+ } else {
+ dynInterface_destroy(intf);
+ }
+ return status;
+}
+
+static int descriptorTranslator_createMethodInfo(dyn_interface_type *intf, json_t *schema, const char *name, int index, json_t *message) {
+ int status = OK;
+
+ method_info_type *mInfo = calloc(1, sizeof(*mInfo));
+ if (mInfo != NULL) {
+ mInfo->identifier = index;
+ status = descriptorTranslator_parseMessage(schema, name, message, false, &mInfo->descriptor);
+ if (status == OK) {
+ mInfo->name = strdup(name);
+ if (mInfo->name == NULL) {
+ status = MEM_ERROR;
+ } else {
+ status = descriptorTranslator_parseMessage(schema, name, message, true, &mInfo->strIdentifier);
+ }
+ }
+ } else {
+ status = MEM_ERROR;
+ }
+
+ if (status == OK) {
+ TAILQ_INSERT_TAIL(&intf->methodInfos, mInfo, entries);
+ } else {
+ if (mInfo != NULL) {
+ if (mInfo->name != NULL) {
+ free(mInfo->name);
+ }
+ if (mInfo->descriptor != NULL) {
+ free(mInfo->descriptor);
+ }
+ if (mInfo->strIdentifier != NULL) {
+ free(mInfo->strIdentifier);
+ }
+ free(mInfo);
+ }
+ }
+
+ return status;
+}
+
+static int descriptorTranslator_parseMessage(json_t *schema, const char *name, json_t *message, bool asJavaSignature, char **descriptor) {
+ int status = OK;
+ //message -> { "request" : [ {"name":"<name>", "type":"<type>"} * ], "response":"<type>" }
+ //array -> "type":"array", "items:"<type>"
+
+ char *ptr = NULL;
+ size_t ptrSize;
+ FILE *memStream = open_memstream(&ptr, &ptrSize);
+
+ if (memStream != NULL) {
+ json_t *request = json_object_get(message, "request");
+ fwrite(name, 1, strlen(name), memStream);
+ fputc('(', memStream);
+ if (!asJavaSignature) {
+ fputc('P', memStream); //handle
+ }
+
+ if (request != NULL) {
+ size_t index;
+ json_t *arg;
+ json_array_foreach(request, index, arg) {
+ //json_t *name = json_object_get(arg, "name");
+ json_t *type = json_object_get(arg, "type");
+ if (type != NULL) {
+ status = descriptorTranslator_parseArgument(memStream, type);
+ } else {
+ LOG_ERROR("expected json object with name value for request argument %zu for message/method %s\n", index, name);
+ status = PARSE_ERROR;
+ }
+ if (status != OK) {
+ break;
+ }
+ }
+ } else {
+ status = PARSE_ERROR;
+ LOG_ERROR("Expected request for message %s\n", name);
+ }
+
+ json_t *response = json_object_get(message, "response");
+ if (status == OK && response != NULL) {
+ if (asJavaSignature) {
+ fputc(')', memStream);
+ } else {
+ fputc('*', memStream); //output parameter
+ }
+ status = descriptorTranslator_parseArgument(memStream, response);
+ }
+
+ if (!asJavaSignature) {
+ fputc(')', memStream);
+ fputc('N', memStream); //error / exceptions
+ }
+ } else {
+ status = MEM_ERROR;
+ }
+
+ if (memStream != NULL) {
+ fclose(memStream);
+ if (status == OK) {
+ *descriptor = ptr;
+ } else {
+ free(ptr);
+ }
+ }
+
+ return status;
+}
+
+static const char * const PRIMITIVE_INT = "int";
+static const char * const PRIMITIVE_LONG = "long";
+static const char * const PRIMITIVE_STRING = "string";
+static const char * const PRIMITIVE_BOOL = "boolean";
+static const char * const PRIMITIVE_FLOAT = "float";
+static const char * const PRIMITIVE_DOUBLE = "double";
+static const char * const PRIMITIVE_NULL = "null";
+static const char * const PRIMITIVE_BYTES = "bytes";
+
+static int descriptorTranslator_parseArgument(FILE *stream, json_t *type) {
+ int status = OK;
+ if (json_is_string(type)) {
+ const char *typeStr = json_string_value(type);
+ char t = '\0';
+ if (strcmp(typeStr, PRIMITIVE_INT) == 0) {
+ t = 'I';
+ } else if (strcmp(typeStr, PRIMITIVE_LONG) == 0) {
+ t = 'J';
+ } else if (strcmp(typeStr, PRIMITIVE_STRING) == 0) {
+ t = 'T';
+ } else if (strcmp(typeStr, PRIMITIVE_BOOL) == 0) {
+ t = 'Z';
+ } else if (strcmp(typeStr, PRIMITIVE_FLOAT) == 0) {
+ t = 'F';
+ } else if (strcmp(typeStr, PRIMITIVE_DOUBLE) == 0) {
+ t = 'D';
+ } else if (strcmp(typeStr, PRIMITIVE_NULL) == 0) {
+ t = 'V';
+ } else if (strcmp(typeStr, PRIMITIVE_BYTES) == 0) {
+ t = 'B';
+ } else {
+ fprintf(stream, "L%s;", typeStr);
+ }
+ if (t != '\0') {
+ fputc(t, stream);
+ }
+ } else {
+ json_t *subType = json_object_get(type, "type");
+ json_t *items = json_object_get(type, "items");
+ if (strcmp("array", json_string_value(subType)) == 0) {
+ //array
+ fputc('[', stream);
+ descriptorTranslator_parseArgument(stream, items);
+ } else {
+ LOG_ERROR("sub type %s not supported\n", json_string_value(subType));
+ status = PARSE_ERROR;
+ }
+ }
+ return status;
+}
+
+static int descriptorTranslator_parseType(dyn_interface_type *intf, json_t *type) {
+ int status = OK;
+ const char *name = json_string_value(json_object_get(type, "name"));
+ type_info_type *tInfo = NULL;
+
+ char *ptr = NULL;
+ size_t ptrSize;
+ FILE *stream = open_memstream(&ptr, &ptrSize);
+
+ if (stream != NULL) {
+ fputc('{', stream);
+ json_t *fields = json_object_get(type, "fields");
+ if (json_is_array(fields)) {
+ int index = 0;
+ json_t *field = NULL;
+ json_array_foreach(fields, index, field) {
+ json_t *type = json_object_get(field, "type");
+ status = descriptorTranslator_parseArgument(stream, type);
+ if (status != OK) {
+ break;
+ }
+ }
+ if (status == OK) {
+ json_array_foreach(fields, index, field) {
+ const char *fieldName = json_string_value(json_object_get(field, "name"));
+ if (fieldName != NULL) {
+ fputc(' ', stream);
+ fwrite(fieldName, 1, strlen(fieldName), stream);
+ } else {
+ status = PARSE_ERROR;
+ printf("Expected name for field\n");
+ break;
+ }
+ }
+ }
+ } else {
+ status = PARSE_ERROR;
+ printf("Expected array type");
+ }
+ fputc('}', stream);
+ fclose(stream);
+ } else {
+ status = MEM_ERROR;
+ LOG_ERROR("Error creating memory stream");
+ }
+
+ if (status == OK) {
+ tInfo = calloc(1, sizeof(*tInfo));
+ if (tInfo != NULL) {
+ tInfo->name = strdup(name);
+ if (tInfo->name != NULL) {
+ tInfo->descriptor = ptr;
+ } else {
+ status = MEM_ERROR;
+ LOG_ERROR("Error allocating memory for type info name");
+ }
+ } else {
+ status = MEM_ERROR;
+ LOG_ERROR("Error allocating memory for type_info");
+ }
+ }
+
+ if (status != 0 ) {
+ if (tInfo != NULL) {
+ if (tInfo->name != NULL) {
+ free(tInfo->name);
+ }
+ free(tInfo);
+ }
+ if (ptr != NULL) {
+ free(ptr);
+ }
+ }
+
+ if (status == OK) {
+ TAILQ_INSERT_TAIL(&intf->typeInfos, tInfo, entries);
+ }
+
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/descriptor_translator.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/descriptor_translator.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/descriptor_translator.h
new file mode 100644
index 0000000..6473d0d
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/descriptor_translator.h
@@ -0,0 +1,18 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef __DESCRIPTOR_TRANSLATOR_H_
+#define __DESCRIPTOR_TRANSLATOR_H_
+
+#include <stdio.h>
+#include <sys/queue.h>
+
+#include "dfi_log_util.h"
+#include "dyn_interface.h"
+
+//logging
+DFI_SETUP_LOG_HEADER(descriptorTranslator);
+
+int descriptorTranslator_translate(const char *schemaStr, dyn_interface_type **out);
+
+#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/descriptors/example1.descriptor
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/descriptors/example1.descriptor b/remote_services/remote_service_admin_dfi/dynamic_function_interface/descriptors/example1.descriptor
new file mode 100644
index 0000000..97b1df8
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/descriptors/example1.descriptor
@@ -0,0 +1,13 @@
+:header
+type=interface
+name=calculator
+version=1.0.0
+:annotations
+classname=org.example.Calculator
+:types
+StatsResult={DDD[D average min max input}
+:methods
+add(DD)D=add(PDD*D)N
+sub(DD)D=sub(PDD*D)N
+sqrt(D)D=sqrt(PD*D)N
+stats([D)LStatsResult;=stats(P[D*LStatsResult;)N
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/dfi_log_util.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dfi_log_util.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dfi_log_util.h
new file mode 100644
index 0000000..8dfd9bd
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dfi_log_util.h
@@ -0,0 +1,48 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef _DFI_LOG_UTIL_H_
+#define _DFI_LOG_UTIL_H_
+
+typedef void (*logf_ft)(void *handle, int level, const char *file, int line, const char *format, ...);
+
+#define DFI_SETUP_LOG_HEADER(cmp) \
+ void cmp ## _logSetup(logf_ft logf, void *handle, int currentLogLevel);
+
+#define DFI_SETUP_LOG(cmp) \
+ static logf_ft g_logf = NULL; \
+ static void *g_logHandle = NULL; \
+ static int g_currentLogLevel = 1; \
+ \
+ void cmp ## _logSetup(logf_ft logf, void *handle, int currentLogLevel) { \
+ g_currentLogLevel = currentLogLevel; \
+ g_logHandle = handle; \
+ g_logf = logf; \
+ }
+
+#define LOG_LVL_ERROR 1
+#define LOG_LVL_WARNING 2
+#define LOG_LVL_INFO 3
+#define LOG_LVL_DEBUG 4
+
+#define LOG_ERROR(msg, ...) \
+ if (g_logf != NULL && g_currentLogLevel >= LOG_LVL_ERROR) { \
+ g_logf(g_logHandle, LOG_LVL_ERROR, __FILE__, __LINE__, (msg), ##__VA_ARGS__); \
+ }
+
+#define LOG_WARNING(msg, ...) \
+ if (g_logf != NULL && g_currentLogLevel >= LOG_LVL_WARNING) { \
+ g_logf(g_logHandle, LOG_LVL_WARNING, __FILE__, __LINE__, (msg), ##__VA_ARGS__); \
+ }
+
+#define LOG_INFO(msg, ...) \
+ if (g_logf != NULL && g_currentLogLevel >= LOG_LVL_INFO) { \
+ g_logf(g_logHandle, LOG_LVL_INFO, __FILE__, __LINE__, (msg), ##__VA_ARGS__); \
+ }
+
+#define LOG_DEBUG(msg, ...) \
+ if (g_logf != NULL && g_currentLogLevel >= LOG_LVL_DEBUG) { \
+ g_logf(g_logHandle, LOG_LVL_DEBUG, __FILE__, __LINE__, (msg), ##__VA_ARGS__); \
+ }
+
+#endif
[05/10] celix git commit: CELIX-237: Moved dynamic function interface
under remote_service_admin_dfi
Posted by pn...@apache.org.
CELIX-237: Moved dynamic function interface under remote_service_admin_dfi
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/bf76d213
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/bf76d213
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/bf76d213
Branch: refs/heads/feature/CELIX-237_rsa-ffi
Commit: bf76d21309f1c8b17c84479bc107d6540c7de7cf
Parents: a2b09e2
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri Jul 31 16:06:23 2015 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri Jul 31 16:06:23 2015 +0200
----------------------------------------------------------------------
remote_services/CMakeLists.txt | 5 +-
.../dynamic_function_interface/CMakeLists.txt | 53 -
.../avro_descriptor_translator.c | 319 ------
.../descriptor_translator.h | 18 -
.../descriptors/example1.descriptor | 13 -
.../dynamic_function_interface/dfi_log_util.h | 48 -
.../dynamic_function_interface/dyn_common.c | 136 ---
.../dynamic_function_interface/dyn_common.h | 32 -
.../dynamic_function_interface/dyn_function.c | 243 -----
.../dynamic_function_interface/dyn_function.h | 31 -
.../dynamic_function_interface/dyn_interface.c | 371 -------
.../dynamic_function_interface/dyn_interface.h | 58 -
.../dynamic_function_interface/dyn_type.c | 1031 ------------------
.../dynamic_function_interface/dyn_type.h | 140 ---
.../json_serializer.c | 414 -------
.../json_serializer.h | 16 -
.../memstream/README.md | 49 -
.../memstream/fmemopen.c | 78 --
.../memstream/fmemopen.h | 52 -
.../memstream/open_memstream.c | 130 ---
.../memstream/open_memstream.h | 15 -
.../schemas/complex.avdl | 11 -
.../schemas/complex.avpr | 36 -
.../schemas/invalid1.avpr | 29 -
.../schemas/invalid2.avpr | 31 -
.../schemas/simple.avdl | 6 -
.../schemas/simple.avpr | 33 -
.../schemas/simple_min.avpr | 1 -
.../tst/avro_descriptor_translator_tests.cpp | 164 ---
.../tst/dyn_closure_tests.cpp | 146 ---
.../tst/dyn_function_tests.cpp | 115 --
.../tst/dyn_interface_tests.cpp | 79 --
.../tst/dyn_type_tests.cpp | 190 ----
.../tst/json_serializer_tests.cpp | 398 -------
.../tst/run_tests.cpp | 9 -
.../remote_service_admin_dfi/CMakeLists.txt | 52 +
.../dynamic_function_interface/CMakeLists.txt | 53 +
.../avro_descriptor_translator.c | 319 ++++++
.../descriptor_translator.h | 18 +
.../descriptors/example1.descriptor | 13 +
.../dynamic_function_interface/dfi_log_util.h | 48 +
.../dynamic_function_interface/dyn_common.c | 136 +++
.../dynamic_function_interface/dyn_common.h | 32 +
.../dynamic_function_interface/dyn_function.c | 243 +++++
.../dynamic_function_interface/dyn_function.h | 31 +
.../dynamic_function_interface/dyn_interface.c | 371 +++++++
.../dynamic_function_interface/dyn_interface.h | 58 +
.../dynamic_function_interface/dyn_type.c | 1031 ++++++++++++++++++
.../dynamic_function_interface/dyn_type.h | 140 +++
.../json_serializer.c | 414 +++++++
.../json_serializer.h | 16 +
.../memstream/README.md | 49 +
.../memstream/fmemopen.c | 78 ++
.../memstream/fmemopen.h | 52 +
.../memstream/open_memstream.c | 130 +++
.../memstream/open_memstream.h | 15 +
.../schemas/complex.avdl | 11 +
.../schemas/complex.avpr | 36 +
.../schemas/invalid1.avpr | 29 +
.../schemas/invalid2.avpr | 31 +
.../schemas/simple.avdl | 6 +
.../schemas/simple.avpr | 33 +
.../schemas/simple_min.avpr | 1 +
.../tst/avro_descriptor_translator_tests.cpp | 164 +++
.../tst/dyn_closure_tests.cpp | 146 +++
.../tst/dyn_function_tests.cpp | 115 ++
.../tst/dyn_interface_tests.cpp | 79 ++
.../tst/dyn_type_tests.cpp | 190 ++++
.../tst/json_serializer_tests.cpp | 398 +++++++
.../tst/run_tests.cpp | 9 +
70 files changed, 4548 insertions(+), 4499 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/CMakeLists.txt b/remote_services/CMakeLists.txt
index 957f468..a16977f 100644
--- a/remote_services/CMakeLists.txt
+++ b/remote_services/CMakeLists.txt
@@ -35,16 +35,13 @@ if (REMOTE_SERVICE_ADMIN)
add_subdirectory(remote_service_admin)
add_subdirectory(remote_service_admin_http)
- #add_subdirectory(remote_service_admin_http_ffi)
+ add_subdirectory(remote_service_admin_dfi)
add_subdirectory(remote_service_admin_shm)
add_subdirectory(discovery_configured)
add_subdirectory(discovery_etcd)
add_subdirectory(discovery_shm)
- add_subdirectory(dynamic_function_interface)
-
-
endif (REMOTE_SERVICE_ADMIN)
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/CMakeLists.txt b/remote_services/dynamic_function_interface/CMakeLists.txt
deleted file mode 100644
index 309176f..0000000
--- a/remote_services/dynamic_function_interface/CMakeLists.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# Licensed under Apache License v2. See LICENSE for more information.
-#
-find_package(Jansson REQUIRED)
-find_package(CppUTest REQUIRED)
-find_package(FFI REQUIRED)
-
-include_directories(
- ${CPPUTEST_INCLUDE_DIR}
- ${JANSSON_INCLUDE_DIRS}
- ${CMAKE_CURRENT_LIST_DIR}
- ${FFI_INCLUDE_DIRS}
- memstream
-)
-
-set(MEMSTREAM_SOURCES "")
-if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
- set(MEMSTREAM_SOURCES memstream/open_memstream.c memstream/fmemopen.c)
-endif()
-
-add_library(dfi
- dyn_common.c
- dyn_type.c
- dyn_function.c
- dyn_interface.c
- json_serializer.c
-# avro_descriptor_translator.c
- ${MEMSTREAM_SOURCES}
-)
-target_link_libraries(dfi ${FFI_LIBRARIES} ${JANSSON_LIBRARY})
-
-
-#if (FRAMEWORK_TESTS)
- add_executable(dfi_tests
- tst/dyn_type_tests.cpp
- tst/dyn_function_tests.cpp
- tst/dyn_closure_tests.cpp
- tst/dyn_interface_tests.cpp
- tst/json_serializer_tests.cpp
-# tst/avro_descriptor_translator_tests.cpp
- tst/run_tests.cpp
- )
- target_link_libraries(dfi_tests dfi ${FFI_LIBRARIES} ${CPPUTEST_LIBRARY} ${JANSSON_LIBRARY})
-
- add_custom_target(copy-input
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/schemas schemas
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/descriptors descriptors
- )
- add_dependencies(dfi_tests copy-input)
-
- add_test(NAME run_dfi_tests COMMAND dfi_tests)
- SETUP_TARGET_FOR_COVERAGE(dfi_tests_cov dfi_tests ${CMAKE_BINARY_DIR}/coverage/dfi)
-#endif()
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/avro_descriptor_translator.c
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/avro_descriptor_translator.c b/remote_services/dynamic_function_interface/avro_descriptor_translator.c
deleted file mode 100644
index a9fea1d..0000000
--- a/remote_services/dynamic_function_interface/avro_descriptor_translator.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/**
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#include "descriptor_translator.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-
-#include <jansson.h>
-
-#if defined(BSD) || defined(__APPLE__)
-#include "open_memstream.h"
-#include "fmemopen.h"
-#endif
-
-DFI_SETUP_LOG(descriptorTranslator)
-
-static const int OK = 0;
-static const int MEM_ERROR = 1;
-static const int PARSE_ERROR = 2;
-static const int INV_ARG_ERROR = 2;
-
-static int descriptorTranslator_createMethodInfo(dyn_interface_type *intf, json_t *schema, const char *name, int index, json_t *message);
-static int descriptorTranslator_parseType(dyn_interface_type *intf, json_t *type);
-static int descriptorTranslator_parseMessage(json_t *schema, const char *name, json_t *message, bool asJavaSignature, char **descriptor);
-static int descriptorTranslator_parseArgument(FILE *stream, json_t *type);
-
-int descriptorTranslator_translate(const char *schemaStr, dyn_interface_type **out) {
- LOG_DEBUG("translating descriptor for schema '%s'\n", schemaStr);
- int status = OK;
-
- dyn_interface_type *intf = NULL;
- status = dynInterface_create("TODO", &intf); //TODO parse json first retreive 'Protocol' string value
- if (status == 0) {
- json_error_t error;
- json_t *schema = json_loads(schemaStr, JSON_DECODE_ANY, &error);
-
- if (schema != NULL) {
- json_t *types = json_object_get(schema, "types");
- if (types != NULL) {
- json_t *type = NULL;
- int index = 0;
- json_array_foreach(types, index, type) {
- status = descriptorTranslator_parseType(intf, type);
- if (status != OK) {
- break;
- }
- }
- }
- json_t *messages = json_object_get(schema, "messages");
- if (status == OK && messages != NULL) {
- const char *name;
- json_t *message;
- int index = 0;
- json_object_foreach(messages, name, message) {
- status = descriptorTranslator_createMethodInfo(intf, schema, name, index++, message);
- if (status != OK) {
- break;
- }
- }
- }
- json_decref(schema);
- } else {
- status = PARSE_ERROR;
- printf("AVRO_DESCRIPTOR_TRANSLATOR: error parsing json input '%s'. Error is %s\n", schemaStr, error.text);
- }
- } else {
- status = MEM_ERROR;
- }
-
-
- if (status == OK) {
- *out = intf;
- } else {
- dynInterface_destroy(intf);
- }
- return status;
-}
-
-static int descriptorTranslator_createMethodInfo(dyn_interface_type *intf, json_t *schema, const char *name, int index, json_t *message) {
- int status = OK;
-
- method_info_type *mInfo = calloc(1, sizeof(*mInfo));
- if (mInfo != NULL) {
- mInfo->identifier = index;
- status = descriptorTranslator_parseMessage(schema, name, message, false, &mInfo->descriptor);
- if (status == OK) {
- mInfo->name = strdup(name);
- if (mInfo->name == NULL) {
- status = MEM_ERROR;
- } else {
- status = descriptorTranslator_parseMessage(schema, name, message, true, &mInfo->strIdentifier);
- }
- }
- } else {
- status = MEM_ERROR;
- }
-
- if (status == OK) {
- TAILQ_INSERT_TAIL(&intf->methodInfos, mInfo, entries);
- } else {
- if (mInfo != NULL) {
- if (mInfo->name != NULL) {
- free(mInfo->name);
- }
- if (mInfo->descriptor != NULL) {
- free(mInfo->descriptor);
- }
- if (mInfo->strIdentifier != NULL) {
- free(mInfo->strIdentifier);
- }
- free(mInfo);
- }
- }
-
- return status;
-}
-
-static int descriptorTranslator_parseMessage(json_t *schema, const char *name, json_t *message, bool asJavaSignature, char **descriptor) {
- int status = OK;
- //message -> { "request" : [ {"name":"<name>", "type":"<type>"} * ], "response":"<type>" }
- //array -> "type":"array", "items:"<type>"
-
- char *ptr = NULL;
- size_t ptrSize;
- FILE *memStream = open_memstream(&ptr, &ptrSize);
-
- if (memStream != NULL) {
- json_t *request = json_object_get(message, "request");
- fwrite(name, 1, strlen(name), memStream);
- fputc('(', memStream);
- if (!asJavaSignature) {
- fputc('P', memStream); //handle
- }
-
- if (request != NULL) {
- size_t index;
- json_t *arg;
- json_array_foreach(request, index, arg) {
- //json_t *name = json_object_get(arg, "name");
- json_t *type = json_object_get(arg, "type");
- if (type != NULL) {
- status = descriptorTranslator_parseArgument(memStream, type);
- } else {
- LOG_ERROR("expected json object with name value for request argument %zu for message/method %s\n", index, name);
- status = PARSE_ERROR;
- }
- if (status != OK) {
- break;
- }
- }
- } else {
- status = PARSE_ERROR;
- LOG_ERROR("Expected request for message %s\n", name);
- }
-
- json_t *response = json_object_get(message, "response");
- if (status == OK && response != NULL) {
- if (asJavaSignature) {
- fputc(')', memStream);
- } else {
- fputc('*', memStream); //output parameter
- }
- status = descriptorTranslator_parseArgument(memStream, response);
- }
-
- if (!asJavaSignature) {
- fputc(')', memStream);
- fputc('N', memStream); //error / exceptions
- }
- } else {
- status = MEM_ERROR;
- }
-
- if (memStream != NULL) {
- fclose(memStream);
- if (status == OK) {
- *descriptor = ptr;
- } else {
- free(ptr);
- }
- }
-
- return status;
-}
-
-static const char * const PRIMITIVE_INT = "int";
-static const char * const PRIMITIVE_LONG = "long";
-static const char * const PRIMITIVE_STRING = "string";
-static const char * const PRIMITIVE_BOOL = "boolean";
-static const char * const PRIMITIVE_FLOAT = "float";
-static const char * const PRIMITIVE_DOUBLE = "double";
-static const char * const PRIMITIVE_NULL = "null";
-static const char * const PRIMITIVE_BYTES = "bytes";
-
-static int descriptorTranslator_parseArgument(FILE *stream, json_t *type) {
- int status = OK;
- if (json_is_string(type)) {
- const char *typeStr = json_string_value(type);
- char t = '\0';
- if (strcmp(typeStr, PRIMITIVE_INT) == 0) {
- t = 'I';
- } else if (strcmp(typeStr, PRIMITIVE_LONG) == 0) {
- t = 'J';
- } else if (strcmp(typeStr, PRIMITIVE_STRING) == 0) {
- t = 'T';
- } else if (strcmp(typeStr, PRIMITIVE_BOOL) == 0) {
- t = 'Z';
- } else if (strcmp(typeStr, PRIMITIVE_FLOAT) == 0) {
- t = 'F';
- } else if (strcmp(typeStr, PRIMITIVE_DOUBLE) == 0) {
- t = 'D';
- } else if (strcmp(typeStr, PRIMITIVE_NULL) == 0) {
- t = 'V';
- } else if (strcmp(typeStr, PRIMITIVE_BYTES) == 0) {
- t = 'B';
- } else {
- fprintf(stream, "L%s;", typeStr);
- }
- if (t != '\0') {
- fputc(t, stream);
- }
- } else {
- json_t *subType = json_object_get(type, "type");
- json_t *items = json_object_get(type, "items");
- if (strcmp("array", json_string_value(subType)) == 0) {
- //array
- fputc('[', stream);
- descriptorTranslator_parseArgument(stream, items);
- } else {
- LOG_ERROR("sub type %s not supported\n", json_string_value(subType));
- status = PARSE_ERROR;
- }
- }
- return status;
-}
-
-static int descriptorTranslator_parseType(dyn_interface_type *intf, json_t *type) {
- int status = OK;
- const char *name = json_string_value(json_object_get(type, "name"));
- type_info_type *tInfo = NULL;
-
- char *ptr = NULL;
- size_t ptrSize;
- FILE *stream = open_memstream(&ptr, &ptrSize);
-
- if (stream != NULL) {
- fputc('{', stream);
- json_t *fields = json_object_get(type, "fields");
- if (json_is_array(fields)) {
- int index = 0;
- json_t *field = NULL;
- json_array_foreach(fields, index, field) {
- json_t *type = json_object_get(field, "type");
- status = descriptorTranslator_parseArgument(stream, type);
- if (status != OK) {
- break;
- }
- }
- if (status == OK) {
- json_array_foreach(fields, index, field) {
- const char *fieldName = json_string_value(json_object_get(field, "name"));
- if (fieldName != NULL) {
- fputc(' ', stream);
- fwrite(fieldName, 1, strlen(fieldName), stream);
- } else {
- status = PARSE_ERROR;
- printf("Expected name for field\n");
- break;
- }
- }
- }
- } else {
- status = PARSE_ERROR;
- printf("Expected array type");
- }
- fputc('}', stream);
- fclose(stream);
- } else {
- status = MEM_ERROR;
- LOG_ERROR("Error creating memory stream");
- }
-
- if (status == OK) {
- tInfo = calloc(1, sizeof(*tInfo));
- if (tInfo != NULL) {
- tInfo->name = strdup(name);
- if (tInfo->name != NULL) {
- tInfo->descriptor = ptr;
- } else {
- status = MEM_ERROR;
- LOG_ERROR("Error allocating memory for type info name");
- }
- } else {
- status = MEM_ERROR;
- LOG_ERROR("Error allocating memory for type_info");
- }
- }
-
- if (status != 0 ) {
- if (tInfo != NULL) {
- if (tInfo->name != NULL) {
- free(tInfo->name);
- }
- free(tInfo);
- }
- if (ptr != NULL) {
- free(ptr);
- }
- }
-
- if (status == OK) {
- TAILQ_INSERT_TAIL(&intf->typeInfos, tInfo, entries);
- }
-
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/descriptor_translator.h
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/descriptor_translator.h b/remote_services/dynamic_function_interface/descriptor_translator.h
deleted file mode 100644
index 6473d0d..0000000
--- a/remote_services/dynamic_function_interface/descriptor_translator.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#ifndef __DESCRIPTOR_TRANSLATOR_H_
-#define __DESCRIPTOR_TRANSLATOR_H_
-
-#include <stdio.h>
-#include <sys/queue.h>
-
-#include "dfi_log_util.h"
-#include "dyn_interface.h"
-
-//logging
-DFI_SETUP_LOG_HEADER(descriptorTranslator);
-
-int descriptorTranslator_translate(const char *schemaStr, dyn_interface_type **out);
-
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/descriptors/example1.descriptor
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/descriptors/example1.descriptor b/remote_services/dynamic_function_interface/descriptors/example1.descriptor
deleted file mode 100644
index 97b1df8..0000000
--- a/remote_services/dynamic_function_interface/descriptors/example1.descriptor
+++ /dev/null
@@ -1,13 +0,0 @@
-:header
-type=interface
-name=calculator
-version=1.0.0
-:annotations
-classname=org.example.Calculator
-:types
-StatsResult={DDD[D average min max input}
-:methods
-add(DD)D=add(PDD*D)N
-sub(DD)D=sub(PDD*D)N
-sqrt(D)D=sqrt(PD*D)N
-stats([D)LStatsResult;=stats(P[D*LStatsResult;)N
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/dfi_log_util.h
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/dfi_log_util.h b/remote_services/dynamic_function_interface/dfi_log_util.h
deleted file mode 100644
index 8dfd9bd..0000000
--- a/remote_services/dynamic_function_interface/dfi_log_util.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#ifndef _DFI_LOG_UTIL_H_
-#define _DFI_LOG_UTIL_H_
-
-typedef void (*logf_ft)(void *handle, int level, const char *file, int line, const char *format, ...);
-
-#define DFI_SETUP_LOG_HEADER(cmp) \
- void cmp ## _logSetup(logf_ft logf, void *handle, int currentLogLevel);
-
-#define DFI_SETUP_LOG(cmp) \
- static logf_ft g_logf = NULL; \
- static void *g_logHandle = NULL; \
- static int g_currentLogLevel = 1; \
- \
- void cmp ## _logSetup(logf_ft logf, void *handle, int currentLogLevel) { \
- g_currentLogLevel = currentLogLevel; \
- g_logHandle = handle; \
- g_logf = logf; \
- }
-
-#define LOG_LVL_ERROR 1
-#define LOG_LVL_WARNING 2
-#define LOG_LVL_INFO 3
-#define LOG_LVL_DEBUG 4
-
-#define LOG_ERROR(msg, ...) \
- if (g_logf != NULL && g_currentLogLevel >= LOG_LVL_ERROR) { \
- g_logf(g_logHandle, LOG_LVL_ERROR, __FILE__, __LINE__, (msg), ##__VA_ARGS__); \
- }
-
-#define LOG_WARNING(msg, ...) \
- if (g_logf != NULL && g_currentLogLevel >= LOG_LVL_WARNING) { \
- g_logf(g_logHandle, LOG_LVL_WARNING, __FILE__, __LINE__, (msg), ##__VA_ARGS__); \
- }
-
-#define LOG_INFO(msg, ...) \
- if (g_logf != NULL && g_currentLogLevel >= LOG_LVL_INFO) { \
- g_logf(g_logHandle, LOG_LVL_INFO, __FILE__, __LINE__, (msg), ##__VA_ARGS__); \
- }
-
-#define LOG_DEBUG(msg, ...) \
- if (g_logf != NULL && g_currentLogLevel >= LOG_LVL_DEBUG) { \
- g_logf(g_logHandle, LOG_LVL_DEBUG, __FILE__, __LINE__, (msg), ##__VA_ARGS__); \
- }
-
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/dyn_common.c
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/dyn_common.c b/remote_services/dynamic_function_interface/dyn_common.c
deleted file mode 100644
index 0cca69b..0000000
--- a/remote_services/dynamic_function_interface/dyn_common.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#include "dyn_common.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdbool.h>
-
-#if defined(BSD) || defined(__APPLE__)
-#include "open_memstream.h"
-#include "fmemopen.h"
-#endif
-
-static const int OK = 0;
-static const int ERROR = 1;
-
-DFI_SETUP_LOG(dynCommon)
-
-static bool dynCommon_charIn(int c, const char *acceptedChars);
-
-int dynCommon_parseName(FILE *stream, char **result) {
- return dynCommon_parseNameAlsoAccept(stream, NULL, result);
-}
-
-int dynCommon_parseNameAlsoAccept(FILE *stream, const char *acceptedChars, char **result) {
- int status = OK;
-
- char *buf = NULL;
- size_t size = 0;
- int strLen = 0;
- FILE *name = open_memstream(&buf, &size);
-
- if (name != NULL) {
- int c = getc(stream);
- while (isalnum(c) || c == '_' || dynCommon_charIn(c, acceptedChars)) {
- fputc(c, name);
- c = getc(stream);
- strLen += 1;
- }
- fflush(name);
- fclose(name);
- ungetc(c, stream);
- } else {
- status = ERROR;
- LOG_ERROR("Error creating mem stream for name. %s", strerror(errno));
- }
-
- if (status == OK) {
- if (strLen == 0) {
- status = ERROR;
- LOG_ERROR("Parsed empty name");
- }
- }
-
- if (status == OK) {
- LOG_DEBUG("Parsed name '%s'", buf);
- *result = buf;
- } else if (buf != NULL) {
- free(buf);
- }
-
- return status;
-}
-
-int dynCommon_parseNameValue(FILE *stream, char **outName, char **outValue) {
- int status = OK;
- char *name = NULL;
- char *value = NULL;
- const char *valueAcceptedChars = ".<>{}[]?;:~!@#$%^&*()_+-=,./\\'\"";
-
- status = dynCommon_parseName(stream, &name);
- if (status == OK) {
- status = dynCommon_eatChar(stream, '=');
- }
- if (status == OK) {
- status = dynCommon_parseNameAlsoAccept(stream, valueAcceptedChars, &value); //NOTE use different more lenient function e.g. only stop at '\n' ?
- }
-
- if (status == OK) {
- *outName = name;
- *outValue = value;
- } else {
- if (name != NULL) {
- free(name);
- }
- if (value != NULL) {
- free(value);
- }
- }
- return status;
-}
-
-int dynCommon_eatChar(FILE *stream, int expected) {
- int status = OK;
- long loc = ftell(stream);
- int c = fgetc(stream);
- if (c != expected) {
- status = ERROR;
- LOG_ERROR("Error parsing, expected token '%c' got '%c' at position %li", expected, loc);
- }
- return status;
-}
-
-static bool dynCommon_charIn(int c, const char *acceptedChars) {
- bool status = false;
- if (acceptedChars != NULL) {
- int i;
- for (i = 0; acceptedChars[i] != '\0'; i += 1) {
- if (c == acceptedChars[i]) {
- status = true;
- break;
- }
- }
- }
-
- return status;
-}
-
-void dynCommon_clearNamValHead(struct namvals_head *head) {
- struct namval_entry *tmp = NULL;
- struct namval_entry *entry = TAILQ_FIRST(head);
- while (entry != NULL) {
- tmp = entry;
-
- if (entry->name != NULL) {
- free(entry->name);
- }
- if (entry->value != NULL) {
- free(entry->value);
- }
- entry = TAILQ_NEXT(entry, entries);
- free(tmp);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/dyn_common.h
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/dyn_common.h b/remote_services/dynamic_function_interface/dyn_common.h
deleted file mode 100644
index a31cbc4..0000000
--- a/remote_services/dynamic_function_interface/dyn_common.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#ifndef _DYN_COMMON_H_
-#define _DYN_COMMON_H_
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/queue.h>
-
-#include "dfi_log_util.h"
-
-//logging
-DFI_SETUP_LOG_HEADER(dynCommon);
-
-TAILQ_HEAD(namvals_head, namval_entry);
-
-struct namval_entry {
- char *name;
- char *value;
- TAILQ_ENTRY(namval_entry) entries;
-};
-
-int dynCommon_parseName(FILE *stream, char **result);
-int dynCommon_parseNameAlsoAccept(FILE *stream, const char *acceptedChars, char **result);
-int dynCommon_parseNameValue(FILE *stream, char **name, char **value);
-int dynCommon_eatChar(FILE *stream, int c);
-
-void dynCommon_clearNamValHead(struct namvals_head *head);
-
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/dyn_function.c
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/dyn_function.c b/remote_services/dynamic_function_interface/dyn_function.c
deleted file mode 100644
index 0ae2a8a..0000000
--- a/remote_services/dynamic_function_interface/dyn_function.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#include "dyn_function.h"
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <strings.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <ffi.h>
-
-#include "dyn_common.h"
-#include "dyn_type.h"
-#include "dfi_log_util.h"
-
-DFI_SETUP_LOG(dynFunction)
-
-struct _dyn_function_type {
- char *name;
- struct types_head *refTypes; //NOTE not owned
- TAILQ_HEAD(,_dyn_function_argument_type) arguments;
- ffi_type **ffiArguments;
- dyn_type *funcReturn;
- ffi_cif cif;
-
- //closure part
- ffi_closure *ffiClosure;
- void (*fn)(void);
- void *userData;
- void (*bind)(void *userData, void *args[], void *ret);
-};
-
-typedef struct _dyn_function_argument_type dyn_function_argument_type;
-struct _dyn_function_argument_type {
- int index;
- char *name;
- dyn_type *type;
- TAILQ_ENTRY(_dyn_function_argument_type) entries;
-};
-
-static const int OK = 0;
-static const int MEM_ERROR = 1;
-static const int PARSE_ERROR = 2;
-static const int ERROR = 2;
-
-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);
-
-int dynFunction_parse(FILE *descriptor, struct types_head *refTypes, dyn_function_type **out) {
- int status = OK;
- dyn_function_type *dynFunc = NULL;
- LOG_DEBUG("Creating dyn function", descriptor);
-
- dynFunc = calloc(1, sizeof(*dynFunc));
-
- if (dynFunc != NULL) {
- TAILQ_INIT(&dynFunc->arguments);
- dynFunc->refTypes = refTypes;
- status = dynFunction_parseDescriptor(dynFunc, descriptor);
- if (status == 0) {
- int rc = dynFunction_initCif(dynFunc);
- if (rc != 0) {
- LOG_ERROR("Error initializing cif");
- status = ERROR;
- }
- }
- } else {
- LOG_ERROR("Error allocationg memory for dyn functipn\n");
- status = MEM_ERROR;
- }
-
- if (status == 0) {
- *out = dynFunc;
- }
-
- return status;
-}
-
-int dynFunction_parseWithStr(const char *descriptor, struct types_head *refTypes, dyn_function_type **out) {
- int status = OK;
- FILE *stream = fmemopen((char *)descriptor, strlen(descriptor), "r");
- if (stream != NULL) {
- status = dynFunction_parse(stream, refTypes, out);
- fclose(stream);
- } else {
- status = MEM_ERROR;
- LOG_ERROR("Error creating mem stream for descriptor string. %s", strerror(errno));
- }
- return status;
-}
-
-static int dynFunction_parseDescriptor(dyn_function_type *dynFunc, FILE *descriptor) {
- int status = OK;
- char *name = NULL;
-
- status = dynCommon_parseName(descriptor, &name);
-
- if (status == OK) {
- dynFunc->name = name;
- }
-
- if (status == OK) {
- int c = fgetc(descriptor);
- if ( c != '(') {
- status = PARSE_ERROR;
- LOG_ERROR("Expected '(' token got '%c'", c);
- }
- }
-
- int nextChar = fgetc(descriptor);
- int index = 0;
- dyn_type *type = NULL;
- while (nextChar != ')' && status == 0) {
- type = NULL;
- ungetc(nextChar, descriptor);
- 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
- if (arg != NULL) {
- TAILQ_INSERT_TAIL(&dynFunc->arguments, arg, entries);
- } else {
- LOG_ERROR("Error allocating memory");
- status = MEM_ERROR;
- }
- }
- nextChar = fgetc(descriptor);
- }
-
- if (status == 0) {
- status = dynType_parse(descriptor, NULL, dynFunc->refTypes, &dynFunc->funcReturn);
- }
-
- return status;
-}
-
-static int dynFunction_initCif(dyn_function_type *dynFunc) {
- int status = 0;
-
- int count = 0;
- dyn_function_argument_type *entry = NULL;
- TAILQ_FOREACH(entry, &dynFunc->arguments, entries) {
- count +=1;
- }
-
- dynFunc->ffiArguments = calloc(count, sizeof(ffi_type));
-
- TAILQ_FOREACH(entry, &dynFunc->arguments, entries) {
- dynFunc->ffiArguments[entry->index] = dynType_ffiType(entry->type);
- }
-
- ffi_type **args = dynFunc->ffiArguments;
- ffi_type *returnType = dynType_ffiType(dynFunc->funcReturn);
-
- int ffiResult = ffi_prep_cif(&dynFunc->cif, FFI_DEFAULT_ABI, count, returnType, args);
- if (ffiResult != FFI_OK) {
- status = 1;
- }
-
- return status;
-}
-
-void dynFunction_destroy(dyn_function_type *dynFunc) {
- if (dynFunc != NULL) {
- if (dynFunc->funcReturn != NULL) {
- dynType_destroy(dynFunc->funcReturn);
- }
- if (dynFunc->ffiClosure != NULL) {
- ffi_closure_free(dynFunc->ffiClosure);
- }
- if (dynFunc->name != NULL) {
- free(dynFunc->name);
- }
- if (dynFunc->ffiArguments != NULL) {
- free(dynFunc->ffiArguments);
- }
-
- dyn_function_argument_type *entry = NULL;
- dyn_function_argument_type *tmp = NULL;
- entry = TAILQ_FIRST(&dynFunc->arguments);
- while (entry != NULL) {
- if (entry->name != NULL) {
- free(entry->name);
- }
- dynType_destroy(entry->type);
- tmp = entry;
- entry = TAILQ_NEXT(entry, entries);
- free(tmp);
- }
-
- free(dynFunc);
- }
-}
-
-int dynFunction_call(dyn_function_type *dynFunc, void(*fn)(void), void *returnValue, void **argValues) {
- //TODO check dynFunc arg
- ffi_call(&dynFunc->cif, fn, returnValue, argValues);
- return 0;
-}
-
-static void dynFunction_ffiBind(ffi_cif *cif, void *ret, void *args[], void *userData) {
- dyn_function_type *dynFunc = userData;
- dynFunc->bind(dynFunc->userData, args, ret);
-}
-
-int dynFunction_createClosure(dyn_function_type *dynFunc, void (*bind)(void *, void **, void*), void *userData, void(**out)(void)) {
- int status = 0;
- void (*fn)(void);
- dynFunc->ffiClosure = ffi_closure_alloc(sizeof(ffi_closure), (void **)&fn);
- if (dynFunc->ffiClosure != NULL) {
- int rc = ffi_prep_closure_loc(dynFunc->ffiClosure, &dynFunc->cif, dynFunction_ffiBind, dynFunc, fn);
- if (rc != FFI_OK) {
- status = 1;
- }
- } else {
- status = 2;
- }
-
- if (status == 0) {
- dynFunc->bind = bind;
- dynFunc->fn = fn;
- *out =fn;
- }
-
- return status;
-}
-
-int dynFunction_getFnPointer(dyn_function_type *dynFunc, void (**fn)(void)) {
- int status = 0;
- if (dynFunc != NULL && dynFunc->fn != NULL) {
- (*fn) = dynFunc->fn;
- } else {
- status = 1;
- }
- return status;
-}
-
-
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/dyn_function.h
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/dyn_function.h b/remote_services/dynamic_function_interface/dyn_function.h
deleted file mode 100644
index 2d5d6bb..0000000
--- a/remote_services/dynamic_function_interface/dyn_function.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#ifndef __DYN_FUNCTION_H_
-#define __DYN_FUNCTION_H_
-
-#include <ffi.h>
-#include "dyn_type.h"
-#include "dfi_log_util.h"
-
-/**
- * Uses the following schema
- * (Name)([Type]*)Type
- * e.g add(DD)D or sum({[D[D setA setB})D
- */
-
-typedef struct _dyn_function_type dyn_function_type;
-typedef struct _dyn_closure_type dyn_closure_type;
-
-DFI_SETUP_LOG_HEADER(dynFunction);
-
-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);
-
-void dynFunction_destroy(dyn_function_type *dynFunc);
-int dynFunction_call(dyn_function_type *dynFunc, void(*fn)(void), void *returnValue, void **argValues);
-
-int dynFunction_createClosure(dyn_function_type *func, void (*bind)(void *, void **, void*), void *userData, void(**fn)(void));
-int dynFunction_getFnPointer(dyn_function_type *func, void (**fn)(void));
-
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/dyn_interface.c
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/dyn_interface.c b/remote_services/dynamic_function_interface/dyn_interface.c
deleted file mode 100644
index 878cfea..0000000
--- a/remote_services/dynamic_function_interface/dyn_interface.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/**
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#include "dyn_interface.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "dyn_common.h"
-#include "dyn_type.h"
-#include "dyn_interface.h"
-
-DFI_SETUP_LOG(dynInterface);
-
-const int OK = 0;
-const int ERROR = 1;
-
-static int dynInterface_parseSection(dyn_interface_type *intf, FILE *stream);
-static int dynInterface_parseAnnotations(dyn_interface_type *intf, FILE *stream);
-static int dynInterface_parseTypes(dyn_interface_type *intf, FILE *stream);
-static int dynInterface_parseMethods(dyn_interface_type *intf, FILE *stream);
-static int dynInterface_parseHeader(dyn_interface_type *intf, FILE *stream);
-static int dynInterface_parseNameValueSection(dyn_interface_type *intf, FILE *stream, struct namvals_head *head);
-static int dynInterface_checkInterface(dyn_interface_type *intf);
-static int dynInterface_getEntryForHead(struct namvals_head *head, const char *name, char **value);
-
-int dynInterface_parse(FILE *descriptor, dyn_interface_type **out) {
- int status = OK;
-
- dyn_interface_type *intf = calloc(1, sizeof(*intf));
- if (intf != NULL) {
- TAILQ_INIT(&intf->header);
- TAILQ_INIT(&intf->annotations);
- TAILQ_INIT(&intf->types);
- TAILQ_INIT(&intf->methods);
-
- char peek = fgetc(descriptor);
- while (peek == ':') {
- ungetc(peek, descriptor);
- status = dynInterface_parseSection(intf, descriptor);
- if (status == OK) {
- peek = fgetc(descriptor);
- } else {
- break;
- }
- }
-
- if (status == OK) {
- status = dynCommon_eatChar(descriptor, EOF);
- }
-
- if (status == OK) {
- status = dynInterface_checkInterface(intf);
- }
- } else {
- status = ERROR;
- LOG_ERROR("Error allocating memory for dynamic interface\n");
- }
-
- if (status == OK) {
- *out = intf;
- } else if (intf != NULL) {
- dynInterface_destroy(intf);
- }
- return status;
-}
-
-static int dynInterface_checkInterface(dyn_interface_type *intf) {
- int status = OK;
-
- //check header section
- if (status == OK) {
- bool foundType = false;
- bool foundVersion = false;
- bool foundName = false;
- struct namval_entry *entry = NULL;
- TAILQ_FOREACH(entry, &intf->header, entries) {
- if (strcmp(entry->name, "type") == 0) {
- foundType = true;
- } else if (strcmp(entry->name, "version") == 0) {
- foundVersion = true;
- } else if (strcmp(entry->name, "name") == 0) {
- foundName = true;
- }
- }
-
- if (!foundType || !foundVersion || !foundName) {
- status = ERROR;
- LOG_ERROR("Parse Error. There must be a header section with a type, version and name entry");
- }
- }
-
- return status;
-}
-
-static int dynInterface_parseSection(dyn_interface_type *intf, FILE *stream) {
- int status = OK;
- char *sectionName = NULL;
-
- status = dynCommon_eatChar(stream, ':');
-
- if (status == OK) {
- status = dynCommon_parseName(stream, §ionName);
- }
-
- if (status == OK) {
- status = dynCommon_eatChar(stream, '\n');
- }
-
- if (status == OK) {
- if (strcmp("header", sectionName) == 0) {
- status = dynInterface_parseHeader(intf, stream);
- } else if (strcmp("annotations", sectionName) == 0) {
- status = dynInterface_parseAnnotations(intf, stream);
- } else if (strcmp("types", sectionName) == 0) {
- status = dynInterface_parseTypes(intf, stream);
- } else if (strcmp("methods", sectionName) == 0) {
- status = dynInterface_parseMethods(intf, stream);
- } else {
- status = ERROR;
- LOG_ERROR("unsupported section '%s'", sectionName);
- }
- }
-
- if (sectionName != NULL) {
- free(sectionName);
- }
-
- return status;
-}
-
-static int dynInterface_parseHeader(dyn_interface_type *intf, FILE *stream) {
- return dynInterface_parseNameValueSection(intf, stream, &intf->header);
-}
-
-static int dynInterface_parseAnnotations(dyn_interface_type *intf, FILE *stream) {
- return dynInterface_parseNameValueSection(intf, stream, &intf->annotations);
-}
-
-static int dynInterface_parseNameValueSection(dyn_interface_type *intf, FILE *stream, struct namvals_head *head) {
- int status = OK;
-
- int peek = fgetc(stream);
- while (peek != ':' && peek != EOF) {
- ungetc(peek, stream);
-
- char *name;
- char *value;
- status = dynCommon_parseNameValue(stream, &name, &value);
-
- if (status == OK) {
- status = dynCommon_eatChar(stream, '\n');
- }
-
- struct namval_entry *entry = NULL;
- if (status == OK) {
- entry = calloc(1, sizeof(*entry));
- if (entry != NULL) {
- entry->name = name;
- entry->value = value;
- TAILQ_INSERT_TAIL(head, entry, entries);
- } else {
- status = ERROR;
- LOG_ERROR("Error allocating memory for namval entry");
- }
- }
-
- if (status != OK) {
- if (name != NULL) {
- free(name);
- }
- if (value != NULL) {
- free(value);
- }
- if (entry != NULL) {
- free(entry);
- }
- break;
- }
- peek = fgetc(stream);
- }
- ungetc(peek, stream);
-
- return status;
-}
-
-static int dynInterface_parseTypes(dyn_interface_type *intf, FILE *stream) {
- int status = OK;
-
- //expected input (Name)=<Type>\n
- int peek = fgetc(stream);
- while (peek != ':' && peek != EOF) {
- ungetc(peek, stream);
-
- char *name;
- status = dynCommon_parseName(stream, &name);
-
- if (status == OK) {
- status = dynCommon_eatChar(stream, '=');
- }
-
- dyn_type *type = NULL;
- if (status == OK) {
- dynType_parse(stream, name, &intf->types, &type);
- }
- if (name != NULL) {
- free(name);
- }
-
- if (status == OK) {
- status = dynCommon_eatChar(stream, '\n');
- }
-
- struct type_entry *entry = NULL;
- if (status == OK) {
- entry = calloc(1, sizeof(*entry));
- if (entry != NULL) {
- entry->type = type;
- TAILQ_INSERT_TAIL(&intf->types, entry, entries);
- } else {
- status = ERROR;
- LOG_ERROR("Error allocating memory for type entry");
- }
- }
-
- if (status != OK) {
- if (type != NULL) {
- dynType_destroy(type);
- }
- if (entry != NULL) {
- free(entry);
- }
- break;
- }
- peek = fgetc(stream);
- }
- ungetc(peek, stream);
-
- return status;
-}
-
-static int dynInterface_parseMethods(dyn_interface_type *intf, FILE *stream) {
- int status = OK;
-
- //expected input (Name)=<Method>\n
- int peek = fgetc(stream);
- int index = 0;
- while (peek != ':' && peek != EOF) {
- ungetc(peek, stream);
-
- char *id;
- status = dynCommon_parseNameAlsoAccept(stream, "();[{}", &id);
-
- if (status == OK) {
- status = dynCommon_eatChar(stream, '=');
- }
-
-
- dyn_function_type *func = NULL;
- if (status == OK) {
- status = dynFunction_parse(stream, &intf->types, &func);
- }
-
- if (status == OK) {
- status = dynCommon_eatChar(stream, '\n');
- }
-
- struct method_entry *entry = NULL;
- if (status == OK) {
- entry = calloc(1, sizeof(*entry));
- if (entry != NULL) {
- entry->index = index++;
- entry->id = id;
- entry->dynFunc = func;
- TAILQ_INSERT_TAIL(&intf->methods, entry, entries);
- } else {
- status = ERROR;
- LOG_ERROR("Error allocating memory for method entry");
- }
- }
-
- if (status != OK) {
- if (id != NULL) {
- free(id);
- }
- if (func != NULL) {
- dynFunction_destroy(func);
- //TODO free strIdentier, name
- }
- if (entry != NULL) {
- free(entry);
- }
- break;
- }
- peek = fgetc(stream);
- }
- ungetc(peek, stream);
-
- return status;
-}
-
-void dynInterface_destroy(dyn_interface_type *intf) {
- if (intf != NULL) {
- dynCommon_clearNamValHead(&intf->header);
- dynCommon_clearNamValHead(&intf->annotations);
-
- struct type_entry *tmp = NULL;
- struct type_entry *tInfo = TAILQ_FIRST(&intf->types);
- while (tInfo != NULL) {
- tmp = tInfo;
- tInfo = TAILQ_NEXT(tInfo, entries);
- dynType_destroy(tmp->type);
- free(tmp);
- }
-
- struct method_entry *mTmp = NULL;
- struct method_entry *mInfo = TAILQ_FIRST(&intf->methods);
- while (mInfo != NULL) {
- mTmp = mInfo;
- mInfo = TAILQ_NEXT(mInfo, entries);
-
- if (mTmp->id != NULL) {
- free(mTmp->id);
- }
- if (mTmp->name != NULL) {
- free(mTmp->name);
- }
- if (mTmp->dynFunc != NULL) {
- dynFunction_destroy(mTmp->dynFunc);
- }
- free(mTmp);
- }
-
- free(intf);
- }
-}
-
-int dynInterface_getName(dyn_interface_type *intf, char **out) {
- return dynInterface_getEntryForHead(&intf->header, "name", out);
-}
-
-int dynInterface_getVersion(dyn_interface_type *intf, char **version) {
- return dynInterface_getEntryForHead(&intf->header, "version", version);
-}
-
-int dynInterface_getHeaderEntry(dyn_interface_type *intf, const char *name, char **value) {
- return dynInterface_getEntryForHead(&intf->header, name, value);
-}
-
-int dynInterface_getAnnotationEntry(dyn_interface_type *intf, const char *name, char **value) {
- return dynInterface_getEntryForHead(&intf->annotations, name, value);
-}
-
-static int dynInterface_getEntryForHead(struct namvals_head *head, const char *name, char **out) {
- int status = OK;
- char *value = NULL;
- struct namval_entry *entry = NULL;
- TAILQ_FOREACH(entry, head, entries) {
- if (strcmp(name, entry->name) == 0) {
- value = entry->value;
- break;
- }
- }
- if (value != NULL) {
- *out = value;
- } else {
- status = ERROR;
- LOG_WARNING("Cannot find '%s' in list", name);
- }
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/dyn_interface.h
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/dyn_interface.h b/remote_services/dynamic_function_interface/dyn_interface.h
deleted file mode 100644
index 0b0898f..0000000
--- a/remote_services/dynamic_function_interface/dyn_interface.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#ifndef __DYN_INTERFACE_H_
-#define __DYN_INTERFACE_H_
-
-#include "dyn_common.h"
-#include "dyn_type.h"
-#include "dyn_function.h"
-#include "dfi_log_util.h"
-
-DFI_SETUP_LOG_HEADER(dynInterface);
-
-/* Description string
- *
- * Descriptor (interface) = HeaderSection AnnotationSection TypesSection MethodsSection
- *
- * HeaderSection=
- * ':header\n' [NameValue]*
- * ':annotations\n' [NameValue]*
- * ':types\n' [TypeIdValue]*
- * ':methods\n' [MethodIdValue]
- *
- */
-
-//struct namvals_head in dyn_common.h
-TAILQ_HEAD(methods_head, method_entry);
-//struct reference_types_head in dyn_type.h
-
-typedef struct _dyn_interface_type dyn_interface_type;
-
-struct _dyn_interface_type {
- struct namvals_head header;
- struct namvals_head annotations;
- struct types_head types;
- struct methods_head methods;
-};
-
-struct method_entry {
- int index;
- char *id;
- char *name;
-
- dyn_function_type *dynFunc;
-
- TAILQ_ENTRY(method_entry) entries;
-};
-
-int dynInterface_parse(FILE *descriptor, dyn_interface_type **out);
-void dynInterface_destroy(dyn_interface_type *intf);
-
-int dynInterface_getName(dyn_interface_type *intf, char **name);
-int dynInterface_getVersion(dyn_interface_type *intf, char **version);
-int dynInterface_getHeaderEntry(dyn_interface_type *intf, const char *name, char **value);
-int dynInterface_getAnnotationEntry(dyn_interface_type *intf, const char *name, char **value);
-
-
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/dyn_type.c
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/dyn_type.c b/remote_services/dynamic_function_interface/dyn_type.c
deleted file mode 100644
index 2946607..0000000
--- a/remote_services/dynamic_function_interface/dyn_type.c
+++ /dev/null
@@ -1,1031 +0,0 @@
-/**
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#include "dyn_type.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-#include <errno.h>
-
-#include "dyn_common.h"
-
-DFI_SETUP_LOG(dynType)
-
-static int dynType_parseWithStream(FILE *stream, const char *name, dyn_type *parent, struct types_head *refTypes, dyn_type **result);
-static void dynType_clear(dyn_type *type);
-static void dynType_clearComplex(dyn_type *type);
-static void dynType_clearSequence(dyn_type *type);
-static void dynType_clearTypedPointer(dyn_type *type);
-
-static struct type_entry *dynType_allocTypeEntry(void);
-
-static ffi_type * dynType_ffiTypeFor(int c);
-static dyn_type * dynType_findType(dyn_type *type, char *name);
-static int dynType_parseAny(FILE *stream, dyn_type *type);
-static int dynType_parseComplex(FILE *stream, dyn_type *type);
-static int dynType_parseNestedType(FILE *stream, dyn_type *type);
-static int dynType_parseReference(FILE *stream, dyn_type *type);
-static int dynType_parseRefByValue(FILE *stream, dyn_type *type);
-static int dynType_parseSequence(FILE *stream, dyn_type *type);
-static int dynType_parseSimple(int c, dyn_type *type);
-static int dynType_parseTypedPointer(FILE *stream, dyn_type *type);
-static void dynType_prepCif(ffi_type *type);
-static unsigned short dynType_getOffset(dyn_type *type, int index);
-
-static void dynType_printAny(char *name, dyn_type *type, int depth, FILE *stream);
-static void dynType_printComplex(char *name, dyn_type *type, int depth, FILE *stream);
-static void dynType_printSequence(char *name, dyn_type *type, int depth, FILE *stream);
-static void dynType_printSimple(char *name, dyn_type *type, int depth, FILE *stream);
-static void dynType_printTypedPointer(char *name, dyn_type *type, int depth, FILE *stream);
-static void dynType_printDepth(int depth, FILE *stream);
-
-static void dynType_printTypes(dyn_type *type, FILE *stream);
-static void dynType_printComplexType(dyn_type *type, FILE *stream);
-static void dynType_printSimpleType(dyn_type *type, FILE *stream);
-
-static int dynType_parseText(FILE *stream, dyn_type *type);
-void dynType_freeComplexType(dyn_type *type, void *loc);
-void dynType_deepFree(dyn_type *type, void *loc, bool alsoDeleteSelf);
-void dynType_freeSequenceType(dyn_type *type, void *seqLoc);
-
-struct generic_sequence {
- uint32_t cap;
- uint32_t len;
- void *buf;
-};
-
-struct _dyn_type {
- char *name;
- char descriptor;
- int type;
- ffi_type *ffiType;
- dyn_type *parent;
- struct types_head *referenceTypes; //NOTE: not owned
- struct types_head nestedTypesHead;
- union {
- struct {
- struct complex_type_entries_head entriesHead;
- ffi_type structType; //dyn_type.ffiType points to this
- dyn_type **types; //based on entriesHead for fast access
- } complex;
- struct {
- ffi_type seqType; //dyn_type.ffiType points to this
- dyn_type *itemType;
- } sequence;
- struct {
- dyn_type *typedType;
- } typedPointer;
- struct {
- dyn_type *ref;
- } ref;
- };
-};
-
-static const int OK = 0;
-static const int ERROR = 1;
-static const int MEM_ERROR = 2;
-static const int PARSE_ERROR = 3;
-
-int dynType_parse(FILE *descriptorStream, const char *name, struct types_head *refTypes, dyn_type **type) {
- return dynType_parseWithStream(descriptorStream, name, NULL, refTypes, type);
-}
-
-int dynType_parseWithStr(const char *descriptor, const char *name, struct types_head *refTypes, dyn_type **type) {
- int status = OK;
- FILE *stream = fmemopen((char *)descriptor, strlen(descriptor), "r");
- if (stream != NULL) {
- status = dynType_parseWithStream(stream, name, NULL, refTypes, type);
- if (status == OK) {
- int c = fgetc(stream);
- if (c != '\0' && c != EOF) {
- status = PARSE_ERROR;
- LOG_ERROR("Expected EOF got %c", c);
- }
- }
- fclose(stream);
- } else {
- status = ERROR;
- LOG_ERROR("Error creating mem stream for descriptor string. %s", strerror(errno));
- }
- return status;
-}
-
-static int dynType_parseWithStream(FILE *stream, const char *name, dyn_type *parent, struct types_head *refTypes, dyn_type **result) {
- int status = OK;
- dyn_type *type = calloc(1, sizeof(*type));
- if (type != NULL) {
- type->parent = parent;
- type->type = DYN_TYPE_INVALID;
- type->referenceTypes = refTypes;
- TAILQ_INIT(&type->nestedTypesHead);
- if (name != NULL) {
- type->name = strdup(name);
- if (type->name == NULL) {
- status = MEM_ERROR;
- LOG_ERROR("Error strdup'ing name '%s'\n", name);
- }
- }
- if (status == OK) {
- status = dynType_parseAny(stream, type);
- }
- if (status == OK) {
- *result = type;
- } else {
- dynType_destroy(type);
- }
- } else {
- status = MEM_ERROR;
- LOG_ERROR("Error allocating memory for type");
- }
- return status;
-}
-
-static int dynType_parseAny(FILE *stream, dyn_type *type) {
- int status = OK;
-
- int c = fgetc(stream);
- switch(c) {
- case 'T' :
- status = dynType_parseNestedType(stream, type);
- if (status == OK) {
- status = dynType_parseAny(stream, type);
- }
- break;
- case 'L' :
- status = dynType_parseReference(stream, type);
- break;
- case 'l' :
- status = dynType_parseRefByValue(stream, type);
- break;
- case '{' :
- status = dynType_parseComplex(stream, type);
- break;
- case '[' :
- status = dynType_parseSequence(stream, type);
- break;
- case '*' :
- status = dynType_parseTypedPointer(stream, type);
- break;
- case 't' :
- status = dynType_parseText(stream, type);
- break;
- default :
- status = dynType_parseSimple(c, type);
- break;
- }
-
- return status;
-}
-
-static int dynType_parseText(FILE *stream, dyn_type *type) {
- int status = OK;
- type->type = DYN_TYPE_TEXT;
- type->descriptor = 't';
- type->ffiType = &ffi_type_pointer;
- return status;
-}
-
-static int dynType_parseComplex(FILE *stream, dyn_type *type) {
- int status = OK;
- type->type = DYN_TYPE_COMPLEX;
- type->descriptor = '{';
- type->ffiType = &type->complex.structType;
- TAILQ_INIT(&type->complex.entriesHead);
-
- int c = fgetc(stream);
- struct complex_type_entry *entry = NULL;
- while (c != ' ' && c != '}') {
- ungetc(c,stream);
- entry = calloc(1, sizeof(*entry));
- if (entry != NULL) {
- entry->type = calloc(1, sizeof(*entry->type));
- }
- if (entry != NULL && entry->type != NULL) {
- entry->type->parent = type;
- entry->type->type = DYN_TYPE_INVALID;
- TAILQ_INIT(&entry->type->nestedTypesHead);
- TAILQ_INSERT_TAIL(&type->complex.entriesHead, entry, entries);
- status = dynType_parseAny(stream, entry->type);
- } else {
- if (entry != NULL) {
- free(entry);
- }
- status = MEM_ERROR;
- LOG_ERROR("Error allocating memory for type");
- }
- c = fgetc(stream);
- }
-
- entry = TAILQ_FIRST(&type->complex.entriesHead);
- char *name = NULL;
- while (c == ' ' && entry != NULL) {
- status = dynCommon_parseName(stream, &name);
- if (status == OK) {
- entry->name = name;
- entry = TAILQ_NEXT(entry, entries);
- } else {
- break;
- }
- c = getc(stream);
- }
-
- int count = 0;
- TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
- count +=1;
- }
-
- if (status == OK) {
- type->complex.structType.type = FFI_TYPE_STRUCT;
- type->complex.structType.elements = calloc(count + 1, sizeof(ffi_type));
- type->complex.structType.elements[count] = NULL;
- if (type->complex.structType.elements != NULL) {
- int index = 0;
- TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
- type->complex.structType.elements[index++] = entry->type->ffiType;
- }
- } else {
- status = MEM_ERROR;
- //T\nODO log: error allocating memory
- }
- }
-
- if (status == OK) {
- type->complex.types = calloc(count, sizeof(dyn_type *));
- if (type != NULL) {
- int index = 0;
- TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
- type->complex.types[index++] = entry->type;
- }
- } else {
- status = MEM_ERROR;
- LOG_ERROR("Error allocating memory for type")
- }
- }
-
- if (status == OK) {
- dynType_prepCif(type->ffiType);
- }
-
-
- return status;
-}
-
-static int dynType_parseNestedType(FILE *stream, dyn_type *type) {
- int status = OK;
- char *name = NULL;
- struct type_entry *entry = NULL;
-
- entry = dynType_allocTypeEntry();
- if (entry != NULL) {
- entry->type->parent = type;
- entry->type->type = DYN_TYPE_INVALID;
- TAILQ_INIT(&entry->type->nestedTypesHead);
- TAILQ_INSERT_TAIL(&type->nestedTypesHead, entry, entries);
- status = dynCommon_parseName(stream, &name);
- entry->type->name = name;
- } else {
- status = MEM_ERROR;
- LOG_ERROR("Error allocating entry");
- }
-
- if (status == OK) {
- int c = fgetc(stream);
- if (c != '=') {
- status = PARSE_ERROR;
- LOG_ERROR("Error parsing nested type expected '=' got '%c'", c);
- }
- }
-
- if (status == OK) {
- status = dynType_parseAny(stream, entry->type);
- int c = fgetc(stream);
- if (c != ';') {
- status = PARSE_ERROR;
- LOG_ERROR("Expected ';' got '%c'\n", c);
- }
- }
-
- return status;
-}
-
-static int dynType_parseReference(FILE *stream, dyn_type *type) {
- int status = OK;
- type->type = DYN_TYPE_TYPED_POINTER;
- type->descriptor = '*';
-
- type->ffiType = &ffi_type_pointer;
- type->typedPointer.typedType = NULL;
-
- dyn_type *subType = calloc(1, sizeof(*subType));
-
- if (subType != NULL) {
- type->typedPointer.typedType = subType;
- subType->parent = type;
- subType->type = DYN_TYPE_INVALID;
- TAILQ_INIT(&subType->nestedTypesHead);
- status = dynType_parseRefByValue(stream, subType);
- } else {
- status = MEM_ERROR;
- LOG_ERROR("Error allocating memory for subtype\n");
- }
-
- return status;
-}
-
-static int dynType_parseRefByValue(FILE *stream, dyn_type *type) {
- int status = OK;
- type->type = DYN_TYPE_REF;
- type->descriptor = 'l';
-
- char *name = NULL;
- status = dynCommon_parseName(stream, &name);
- if (status == OK) {
- dyn_type *ref = dynType_findType(type, name);
- if (ref != NULL) {
- type->ref.ref = ref;
- } else {
- status = PARSE_ERROR;
- LOG_ERROR("Error cannot find type '%s'", name);
- }
- free(name);
- }
-
- if (status == OK) {
- int c = fgetc(stream);
- if (c != ';') {
- status = PARSE_ERROR;
- LOG_ERROR("Error expected ';' got '%c'", c);
- }
- }
-
- return status;
-}
-
-static struct type_entry *dynType_allocTypeEntry(void) {
- struct type_entry *entry = calloc(1, sizeof(*entry));
- if (entry != NULL) {
- entry->type = calloc(1, sizeof(*entry->type));
- if (entry->type == NULL) {
- free(entry);
- entry = NULL;
- }
- }
- return entry;
-}
-
-static ffi_type *seq_types[] = {&ffi_type_uint32, &ffi_type_uint32, &ffi_type_pointer, NULL};
-
-static int dynType_parseSequence(FILE *stream, dyn_type *type) {
- int status = OK;
- type->type = DYN_TYPE_SEQUENCE;
- type->descriptor = '[';
-
- type->sequence.seqType.elements = seq_types;
- status = dynType_parseWithStream(stream, NULL, type, NULL, &type->sequence.itemType);
-
- if (status == OK) {
- type->ffiType = &type->sequence.seqType;
- dynType_prepCif(&type->sequence.seqType);
- }
-
- return status;
-}
-
-static int dynType_parseSimple(int c, dyn_type *type) {
- int status = OK;
- ffi_type *ffiType = dynType_ffiTypeFor(c);
- if (ffiType != NULL) {
- type->type = DYN_TYPE_SIMPLE;
- type->descriptor = c;
- type->ffiType = ffiType;
- } else {
- status = PARSE_ERROR;
- LOG_ERROR("Error unsupported type '%c'", c);
- }
-
- return status;
-}
-
-static int dynType_parseTypedPointer(FILE *stream, dyn_type *type) {
- int status = OK;
- type->type = DYN_TYPE_TYPED_POINTER;
- type->descriptor = '*';
- type->ffiType = &ffi_type_pointer;
-
- status = dynType_parseWithStream(stream, NULL, type, NULL, &type->typedPointer.typedType);
-
- return status;
-}
-
-static void dynType_prepCif(ffi_type *type) {
- ffi_cif cif;
- ffi_type *args[1];
- args[0] = type;
- ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uint, args);
-}
-
-void dynType_destroy(dyn_type *type) {
- if (type != NULL) {
- dynType_clear(type);
- free(type);
- }
-}
-
-static void dynType_clear(dyn_type *type) {
- struct type_entry *entry = TAILQ_FIRST(&type->nestedTypesHead);
- struct type_entry *tmp = NULL;
- while (entry != NULL) {
- tmp = entry;
- entry = TAILQ_NEXT(entry, entries);
- if (tmp->type != NULL) {
- dynType_destroy(tmp->type);
- tmp->type = NULL;
- }
- free(tmp);
- }
-
- switch (type->type) {
- case DYN_TYPE_COMPLEX :
- dynType_clearComplex(type);
- break;
- case DYN_TYPE_SEQUENCE :
- dynType_clearSequence(type);
- break;
- case DYN_TYPE_TYPED_POINTER :
- dynType_clearTypedPointer(type);
- break;
- }
-
- if (type->name != NULL) {
- free(type->name);
- }
-}
-
-static void dynType_clearComplex(dyn_type *type) {
- assert(type->type == DYN_TYPE_COMPLEX);
- struct complex_type_entry *entry = TAILQ_FIRST(&type->complex.entriesHead);
- struct complex_type_entry *tmp = NULL;
- while (entry != NULL) {
- dynType_destroy(entry->type);
- if (entry->name != NULL) {
- free(entry->name);
- }
- tmp = entry;
- entry = TAILQ_NEXT(entry, entries);
- free(tmp);
- }
- if (type->complex.types != NULL) {
- free(type->complex.types);
- }
- if (type->complex.structType.elements != NULL) {
- free(type->complex.structType.elements);
- }
-}
-
-static void dynType_clearSequence(dyn_type *type) {
- assert(type->type == DYN_TYPE_SEQUENCE);
- if (type->sequence.itemType != NULL) {
- dynType_destroy(type->sequence.itemType);
- }
-}
-
-static void dynType_clearTypedPointer(dyn_type *type) {
- assert(type->type == DYN_TYPE_TYPED_POINTER);
- if (type->typedPointer.typedType != NULL) {
- dynType_destroy(type->typedPointer.typedType);
- }
-}
-
-int dynType_alloc(dyn_type *type, void **bufLoc) {
- assert(type->type != DYN_TYPE_REF);
- int status = OK;
-
- void *inst = calloc(1, type->ffiType->size);
- if (inst != NULL) {
- *bufLoc = inst;
- } else {
- status = MEM_ERROR;
- LOG_ERROR("Error allocating memory for type '%c'", type->descriptor);
- }
-
- return status;
-}
-
-
-int dynType_complex_indexForName(dyn_type *type, const char *name) {
- assert(type->type == DYN_TYPE_COMPLEX);
- int i = 0;
- int index = -1;
- struct complex_type_entry *entry = NULL;
- TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
- if (strcmp(name, entry->name) == 0) {
- index = i;
- }
- i +=1;
- }
- return index;
-}
-
-int dynType_complex_dynTypeAt(dyn_type *type, int index, dyn_type **result) {
- assert(type->type == DYN_TYPE_COMPLEX);
- dyn_type *sub = type->complex.types[index];
- if (sub->type == DYN_TYPE_REF) {
- sub = sub->ref.ref;
- }
- *result = sub;
- return 0;
-}
-
-int dynType_complex_setValueAt(dyn_type *type, int index, void *start, void *in) {
- assert(type->type == DYN_TYPE_COMPLEX);
- char *loc = ((char *)start) + dynType_getOffset(type, index);
- size_t size = type->complex.structType.elements[index]->size;
- memcpy(loc, in, size);
- return 0;
-}
-
-int dynType_complex_valLocAt(dyn_type *type, int index, void *inst, void **result) {
- assert(type->type == DYN_TYPE_COMPLEX);
- char *l = (char *)inst;
- void *loc = (void *)(l + dynType_getOffset(type, index));
- *result = loc;
- return 0;
-}
-
-int dynType_complex_entries(dyn_type *type, struct complex_type_entries_head **entries) {
- assert(type->type == DYN_TYPE_COMPLEX);
- int status = OK;
- *entries = &type->complex.entriesHead;
- return status;
-}
-
-//sequence
-int dynType_sequence_alloc(dyn_type *type, void *inst, uint32_t cap) {
- assert(type->type == DYN_TYPE_SEQUENCE);
- int status = OK;
- struct generic_sequence *seq = inst;
- if (seq != NULL) {
- size_t size = dynType_size(type->sequence.itemType);
- seq->buf = calloc(cap, size);
- if (seq->buf != NULL) {
- seq->cap = cap;
- seq->len = 0;;
- } else {
- seq->cap = 0;
- status = MEM_ERROR;
- LOG_ERROR("Error allocating memory for buf")
- }
- } else {
- status = MEM_ERROR;
- LOG_ERROR("Error allocating memory for seq")
- }
- return status;
-}
-
-void dynType_free(dyn_type *type, void *loc) {
- dynType_deepFree(type, loc, true);
-}
-
-void dynType_deepFree(dyn_type *type, void *loc, bool alsoDeleteSelf) {
- if (loc != NULL) {
- dyn_type *subType = NULL;
- char *text = NULL;
- switch (type->type) {
- case DYN_TYPE_COMPLEX :
- dynType_freeComplexType(type, loc);
- break;
- case DYN_TYPE_SEQUENCE :
- dynType_freeSequenceType(type, loc);
- break;
- case DYN_TYPE_TYPED_POINTER:
- dynType_typedPointer_getTypedType(type, &subType);
- dynType_deepFree(subType, *(void **)loc, true);
- break;
- case DYN_TYPE_TEXT :
- text = *(char **)loc;
- free(text);
- break;
- }
-
- if (alsoDeleteSelf) {
- free(loc);
- }
- }
-}
-
-void dynType_freeSequenceType(dyn_type *type, void *seqLoc) {
- struct generic_sequence *seq = seqLoc;
- dyn_type *itemType = dynType_sequence_itemType(type);
- void *itemLoc = NULL;
- int i;
- for (i = 0; i < seq->len; i += 1) {
- dynType_sequence_locForIndex(type, seqLoc, i, &itemLoc);
- dynType_deepFree(itemType, itemLoc, false);
- }
- free(seq->buf);
-}
-
-void dynType_freeComplexType(dyn_type *type, void *loc) {
- struct complex_type_entry *entry = NULL;
- int index = 0;
- void *entryLoc = NULL;
- TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
- dynType_complex_valLocAt(type, index++, loc, &entryLoc);
- dynType_deepFree(entry->type, entryLoc, false);
- }
-}
-
-
-uint32_t dynType_sequence_length(void *seqLoc) {
- struct generic_sequence *seq = seqLoc;
- return seq->len;
-}
-
-int dynType_sequence_locForIndex(dyn_type *type, void *seqLoc, int index, void **out) {
- assert(type->type == DYN_TYPE_SEQUENCE);
- int status = OK;
-
- struct generic_sequence *seq = seqLoc;
- char *valLoc = seq->buf;
- size_t itemSize = type->sequence.itemType->ffiType->size;
-
- if (index >= seq->cap) {
- status = ERROR;
- LOG_ERROR("Requested index (%i) is greater than capacity (%u) of sequence", index, seq->cap);
- }
-
- if (index >= seq->len) {
- LOG_WARNING("Requesting index (%i) outsize defined length (%u) but within capacity", index, seq->len);
- }
-
- if (status == OK) { }
- int i;
- for (i = 0; i < seq->cap; i += 1) {
- if (index == i) {
- break;
- } else {
- valLoc += itemSize;
- }
- }
-
- (*out) = valLoc;
-
- return status;
-}
-
-int dynType_sequence_increaseLengthAndReturnLastLoc(dyn_type *type, void *seqLoc, void **valLoc) {
- assert(type->type == DYN_TYPE_SEQUENCE);
- int status = OK;
- struct generic_sequence *seq = seqLoc;
-
- int lastIndex = seq->len;
- if (seq->len < seq->cap) {
- seq->len += 1;
- } else {
- status = ERROR;
- LOG_ERROR("Cannot increase sequence length beyond capacity (%u)", seq->cap);
- }
-
- if (status == OK) {
- status = dynType_sequence_locForIndex(type, seqLoc, lastIndex, valLoc);
- }
-
- return status;
-}
-
-dyn_type * dynType_sequence_itemType(dyn_type *type) {
- assert(type->type == DYN_TYPE_SEQUENCE);
- dyn_type *itemType = type->sequence.itemType;
- if (itemType->type == DYN_TYPE_REF) {
- itemType = itemType->ref.ref;
- }
- return itemType;
-}
-
-void dynType_simple_setValue(dyn_type *type, void *inst, void *in) {
- size_t size = dynType_size(type);
- memcpy(inst, in, size);
-}
-
-
-int dynType_descriptorType(dyn_type *type) {
- return type->descriptor;
-}
-
-ffi_type *dynType_ffiType(dyn_type *type) {
- if (type->type == DYN_TYPE_REF) {
- return type->ref.ref->ffiType;
- }
- return type->ffiType;
-}
-
-static ffi_type * dynType_ffiTypeFor(int c) {
- ffi_type *type = NULL;
- switch (c) {
- case 'F' :
- type = &ffi_type_float;
- break;
- case 'D' :
- type = &ffi_type_double;
- break;
- case 'B' :
- type = &ffi_type_sint8;
- break;
- case 'b' :
- type = &ffi_type_uint8;
- break;
- case 'S' :
- type = &ffi_type_sint16;
- break;
- case 's' :
- type = &ffi_type_uint16;
- break;
- case 'I' :
- type = &ffi_type_sint32;
- break;
- case 'i' :
- type = &ffi_type_uint32;
- break;
- case 'J' :
- type = &ffi_type_sint64;
- break;
- case 'j' :
- type = &ffi_type_sint64;
- break;
- case 'N' :
- type = &ffi_type_sint;
- break;
- case 'P' :
- type = &ffi_type_pointer;
- break;
- }
- return type;
-}
-
-static dyn_type * dynType_findType(dyn_type *type, char *name) {
- dyn_type *result = NULL;
-
- struct type_entry *entry = NULL;
- if (type->referenceTypes != NULL) {
- TAILQ_FOREACH(entry, type->referenceTypes, entries) {
- LOG_DEBUG("checking ref type '%s' with name '%s'", entry->type->name, name);
- if (strcmp(name, entry->type->name) == 0) {
- result = entry->type;
- break;
- }
- }
- }
-
- if (result == NULL) {
- struct type_entry *nEntry = NULL;
- TAILQ_FOREACH(nEntry, &type->nestedTypesHead, entries) {
- LOG_DEBUG("checking nested type '%s' with name '%s'", nEntry->type->name, name);
- if (strcmp(name, nEntry->type->name) == 0) {
- result = nEntry->type;
- break;
- }
- }
- }
-
- if (result == NULL && type->parent != NULL) {
- result = dynType_findType(type->parent, name);
- }
-
- return result;
-}
-
-static unsigned short dynType_getOffset(dyn_type *type, int index) {
- assert(type->type == DYN_TYPE_COMPLEX);
- unsigned short offset = 0;
-
- ffi_type *ffiType = &type->complex.structType;
- int i;
- for (i = 0; i <= index && ffiType->elements[i] != NULL; i += 1) {
- size_t size = ffiType->elements[i]->size;
- unsigned short alignment = ffiType->elements[i]->alignment;
- int alignment_diff = offset % alignment;
- if (alignment_diff > 0) {
- offset += (alignment - alignment_diff);
- }
- if (i < index) {
- offset += size;
- }
- }
-
- return offset;
-}
-
-size_t dynType_size(dyn_type *type) {
- return type->ffiType->size;
-}
-
-int dynType_type(dyn_type *type) {
- return type->type;
-}
-
-
-int dynType_typedPointer_getTypedType(dyn_type *type, dyn_type **out) {
- assert(type->type == DYN_TYPE_TYPED_POINTER);
- int status = 0;
-
- dyn_type *typedType = type->typedPointer.typedType;
- if (typedType->type == DYN_TYPE_REF) {
- typedType = typedType->ref.ref;
- }
-
- *out = typedType;
- return status;
-}
-
-
-int dynType_text_allocAndInit(dyn_type *type, void *textLoc, const char *value) {
- assert(type->type == DYN_TYPE_TEXT);
- int status = 0;
- const char *str = strdup(value);
- char const **loc = textLoc;
- if (str != NULL) {
- *loc = str;
- } else {
- status = ERROR;
- LOG_ERROR("Cannot allocate memory for string");
- }
- return status;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-void dynType_print(dyn_type *type, FILE *stream) {
- if (type != NULL) {
- dynType_printTypes(type, stream);
-
- fprintf(stream, "main type:\n");
- dynType_printAny("root", type, 0, stream);
- } else {
- fprintf(stream, "invalid type\n");
- }
-}
-
-static void dynType_printDepth(int depth, FILE *stream) {
- int i;
- for (i = 0; i < depth; i +=1 ) {
- fprintf(stream, "\t");
- }
-}
-
-static void dynType_printAny(char *name, dyn_type *type, int depth, FILE *stream) {
- dyn_type *toPrint = type;
- if (toPrint->type == DYN_TYPE_REF) {
- toPrint = toPrint->ref.ref;
- }
- switch(toPrint->type) {
- case DYN_TYPE_COMPLEX :
- dynType_printComplex(name, toPrint, depth, stream);
- break;
- case DYN_TYPE_SIMPLE :
- dynType_printSimple(name, toPrint, depth, stream);
- break;
- case DYN_TYPE_SEQUENCE :
- dynType_printSequence(name, toPrint, depth, stream);
- break;
- case DYN_TYPE_TYPED_POINTER :
- dynType_printTypedPointer(name, toPrint, depth, stream);
- break;
- default :
- fprintf(stream, "TODO Unsupported type %i\n", toPrint->type);
- break;
- }
-}
-
-static void dynType_printComplex(char *name, dyn_type *type, int depth, FILE *stream) {
- if (type->name == NULL) {
- dynType_printDepth(depth, stream);
- fprintf(stream, "%s: complex type (anon), size is %zu, alignment is %i, descriptor is '%c'. fields:\n", name, type->ffiType->size, type->ffiType->alignment, type->descriptor);
-
- struct complex_type_entry *entry = NULL;
- TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
- dynType_printAny(entry->name, entry->type, depth + 1, stream);
- }
-
- dynType_printDepth(depth, stream);
- printf("}\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);
- }
-}
-
-static void dynType_printSequence(char *name, dyn_type *type, int depth, FILE *stream) {
- dynType_printDepth(depth, stream);
- fprintf(stream, "sequence, size is %zu, alignment is %i, descriptor is '%c'. fields:\n", type->ffiType->size, type->ffiType->alignment, type->descriptor);
-
- dynType_printDepth(depth + 1, stream);
- fprintf(stream, "cap: simple type, size is %zu, alignment is %i.\n", type->sequence.seqType.elements[0]->size, type->sequence.seqType.elements[0]->alignment);
-
- dynType_printDepth(depth + 1, stream);
- fprintf(stream, "len: simple type, size is %zu, alignment is %i.\n", type->sequence.seqType.elements[1]->size, type->sequence.seqType.elements[1]->alignment);
-
- dynType_printDepth(depth + 1, stream);
- fprintf(stream, "buf: array, size is %zu, alignment is %i. points to ->\n", type->sequence.seqType.elements[2]->size, type->sequence.seqType.elements[2]->alignment);
- dynType_printAny("element", type->sequence.itemType, depth + 1, stream);
-}
-
-static void dynType_printSimple(char *name, dyn_type *type, int depth, FILE *stream) {
- dynType_printDepth(depth, stream);
- fprintf(stream, "%s: simple type, size is %zu, alignment is %i, descriptor is '%c'.\n", name, type->ffiType->size, type->ffiType->alignment, type->descriptor);
-}
-
-static void dynType_printTypedPointer(char *name, dyn_type *type, int depth, FILE *stream) {
- dynType_printDepth(depth, stream);
- fprintf(stream, "%s: typed pointer, size is %zu, alignment is %i, points to ->\n", name, type->ffiType->size, type->ffiType->alignment);
- char *subName = NULL;
- if (name != NULL) {
- char buf[128];
- snprintf(buf, 128, "*%s", name);
- subName = buf;
- }
- dynType_printAny(subName, type->typedPointer.typedType, depth + 1, stream);
-}
-
-static void dynType_printTypes(dyn_type *type, FILE *stream) {
-
- dyn_type *parent = type->parent;
- struct type_entry *pentry = NULL;
- while (parent != NULL) {
- TAILQ_FOREACH(pentry, &parent->nestedTypesHead, entries) {
- if (pentry->type == type) {
- return;
- }
- }
- parent = parent->parent;
- }
-
- struct type_entry *entry = NULL;
- TAILQ_FOREACH(entry, &type->nestedTypesHead, entries) {
- dyn_type *toPrint = entry->type;
- if (toPrint->type == DYN_TYPE_REF) {
- toPrint = toPrint->ref.ref;
- }
-
- switch(toPrint->type) {
- case DYN_TYPE_COMPLEX :
- dynType_printComplexType(toPrint, stream);
- break;
- case DYN_TYPE_SIMPLE :
- dynType_printSimpleType(toPrint, stream);
- break;
- default :
- printf("TODO Print Type\n");
- break;
- }
- }
-
-
- struct complex_type_entry *centry = NULL;
- switch(type->type) {
- case DYN_TYPE_COMPLEX :
- TAILQ_FOREACH(centry, &type->complex.entriesHead, entries) {
- dynType_printTypes(centry->type, stream);
- }
- break;
- case DYN_TYPE_SEQUENCE :
- dynType_printTypes(type->sequence.itemType, stream);
- break;
- case DYN_TYPE_TYPED_POINTER :
- dynType_printTypes(type->typedPointer.typedType, stream);
- break;
- }
-}
-
-static void dynType_printComplexType(dyn_type *type, FILE *stream) {
- fprintf(stream, "type '%s': complex type, size is %zu, alignment is %i, descriptor is '%c'. fields:\n", type->name, type->ffiType->size, type->ffiType->alignment, type->descriptor);
-
- struct complex_type_entry *entry = NULL;
- TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
- dynType_printAny(entry->name, entry->type, 2, stream);
- }
-
- fprintf(stream, "}\n");
-}
-
-static void dynType_printSimpleType(dyn_type *type, FILE *stream) {
- fprintf(stream, "\ttype '%s': simple type, size is %zu, alignment is %i, descriptor is '%c'\n", type->name, type->ffiType->size, type->ffiType->alignment, type->descriptor);
-}
-
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/dynamic_function_interface/dyn_type.h
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/dyn_type.h b/remote_services/dynamic_function_interface/dyn_type.h
deleted file mode 100644
index 9fdbff2..0000000
--- a/remote_services/dynamic_function_interface/dyn_type.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-
-#ifndef _DYN_TYPE_H_
-#define _DYN_TYPE_H_
-
-#include <stdio.h>
-#include <sys/queue.h>
-#include <stdbool.h>
-
-#include <ffi.h>
-#include <stdint.h>
-
-#include "dfi_log_util.h"
-
-#if defined(BSD) || defined(__APPLE__)
-#include "open_memstream.h"
-#include "fmemopen.h"
-#endif
-
-/* Description string
- *
- * Type = [TypeDef]* (SimpleType | ComplexType | SequenceType | TypedPointer | PointerReference ) [TypeDef]* [Annotation]*
- * Name = alpha[(alpha|numeric)*]
- * SPACE = ' '
- *
- * SimplesTypes (based on java bytecode method signatures)
- * //Java based:
- * B char
- * C (not supported)
- * D double
- * F float
- * I int32_t
- * J int64_t
- * S int16_t
- * V void
- * Z boolean
- * //Extended
- * b unsigned char
- * i uint32_t
- * j uint62_t
- * s uint64_t
- * P untyped pointer (void *)
- * t char* string
- * N native int
- *
- * ComplexTypes (Struct)
- * {[Type]+ [(Name)(SPACE)]+}
- *
- * ReferenceByValue
- * l(name);
- *
- * PointerReference -> note shortcut for *l(name);
- * L(Name);
- *
- * TypeDef
- * T(Name)=Type;
- *
- * SequenceType
- * [(Type)
- *
- * TypedPointer
- * *(Type)
- *
- * Annotation TODO
- * <(Name)=(Value)>
- *
- * examples
- * "{DDII a b c d}" -> struct { double a; double b; int c; int d; };
- * "{DD{FF c1 c2} a b c}" -> struct { double a; double b; struct c { float c1; float c2; }; };
- *
- *
- */
-
-#define DYN_TYPE_INVALID 0
-#define DYN_TYPE_SIMPLE 1
-#define DYN_TYPE_COMPLEX 2
-#define DYN_TYPE_SEQUENCE 3
-#define DYN_TYPE_TYPED_POINTER 4
-#define DYN_TYPE_TEXT 5
-#define DYN_TYPE_REF 6
-
-typedef struct _dyn_type dyn_type;
-
-//TODO rename
-TAILQ_HEAD(types_head, type_entry);
-struct type_entry {
- dyn_type *type;
- TAILQ_ENTRY(type_entry) entries;
-};
-
-TAILQ_HEAD(complex_type_entries_head, complex_type_entry);
-struct complex_type_entry {
- dyn_type *type;
- char *name;
- TAILQ_ENTRY(complex_type_entry) entries;
-};
-
-//logging
-DFI_SETUP_LOG_HEADER(dynType);
-
-//generic
-int dynType_parse(FILE *descriptorStream, const char *name, struct types_head *refTypes, dyn_type **type);
-int dynType_parseWithStr(const char *descriptor, const char *name, struct types_head *refTypes, dyn_type **type);
-void dynType_destroy(dyn_type *type);
-
-int dynType_alloc(dyn_type *type, void **bufLoc);
-void dynType_free(dyn_type *type, void *loc);
-
-void dynType_print(dyn_type *type, FILE *stream);
-size_t dynType_size(dyn_type *type);
-int dynType_type(dyn_type *type);
-int dynType_descriptorType(dyn_type *type);
-ffi_type *dynType_ffiType(dyn_type *type);
-
-//complexType
-int dynType_complex_indexForName(dyn_type *type, const char *name);
-int dynType_complex_dynTypeAt(dyn_type *type, int index, dyn_type **subType);
-int dynType_complex_setValueAt(dyn_type *type, int index, void *inst, void *in);
-int dynType_complex_valLocAt(dyn_type *type, int index, void *inst, void **valLoc);
-int dynType_complex_entries(dyn_type *type, struct complex_type_entries_head **entries);
-
-//sequence
-int dynType_sequence_alloc(dyn_type *type, void *inst, uint32_t cap);
-int dynType_sequence_locForIndex(dyn_type *type, void *seqLoc, int index, void **valLoc);
-int dynType_sequence_increaseLengthAndReturnLastLoc(dyn_type *type, void *seqLoc, void **valLoc);
-dyn_type * dynType_sequence_itemType(dyn_type *type);
-uint32_t dynType_sequence_length(void *seqLoc);
-
-//typed pointer
-int dynType_typedPointer_getTypedType(dyn_type *type, dyn_type **typedType);
-
-//text
-int dynType_text_allocAndInit(dyn_type *type, void *textLoc, const char *value);
-
-//simple
-void dynType_simple_setValue(dyn_type *type, void *inst, void *in);
-
-#endif
[07/10] celix git commit: CELIX-237: moved rsa_http_ffi source to
rsa_dfi
Posted by pn...@apache.org.
CELIX-237: moved rsa_http_ffi source to rsa_dfi
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/3d7f7641
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/3d7f7641
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/3d7f7641
Branch: refs/heads/feature/CELIX-237_rsa-ffi
Commit: 3d7f7641fbd58c79b54e00d9d7d1395f54db166c
Parents: bf76d21
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri Jul 31 16:11:31 2015 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri Jul 31 16:11:31 2015 +0200
----------------------------------------------------------------------
.../remote_service_admin_dfi/CMakeLists.txt | 26 +-
.../dynamic_function_interface/CMakeLists.txt | 5 +-
.../include/remote_service_admin_http_impl.h | 52 +
.../src/remote_service_admin_activator.c | 122 ++
.../private/src/remote_service_admin_impl.c | 1085 ++++++++++++++++++
.../CMakeLists.txt | 51 -
.../include/remote_service_admin_http_impl.h | 52 -
.../src/remote_service_admin_activator.c | 122 --
.../private/src/remote_service_admin_impl.c | 1085 ------------------
9 files changed, 1274 insertions(+), 1326 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_dfi/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/CMakeLists.txt b/remote_services/remote_service_admin_dfi/CMakeLists.txt
index f74cac1..500e40e 100644
--- a/remote_services/remote_service_admin_dfi/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/CMakeLists.txt
@@ -34,19 +34,19 @@ if (RSA_REMOTE_SERVICE_ADMIN_DFI)
include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_http/private/include")
include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
- #SET_HEADER(BUNDLE_SYMBOLICNAME "apache_celix_remote_service_admin_dfi")
- #SET(BUNDLE_VERSION "0.0.1")
- #SET_HEADERS("Bundle-Name: Apache Celix Remote Service Admin HTTP for dynamic function interface")
+ SET_HEADER(BUNDLE_SYMBOLICNAME "apache_celix_remote_service_admin_dfi")
+ SET(BUNDLE_VERSION "0.0.1")
+ SET_HEADERS("Bundle-Name: Apache Celix Remote Service Admin HTTP for dynamic function interface")
- #bundle(remote_service_admin_dfi SOURCES
- # private/src/remote_service_admin_impl
- # private/src/remote_service_admin_activator
- # ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/export_registration_impl
- # ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/import_registration_impl
- # ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
- # ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
- #)
- #target_link_libraries(remote_service_admin_dfi celix_framework ${CURL_LIBRARIES} ${JANSSON_LIBRARIES} ${FFI_LIBRARIES})
+ bundle(remote_service_admin_dfi SOURCES
+ private/src/remote_service_admin_impl
+ private/src/remote_service_admin_activator
+ ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/export_registration_impl
+ ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/import_registration_impl
+ ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
+ ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
+ )
+ target_link_libraries(remote_service_admin_dfi celix_framework ${CURL_LIBRARIES} ${JANSSON_LIBRARIES} ${FFI_LIBRARIES} dfi)
- #install_bundle(remote_service_admin_dfi)
+ install_bundle(remote_service_admin_dfi)
endif (RSA_REMOTE_SERVICE_ADMIN_DFI)
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt b/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
index 309176f..ae1d5c3 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
@@ -18,7 +18,7 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
set(MEMSTREAM_SOURCES memstream/open_memstream.c memstream/fmemopen.c)
endif()
-add_library(dfi
+add_library(dfi STATIC
dyn_common.c
dyn_type.c
dyn_function.c
@@ -30,14 +30,13 @@ add_library(dfi
target_link_libraries(dfi ${FFI_LIBRARIES} ${JANSSON_LIBRARY})
-#if (FRAMEWORK_TESTS)
+#if (FRAMEWORK_TESTS) TODO
add_executable(dfi_tests
tst/dyn_type_tests.cpp
tst/dyn_function_tests.cpp
tst/dyn_closure_tests.cpp
tst/dyn_interface_tests.cpp
tst/json_serializer_tests.cpp
-# tst/avro_descriptor_translator_tests.cpp
tst/run_tests.cpp
)
target_link_libraries(dfi_tests dfi ${FFI_LIBRARIES} ${CPPUTEST_LIBRARY} ${JANSSON_LIBRARY})
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_dfi/private/include/remote_service_admin_http_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/include/remote_service_admin_http_impl.h b/remote_services/remote_service_admin_dfi/private/include/remote_service_admin_http_impl.h
new file mode 100644
index 0000000..dbf71c9
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/private/include/remote_service_admin_http_impl.h
@@ -0,0 +1,52 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_service_admin_http_impl.h
+ *
+ * \date Sep 30, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
+#define REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
+
+#include "remote_service_admin_impl.h"
+#include "log_helper.h"
+#include "civetweb.h"
+
+struct remote_service_admin {
+ bundle_context_pt context;
+ log_helper_pt loghelper;
+
+ celix_thread_mutex_t exportedServicesLock;
+ hash_map_pt exportedServices;
+
+ celix_thread_mutex_t importedServicesLock;
+ hash_map_pt importedServices;
+
+ char *port;
+ char *ip;
+
+ struct mg_context *ctx;
+};
+
+celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin);
+
+#endif /* REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_activator.c b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_activator.c
new file mode 100644
index 0000000..e4125fc
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_activator.c
@@ -0,0 +1,122 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_service_admin_activator.c
+ *
+ * \date Sep 30, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include "bundle_activator.h"
+#include "service_registration.h"
+
+#include "remote_service_admin_http_impl.h"
+#include "export_registration_impl.h"
+#include "import_registration_impl.h"
+
+struct activator {
+ remote_service_admin_pt admin;
+ remote_service_admin_service_pt adminService;
+ service_registration_pt registration;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator;
+
+ activator = calloc(1, sizeof(*activator));
+ if (!activator) {
+ status = CELIX_ENOMEM;
+ } else {
+ activator->admin = NULL;
+ activator->registration = NULL;
+
+ *userData = activator;
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+ remote_service_admin_service_pt remoteServiceAdmin = NULL;
+
+ status = remoteServiceAdmin_create(context, &activator->admin);
+ if (status == CELIX_SUCCESS) {
+ remoteServiceAdmin = calloc(1, sizeof(*remoteServiceAdmin));
+ if (!remoteServiceAdmin) {
+ status = CELIX_ENOMEM;
+ } else {
+ remoteServiceAdmin->admin = activator->admin;
+ remoteServiceAdmin->exportService = remoteServiceAdmin_exportService;
+
+ remoteServiceAdmin->getExportedServices = remoteServiceAdmin_getExportedServices;
+ remoteServiceAdmin->getImportedEndpoints = remoteServiceAdmin_getImportedEndpoints;
+ remoteServiceAdmin->importService = remoteServiceAdmin_importService;
+
+ remoteServiceAdmin->exportReference_getExportedEndpoint = exportReference_getExportedEndpoint;
+ remoteServiceAdmin->exportReference_getExportedService = exportReference_getExportedService;
+
+ remoteServiceAdmin->exportRegistration_close = exportRegistration_close;
+ remoteServiceAdmin->exportRegistration_getException = exportRegistration_getException;
+ remoteServiceAdmin->exportRegistration_getExportReference = exportRegistration_getExportReference;
+
+ remoteServiceAdmin->importReference_getImportedEndpoint = importReference_getImportedEndpoint;
+ remoteServiceAdmin->importReference_getImportedService = importReference_getImportedService;
+
+ remoteServiceAdmin->importRegistration_close = remoteServiceAdmin_removeImportedService;
+ remoteServiceAdmin->importRegistration_getException = importRegistration_getException;
+ remoteServiceAdmin->importRegistration_getImportReference = importRegistration_getImportReference;
+
+ status = bundleContext_registerService(context, OSGI_RSA_REMOTE_SERVICE_ADMIN, remoteServiceAdmin, NULL, &activator->registration);
+ activator->adminService = remoteServiceAdmin;
+ }
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ remoteServiceAdmin_stop(activator->admin);
+ serviceRegistration_unregister(activator->registration);
+ activator->registration = NULL;
+
+ remoteServiceAdmin_destroy(&activator->admin);
+
+ free(activator->adminService);
+
+ return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ free(activator);
+
+ return status;
+}
+
+
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_impl.c b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_impl.c
new file mode 100644
index 0000000..ac54e8d
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_impl.c
@@ -0,0 +1,1085 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_service_admin_impl.c
+ *
+ * \date May 21, 2015
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <ifaddrs.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <uuid/uuid.h>
+
+#include <curl/curl.h>
+
+#include <ffi.h>
+#include <jansson.h>
+
+#include "export_registration_impl.h"
+#include "import_registration_impl.h"
+#include "remote_service_admin_impl.h"
+#include "remote_constants.h"
+#include "constants.h"
+#include "utils.h"
+#include "bundle_context.h"
+#include "bundle.h"
+#include "service_reference.h"
+#include "service_registration.h"
+#include "log_helper.h"
+#include "log_service.h"
+#include "celix_threads.h"
+#include "civetweb.h"
+#include "log_helper.h"
+#include "endpoint_description.h"
+
+// defines how often the webserver is restarted (with an increased port number)
+#define MAX_NUMBER_OF_RESTARTS 5
+
+typedef void (*GEN_FUNC_TYPE)(void);
+
+struct generic_service_layout {
+ void *handle;
+ GEN_FUNC_TYPE functions[];
+};
+
+struct proxy {
+ remote_service_admin_pt admin;
+ char *sig;
+ int index;
+ ffi_cif cif;
+ ffi_closure *closure;
+ endpoint_description_pt endpointDescription
+};
+
+
+
+
+
+struct remote_service_admin {
+ bundle_context_pt context;
+ log_helper_pt loghelper;
+
+ celix_thread_mutex_t exportedServicesLock;
+ hash_map_pt exportedServices;
+
+ celix_thread_mutex_t importedServicesLock;
+ hash_map_pt importedServices;
+
+ char *port;
+ char *ip;
+
+ struct mg_context *ctx;
+};
+
+struct post {
+ const char *readptr;
+ int size;
+};
+
+struct get {
+ char *writeptr;
+ int size;
+};
+
+static const char *data_response_headers =
+ "HTTP/1.1 200 OK\r\n"
+ "Cache: no-cache\r\n"
+ "Content-Type: application/json\r\n"
+ "\r\n";
+
+static const char *no_content_response_headers =
+ "HTTP/1.1 204 OK\r\n";
+
+// TODO do we need to specify a non-Amdatu specific configuration type?!
+static const char * const CONFIGURATION_TYPE = "org.amdatu.remote.admin.http";
+static const char * const ENDPOINT_URL = "org.amdatu.remote.admin.http.url";
+
+static const char *DEFAULT_PORT = "8888";
+static const char *DEFAULT_IP = "127.0.0.1";
+
+static const unsigned int DEFAULT_TIMEOUT = 0;
+
+static int remoteServiceAdmin_callback(struct mg_connection *conn);
+
+static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, char *interface, endpoint_description_pt *description);
+
+static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip);
+
+static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp);
+static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp);
+
+celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *admin = calloc(1, sizeof(**admin));
+
+ if (!*admin) {
+ status = CELIX_ENOMEM;
+ } else {
+ unsigned int port_counter = 0;
+ char *port = NULL;
+ char *ip = NULL;
+ char *detectedIp = NULL;
+ (*admin)->context = context;
+ (*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL);
+ (*admin)->importedServices = hashMap_create(NULL, NULL, NULL, NULL);
+
+ celixThreadMutex_create(&(*admin)->exportedServicesLock, NULL);
+ celixThreadMutex_create(&(*admin)->importedServicesLock, NULL);
+
+ if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
+ logHelper_start((*admin)->loghelper);
+ }
+
+ bundleContext_getProperty(context, "RSA_PORT", &port);
+ if (port == NULL) {
+ port = (char *)DEFAULT_PORT;
+ }
+
+ bundleContext_getProperty(context, "RSA_IP", &ip);
+ if (ip == NULL) {
+ char *interface = NULL;
+
+ bundleContext_getProperty(context, "RSA_INTERFACE", &interface);
+ if ((interface != NULL) && (remoteServiceAdmin_getIpAdress(interface, &detectedIp) != CELIX_SUCCESS)) {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: Could not retrieve IP adress for interface %s", interface);
+ }
+
+ if (ip == NULL) {
+ remoteServiceAdmin_getIpAdress(NULL, &detectedIp);
+ }
+
+ ip = detectedIp;
+ }
+
+ if (ip != NULL) {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Using %s for service annunciation", ip);
+ (*admin)->ip = strdup(ip);
+ }
+ else {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No IP address for service annunciation set. Using %s", DEFAULT_IP);
+ (*admin)->ip = (char*) DEFAULT_IP;
+ }
+
+ if (detectedIp != NULL) {
+ free(detectedIp);
+ }
+
+ // Prepare callbacks structure. We have only one callback, the rest are NULL.
+ struct mg_callbacks callbacks;
+ memset(&callbacks, 0, sizeof(callbacks));
+ callbacks.begin_request = remoteServiceAdmin_callback;
+
+ do {
+ char newPort[10];
+ const char *options[] = { "listening_ports", port, NULL};
+
+ (*admin)->ctx = mg_start(&callbacks, (*admin), options);
+
+ if ((*admin)->ctx != NULL) {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Start webserver: %s", port);
+ (*admin)->port = strdup(port);
+
+ }
+ else {
+ char* endptr = port;
+ int currentPort = strtol(port, &endptr, 10);
+
+ errno = 0;
+
+ if (*endptr || errno != 0) {
+ currentPort = strtol(DEFAULT_PORT, NULL, 10);
+ }
+
+ port_counter++;
+ snprintf(&newPort[0], 6, "%d", (currentPort+1));
+
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting rsa server on port %s - retrying on port %s...", port, newPort);
+ port = newPort;
+ }
+ } while(((*admin)->ctx == NULL) && (port_counter < MAX_NUMBER_OF_RESTARTS));
+
+ }
+ return status;
+}
+
+
+celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin)
+{
+ celix_status_t status = CELIX_SUCCESS;
+
+ free((*admin)->ip);
+ free((*admin)->port);
+ free(*admin);
+
+ *admin = NULL;
+
+ return status;
+}
+
+celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&admin->exportedServicesLock);
+
+ hash_map_iterator_pt iter = hashMapIterator_create(admin->exportedServices);
+ while (hashMapIterator_hasNext(iter)) {
+ array_list_pt exports = hashMapIterator_nextValue(iter);
+ int i;
+ for (i = 0; i < arrayList_size(exports); i++) {
+ export_registration_pt export = arrayList_get(exports, i);
+ exportRegistration_stopTracking(export);
+ }
+ }
+ hashMapIterator_destroy(iter);
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+
+ iter = hashMapIterator_create(admin->importedServices);
+ while (hashMapIterator_hasNext(iter))
+ {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+
+ import_registration_factory_pt importFactory = hashMapEntry_getValue(entry);
+
+ if (importFactory != NULL) {
+ int i;
+ for (i = 0; i < arrayList_size(importFactory->registrations); i++)
+ {
+ import_registration_pt importRegistration = arrayList_get(importFactory->registrations, i);
+
+ if (importFactory->trackedFactory != NULL)
+ {
+ importFactory->trackedFactory->unregisterProxyService(importFactory->trackedFactory->factory, importRegistration->endpointDescription);
+ }
+ }
+
+ serviceTracker_close(importFactory->proxyFactoryTracker);
+ importRegistrationFactory_close(importFactory);
+
+ hashMapIterator_remove(iter);
+ importRegistrationFactory_destroy(&importFactory);
+ }
+ }
+ hashMapIterator_destroy(iter);
+ celixThreadMutex_unlock(&admin->importedServicesLock);
+
+ if (admin->ctx != NULL) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Stopping webserver...");
+ mg_stop(admin->ctx);
+ admin->ctx = NULL;
+ }
+
+ hashMap_destroy(admin->exportedServices, false, false);
+ hashMap_destroy(admin->importedServices, false, false);
+
+ logHelper_stop(admin->loghelper);
+ logHelper_destroy(&admin->loghelper);
+
+ return status;
+}
+
+/**
+ * Request: http://host:port/services/{service}/{request}
+ */
+//void *remoteServiceAdmin_callback(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info) {
+
+static int remoteServiceAdmin_callback(struct mg_connection *conn) {
+ int result = 0; // zero means: let civetweb handle it further, any non-zero value means it is handled by us...
+
+ const struct mg_request_info *request_info = mg_get_request_info(conn);
+ if (request_info->uri != NULL) {
+ remote_service_admin_pt rsa = request_info->user_data;
+
+
+ if (strncmp(request_info->uri, "/service/", 9) == 0 && strcmp("POST", request_info->request_method) == 0) {
+
+ // uri = /services/myservice/call
+ const char *uri = request_info->uri;
+ // rest = myservice/call
+
+ const char *rest = uri+9;
+ char *interfaceStart = strchr(rest, '/');
+ int pos = interfaceStart - rest;
+ char service[pos+1];
+ strncpy(service, rest, pos);
+ service[pos] = '\0';
+ long serviceId = atol(service);
+
+ celixThreadMutex_lock(&rsa->exportedServicesLock);
+
+ //find endpoint
+ export_registration_pt export = NULL;
+ hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ array_list_pt exports = hashMapEntry_getValue(entry);
+ int expIt = 0;
+ for (expIt = 0; expIt < arrayList_size(exports); expIt++) {
+ export_registration_pt check = arrayList_get(exports, expIt);
+ if (serviceId == check->endpointDescription->serviceId) {
+ export = check;
+ break;
+ }
+ }
+ }
+ hashMapIterator_destroy(iter);
+
+ if (export != NULL) {
+ uint64_t datalength = request_info->content_length;
+ char* data = malloc(datalength + 1);
+ mg_read(conn, data, datalength);
+ data[datalength] = '\0';
+
+ char *response = NULL;
+
+ //FIXME assuming add signature (add(double, double) : double)
+ /*TODO
+ export->endpoint->handleRequest(export->endpoint->endpoint, data, &response);
+ */
+
+
+ //retreive schema.
+ char *schema = NULL;
+ schema = properties_get(export->endpointDescription->properties, "protocol.schema");
+ printf("RSA: got schema %s\n", schema);
+
+
+ printf("Parsing data: %s\n", data);
+ json_error_t error;
+ json_t *js_request = json_loads(data, 0, &error);
+ 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 {
+ printf("RSA: got error '%s' for '%s'\n", error.text, data);
+ return 0;
+ }
+
+ printf("RSA: Looking for method %s\n", sig);
+
+ json_t *js_schema = json_loads(schema, 0, &error);
+ int methodIndex = -1;
+ if (js_schema) {
+ //TODO parse schema and create cif
+ size_t index;
+ json_t *value;
+ json_array_foreach(js_schema, index, value) {
+ if (strcmp(sig, json_string_value(value)) == 0) {
+ //found match
+ methodIndex = index;
+ break;
+ }
+ }
+ } else {
+ printf("RSA: got error '%s' for '%s'\n", error.text, schema);
+ return 0;
+ }
+
+ if (methodIndex < 0) {
+ printf("RSA: cannot find method '%s'\n", sig);
+ return 1;
+ }
+
+ size_t sigLength = strlen(sig);
+ char provArgs[sigLength];
+ bool startFound = false;
+ int i = 0;
+ int argIndex = 0;
+ for (; i < sigLength; i += 1) {
+ if (!startFound) {
+ if (sig[i] == '(') {
+ startFound = true;
+ }
+ } else {
+ if (sig[i] != ')') {
+ provArgs[argIndex++] = sig[i];
+ }
+ }
+ }
+ provArgs[argIndex] = '\0';
+ size_t provArgsLength = strlen(provArgs) -1;
+ printf("method index is %i and args are '%s'\n", methodIndex, provArgs);
+
+
+ //FFI part
+ ffi_cif cif;
+ ffi_type *argTypes[provArgsLength + 2]; //e.g. void *handle (extra), double a, double b, double *result (extra)
+ void *valuePointers[provArgsLength + 2];
+ //note assuming doubles!!
+ double values[provArgsLength];
+ double result = 0.0;
+ double *resultPointer = &result;
+ int rvalue = 0;
+
+ argTypes[0] = &ffi_type_pointer;
+ argTypes[provArgsLength +1] = &ffi_type_pointer; //last argument is return value, handled as a pointer
+ for (i = 0; i < provArgsLength; i += 1) {
+ //FIXME for now assuming double as arguments
+ argTypes[i+1] = &ffi_type_double;
+ }
+
+ valuePointers[0] = NULL;
+ valuePointers[provArgsLength+1] = &resultPointer;
+ for (i = 0; i < provArgsLength; i += 1) {
+ values[i] = 0.0;
+ valuePointers[i+1] = &(values[i]);
+ }
+
+ json_t *arguments = json_object_get(js_request, "a");
+ json_t *value;
+ size_t index;
+ json_array_foreach(arguments, index, value) {
+ values[index] = json_real_value(value); //setting values, again assuming double
+ }
+
+ json_decref(js_schema);
+ json_decref(js_request);
+
+ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, provArgsLength + 2,
+ &ffi_type_sint, argTypes) == FFI_OK)
+ {
+ printf("RSA: FFI PREP OK\n");
+
+ //TRYING TO CALL Calculate service
+ void *service = NULL;
+ bundleContext_getService(rsa->context, export->reference, &service);
+ if (service == NULL) {
+ printf("RSA: Ouch service is NULL\n");
+ return 0;
+ } else {
+ printf("RSA: service ok\n");
+ }
+
+ struct generic_service_layout *serv = service;
+
+ printf("RSA:Trying to call service using ffi\n");
+ valuePointers[0] = serv->handle;
+ ffi_call(&cif, serv->functions[methodIndex], &rvalue, valuePointers);
+ printf("RSA: Done calling service through ffi, got value %f\n", result);
+
+ json_t *resultRoot;
+ resultRoot = json_pack("{s:f}", "r", result);
+ response = json_dumps(resultRoot, 0);
+ json_decref(resultRoot);
+ }
+
+ if (response != NULL) {
+ mg_write(conn, data_response_headers, strlen(data_response_headers));
+// mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
+ mg_write(conn, response, strlen(response));
+// mg_send_data(conn, response, strlen(response));
+// mg_write_data(conn, response, strlen(response));
+
+ free(response);
+ } else {
+ mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
+ }
+ result = 0;
+
+ free(data);
+ } else {
+ //TODO log warning
+ }
+
+ celixThreadMutex_unlock(&rsa->exportedServicesLock);
+
+ }
+ }
+
+ return 1;
+}
+
+celix_status_t remoteServiceAdmin_handleRequest(remote_service_admin_pt rsa, char *service, char *data, char **reply) {
+ celixThreadMutex_lock(&rsa->exportedServicesLock);
+
+ hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ array_list_pt exports = hashMapEntry_getValue(entry);
+ int expIt = 0;
+ for (expIt = 0; expIt < arrayList_size(exports); expIt++) {
+ export_registration_pt export = arrayList_get(exports, expIt);
+ if (strcmp(service, export->endpointDescription->service) == 0) {
+ export->endpoint->handleRequest(export->endpoint->endpoint, data, reply);
+ }
+ }
+ }
+ hashMapIterator_destroy(iter);
+
+ celixThreadMutex_unlock(&rsa->exportedServicesLock);
+
+ return CELIX_SUCCESS;
+}
+
+celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations) {
+ celix_status_t status = CELIX_SUCCESS;
+ arrayList_create(registrations);
+ array_list_pt references = NULL;
+ service_reference_pt reference = NULL;
+ char filter [256];
+
+ snprintf(filter, 256, "(%s=%s)", (char *)OSGI_FRAMEWORK_SERVICE_ID, serviceId);
+
+ bundleContext_getServiceReferences(admin->context, NULL, filter, &references); //FIXME not safe
+
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: exportService called for serviceId %s", serviceId);
+
+ if (arrayList_size(references) >= 1) {
+ reference = arrayList_get(references, 0);
+ }
+
+ if(references!=NULL){
+ arrayList_destroy(references);
+ }
+
+ if (reference == NULL) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "ERROR: expected a reference for service id %s.", serviceId);
+ return CELIX_ILLEGAL_STATE;
+ }
+
+ char *exports = NULL;
+ char *provided = NULL;
+ char *schema = NULL;
+ serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports);
+ serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_OBJECTCLASS, &provided);
+ serviceReference_getProperty(reference, (char *) "protocol.schema", &schema);
+
+ if (exports == NULL || provided == NULL) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No Services to export.");
+ status = CELIX_ILLEGAL_STATE;
+ } else {
+ if (schema == NULL) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: no protocol.schema found.");
+ status = CELIX_ILLEGAL_STATE;
+ } else {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Export service (%s)", provided);
+
+ char *interface = provided;
+ endpoint_description_pt endpoint = NULL;
+ export_registration_pt registration = NULL;
+
+ remoteServiceAdmin_createEndpointDescription(admin, reference, interface, &endpoint);
+ printf("RSA: Creating export registration with endpoint pointer %p\n", endpoint);
+ exportRegistration_create(admin->loghelper, reference, endpoint, admin, admin->context, ®istration);
+ arrayList_add(*registrations, registration);
+
+ exportRegistration_open(registration);
+ exportRegistration_startTracking(registration);
+
+ celixThreadMutex_lock(&admin->exportedServicesLock);
+ hashMap_put(admin->exportedServices, reference, *registrations);
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+ }
+ }
+ return status;
+}
+
+celix_status_t remoteServiceAdmin_removeExportedService(export_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+ remote_service_admin_pt admin = registration->rsa;
+
+ celixThreadMutex_lock(&admin->exportedServicesLock);
+
+ hashMap_remove(admin->exportedServices, registration->reference);
+
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+
+ return status;
+}
+
+static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, char *interface, endpoint_description_pt *endpoint) {
+ celix_status_t status = CELIX_SUCCESS;
+ properties_pt endpointProperties = properties_create();
+
+
+ unsigned int size = 0;
+ char **keys;
+
+ serviceReference_getPropertyKeys(reference, &keys, &size);
+ for (int i = 0; i < size; i++) {
+ char *key = keys[i];
+ char *value = NULL;
+
+ if (serviceReference_getProperty(reference, key, &value) == CELIX_SUCCESS
+ && strcmp(key, (char*) OSGI_RSA_SERVICE_EXPORTED_INTERFACES) != 0
+ && strcmp(key, (char*) OSGI_FRAMEWORK_OBJECTCLASS) != 0) {
+ properties_set(endpointProperties, key, value);
+ printf("Added property '%s' with value '%s'\n", key, value);
+ }
+ }
+
+ hash_map_entry_pt entry = hashMap_getEntry(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
+
+ char* key = hashMapEntry_getKey(entry);
+ char *serviceId = (char *) hashMap_remove(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
+ char *uuid = NULL;
+
+ char buf[512];
+ snprintf(buf, 512, "/service/%s/%s", serviceId, interface);
+
+ char url[1024];
+ snprintf(url, 1024, "http://%s:%s%s", admin->ip, admin->port, buf);
+
+ uuid_t endpoint_uid;
+ uuid_generate(endpoint_uid);
+ char endpoint_uuid[37];
+ uuid_unparse_lower(endpoint_uid, endpoint_uuid);
+
+ bundleContext_getProperty(admin->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+ properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
+ properties_set(endpointProperties, (char*) OSGI_FRAMEWORK_OBJECTCLASS, interface);
+ properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_SERVICE_ID, serviceId);
+ properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID, endpoint_uuid);
+ properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED, "true");
+ properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED_CONFIGS, (char*) CONFIGURATION_TYPE);
+ properties_set(endpointProperties, (char*) ENDPOINT_URL, url);
+
+
+
+ *endpoint = calloc(1, sizeof(**endpoint));
+ if (!*endpoint) {
+ status = CELIX_ENOMEM;
+ } else {
+ (*endpoint)->id = properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID);
+ char *serviceId = NULL;
+ serviceReference_getProperty(reference, (char*) OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
+ (*endpoint)->serviceId = strtoull(serviceId, NULL, 0);
+ (*endpoint)->frameworkUUID = properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
+ (*endpoint)->service = interface;
+ (*endpoint)->properties = endpointProperties;
+ }
+
+ free(key);
+ free(serviceId);
+ free(keys);
+
+ return status;
+}
+
+static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip) {
+ celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+ struct ifaddrs *ifaddr, *ifa;
+ char host[NI_MAXHOST];
+
+ if (getifaddrs(&ifaddr) != -1)
+ {
+ for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
+ {
+ if (ifa->ifa_addr == NULL)
+ continue;
+
+ if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
+ if (interface == NULL) {
+ *ip = strdup(host);
+ status = CELIX_SUCCESS;
+ }
+ else if (strcmp(ifa->ifa_name, interface) == 0) {
+ *ip = strdup(host);
+ status = CELIX_SUCCESS;
+ }
+ }
+ }
+
+ freeifaddrs(ifaddr);
+ }
+
+ return status;
+}
+
+
+celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description)
+{
+ celix_status_t status = CELIX_SUCCESS;
+
+ properties_destroy((*description)->properties);
+ free(*description);
+
+ return status;
+}
+
+
+celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
+
+celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
+
+
+static int remoteServiceAdmin_remoteFunctionProxy(ffi_cif *cif, int *ret, void* args[], void *userData); //TODO MOVE
+static int remoteServiceAdmin_remoteFunctionProxy(ffi_cif *cif, int *ret, void* args[], void *userData) {
+ void **handle = args[0];
+ remote_service_admin_pt admin = (*handle);
+
+ struct proxy *proxy = userData;
+
+ printf("ffi closure got called for method sig %s with index %i\n", proxy->sig, proxy->index);
+
+ json_t *root = json_object();
+ json_t *sig = json_string(proxy->sig);
+ json_object_set(root, "m", sig);
+
+ json_t *arguments = json_array();
+ int i;
+ for (i = 1; i < proxy->cif.nargs -1; i += 1) {
+ //NOTE assuming double
+ double *dval = args[i];
+ json_t *value = json_real(*dval);
+ json_array_append(arguments, value);
+ }
+ json_object_set(root, "a", arguments);
+
+ char *data = json_dumps(root, 0);
+ char *reply = NULL;
+ int replyStatus;
+
+ remoteServiceAdmin_send(proxy->admin, proxy->endpointDescription, data, &reply, &replyStatus);
+ (*ret) = replyStatus;
+ printf("got reply from server '%s'\n", reply);
+
+ json_error_t error;
+ json_t *js_reply = json_loads(reply, JSON_DECODE_ANY, &error);
+ if (js_reply) {
+ //note assuming double
+ double **result = args[proxy->cif.nargs - 1];
+ json_unpack(js_reply, "{s:f}", "r", *result);
+ json_decref(js_reply);
+ } else {
+ printf("PROXY: got error '%s' for '%s'\n", error.text, reply);
+ }
+
+ json_decref(root);
+
+ free(data);
+ free(reply);
+
+ return 0;
+}
+
+
+celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpointDescription, import_registration_pt *registration) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Import service %s", endpointDescription->service);
+
+ char *schema = properties_get(endpointDescription->properties, "protocol.schema");
+ if (schema == NULL) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: protocol schema not found for endpoint\n");
+ return CELIX_SUCCESS;
+ }
+
+ printf("protocol.schema is '%s'\n", schema);
+ json_error_t error;
+ json_t *js_schema = json_loads(schema, 0, &error);
+ if (js_schema) {
+ //TODO parse schema and create cif
+ size_t numOfMethods = json_array_size(js_schema);
+ printf("RSA: num of method for proxy is %i\n", (int) numOfMethods);
+
+ struct generic_service_layout *service = calloc(1, sizeof(*service) + (numOfMethods-1) * sizeof(GEN_FUNC_TYPE));
+ service->handle = admin;
+
+ //struct generic_service_layout {
+ // void *handle;
+ // GEN_FUNC_TYPE functions[];
+ //};
+
+ size_t index;
+ json_t *value;
+ json_array_foreach(js_schema, index, value) {
+ //create closure
+
+ char *sig = json_string_value(value);
+ size_t sigLength = strlen(sig);
+ char provArgs[sigLength];
+ bool startFound = false;
+ int i = 0;
+ int argIndex = 0;
+ for (; i < sigLength; i += 1) {
+ if (!startFound) {
+ if (sig[i] == '(') {
+ startFound = true;
+ }
+ } else {
+ if (sig[i] != ')') {
+ provArgs[argIndex++] = sig[i];
+ }
+ }
+ }
+ provArgs[argIndex] = '\0';
+ printf("method index is %i and args are '%s'\n", index, provArgs);
+
+ int provArgLength = strlen(provArgs) -1;
+
+ struct proxy *proxy = malloc(sizeof(*proxy));
+ proxy->admin = admin;
+ proxy->sig = strdup(sig);
+ proxy->index = index;
+ proxy->endpointDescription = endpointDescription;
+
+ ffi_type **args = calloc(provArgLength +2, sizeof(ffi_type)); //TODO test if this can be on the stack
+
+ void (*function)(void);
+ proxy->closure = ffi_closure_alloc(sizeof(ffi_closure), &function);
+ service->functions[index] = function;
+
+ /* Initialize the argument info vectors */
+ args[0] = &ffi_type_pointer;
+ args[provArgLength + 1] = &ffi_type_pointer;
+ for (i = 0; i < provArgLength; i += 1) {
+ args[i+1] = &ffi_type_double;
+ }
+
+ if (proxy->closure) {
+ if (ffi_prep_cif(&proxy->cif, FFI_DEFAULT_ABI, provArgLength + 2, &ffi_type_sint, args) == FFI_OK) {
+ if (ffi_prep_closure_loc(proxy->closure, &proxy->cif, remoteServiceAdmin_remoteFunctionProxy, proxy, function) == FFI_OK) {
+ printf("RSA: created closure for method '%s'\n", sig);
+ }
+ }
+ }
+ }
+
+ //TODO register with imported properties
+ char *objectClass = properties_get(endpointDescription->properties, "objectClass");
+ service_registration_pt reg = NULL;
+ bundleContext_registerService(admin->context, objectClass, service, NULL, ®);
+ printf("registered proxy service with objectclass '%s'\n", objectClass);
+
+ } else {
+ printf("RSA: got error '%s' for '%s'\n", error.text, schema);
+ return CELIX_ILLEGAL_STATE;
+ }
+
+
+ //celixThreadMutex_lock(&admin->importedServicesLock);
+ //celixThreadMutex_unlock(&admin->importedServicesLock);
+
+
+ return status;
+ /*
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+
+ import_registration_factory_pt registration_factory = (import_registration_factory_pt) hashMap_get(admin->importedServices, endpointDescription->service);
+
+ // check whether we already have a registration_factory registered in the hashmap
+ if (registration_factory == NULL)
+ {
+ status = importRegistrationFactory_install(admin->loghelper, endpointDescription->service, admin->context, ®istration_factory);
+ if (status == CELIX_SUCCESS) {
+ hashMap_put(admin->importedServices, endpointDescription->service, registration_factory);
+ }
+ }
+
+ // factory available
+ if (status != CELIX_SUCCESS || (registration_factory->trackedFactory == NULL))
+ {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: no proxyFactory available.");
+ if (status == CELIX_SUCCESS) {
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+ }
+ else
+ {
+ // we create an importRegistration per imported service
+ importRegistration_create(endpointDescription, admin, (sendToHandle) &remoteServiceAdmin_send, admin->context, registration);
+ registration_factory->trackedFactory->registerProxyService(registration_factory->trackedFactory->factory, endpointDescription, admin, (sendToHandle) &remoteServiceAdmin_send);
+
+ arrayList_add(registration_factory->registrations, *registration);
+ }
+
+ celixThreadMutex_unlock(&admin->importedServicesLock);
+
+
+ return status;
+ */
+}
+
+
+celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+ /*
+
+ endpoint_description_pt endpointDescription = (endpoint_description_pt) registration->endpointDescription;
+ import_registration_factory_pt registration_factory = NULL;
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+
+ registration_factory = (import_registration_factory_pt) hashMap_get(admin->importedServices, endpointDescription->service);
+
+ // factory available
+ if ((registration_factory == NULL) || (registration_factory->trackedFactory == NULL))
+ {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: Error while retrieving registration factory for imported service %s", endpointDescription->service);
+ }
+ else
+ {
+ registration_factory->trackedFactory->unregisterProxyService(registration_factory->trackedFactory->factory, endpointDescription);
+ arrayList_removeElement(registration_factory->registrations, registration);
+ importRegistration_destroy(registration);
+
+ if (arrayList_isEmpty(registration_factory->registrations))
+ {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: closing proxy.");
+
+ serviceTracker_close(registration_factory->proxyFactoryTracker);
+ importRegistrationFactory_close(registration_factory);
+
+ hashMap_remove(admin->importedServices, endpointDescription->service);
+
+ importRegistrationFactory_destroy(®istration_factory);
+ }
+ }
+
+ celixThreadMutex_unlock(&admin->importedServicesLock);
+
+ return status;
+ */
+}
+
+
+celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) {
+
+ struct post post;
+ post.readptr = request;
+ post.size = strlen(request);
+
+ struct get get;
+ get.size = 0;
+ get.writeptr = malloc(1);
+
+ char *serviceUrl = properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
+ char url[256];
+ snprintf(url, 256, "%s", serviceUrl);
+
+ // assume the default timeout
+ int timeout = DEFAULT_TIMEOUT;
+
+ char *timeoutStr = NULL;
+ // Check if the endpoint has a timeout, if so, use it.
+ timeoutStr = properties_get(endpointDescription->properties, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT);
+ if (timeoutStr == NULL) {
+ // If not, get the global variable and use that one.
+ bundleContext_getProperty(rsa->context, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr);
+ }
+
+ // Update timeout if a property is used to set it.
+ if (timeoutStr != NULL) {
+ timeout = atoi(timeoutStr);
+ }
+
+ celix_status_t status = CELIX_SUCCESS;
+ CURL *curl;
+ CURLcode res;
+
+ curl = curl_easy_init();
+ if(!curl) {
+ status = CELIX_ILLEGAL_STATE;
+ } else {
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
+ curl_easy_setopt(curl, CURLOPT_URL, &url[0]);
+ curl_easy_setopt(curl, CURLOPT_POST, 1L);
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, remoteServiceAdmin_readCallback);
+ curl_easy_setopt(curl, CURLOPT_READDATA, &post);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&get);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)post.size);
+ res = curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
+
+ *reply = get.writeptr;
+ *replyStatus = res;
+ }
+
+ return status;
+}
+
+static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp) {
+ struct post *post = userp;
+
+ if (post->size) {
+ *(char *) ptr = post->readptr[0];
+ post->readptr++;
+ post->size--;
+ return 1;
+ }
+
+ return 0;
+}
+
+static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp) {
+ size_t realsize = size * nmemb;
+ struct get *mem = (struct get *)userp;
+
+ mem->writeptr = realloc(mem->writeptr, mem->size + realsize + 1);
+ if (mem->writeptr == NULL) {
+ /* out of memory! */
+ printf("not enough memory (realloc returned NULL)");
+ exit(EXIT_FAILURE);
+ }
+
+ memcpy(&(mem->writeptr[mem->size]), contents, realsize);
+ mem->size += realsize;
+ mem->writeptr[mem->size] = 0;
+
+ return realsize;
+}
+
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *endpoint = reference->endpoint;
+
+ return status;
+}
+
+celix_status_t exportReference_getExportedService(export_reference_pt reference) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
+
+celix_status_t importReference_getImportedService(import_reference_pt reference) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_http_ffi/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_http_ffi/CMakeLists.txt b/remote_services/remote_service_admin_http_ffi/CMakeLists.txt
deleted file mode 100644
index 6180ef0..0000000
--- a/remote_services/remote_service_admin_http_ffi/CMakeLists.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-celix_subproject(RSA_REMOTE_SERVICE_ADMIN_HTTP "Option to enable building the Remote Service Admin Service HTTP ffi" OFF)
-if (RSA_REMOTE_SERVICE_ADMIN_HTTP)
- find_package(CURL REQUIRED)
- find_package(Jansson REQUIRED)
- find_package(FFI REQUIRED)
-
- include_directories(${FFI_INCLUDE_DIRS})
- include_directories(${CURL_INCLUDE_DIRS})
- include_directories(${JANSSON_INCLUDE_DIRS})
- include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_http/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
-
- SET_HEADER(BUNDLE_SYMBOLICNAME "apache_celix_remote_service_admin_http_ffi")
- SET(BUNDLE_VERSION "0.0.1")
- SET_HEADERS("Bundle-Name: Apache Celix Remote Service Admin HTTP for ffi")
-
- bundle(remote_service_admin_http SOURCES
- private/src/remote_service_admin_impl
- private/src/remote_service_admin_activator
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/export_registration_impl
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/import_registration_impl
- ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
- ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
- )
-
- install_bundle(remote_service_admin_http)
-
- target_link_libraries(remote_service_admin_http celix_framework ${CURL_LIBRARIES} ${JANSSON_LIBRARIES} ${FFI_LIBRARIES})
-endif (RSA_REMOTE_SERVICE_ADMIN_HTTP)
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_http_ffi/private/include/remote_service_admin_http_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_http_ffi/private/include/remote_service_admin_http_impl.h b/remote_services/remote_service_admin_http_ffi/private/include/remote_service_admin_http_impl.h
deleted file mode 100644
index dbf71c9..0000000
--- a/remote_services/remote_service_admin_http_ffi/private/include/remote_service_admin_http_impl.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin_http_impl.h
- *
- * \date Sep 30, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
-#define REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
-
-#include "remote_service_admin_impl.h"
-#include "log_helper.h"
-#include "civetweb.h"
-
-struct remote_service_admin {
- bundle_context_pt context;
- log_helper_pt loghelper;
-
- celix_thread_mutex_t exportedServicesLock;
- hash_map_pt exportedServices;
-
- celix_thread_mutex_t importedServicesLock;
- hash_map_pt importedServices;
-
- char *port;
- char *ip;
-
- struct mg_context *ctx;
-};
-
-celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin);
-
-#endif /* REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_activator.c b/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_activator.c
deleted file mode 100644
index e4125fc..0000000
--- a/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_activator.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin_activator.c
- *
- * \date Sep 30, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdlib.h>
-
-#include "bundle_activator.h"
-#include "service_registration.h"
-
-#include "remote_service_admin_http_impl.h"
-#include "export_registration_impl.h"
-#include "import_registration_impl.h"
-
-struct activator {
- remote_service_admin_pt admin;
- remote_service_admin_service_pt adminService;
- service_registration_pt registration;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator;
-
- activator = calloc(1, sizeof(*activator));
- if (!activator) {
- status = CELIX_ENOMEM;
- } else {
- activator->admin = NULL;
- activator->registration = NULL;
-
- *userData = activator;
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
- remote_service_admin_service_pt remoteServiceAdmin = NULL;
-
- status = remoteServiceAdmin_create(context, &activator->admin);
- if (status == CELIX_SUCCESS) {
- remoteServiceAdmin = calloc(1, sizeof(*remoteServiceAdmin));
- if (!remoteServiceAdmin) {
- status = CELIX_ENOMEM;
- } else {
- remoteServiceAdmin->admin = activator->admin;
- remoteServiceAdmin->exportService = remoteServiceAdmin_exportService;
-
- remoteServiceAdmin->getExportedServices = remoteServiceAdmin_getExportedServices;
- remoteServiceAdmin->getImportedEndpoints = remoteServiceAdmin_getImportedEndpoints;
- remoteServiceAdmin->importService = remoteServiceAdmin_importService;
-
- remoteServiceAdmin->exportReference_getExportedEndpoint = exportReference_getExportedEndpoint;
- remoteServiceAdmin->exportReference_getExportedService = exportReference_getExportedService;
-
- remoteServiceAdmin->exportRegistration_close = exportRegistration_close;
- remoteServiceAdmin->exportRegistration_getException = exportRegistration_getException;
- remoteServiceAdmin->exportRegistration_getExportReference = exportRegistration_getExportReference;
-
- remoteServiceAdmin->importReference_getImportedEndpoint = importReference_getImportedEndpoint;
- remoteServiceAdmin->importReference_getImportedService = importReference_getImportedService;
-
- remoteServiceAdmin->importRegistration_close = remoteServiceAdmin_removeImportedService;
- remoteServiceAdmin->importRegistration_getException = importRegistration_getException;
- remoteServiceAdmin->importRegistration_getImportReference = importRegistration_getImportReference;
-
- status = bundleContext_registerService(context, OSGI_RSA_REMOTE_SERVICE_ADMIN, remoteServiceAdmin, NULL, &activator->registration);
- activator->adminService = remoteServiceAdmin;
- }
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- remoteServiceAdmin_stop(activator->admin);
- serviceRegistration_unregister(activator->registration);
- activator->registration = NULL;
-
- remoteServiceAdmin_destroy(&activator->admin);
-
- free(activator->adminService);
-
- return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- free(activator);
-
- return status;
-}
-
-
[03/10] celix git commit: CELIX-237: Moved dynamic function interface
under remote_service_admin_dfi
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_common.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_common.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_common.c
new file mode 100644
index 0000000..0cca69b
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_common.c
@@ -0,0 +1,136 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include "dyn_common.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdbool.h>
+
+#if defined(BSD) || defined(__APPLE__)
+#include "open_memstream.h"
+#include "fmemopen.h"
+#endif
+
+static const int OK = 0;
+static const int ERROR = 1;
+
+DFI_SETUP_LOG(dynCommon)
+
+static bool dynCommon_charIn(int c, const char *acceptedChars);
+
+int dynCommon_parseName(FILE *stream, char **result) {
+ return dynCommon_parseNameAlsoAccept(stream, NULL, result);
+}
+
+int dynCommon_parseNameAlsoAccept(FILE *stream, const char *acceptedChars, char **result) {
+ int status = OK;
+
+ char *buf = NULL;
+ size_t size = 0;
+ int strLen = 0;
+ FILE *name = open_memstream(&buf, &size);
+
+ if (name != NULL) {
+ int c = getc(stream);
+ while (isalnum(c) || c == '_' || dynCommon_charIn(c, acceptedChars)) {
+ fputc(c, name);
+ c = getc(stream);
+ strLen += 1;
+ }
+ fflush(name);
+ fclose(name);
+ ungetc(c, stream);
+ } else {
+ status = ERROR;
+ LOG_ERROR("Error creating mem stream for name. %s", strerror(errno));
+ }
+
+ if (status == OK) {
+ if (strLen == 0) {
+ status = ERROR;
+ LOG_ERROR("Parsed empty name");
+ }
+ }
+
+ if (status == OK) {
+ LOG_DEBUG("Parsed name '%s'", buf);
+ *result = buf;
+ } else if (buf != NULL) {
+ free(buf);
+ }
+
+ return status;
+}
+
+int dynCommon_parseNameValue(FILE *stream, char **outName, char **outValue) {
+ int status = OK;
+ char *name = NULL;
+ char *value = NULL;
+ const char *valueAcceptedChars = ".<>{}[]?;:~!@#$%^&*()_+-=,./\\'\"";
+
+ status = dynCommon_parseName(stream, &name);
+ if (status == OK) {
+ status = dynCommon_eatChar(stream, '=');
+ }
+ if (status == OK) {
+ status = dynCommon_parseNameAlsoAccept(stream, valueAcceptedChars, &value); //NOTE use different more lenient function e.g. only stop at '\n' ?
+ }
+
+ if (status == OK) {
+ *outName = name;
+ *outValue = value;
+ } else {
+ if (name != NULL) {
+ free(name);
+ }
+ if (value != NULL) {
+ free(value);
+ }
+ }
+ return status;
+}
+
+int dynCommon_eatChar(FILE *stream, int expected) {
+ int status = OK;
+ long loc = ftell(stream);
+ int c = fgetc(stream);
+ if (c != expected) {
+ status = ERROR;
+ LOG_ERROR("Error parsing, expected token '%c' got '%c' at position %li", expected, loc);
+ }
+ return status;
+}
+
+static bool dynCommon_charIn(int c, const char *acceptedChars) {
+ bool status = false;
+ if (acceptedChars != NULL) {
+ int i;
+ for (i = 0; acceptedChars[i] != '\0'; i += 1) {
+ if (c == acceptedChars[i]) {
+ status = true;
+ break;
+ }
+ }
+ }
+
+ return status;
+}
+
+void dynCommon_clearNamValHead(struct namvals_head *head) {
+ struct namval_entry *tmp = NULL;
+ struct namval_entry *entry = TAILQ_FIRST(head);
+ while (entry != NULL) {
+ tmp = entry;
+
+ if (entry->name != NULL) {
+ free(entry->name);
+ }
+ if (entry->value != NULL) {
+ free(entry->value);
+ }
+ entry = TAILQ_NEXT(entry, entries);
+ free(tmp);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_common.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_common.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_common.h
new file mode 100644
index 0000000..a31cbc4
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_common.h
@@ -0,0 +1,32 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef _DYN_COMMON_H_
+#define _DYN_COMMON_H_
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/queue.h>
+
+#include "dfi_log_util.h"
+
+//logging
+DFI_SETUP_LOG_HEADER(dynCommon);
+
+TAILQ_HEAD(namvals_head, namval_entry);
+
+struct namval_entry {
+ char *name;
+ char *value;
+ TAILQ_ENTRY(namval_entry) entries;
+};
+
+int dynCommon_parseName(FILE *stream, char **result);
+int dynCommon_parseNameAlsoAccept(FILE *stream, const char *acceptedChars, char **result);
+int dynCommon_parseNameValue(FILE *stream, char **name, char **value);
+int dynCommon_eatChar(FILE *stream, int c);
+
+void dynCommon_clearNamValHead(struct namvals_head *head);
+
+#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/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
new file mode 100644
index 0000000..0ae2a8a
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c
@@ -0,0 +1,243 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include "dyn_function.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <strings.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <ffi.h>
+
+#include "dyn_common.h"
+#include "dyn_type.h"
+#include "dfi_log_util.h"
+
+DFI_SETUP_LOG(dynFunction)
+
+struct _dyn_function_type {
+ char *name;
+ struct types_head *refTypes; //NOTE not owned
+ TAILQ_HEAD(,_dyn_function_argument_type) arguments;
+ ffi_type **ffiArguments;
+ dyn_type *funcReturn;
+ ffi_cif cif;
+
+ //closure part
+ ffi_closure *ffiClosure;
+ void (*fn)(void);
+ void *userData;
+ void (*bind)(void *userData, void *args[], void *ret);
+};
+
+typedef struct _dyn_function_argument_type dyn_function_argument_type;
+struct _dyn_function_argument_type {
+ int index;
+ char *name;
+ dyn_type *type;
+ TAILQ_ENTRY(_dyn_function_argument_type) entries;
+};
+
+static const int OK = 0;
+static const int MEM_ERROR = 1;
+static const int PARSE_ERROR = 2;
+static const int ERROR = 2;
+
+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);
+
+int dynFunction_parse(FILE *descriptor, struct types_head *refTypes, dyn_function_type **out) {
+ int status = OK;
+ dyn_function_type *dynFunc = NULL;
+ LOG_DEBUG("Creating dyn function", descriptor);
+
+ dynFunc = calloc(1, sizeof(*dynFunc));
+
+ if (dynFunc != NULL) {
+ TAILQ_INIT(&dynFunc->arguments);
+ dynFunc->refTypes = refTypes;
+ status = dynFunction_parseDescriptor(dynFunc, descriptor);
+ if (status == 0) {
+ int rc = dynFunction_initCif(dynFunc);
+ if (rc != 0) {
+ LOG_ERROR("Error initializing cif");
+ status = ERROR;
+ }
+ }
+ } else {
+ LOG_ERROR("Error allocationg memory for dyn functipn\n");
+ status = MEM_ERROR;
+ }
+
+ if (status == 0) {
+ *out = dynFunc;
+ }
+
+ return status;
+}
+
+int dynFunction_parseWithStr(const char *descriptor, struct types_head *refTypes, dyn_function_type **out) {
+ int status = OK;
+ FILE *stream = fmemopen((char *)descriptor, strlen(descriptor), "r");
+ if (stream != NULL) {
+ status = dynFunction_parse(stream, refTypes, out);
+ fclose(stream);
+ } else {
+ status = MEM_ERROR;
+ LOG_ERROR("Error creating mem stream for descriptor string. %s", strerror(errno));
+ }
+ return status;
+}
+
+static int dynFunction_parseDescriptor(dyn_function_type *dynFunc, FILE *descriptor) {
+ int status = OK;
+ char *name = NULL;
+
+ status = dynCommon_parseName(descriptor, &name);
+
+ if (status == OK) {
+ dynFunc->name = name;
+ }
+
+ if (status == OK) {
+ int c = fgetc(descriptor);
+ if ( c != '(') {
+ status = PARSE_ERROR;
+ LOG_ERROR("Expected '(' token got '%c'", c);
+ }
+ }
+
+ int nextChar = fgetc(descriptor);
+ int index = 0;
+ dyn_type *type = NULL;
+ while (nextChar != ')' && status == 0) {
+ type = NULL;
+ ungetc(nextChar, descriptor);
+ 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
+ if (arg != NULL) {
+ TAILQ_INSERT_TAIL(&dynFunc->arguments, arg, entries);
+ } else {
+ LOG_ERROR("Error allocating memory");
+ status = MEM_ERROR;
+ }
+ }
+ nextChar = fgetc(descriptor);
+ }
+
+ if (status == 0) {
+ status = dynType_parse(descriptor, NULL, dynFunc->refTypes, &dynFunc->funcReturn);
+ }
+
+ return status;
+}
+
+static int dynFunction_initCif(dyn_function_type *dynFunc) {
+ int status = 0;
+
+ int count = 0;
+ dyn_function_argument_type *entry = NULL;
+ TAILQ_FOREACH(entry, &dynFunc->arguments, entries) {
+ count +=1;
+ }
+
+ dynFunc->ffiArguments = calloc(count, sizeof(ffi_type));
+
+ TAILQ_FOREACH(entry, &dynFunc->arguments, entries) {
+ dynFunc->ffiArguments[entry->index] = dynType_ffiType(entry->type);
+ }
+
+ ffi_type **args = dynFunc->ffiArguments;
+ ffi_type *returnType = dynType_ffiType(dynFunc->funcReturn);
+
+ int ffiResult = ffi_prep_cif(&dynFunc->cif, FFI_DEFAULT_ABI, count, returnType, args);
+ if (ffiResult != FFI_OK) {
+ status = 1;
+ }
+
+ return status;
+}
+
+void dynFunction_destroy(dyn_function_type *dynFunc) {
+ if (dynFunc != NULL) {
+ if (dynFunc->funcReturn != NULL) {
+ dynType_destroy(dynFunc->funcReturn);
+ }
+ if (dynFunc->ffiClosure != NULL) {
+ ffi_closure_free(dynFunc->ffiClosure);
+ }
+ if (dynFunc->name != NULL) {
+ free(dynFunc->name);
+ }
+ if (dynFunc->ffiArguments != NULL) {
+ free(dynFunc->ffiArguments);
+ }
+
+ dyn_function_argument_type *entry = NULL;
+ dyn_function_argument_type *tmp = NULL;
+ entry = TAILQ_FIRST(&dynFunc->arguments);
+ while (entry != NULL) {
+ if (entry->name != NULL) {
+ free(entry->name);
+ }
+ dynType_destroy(entry->type);
+ tmp = entry;
+ entry = TAILQ_NEXT(entry, entries);
+ free(tmp);
+ }
+
+ free(dynFunc);
+ }
+}
+
+int dynFunction_call(dyn_function_type *dynFunc, void(*fn)(void), void *returnValue, void **argValues) {
+ //TODO check dynFunc arg
+ ffi_call(&dynFunc->cif, fn, returnValue, argValues);
+ return 0;
+}
+
+static void dynFunction_ffiBind(ffi_cif *cif, void *ret, void *args[], void *userData) {
+ dyn_function_type *dynFunc = userData;
+ dynFunc->bind(dynFunc->userData, args, ret);
+}
+
+int dynFunction_createClosure(dyn_function_type *dynFunc, void (*bind)(void *, void **, void*), void *userData, void(**out)(void)) {
+ int status = 0;
+ void (*fn)(void);
+ dynFunc->ffiClosure = ffi_closure_alloc(sizeof(ffi_closure), (void **)&fn);
+ if (dynFunc->ffiClosure != NULL) {
+ int rc = ffi_prep_closure_loc(dynFunc->ffiClosure, &dynFunc->cif, dynFunction_ffiBind, dynFunc, fn);
+ if (rc != FFI_OK) {
+ status = 1;
+ }
+ } else {
+ status = 2;
+ }
+
+ if (status == 0) {
+ dynFunc->bind = bind;
+ dynFunc->fn = fn;
+ *out =fn;
+ }
+
+ return status;
+}
+
+int dynFunction_getFnPointer(dyn_function_type *dynFunc, void (**fn)(void)) {
+ int status = 0;
+ if (dynFunc != NULL && dynFunc->fn != NULL) {
+ (*fn) = dynFunc->fn;
+ } else {
+ status = 1;
+ }
+ return status;
+}
+
+
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/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
new file mode 100644
index 0000000..2d5d6bb
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h
@@ -0,0 +1,31 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef __DYN_FUNCTION_H_
+#define __DYN_FUNCTION_H_
+
+#include <ffi.h>
+#include "dyn_type.h"
+#include "dfi_log_util.h"
+
+/**
+ * Uses the following schema
+ * (Name)([Type]*)Type
+ * e.g add(DD)D or sum({[D[D setA setB})D
+ */
+
+typedef struct _dyn_function_type dyn_function_type;
+typedef struct _dyn_closure_type dyn_closure_type;
+
+DFI_SETUP_LOG_HEADER(dynFunction);
+
+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);
+
+void dynFunction_destroy(dyn_function_type *dynFunc);
+int dynFunction_call(dyn_function_type *dynFunc, void(*fn)(void), void *returnValue, void **argValues);
+
+int dynFunction_createClosure(dyn_function_type *func, void (*bind)(void *, void **, void*), void *userData, void(**fn)(void));
+int dynFunction_getFnPointer(dyn_function_type *func, void (**fn)(void));
+
+#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/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
new file mode 100644
index 0000000..878cfea
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.c
@@ -0,0 +1,371 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include "dyn_interface.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "dyn_common.h"
+#include "dyn_type.h"
+#include "dyn_interface.h"
+
+DFI_SETUP_LOG(dynInterface);
+
+const int OK = 0;
+const int ERROR = 1;
+
+static int dynInterface_parseSection(dyn_interface_type *intf, FILE *stream);
+static int dynInterface_parseAnnotations(dyn_interface_type *intf, FILE *stream);
+static int dynInterface_parseTypes(dyn_interface_type *intf, FILE *stream);
+static int dynInterface_parseMethods(dyn_interface_type *intf, FILE *stream);
+static int dynInterface_parseHeader(dyn_interface_type *intf, FILE *stream);
+static int dynInterface_parseNameValueSection(dyn_interface_type *intf, FILE *stream, struct namvals_head *head);
+static int dynInterface_checkInterface(dyn_interface_type *intf);
+static int dynInterface_getEntryForHead(struct namvals_head *head, const char *name, char **value);
+
+int dynInterface_parse(FILE *descriptor, dyn_interface_type **out) {
+ int status = OK;
+
+ dyn_interface_type *intf = calloc(1, sizeof(*intf));
+ if (intf != NULL) {
+ TAILQ_INIT(&intf->header);
+ TAILQ_INIT(&intf->annotations);
+ TAILQ_INIT(&intf->types);
+ TAILQ_INIT(&intf->methods);
+
+ char peek = fgetc(descriptor);
+ while (peek == ':') {
+ ungetc(peek, descriptor);
+ status = dynInterface_parseSection(intf, descriptor);
+ if (status == OK) {
+ peek = fgetc(descriptor);
+ } else {
+ break;
+ }
+ }
+
+ if (status == OK) {
+ status = dynCommon_eatChar(descriptor, EOF);
+ }
+
+ if (status == OK) {
+ status = dynInterface_checkInterface(intf);
+ }
+ } else {
+ status = ERROR;
+ LOG_ERROR("Error allocating memory for dynamic interface\n");
+ }
+
+ if (status == OK) {
+ *out = intf;
+ } else if (intf != NULL) {
+ dynInterface_destroy(intf);
+ }
+ return status;
+}
+
+static int dynInterface_checkInterface(dyn_interface_type *intf) {
+ int status = OK;
+
+ //check header section
+ if (status == OK) {
+ bool foundType = false;
+ bool foundVersion = false;
+ bool foundName = false;
+ struct namval_entry *entry = NULL;
+ TAILQ_FOREACH(entry, &intf->header, entries) {
+ if (strcmp(entry->name, "type") == 0) {
+ foundType = true;
+ } else if (strcmp(entry->name, "version") == 0) {
+ foundVersion = true;
+ } else if (strcmp(entry->name, "name") == 0) {
+ foundName = true;
+ }
+ }
+
+ if (!foundType || !foundVersion || !foundName) {
+ status = ERROR;
+ LOG_ERROR("Parse Error. There must be a header section with a type, version and name entry");
+ }
+ }
+
+ return status;
+}
+
+static int dynInterface_parseSection(dyn_interface_type *intf, FILE *stream) {
+ int status = OK;
+ char *sectionName = NULL;
+
+ status = dynCommon_eatChar(stream, ':');
+
+ if (status == OK) {
+ status = dynCommon_parseName(stream, §ionName);
+ }
+
+ if (status == OK) {
+ status = dynCommon_eatChar(stream, '\n');
+ }
+
+ if (status == OK) {
+ if (strcmp("header", sectionName) == 0) {
+ status = dynInterface_parseHeader(intf, stream);
+ } else if (strcmp("annotations", sectionName) == 0) {
+ status = dynInterface_parseAnnotations(intf, stream);
+ } else if (strcmp("types", sectionName) == 0) {
+ status = dynInterface_parseTypes(intf, stream);
+ } else if (strcmp("methods", sectionName) == 0) {
+ status = dynInterface_parseMethods(intf, stream);
+ } else {
+ status = ERROR;
+ LOG_ERROR("unsupported section '%s'", sectionName);
+ }
+ }
+
+ if (sectionName != NULL) {
+ free(sectionName);
+ }
+
+ return status;
+}
+
+static int dynInterface_parseHeader(dyn_interface_type *intf, FILE *stream) {
+ return dynInterface_parseNameValueSection(intf, stream, &intf->header);
+}
+
+static int dynInterface_parseAnnotations(dyn_interface_type *intf, FILE *stream) {
+ return dynInterface_parseNameValueSection(intf, stream, &intf->annotations);
+}
+
+static int dynInterface_parseNameValueSection(dyn_interface_type *intf, FILE *stream, struct namvals_head *head) {
+ int status = OK;
+
+ int peek = fgetc(stream);
+ while (peek != ':' && peek != EOF) {
+ ungetc(peek, stream);
+
+ char *name;
+ char *value;
+ status = dynCommon_parseNameValue(stream, &name, &value);
+
+ if (status == OK) {
+ status = dynCommon_eatChar(stream, '\n');
+ }
+
+ struct namval_entry *entry = NULL;
+ if (status == OK) {
+ entry = calloc(1, sizeof(*entry));
+ if (entry != NULL) {
+ entry->name = name;
+ entry->value = value;
+ TAILQ_INSERT_TAIL(head, entry, entries);
+ } else {
+ status = ERROR;
+ LOG_ERROR("Error allocating memory for namval entry");
+ }
+ }
+
+ if (status != OK) {
+ if (name != NULL) {
+ free(name);
+ }
+ if (value != NULL) {
+ free(value);
+ }
+ if (entry != NULL) {
+ free(entry);
+ }
+ break;
+ }
+ peek = fgetc(stream);
+ }
+ ungetc(peek, stream);
+
+ return status;
+}
+
+static int dynInterface_parseTypes(dyn_interface_type *intf, FILE *stream) {
+ int status = OK;
+
+ //expected input (Name)=<Type>\n
+ int peek = fgetc(stream);
+ while (peek != ':' && peek != EOF) {
+ ungetc(peek, stream);
+
+ char *name;
+ status = dynCommon_parseName(stream, &name);
+
+ if (status == OK) {
+ status = dynCommon_eatChar(stream, '=');
+ }
+
+ dyn_type *type = NULL;
+ if (status == OK) {
+ dynType_parse(stream, name, &intf->types, &type);
+ }
+ if (name != NULL) {
+ free(name);
+ }
+
+ if (status == OK) {
+ status = dynCommon_eatChar(stream, '\n');
+ }
+
+ struct type_entry *entry = NULL;
+ if (status == OK) {
+ entry = calloc(1, sizeof(*entry));
+ if (entry != NULL) {
+ entry->type = type;
+ TAILQ_INSERT_TAIL(&intf->types, entry, entries);
+ } else {
+ status = ERROR;
+ LOG_ERROR("Error allocating memory for type entry");
+ }
+ }
+
+ if (status != OK) {
+ if (type != NULL) {
+ dynType_destroy(type);
+ }
+ if (entry != NULL) {
+ free(entry);
+ }
+ break;
+ }
+ peek = fgetc(stream);
+ }
+ ungetc(peek, stream);
+
+ return status;
+}
+
+static int dynInterface_parseMethods(dyn_interface_type *intf, FILE *stream) {
+ int status = OK;
+
+ //expected input (Name)=<Method>\n
+ int peek = fgetc(stream);
+ int index = 0;
+ while (peek != ':' && peek != EOF) {
+ ungetc(peek, stream);
+
+ char *id;
+ status = dynCommon_parseNameAlsoAccept(stream, "();[{}", &id);
+
+ if (status == OK) {
+ status = dynCommon_eatChar(stream, '=');
+ }
+
+
+ dyn_function_type *func = NULL;
+ if (status == OK) {
+ status = dynFunction_parse(stream, &intf->types, &func);
+ }
+
+ if (status == OK) {
+ status = dynCommon_eatChar(stream, '\n');
+ }
+
+ struct method_entry *entry = NULL;
+ if (status == OK) {
+ entry = calloc(1, sizeof(*entry));
+ if (entry != NULL) {
+ entry->index = index++;
+ entry->id = id;
+ entry->dynFunc = func;
+ TAILQ_INSERT_TAIL(&intf->methods, entry, entries);
+ } else {
+ status = ERROR;
+ LOG_ERROR("Error allocating memory for method entry");
+ }
+ }
+
+ if (status != OK) {
+ if (id != NULL) {
+ free(id);
+ }
+ if (func != NULL) {
+ dynFunction_destroy(func);
+ //TODO free strIdentier, name
+ }
+ if (entry != NULL) {
+ free(entry);
+ }
+ break;
+ }
+ peek = fgetc(stream);
+ }
+ ungetc(peek, stream);
+
+ return status;
+}
+
+void dynInterface_destroy(dyn_interface_type *intf) {
+ if (intf != NULL) {
+ dynCommon_clearNamValHead(&intf->header);
+ dynCommon_clearNamValHead(&intf->annotations);
+
+ struct type_entry *tmp = NULL;
+ struct type_entry *tInfo = TAILQ_FIRST(&intf->types);
+ while (tInfo != NULL) {
+ tmp = tInfo;
+ tInfo = TAILQ_NEXT(tInfo, entries);
+ dynType_destroy(tmp->type);
+ free(tmp);
+ }
+
+ struct method_entry *mTmp = NULL;
+ struct method_entry *mInfo = TAILQ_FIRST(&intf->methods);
+ while (mInfo != NULL) {
+ mTmp = mInfo;
+ mInfo = TAILQ_NEXT(mInfo, entries);
+
+ if (mTmp->id != NULL) {
+ free(mTmp->id);
+ }
+ if (mTmp->name != NULL) {
+ free(mTmp->name);
+ }
+ if (mTmp->dynFunc != NULL) {
+ dynFunction_destroy(mTmp->dynFunc);
+ }
+ free(mTmp);
+ }
+
+ free(intf);
+ }
+}
+
+int dynInterface_getName(dyn_interface_type *intf, char **out) {
+ return dynInterface_getEntryForHead(&intf->header, "name", out);
+}
+
+int dynInterface_getVersion(dyn_interface_type *intf, char **version) {
+ return dynInterface_getEntryForHead(&intf->header, "version", version);
+}
+
+int dynInterface_getHeaderEntry(dyn_interface_type *intf, const char *name, char **value) {
+ return dynInterface_getEntryForHead(&intf->header, name, value);
+}
+
+int dynInterface_getAnnotationEntry(dyn_interface_type *intf, const char *name, char **value) {
+ return dynInterface_getEntryForHead(&intf->annotations, name, value);
+}
+
+static int dynInterface_getEntryForHead(struct namvals_head *head, const char *name, char **out) {
+ int status = OK;
+ char *value = NULL;
+ struct namval_entry *entry = NULL;
+ TAILQ_FOREACH(entry, head, entries) {
+ if (strcmp(name, entry->name) == 0) {
+ value = entry->value;
+ break;
+ }
+ }
+ if (value != NULL) {
+ *out = value;
+ } else {
+ status = ERROR;
+ LOG_WARNING("Cannot find '%s' in list", name);
+ }
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.h
new file mode 100644
index 0000000..0b0898f
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.h
@@ -0,0 +1,58 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef __DYN_INTERFACE_H_
+#define __DYN_INTERFACE_H_
+
+#include "dyn_common.h"
+#include "dyn_type.h"
+#include "dyn_function.h"
+#include "dfi_log_util.h"
+
+DFI_SETUP_LOG_HEADER(dynInterface);
+
+/* Description string
+ *
+ * Descriptor (interface) = HeaderSection AnnotationSection TypesSection MethodsSection
+ *
+ * HeaderSection=
+ * ':header\n' [NameValue]*
+ * ':annotations\n' [NameValue]*
+ * ':types\n' [TypeIdValue]*
+ * ':methods\n' [MethodIdValue]
+ *
+ */
+
+//struct namvals_head in dyn_common.h
+TAILQ_HEAD(methods_head, method_entry);
+//struct reference_types_head in dyn_type.h
+
+typedef struct _dyn_interface_type dyn_interface_type;
+
+struct _dyn_interface_type {
+ struct namvals_head header;
+ struct namvals_head annotations;
+ struct types_head types;
+ struct methods_head methods;
+};
+
+struct method_entry {
+ int index;
+ char *id;
+ char *name;
+
+ dyn_function_type *dynFunc;
+
+ TAILQ_ENTRY(method_entry) entries;
+};
+
+int dynInterface_parse(FILE *descriptor, dyn_interface_type **out);
+void dynInterface_destroy(dyn_interface_type *intf);
+
+int dynInterface_getName(dyn_interface_type *intf, char **name);
+int dynInterface_getVersion(dyn_interface_type *intf, char **version);
+int dynInterface_getHeaderEntry(dyn_interface_type *intf, const char *name, char **value);
+int dynInterface_getAnnotationEntry(dyn_interface_type *intf, const char *name, char **value);
+
+
+#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/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
new file mode 100644
index 0000000..2946607
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c
@@ -0,0 +1,1031 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include "dyn_type.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "dyn_common.h"
+
+DFI_SETUP_LOG(dynType)
+
+static int dynType_parseWithStream(FILE *stream, const char *name, dyn_type *parent, struct types_head *refTypes, dyn_type **result);
+static void dynType_clear(dyn_type *type);
+static void dynType_clearComplex(dyn_type *type);
+static void dynType_clearSequence(dyn_type *type);
+static void dynType_clearTypedPointer(dyn_type *type);
+
+static struct type_entry *dynType_allocTypeEntry(void);
+
+static ffi_type * dynType_ffiTypeFor(int c);
+static dyn_type * dynType_findType(dyn_type *type, char *name);
+static int dynType_parseAny(FILE *stream, dyn_type *type);
+static int dynType_parseComplex(FILE *stream, dyn_type *type);
+static int dynType_parseNestedType(FILE *stream, dyn_type *type);
+static int dynType_parseReference(FILE *stream, dyn_type *type);
+static int dynType_parseRefByValue(FILE *stream, dyn_type *type);
+static int dynType_parseSequence(FILE *stream, dyn_type *type);
+static int dynType_parseSimple(int c, dyn_type *type);
+static int dynType_parseTypedPointer(FILE *stream, dyn_type *type);
+static void dynType_prepCif(ffi_type *type);
+static unsigned short dynType_getOffset(dyn_type *type, int index);
+
+static void dynType_printAny(char *name, dyn_type *type, int depth, FILE *stream);
+static void dynType_printComplex(char *name, dyn_type *type, int depth, FILE *stream);
+static void dynType_printSequence(char *name, dyn_type *type, int depth, FILE *stream);
+static void dynType_printSimple(char *name, dyn_type *type, int depth, FILE *stream);
+static void dynType_printTypedPointer(char *name, dyn_type *type, int depth, FILE *stream);
+static void dynType_printDepth(int depth, FILE *stream);
+
+static void dynType_printTypes(dyn_type *type, FILE *stream);
+static void dynType_printComplexType(dyn_type *type, FILE *stream);
+static void dynType_printSimpleType(dyn_type *type, FILE *stream);
+
+static int dynType_parseText(FILE *stream, dyn_type *type);
+void dynType_freeComplexType(dyn_type *type, void *loc);
+void dynType_deepFree(dyn_type *type, void *loc, bool alsoDeleteSelf);
+void dynType_freeSequenceType(dyn_type *type, void *seqLoc);
+
+struct generic_sequence {
+ uint32_t cap;
+ uint32_t len;
+ void *buf;
+};
+
+struct _dyn_type {
+ char *name;
+ char descriptor;
+ int type;
+ ffi_type *ffiType;
+ dyn_type *parent;
+ struct types_head *referenceTypes; //NOTE: not owned
+ struct types_head nestedTypesHead;
+ union {
+ struct {
+ struct complex_type_entries_head entriesHead;
+ ffi_type structType; //dyn_type.ffiType points to this
+ dyn_type **types; //based on entriesHead for fast access
+ } complex;
+ struct {
+ ffi_type seqType; //dyn_type.ffiType points to this
+ dyn_type *itemType;
+ } sequence;
+ struct {
+ dyn_type *typedType;
+ } typedPointer;
+ struct {
+ dyn_type *ref;
+ } ref;
+ };
+};
+
+static const int OK = 0;
+static const int ERROR = 1;
+static const int MEM_ERROR = 2;
+static const int PARSE_ERROR = 3;
+
+int dynType_parse(FILE *descriptorStream, const char *name, struct types_head *refTypes, dyn_type **type) {
+ return dynType_parseWithStream(descriptorStream, name, NULL, refTypes, type);
+}
+
+int dynType_parseWithStr(const char *descriptor, const char *name, struct types_head *refTypes, dyn_type **type) {
+ int status = OK;
+ FILE *stream = fmemopen((char *)descriptor, strlen(descriptor), "r");
+ if (stream != NULL) {
+ status = dynType_parseWithStream(stream, name, NULL, refTypes, type);
+ if (status == OK) {
+ int c = fgetc(stream);
+ if (c != '\0' && c != EOF) {
+ status = PARSE_ERROR;
+ LOG_ERROR("Expected EOF got %c", c);
+ }
+ }
+ fclose(stream);
+ } else {
+ status = ERROR;
+ LOG_ERROR("Error creating mem stream for descriptor string. %s", strerror(errno));
+ }
+ return status;
+}
+
+static int dynType_parseWithStream(FILE *stream, const char *name, dyn_type *parent, struct types_head *refTypes, dyn_type **result) {
+ int status = OK;
+ dyn_type *type = calloc(1, sizeof(*type));
+ if (type != NULL) {
+ type->parent = parent;
+ type->type = DYN_TYPE_INVALID;
+ type->referenceTypes = refTypes;
+ TAILQ_INIT(&type->nestedTypesHead);
+ if (name != NULL) {
+ type->name = strdup(name);
+ if (type->name == NULL) {
+ status = MEM_ERROR;
+ LOG_ERROR("Error strdup'ing name '%s'\n", name);
+ }
+ }
+ if (status == OK) {
+ status = dynType_parseAny(stream, type);
+ }
+ if (status == OK) {
+ *result = type;
+ } else {
+ dynType_destroy(type);
+ }
+ } else {
+ status = MEM_ERROR;
+ LOG_ERROR("Error allocating memory for type");
+ }
+ return status;
+}
+
+static int dynType_parseAny(FILE *stream, dyn_type *type) {
+ int status = OK;
+
+ int c = fgetc(stream);
+ switch(c) {
+ case 'T' :
+ status = dynType_parseNestedType(stream, type);
+ if (status == OK) {
+ status = dynType_parseAny(stream, type);
+ }
+ break;
+ case 'L' :
+ status = dynType_parseReference(stream, type);
+ break;
+ case 'l' :
+ status = dynType_parseRefByValue(stream, type);
+ break;
+ case '{' :
+ status = dynType_parseComplex(stream, type);
+ break;
+ case '[' :
+ status = dynType_parseSequence(stream, type);
+ break;
+ case '*' :
+ status = dynType_parseTypedPointer(stream, type);
+ break;
+ case 't' :
+ status = dynType_parseText(stream, type);
+ break;
+ default :
+ status = dynType_parseSimple(c, type);
+ break;
+ }
+
+ return status;
+}
+
+static int dynType_parseText(FILE *stream, dyn_type *type) {
+ int status = OK;
+ type->type = DYN_TYPE_TEXT;
+ type->descriptor = 't';
+ type->ffiType = &ffi_type_pointer;
+ return status;
+}
+
+static int dynType_parseComplex(FILE *stream, dyn_type *type) {
+ int status = OK;
+ type->type = DYN_TYPE_COMPLEX;
+ type->descriptor = '{';
+ type->ffiType = &type->complex.structType;
+ TAILQ_INIT(&type->complex.entriesHead);
+
+ int c = fgetc(stream);
+ struct complex_type_entry *entry = NULL;
+ while (c != ' ' && c != '}') {
+ ungetc(c,stream);
+ entry = calloc(1, sizeof(*entry));
+ if (entry != NULL) {
+ entry->type = calloc(1, sizeof(*entry->type));
+ }
+ if (entry != NULL && entry->type != NULL) {
+ entry->type->parent = type;
+ entry->type->type = DYN_TYPE_INVALID;
+ TAILQ_INIT(&entry->type->nestedTypesHead);
+ TAILQ_INSERT_TAIL(&type->complex.entriesHead, entry, entries);
+ status = dynType_parseAny(stream, entry->type);
+ } else {
+ if (entry != NULL) {
+ free(entry);
+ }
+ status = MEM_ERROR;
+ LOG_ERROR("Error allocating memory for type");
+ }
+ c = fgetc(stream);
+ }
+
+ entry = TAILQ_FIRST(&type->complex.entriesHead);
+ char *name = NULL;
+ while (c == ' ' && entry != NULL) {
+ status = dynCommon_parseName(stream, &name);
+ if (status == OK) {
+ entry->name = name;
+ entry = TAILQ_NEXT(entry, entries);
+ } else {
+ break;
+ }
+ c = getc(stream);
+ }
+
+ int count = 0;
+ TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
+ count +=1;
+ }
+
+ if (status == OK) {
+ type->complex.structType.type = FFI_TYPE_STRUCT;
+ type->complex.structType.elements = calloc(count + 1, sizeof(ffi_type));
+ type->complex.structType.elements[count] = NULL;
+ if (type->complex.structType.elements != NULL) {
+ int index = 0;
+ TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
+ type->complex.structType.elements[index++] = entry->type->ffiType;
+ }
+ } else {
+ status = MEM_ERROR;
+ //T\nODO log: error allocating memory
+ }
+ }
+
+ if (status == OK) {
+ type->complex.types = calloc(count, sizeof(dyn_type *));
+ if (type != NULL) {
+ int index = 0;
+ TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
+ type->complex.types[index++] = entry->type;
+ }
+ } else {
+ status = MEM_ERROR;
+ LOG_ERROR("Error allocating memory for type")
+ }
+ }
+
+ if (status == OK) {
+ dynType_prepCif(type->ffiType);
+ }
+
+
+ return status;
+}
+
+static int dynType_parseNestedType(FILE *stream, dyn_type *type) {
+ int status = OK;
+ char *name = NULL;
+ struct type_entry *entry = NULL;
+
+ entry = dynType_allocTypeEntry();
+ if (entry != NULL) {
+ entry->type->parent = type;
+ entry->type->type = DYN_TYPE_INVALID;
+ TAILQ_INIT(&entry->type->nestedTypesHead);
+ TAILQ_INSERT_TAIL(&type->nestedTypesHead, entry, entries);
+ status = dynCommon_parseName(stream, &name);
+ entry->type->name = name;
+ } else {
+ status = MEM_ERROR;
+ LOG_ERROR("Error allocating entry");
+ }
+
+ if (status == OK) {
+ int c = fgetc(stream);
+ if (c != '=') {
+ status = PARSE_ERROR;
+ LOG_ERROR("Error parsing nested type expected '=' got '%c'", c);
+ }
+ }
+
+ if (status == OK) {
+ status = dynType_parseAny(stream, entry->type);
+ int c = fgetc(stream);
+ if (c != ';') {
+ status = PARSE_ERROR;
+ LOG_ERROR("Expected ';' got '%c'\n", c);
+ }
+ }
+
+ return status;
+}
+
+static int dynType_parseReference(FILE *stream, dyn_type *type) {
+ int status = OK;
+ type->type = DYN_TYPE_TYPED_POINTER;
+ type->descriptor = '*';
+
+ type->ffiType = &ffi_type_pointer;
+ type->typedPointer.typedType = NULL;
+
+ dyn_type *subType = calloc(1, sizeof(*subType));
+
+ if (subType != NULL) {
+ type->typedPointer.typedType = subType;
+ subType->parent = type;
+ subType->type = DYN_TYPE_INVALID;
+ TAILQ_INIT(&subType->nestedTypesHead);
+ status = dynType_parseRefByValue(stream, subType);
+ } else {
+ status = MEM_ERROR;
+ LOG_ERROR("Error allocating memory for subtype\n");
+ }
+
+ return status;
+}
+
+static int dynType_parseRefByValue(FILE *stream, dyn_type *type) {
+ int status = OK;
+ type->type = DYN_TYPE_REF;
+ type->descriptor = 'l';
+
+ char *name = NULL;
+ status = dynCommon_parseName(stream, &name);
+ if (status == OK) {
+ dyn_type *ref = dynType_findType(type, name);
+ if (ref != NULL) {
+ type->ref.ref = ref;
+ } else {
+ status = PARSE_ERROR;
+ LOG_ERROR("Error cannot find type '%s'", name);
+ }
+ free(name);
+ }
+
+ if (status == OK) {
+ int c = fgetc(stream);
+ if (c != ';') {
+ status = PARSE_ERROR;
+ LOG_ERROR("Error expected ';' got '%c'", c);
+ }
+ }
+
+ return status;
+}
+
+static struct type_entry *dynType_allocTypeEntry(void) {
+ struct type_entry *entry = calloc(1, sizeof(*entry));
+ if (entry != NULL) {
+ entry->type = calloc(1, sizeof(*entry->type));
+ if (entry->type == NULL) {
+ free(entry);
+ entry = NULL;
+ }
+ }
+ return entry;
+}
+
+static ffi_type *seq_types[] = {&ffi_type_uint32, &ffi_type_uint32, &ffi_type_pointer, NULL};
+
+static int dynType_parseSequence(FILE *stream, dyn_type *type) {
+ int status = OK;
+ type->type = DYN_TYPE_SEQUENCE;
+ type->descriptor = '[';
+
+ type->sequence.seqType.elements = seq_types;
+ status = dynType_parseWithStream(stream, NULL, type, NULL, &type->sequence.itemType);
+
+ if (status == OK) {
+ type->ffiType = &type->sequence.seqType;
+ dynType_prepCif(&type->sequence.seqType);
+ }
+
+ return status;
+}
+
+static int dynType_parseSimple(int c, dyn_type *type) {
+ int status = OK;
+ ffi_type *ffiType = dynType_ffiTypeFor(c);
+ if (ffiType != NULL) {
+ type->type = DYN_TYPE_SIMPLE;
+ type->descriptor = c;
+ type->ffiType = ffiType;
+ } else {
+ status = PARSE_ERROR;
+ LOG_ERROR("Error unsupported type '%c'", c);
+ }
+
+ return status;
+}
+
+static int dynType_parseTypedPointer(FILE *stream, dyn_type *type) {
+ int status = OK;
+ type->type = DYN_TYPE_TYPED_POINTER;
+ type->descriptor = '*';
+ type->ffiType = &ffi_type_pointer;
+
+ status = dynType_parseWithStream(stream, NULL, type, NULL, &type->typedPointer.typedType);
+
+ return status;
+}
+
+static void dynType_prepCif(ffi_type *type) {
+ ffi_cif cif;
+ ffi_type *args[1];
+ args[0] = type;
+ ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uint, args);
+}
+
+void dynType_destroy(dyn_type *type) {
+ if (type != NULL) {
+ dynType_clear(type);
+ free(type);
+ }
+}
+
+static void dynType_clear(dyn_type *type) {
+ struct type_entry *entry = TAILQ_FIRST(&type->nestedTypesHead);
+ struct type_entry *tmp = NULL;
+ while (entry != NULL) {
+ tmp = entry;
+ entry = TAILQ_NEXT(entry, entries);
+ if (tmp->type != NULL) {
+ dynType_destroy(tmp->type);
+ tmp->type = NULL;
+ }
+ free(tmp);
+ }
+
+ switch (type->type) {
+ case DYN_TYPE_COMPLEX :
+ dynType_clearComplex(type);
+ break;
+ case DYN_TYPE_SEQUENCE :
+ dynType_clearSequence(type);
+ break;
+ case DYN_TYPE_TYPED_POINTER :
+ dynType_clearTypedPointer(type);
+ break;
+ }
+
+ if (type->name != NULL) {
+ free(type->name);
+ }
+}
+
+static void dynType_clearComplex(dyn_type *type) {
+ assert(type->type == DYN_TYPE_COMPLEX);
+ struct complex_type_entry *entry = TAILQ_FIRST(&type->complex.entriesHead);
+ struct complex_type_entry *tmp = NULL;
+ while (entry != NULL) {
+ dynType_destroy(entry->type);
+ if (entry->name != NULL) {
+ free(entry->name);
+ }
+ tmp = entry;
+ entry = TAILQ_NEXT(entry, entries);
+ free(tmp);
+ }
+ if (type->complex.types != NULL) {
+ free(type->complex.types);
+ }
+ if (type->complex.structType.elements != NULL) {
+ free(type->complex.structType.elements);
+ }
+}
+
+static void dynType_clearSequence(dyn_type *type) {
+ assert(type->type == DYN_TYPE_SEQUENCE);
+ if (type->sequence.itemType != NULL) {
+ dynType_destroy(type->sequence.itemType);
+ }
+}
+
+static void dynType_clearTypedPointer(dyn_type *type) {
+ assert(type->type == DYN_TYPE_TYPED_POINTER);
+ if (type->typedPointer.typedType != NULL) {
+ dynType_destroy(type->typedPointer.typedType);
+ }
+}
+
+int dynType_alloc(dyn_type *type, void **bufLoc) {
+ assert(type->type != DYN_TYPE_REF);
+ int status = OK;
+
+ void *inst = calloc(1, type->ffiType->size);
+ if (inst != NULL) {
+ *bufLoc = inst;
+ } else {
+ status = MEM_ERROR;
+ LOG_ERROR("Error allocating memory for type '%c'", type->descriptor);
+ }
+
+ return status;
+}
+
+
+int dynType_complex_indexForName(dyn_type *type, const char *name) {
+ assert(type->type == DYN_TYPE_COMPLEX);
+ int i = 0;
+ int index = -1;
+ struct complex_type_entry *entry = NULL;
+ TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
+ if (strcmp(name, entry->name) == 0) {
+ index = i;
+ }
+ i +=1;
+ }
+ return index;
+}
+
+int dynType_complex_dynTypeAt(dyn_type *type, int index, dyn_type **result) {
+ assert(type->type == DYN_TYPE_COMPLEX);
+ dyn_type *sub = type->complex.types[index];
+ if (sub->type == DYN_TYPE_REF) {
+ sub = sub->ref.ref;
+ }
+ *result = sub;
+ return 0;
+}
+
+int dynType_complex_setValueAt(dyn_type *type, int index, void *start, void *in) {
+ assert(type->type == DYN_TYPE_COMPLEX);
+ char *loc = ((char *)start) + dynType_getOffset(type, index);
+ size_t size = type->complex.structType.elements[index]->size;
+ memcpy(loc, in, size);
+ return 0;
+}
+
+int dynType_complex_valLocAt(dyn_type *type, int index, void *inst, void **result) {
+ assert(type->type == DYN_TYPE_COMPLEX);
+ char *l = (char *)inst;
+ void *loc = (void *)(l + dynType_getOffset(type, index));
+ *result = loc;
+ return 0;
+}
+
+int dynType_complex_entries(dyn_type *type, struct complex_type_entries_head **entries) {
+ assert(type->type == DYN_TYPE_COMPLEX);
+ int status = OK;
+ *entries = &type->complex.entriesHead;
+ return status;
+}
+
+//sequence
+int dynType_sequence_alloc(dyn_type *type, void *inst, uint32_t cap) {
+ assert(type->type == DYN_TYPE_SEQUENCE);
+ int status = OK;
+ struct generic_sequence *seq = inst;
+ if (seq != NULL) {
+ size_t size = dynType_size(type->sequence.itemType);
+ seq->buf = calloc(cap, size);
+ if (seq->buf != NULL) {
+ seq->cap = cap;
+ seq->len = 0;;
+ } else {
+ seq->cap = 0;
+ status = MEM_ERROR;
+ LOG_ERROR("Error allocating memory for buf")
+ }
+ } else {
+ status = MEM_ERROR;
+ LOG_ERROR("Error allocating memory for seq")
+ }
+ return status;
+}
+
+void dynType_free(dyn_type *type, void *loc) {
+ dynType_deepFree(type, loc, true);
+}
+
+void dynType_deepFree(dyn_type *type, void *loc, bool alsoDeleteSelf) {
+ if (loc != NULL) {
+ dyn_type *subType = NULL;
+ char *text = NULL;
+ switch (type->type) {
+ case DYN_TYPE_COMPLEX :
+ dynType_freeComplexType(type, loc);
+ break;
+ case DYN_TYPE_SEQUENCE :
+ dynType_freeSequenceType(type, loc);
+ break;
+ case DYN_TYPE_TYPED_POINTER:
+ dynType_typedPointer_getTypedType(type, &subType);
+ dynType_deepFree(subType, *(void **)loc, true);
+ break;
+ case DYN_TYPE_TEXT :
+ text = *(char **)loc;
+ free(text);
+ break;
+ }
+
+ if (alsoDeleteSelf) {
+ free(loc);
+ }
+ }
+}
+
+void dynType_freeSequenceType(dyn_type *type, void *seqLoc) {
+ struct generic_sequence *seq = seqLoc;
+ dyn_type *itemType = dynType_sequence_itemType(type);
+ void *itemLoc = NULL;
+ int i;
+ for (i = 0; i < seq->len; i += 1) {
+ dynType_sequence_locForIndex(type, seqLoc, i, &itemLoc);
+ dynType_deepFree(itemType, itemLoc, false);
+ }
+ free(seq->buf);
+}
+
+void dynType_freeComplexType(dyn_type *type, void *loc) {
+ struct complex_type_entry *entry = NULL;
+ int index = 0;
+ void *entryLoc = NULL;
+ TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
+ dynType_complex_valLocAt(type, index++, loc, &entryLoc);
+ dynType_deepFree(entry->type, entryLoc, false);
+ }
+}
+
+
+uint32_t dynType_sequence_length(void *seqLoc) {
+ struct generic_sequence *seq = seqLoc;
+ return seq->len;
+}
+
+int dynType_sequence_locForIndex(dyn_type *type, void *seqLoc, int index, void **out) {
+ assert(type->type == DYN_TYPE_SEQUENCE);
+ int status = OK;
+
+ struct generic_sequence *seq = seqLoc;
+ char *valLoc = seq->buf;
+ size_t itemSize = type->sequence.itemType->ffiType->size;
+
+ if (index >= seq->cap) {
+ status = ERROR;
+ LOG_ERROR("Requested index (%i) is greater than capacity (%u) of sequence", index, seq->cap);
+ }
+
+ if (index >= seq->len) {
+ LOG_WARNING("Requesting index (%i) outsize defined length (%u) but within capacity", index, seq->len);
+ }
+
+ if (status == OK) { }
+ int i;
+ for (i = 0; i < seq->cap; i += 1) {
+ if (index == i) {
+ break;
+ } else {
+ valLoc += itemSize;
+ }
+ }
+
+ (*out) = valLoc;
+
+ return status;
+}
+
+int dynType_sequence_increaseLengthAndReturnLastLoc(dyn_type *type, void *seqLoc, void **valLoc) {
+ assert(type->type == DYN_TYPE_SEQUENCE);
+ int status = OK;
+ struct generic_sequence *seq = seqLoc;
+
+ int lastIndex = seq->len;
+ if (seq->len < seq->cap) {
+ seq->len += 1;
+ } else {
+ status = ERROR;
+ LOG_ERROR("Cannot increase sequence length beyond capacity (%u)", seq->cap);
+ }
+
+ if (status == OK) {
+ status = dynType_sequence_locForIndex(type, seqLoc, lastIndex, valLoc);
+ }
+
+ return status;
+}
+
+dyn_type * dynType_sequence_itemType(dyn_type *type) {
+ assert(type->type == DYN_TYPE_SEQUENCE);
+ dyn_type *itemType = type->sequence.itemType;
+ if (itemType->type == DYN_TYPE_REF) {
+ itemType = itemType->ref.ref;
+ }
+ return itemType;
+}
+
+void dynType_simple_setValue(dyn_type *type, void *inst, void *in) {
+ size_t size = dynType_size(type);
+ memcpy(inst, in, size);
+}
+
+
+int dynType_descriptorType(dyn_type *type) {
+ return type->descriptor;
+}
+
+ffi_type *dynType_ffiType(dyn_type *type) {
+ if (type->type == DYN_TYPE_REF) {
+ return type->ref.ref->ffiType;
+ }
+ return type->ffiType;
+}
+
+static ffi_type * dynType_ffiTypeFor(int c) {
+ ffi_type *type = NULL;
+ switch (c) {
+ case 'F' :
+ type = &ffi_type_float;
+ break;
+ case 'D' :
+ type = &ffi_type_double;
+ break;
+ case 'B' :
+ type = &ffi_type_sint8;
+ break;
+ case 'b' :
+ type = &ffi_type_uint8;
+ break;
+ case 'S' :
+ type = &ffi_type_sint16;
+ break;
+ case 's' :
+ type = &ffi_type_uint16;
+ break;
+ case 'I' :
+ type = &ffi_type_sint32;
+ break;
+ case 'i' :
+ type = &ffi_type_uint32;
+ break;
+ case 'J' :
+ type = &ffi_type_sint64;
+ break;
+ case 'j' :
+ type = &ffi_type_sint64;
+ break;
+ case 'N' :
+ type = &ffi_type_sint;
+ break;
+ case 'P' :
+ type = &ffi_type_pointer;
+ break;
+ }
+ return type;
+}
+
+static dyn_type * dynType_findType(dyn_type *type, char *name) {
+ dyn_type *result = NULL;
+
+ struct type_entry *entry = NULL;
+ if (type->referenceTypes != NULL) {
+ TAILQ_FOREACH(entry, type->referenceTypes, entries) {
+ LOG_DEBUG("checking ref type '%s' with name '%s'", entry->type->name, name);
+ if (strcmp(name, entry->type->name) == 0) {
+ result = entry->type;
+ break;
+ }
+ }
+ }
+
+ if (result == NULL) {
+ struct type_entry *nEntry = NULL;
+ TAILQ_FOREACH(nEntry, &type->nestedTypesHead, entries) {
+ LOG_DEBUG("checking nested type '%s' with name '%s'", nEntry->type->name, name);
+ if (strcmp(name, nEntry->type->name) == 0) {
+ result = nEntry->type;
+ break;
+ }
+ }
+ }
+
+ if (result == NULL && type->parent != NULL) {
+ result = dynType_findType(type->parent, name);
+ }
+
+ return result;
+}
+
+static unsigned short dynType_getOffset(dyn_type *type, int index) {
+ assert(type->type == DYN_TYPE_COMPLEX);
+ unsigned short offset = 0;
+
+ ffi_type *ffiType = &type->complex.structType;
+ int i;
+ for (i = 0; i <= index && ffiType->elements[i] != NULL; i += 1) {
+ size_t size = ffiType->elements[i]->size;
+ unsigned short alignment = ffiType->elements[i]->alignment;
+ int alignment_diff = offset % alignment;
+ if (alignment_diff > 0) {
+ offset += (alignment - alignment_diff);
+ }
+ if (i < index) {
+ offset += size;
+ }
+ }
+
+ return offset;
+}
+
+size_t dynType_size(dyn_type *type) {
+ return type->ffiType->size;
+}
+
+int dynType_type(dyn_type *type) {
+ return type->type;
+}
+
+
+int dynType_typedPointer_getTypedType(dyn_type *type, dyn_type **out) {
+ assert(type->type == DYN_TYPE_TYPED_POINTER);
+ int status = 0;
+
+ dyn_type *typedType = type->typedPointer.typedType;
+ if (typedType->type == DYN_TYPE_REF) {
+ typedType = typedType->ref.ref;
+ }
+
+ *out = typedType;
+ return status;
+}
+
+
+int dynType_text_allocAndInit(dyn_type *type, void *textLoc, const char *value) {
+ assert(type->type == DYN_TYPE_TEXT);
+ int status = 0;
+ const char *str = strdup(value);
+ char const **loc = textLoc;
+ if (str != NULL) {
+ *loc = str;
+ } else {
+ status = ERROR;
+ LOG_ERROR("Cannot allocate memory for string");
+ }
+ return status;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void dynType_print(dyn_type *type, FILE *stream) {
+ if (type != NULL) {
+ dynType_printTypes(type, stream);
+
+ fprintf(stream, "main type:\n");
+ dynType_printAny("root", type, 0, stream);
+ } else {
+ fprintf(stream, "invalid type\n");
+ }
+}
+
+static void dynType_printDepth(int depth, FILE *stream) {
+ int i;
+ for (i = 0; i < depth; i +=1 ) {
+ fprintf(stream, "\t");
+ }
+}
+
+static void dynType_printAny(char *name, dyn_type *type, int depth, FILE *stream) {
+ dyn_type *toPrint = type;
+ if (toPrint->type == DYN_TYPE_REF) {
+ toPrint = toPrint->ref.ref;
+ }
+ switch(toPrint->type) {
+ case DYN_TYPE_COMPLEX :
+ dynType_printComplex(name, toPrint, depth, stream);
+ break;
+ case DYN_TYPE_SIMPLE :
+ dynType_printSimple(name, toPrint, depth, stream);
+ break;
+ case DYN_TYPE_SEQUENCE :
+ dynType_printSequence(name, toPrint, depth, stream);
+ break;
+ case DYN_TYPE_TYPED_POINTER :
+ dynType_printTypedPointer(name, toPrint, depth, stream);
+ break;
+ default :
+ fprintf(stream, "TODO Unsupported type %i\n", toPrint->type);
+ break;
+ }
+}
+
+static void dynType_printComplex(char *name, dyn_type *type, int depth, FILE *stream) {
+ if (type->name == NULL) {
+ dynType_printDepth(depth, stream);
+ fprintf(stream, "%s: complex type (anon), size is %zu, alignment is %i, descriptor is '%c'. fields:\n", name, type->ffiType->size, type->ffiType->alignment, type->descriptor);
+
+ struct complex_type_entry *entry = NULL;
+ TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
+ dynType_printAny(entry->name, entry->type, depth + 1, stream);
+ }
+
+ dynType_printDepth(depth, stream);
+ printf("}\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);
+ }
+}
+
+static void dynType_printSequence(char *name, dyn_type *type, int depth, FILE *stream) {
+ dynType_printDepth(depth, stream);
+ fprintf(stream, "sequence, size is %zu, alignment is %i, descriptor is '%c'. fields:\n", type->ffiType->size, type->ffiType->alignment, type->descriptor);
+
+ dynType_printDepth(depth + 1, stream);
+ fprintf(stream, "cap: simple type, size is %zu, alignment is %i.\n", type->sequence.seqType.elements[0]->size, type->sequence.seqType.elements[0]->alignment);
+
+ dynType_printDepth(depth + 1, stream);
+ fprintf(stream, "len: simple type, size is %zu, alignment is %i.\n", type->sequence.seqType.elements[1]->size, type->sequence.seqType.elements[1]->alignment);
+
+ dynType_printDepth(depth + 1, stream);
+ fprintf(stream, "buf: array, size is %zu, alignment is %i. points to ->\n", type->sequence.seqType.elements[2]->size, type->sequence.seqType.elements[2]->alignment);
+ dynType_printAny("element", type->sequence.itemType, depth + 1, stream);
+}
+
+static void dynType_printSimple(char *name, dyn_type *type, int depth, FILE *stream) {
+ dynType_printDepth(depth, stream);
+ fprintf(stream, "%s: simple type, size is %zu, alignment is %i, descriptor is '%c'.\n", name, type->ffiType->size, type->ffiType->alignment, type->descriptor);
+}
+
+static void dynType_printTypedPointer(char *name, dyn_type *type, int depth, FILE *stream) {
+ dynType_printDepth(depth, stream);
+ fprintf(stream, "%s: typed pointer, size is %zu, alignment is %i, points to ->\n", name, type->ffiType->size, type->ffiType->alignment);
+ char *subName = NULL;
+ if (name != NULL) {
+ char buf[128];
+ snprintf(buf, 128, "*%s", name);
+ subName = buf;
+ }
+ dynType_printAny(subName, type->typedPointer.typedType, depth + 1, stream);
+}
+
+static void dynType_printTypes(dyn_type *type, FILE *stream) {
+
+ dyn_type *parent = type->parent;
+ struct type_entry *pentry = NULL;
+ while (parent != NULL) {
+ TAILQ_FOREACH(pentry, &parent->nestedTypesHead, entries) {
+ if (pentry->type == type) {
+ return;
+ }
+ }
+ parent = parent->parent;
+ }
+
+ struct type_entry *entry = NULL;
+ TAILQ_FOREACH(entry, &type->nestedTypesHead, entries) {
+ dyn_type *toPrint = entry->type;
+ if (toPrint->type == DYN_TYPE_REF) {
+ toPrint = toPrint->ref.ref;
+ }
+
+ switch(toPrint->type) {
+ case DYN_TYPE_COMPLEX :
+ dynType_printComplexType(toPrint, stream);
+ break;
+ case DYN_TYPE_SIMPLE :
+ dynType_printSimpleType(toPrint, stream);
+ break;
+ default :
+ printf("TODO Print Type\n");
+ break;
+ }
+ }
+
+
+ struct complex_type_entry *centry = NULL;
+ switch(type->type) {
+ case DYN_TYPE_COMPLEX :
+ TAILQ_FOREACH(centry, &type->complex.entriesHead, entries) {
+ dynType_printTypes(centry->type, stream);
+ }
+ break;
+ case DYN_TYPE_SEQUENCE :
+ dynType_printTypes(type->sequence.itemType, stream);
+ break;
+ case DYN_TYPE_TYPED_POINTER :
+ dynType_printTypes(type->typedPointer.typedType, stream);
+ break;
+ }
+}
+
+static void dynType_printComplexType(dyn_type *type, FILE *stream) {
+ fprintf(stream, "type '%s': complex type, size is %zu, alignment is %i, descriptor is '%c'. fields:\n", type->name, type->ffiType->size, type->ffiType->alignment, type->descriptor);
+
+ struct complex_type_entry *entry = NULL;
+ TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
+ dynType_printAny(entry->name, entry->type, 2, stream);
+ }
+
+ fprintf(stream, "}\n");
+}
+
+static void dynType_printSimpleType(dyn_type *type, FILE *stream) {
+ fprintf(stream, "\ttype '%s': simple type, size is %zu, alignment is %i, descriptor is '%c'\n", type->name, type->ffiType->size, type->ffiType->alignment, type->descriptor);
+}
+
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.h
new file mode 100644
index 0000000..9fdbff2
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.h
@@ -0,0 +1,140 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+
+#ifndef _DYN_TYPE_H_
+#define _DYN_TYPE_H_
+
+#include <stdio.h>
+#include <sys/queue.h>
+#include <stdbool.h>
+
+#include <ffi.h>
+#include <stdint.h>
+
+#include "dfi_log_util.h"
+
+#if defined(BSD) || defined(__APPLE__)
+#include "open_memstream.h"
+#include "fmemopen.h"
+#endif
+
+/* Description string
+ *
+ * Type = [TypeDef]* (SimpleType | ComplexType | SequenceType | TypedPointer | PointerReference ) [TypeDef]* [Annotation]*
+ * Name = alpha[(alpha|numeric)*]
+ * SPACE = ' '
+ *
+ * SimplesTypes (based on java bytecode method signatures)
+ * //Java based:
+ * B char
+ * C (not supported)
+ * D double
+ * F float
+ * I int32_t
+ * J int64_t
+ * S int16_t
+ * V void
+ * Z boolean
+ * //Extended
+ * b unsigned char
+ * i uint32_t
+ * j uint62_t
+ * s uint64_t
+ * P untyped pointer (void *)
+ * t char* string
+ * N native int
+ *
+ * ComplexTypes (Struct)
+ * {[Type]+ [(Name)(SPACE)]+}
+ *
+ * ReferenceByValue
+ * l(name);
+ *
+ * PointerReference -> note shortcut for *l(name);
+ * L(Name);
+ *
+ * TypeDef
+ * T(Name)=Type;
+ *
+ * SequenceType
+ * [(Type)
+ *
+ * TypedPointer
+ * *(Type)
+ *
+ * Annotation TODO
+ * <(Name)=(Value)>
+ *
+ * examples
+ * "{DDII a b c d}" -> struct { double a; double b; int c; int d; };
+ * "{DD{FF c1 c2} a b c}" -> struct { double a; double b; struct c { float c1; float c2; }; };
+ *
+ *
+ */
+
+#define DYN_TYPE_INVALID 0
+#define DYN_TYPE_SIMPLE 1
+#define DYN_TYPE_COMPLEX 2
+#define DYN_TYPE_SEQUENCE 3
+#define DYN_TYPE_TYPED_POINTER 4
+#define DYN_TYPE_TEXT 5
+#define DYN_TYPE_REF 6
+
+typedef struct _dyn_type dyn_type;
+
+//TODO rename
+TAILQ_HEAD(types_head, type_entry);
+struct type_entry {
+ dyn_type *type;
+ TAILQ_ENTRY(type_entry) entries;
+};
+
+TAILQ_HEAD(complex_type_entries_head, complex_type_entry);
+struct complex_type_entry {
+ dyn_type *type;
+ char *name;
+ TAILQ_ENTRY(complex_type_entry) entries;
+};
+
+//logging
+DFI_SETUP_LOG_HEADER(dynType);
+
+//generic
+int dynType_parse(FILE *descriptorStream, const char *name, struct types_head *refTypes, dyn_type **type);
+int dynType_parseWithStr(const char *descriptor, const char *name, struct types_head *refTypes, dyn_type **type);
+void dynType_destroy(dyn_type *type);
+
+int dynType_alloc(dyn_type *type, void **bufLoc);
+void dynType_free(dyn_type *type, void *loc);
+
+void dynType_print(dyn_type *type, FILE *stream);
+size_t dynType_size(dyn_type *type);
+int dynType_type(dyn_type *type);
+int dynType_descriptorType(dyn_type *type);
+ffi_type *dynType_ffiType(dyn_type *type);
+
+//complexType
+int dynType_complex_indexForName(dyn_type *type, const char *name);
+int dynType_complex_dynTypeAt(dyn_type *type, int index, dyn_type **subType);
+int dynType_complex_setValueAt(dyn_type *type, int index, void *inst, void *in);
+int dynType_complex_valLocAt(dyn_type *type, int index, void *inst, void **valLoc);
+int dynType_complex_entries(dyn_type *type, struct complex_type_entries_head **entries);
+
+//sequence
+int dynType_sequence_alloc(dyn_type *type, void *inst, uint32_t cap);
+int dynType_sequence_locForIndex(dyn_type *type, void *seqLoc, int index, void **valLoc);
+int dynType_sequence_increaseLengthAndReturnLastLoc(dyn_type *type, void *seqLoc, void **valLoc);
+dyn_type * dynType_sequence_itemType(dyn_type *type);
+uint32_t dynType_sequence_length(void *seqLoc);
+
+//typed pointer
+int dynType_typedPointer_getTypedType(dyn_type *type, dyn_type **typedType);
+
+//text
+int dynType_text_allocAndInit(dyn_type *type, void *textLoc, const char *value);
+
+//simple
+void dynType_simple_setValue(dyn_type *type, void *inst, void *in);
+
+#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/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
new file mode 100644
index 0000000..614e948
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c
@@ -0,0 +1,414 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include "json_serializer.h"
+#include "dyn_type.h"
+
+#include <jansson.h>
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+static int jsonSerializer_createObject(dyn_type *type, json_t *object, void **result);
+static int jsonSerializer_parseObject(dyn_type *type, json_t *object, void *inst);
+static int jsonSerializer_parseObjectMember(dyn_type *type, const char *name, json_t *val, void *inst);
+static int jsonSerializer_parseSequence(dyn_type *seq, json_t *array, void *seqLoc);
+static int jsonSerializer_parseAny(dyn_type *type, void *input, json_t *val);
+
+static int jsonSerializer_writeAny(dyn_type *type, void *input, json_t **val);
+
+static int jsonSerializer_writeComplex(dyn_type *type, void *input, json_t **val);
+
+static int jsonSerializer_writeSequence(dyn_type *type, void *input, json_t **out);
+
+static int OK = 0;
+static int ERROR = 1;
+
+DFI_SETUP_LOG(jsonSerializer);
+
+int jsonSerializer_deserialize(dyn_type *type, const char *input, void **result) {
+ assert(dynType_type(type) == DYN_TYPE_COMPLEX);
+ int status = 0;
+
+ json_error_t error;
+ json_t *root = json_loads(input, JSON_DECODE_ANY, &error);
+
+ if (root != NULL) {
+ if (json_is_object(root)) {
+ status = jsonSerializer_createObject(type, root, result);
+ } else {
+ status = ERROR;
+ LOG_ERROR("Error expected root element to be an object");
+ }
+ json_decref(root);
+ } else {
+ status = ERROR;
+ LOG_ERROR("Error parsing json input '%s'. Error is %s\n", input, error.text);
+ }
+
+ return status;
+}
+
+static int jsonSerializer_createObject(dyn_type *type, json_t *object, void **result) {
+ assert(object != NULL);
+ int status = OK;
+
+ void *inst = NULL;
+ status = dynType_alloc(type, &inst);
+
+ if (status == OK) {
+ assert(inst != NULL);
+ status = jsonSerializer_parseObject(type, object, inst);
+
+ if (status != OK) {
+ dynType_free(type, inst);
+ }
+ }
+
+ if (status == OK) {
+ *result = inst;
+ }
+
+ return status;
+}
+
+static int jsonSerializer_parseObject(dyn_type *type, json_t *object, void *inst) {
+ assert(object != NULL);
+ int status = 0;
+ json_t *value;
+ const char *key;
+
+ json_object_foreach(object, key, value) {
+ status = jsonSerializer_parseObjectMember(type, key, value, inst);
+ if (status != OK) {
+ break;
+ }
+ }
+
+ return status;
+}
+
+static int jsonSerializer_parseObjectMember(dyn_type *type, const char *name, json_t *val, void *inst) {
+ int status = OK;
+ int index = dynType_complex_indexForName(type, name);
+ void *valp = NULL;
+ dyn_type *valType = NULL;
+
+ status = dynType_complex_valLocAt(type, index, inst, &valp);
+
+ if (status == OK ) {
+ status = dynType_complex_dynTypeAt(type, index, &valType);
+ }
+
+ if (status == OK) {
+ status = jsonSerializer_parseAny(valType, valp, val);
+ }
+
+ return status;
+}
+
+static int jsonSerializer_parseAny(dyn_type *type, void *loc, json_t *val) {
+ int status = OK;
+
+ dyn_type *subType = NULL;
+ char c = dynType_descriptorType(type);
+
+ float *f; //F
+ double *d; //D
+ char *b; //B
+ int *n; //N
+ int16_t *s; //S
+ int32_t *i; //I
+ int64_t *l; //J
+ uint16_t *us; //s
+ uint32_t *ui; //i
+ uint64_t *ul; //j
+
+ switch (c) {
+ case 'F' :
+ f = loc;
+ *f = (float) json_real_value(val);
+ break;
+ case 'D' :
+ d = loc;
+ *d = json_real_value(val);
+ break;
+ case 'N' :
+ n = loc;
+ *n = (int) json_real_value(val);
+ break;
+ case 'B' :
+ b = loc;
+ *b = (char) json_integer_value(val);
+ break;
+ case 'S' :
+ s = loc;
+ *s = (int16_t) json_integer_value(val);
+ break;
+ case 'I' :
+ i = loc;
+ *i = (int32_t) json_integer_value(val);
+ break;
+ case 'J' :
+ l = loc;
+ *l = (int64_t) json_integer_value(val);
+ break;
+ case 's' :
+ us = loc;
+ *us = (uint16_t) json_integer_value(val);
+ break;
+ case 'i' :
+ ui = loc;
+ *ui = (uint32_t) json_integer_value(val);
+ break;
+ case 'j' :
+ ul = loc;
+ *ul = (uint64_t) json_integer_value(val);
+ break;
+ case 't' :
+ if (json_is_string(val)) {
+ dynType_text_allocAndInit(type, loc, json_string_value(val));
+ } else {
+ status = ERROR;
+ LOG_ERROR("Expected json string type got %i", json_typeof(val));
+ }
+ break;
+ case '[' :
+ if (json_is_array(val)) {
+ status = jsonSerializer_parseSequence(type, val, loc);
+ } else {
+ status = ERROR;
+ LOG_ERROR("Expected json array type got '%i'", json_typeof(val));
+ }
+ break;
+ case '{' :
+ if (status == OK) {
+ status = jsonSerializer_parseObject(type, val, loc);
+ }
+ break;
+ case '*' :
+ status = dynType_typedPointer_getTypedType(type, &subType);
+ if (status == OK) {
+ status = jsonSerializer_createObject(subType, val, (void **)loc);
+ }
+ break;
+ case 'P' :
+ status = ERROR;
+ LOG_WARNING("Untyped pointer are not supported for serialization");
+ break;
+ default :
+ status = ERROR;
+ LOG_ERROR("Error provided type '%c' not supported for JSON\n", dynType_descriptorType(type));
+ break;
+ }
+
+ return status;
+}
+
+static int jsonSerializer_parseSequence(dyn_type *seq, json_t *array, void *seqLoc) {
+ assert(dynType_type(seq) == DYN_TYPE_SEQUENCE);
+ int status = OK;
+
+ size_t size = json_array_size(array);
+ LOG_DEBUG("Allocating sequence with capacity %zu", size);
+ status = dynType_sequence_alloc(seq, seqLoc, (int) size);
+
+ if (status == OK) {
+ dyn_type *itemType = dynType_sequence_itemType(seq);
+ size_t index;
+ json_t *val;
+ json_array_foreach(array, index, val) {
+ void *valLoc = NULL;
+ status = dynType_sequence_increaseLengthAndReturnLastLoc(seq, seqLoc, &valLoc);
+ LOG_DEBUG("Got sequence loc %p", valLoc);
+
+ if (status == OK) {
+ status = jsonSerializer_parseAny(itemType, valLoc, val);
+ if (status != OK) {
+ break;
+ }
+ }
+ }
+ }
+
+ return status;
+}
+
+int jsonSerializer_serialize(dyn_type *type, void *input, char **output) {
+ int status = OK;
+
+ json_t *root = NULL;
+ status = jsonSerializer_writeAny(type, input, &root);
+
+ if (status == OK) {
+ *output = json_dumps(root, JSON_COMPACT);
+ json_decref(root);
+ }
+
+ return status;
+}
+
+static int jsonSerializer_writeAny(dyn_type *type, void *input, json_t **out) {
+ int status = OK;
+
+ int descriptor = dynType_descriptorType(type);
+ json_t *val = NULL;
+ dyn_type *subType = NULL;
+
+ float *f; //F
+ double *d; //D
+ char *b; //B
+ int *n; //N
+ int16_t *s; //S
+ int32_t *i; //I
+ int64_t *l; //J
+ uint16_t *us; //s
+ uint32_t *ui; //i
+ uint64_t *ul; //j
+
+ switch (descriptor) {
+ case 'B' :
+ b = input;
+ val = json_integer((json_int_t)*b);
+ break;
+ case 'S' :
+ s = input;
+ val = json_integer((json_int_t)*s);
+ break;
+ case 'I' :
+ i = input;
+ val = json_integer((json_int_t)*i);
+ break;
+ case 'J' :
+ l = input;
+ val = json_integer((json_int_t)*l);
+ break;
+ case 's' :
+ us = input;
+ val = json_integer((json_int_t)*us);
+ break;
+ case 'i' :
+ ui = input;
+ val = json_integer((json_int_t)*ui);
+ break;
+ case 'j' :
+ ul = input;
+ val = json_integer((json_int_t)*ul);
+ break;
+ case 'N' :
+ n = input;
+ val = json_integer((json_int_t)*n);
+ break;
+ case 'F' :
+ f = input;
+ val = json_real((double) *f);
+ break;
+ case 'D' :
+ d = input;
+ val = json_real(*d);
+ break;
+ case 't' :
+ val = json_string(*(const char **) input);
+ break;
+ case '*' :
+ status = dynType_typedPointer_getTypedType(type, &subType);
+ if (status == OK) {
+ status = jsonSerializer_writeAny(subType, *(void **)input, &val);
+ }
+ break;
+ case '{' :
+ status = jsonSerializer_writeComplex(type, input, &val);
+ break;
+ case '[' :
+ status = jsonSerializer_writeSequence(type, input, &val);
+ break;
+ case 'P' :
+ LOG_WARNING("Untyped pointer not supported for serialization. ignoring");
+ break;
+ default :
+ LOG_ERROR("Unsupported descriptor '%c'", descriptor);
+ status = ERROR;
+ break;
+ }
+
+ if (status == OK && val != NULL) {
+ *out = val;
+ }
+
+ return status;
+}
+
+static int jsonSerializer_writeSequence(dyn_type *type, void *input, json_t **out) {
+ assert(dynType_type(type) == DYN_TYPE_SEQUENCE);
+ int status = OK;
+
+ json_t *array = json_array();
+ dyn_type *itemType = dynType_sequence_itemType(type);
+ uint32_t len = dynType_sequence_length(input);
+
+ int i = 0;
+ void *itemLoc = NULL;
+ json_t *item = NULL;
+ for (i = 0; i < len; i += 1) {
+ item = NULL;
+ status = dynType_sequence_locForIndex(type, input, i, &itemLoc);
+ if (status == OK) {
+ status = jsonSerializer_writeAny(itemType, itemLoc, &item);
+ if (status == OK) {
+ json_array_append(array, item);
+ json_decref(item);
+ }
+ }
+
+ if (status != OK) {
+ break;
+ }
+ }
+
+ if (status == OK && array != NULL) {
+ *out = array;
+ }
+
+ return status;
+}
+
+static int jsonSerializer_writeComplex(dyn_type *type, void *input, json_t **out) {
+ assert(dynType_type(type) == DYN_TYPE_COMPLEX);
+ int status = OK;
+
+ json_t *val = json_object();
+ struct complex_type_entry *entry = NULL;
+ struct complex_type_entries_head *entries = NULL;
+ int index = -1;
+
+ status = dynType_complex_entries(type, &entries);
+ if (status == OK) {
+ TAILQ_FOREACH(entry, entries, entries) {
+ void *subLoc = NULL;
+ json_t *subVal = NULL;
+ dyn_type *subType = NULL;
+ index = dynType_complex_indexForName(type, entry->name);
+ status = dynType_complex_valLocAt(type, index, input, &subLoc);
+ if (status == OK ) {
+ status = dynType_complex_dynTypeAt(type, index, &subType);
+ }
+ if (status == OK) {
+ status = jsonSerializer_writeAny(subType, subLoc, &subVal);
+ }
+ if (status == OK) {
+ json_object_set(val, entry->name, subVal);
+ json_decref(subVal);
+ }
+
+ if (status != OK) {
+ break;
+ }
+ }
+ }
+
+ if (status == OK && val != NULL) {
+ *out = val;
+ }
+
+ return status;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/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
new file mode 100644
index 0000000..eb2e629
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h
@@ -0,0 +1,16 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef __JSON_SERIALIZER_H_
+#define __JSON_SERIALIZER_H_
+
+#include "dfi_log_util.h"
+#include "dyn_type.h"
+
+//logging
+DFI_SETUP_LOG_HEADER(jsonSerializer);
+
+int jsonSerializer_deserialize(dyn_type *type, const char *input, void **result);
+int jsonSerializer_serialize(dyn_type *type, void *input, char **output);
+
+#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/README.md
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/README.md b/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/README.md
new file mode 100644
index 0000000..476810e
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/README.md
@@ -0,0 +1,49 @@
+fmemopen for Mac OS and iOS
+===========================
+
+Originally ported from [ingenuitas python-tesseract](https://github.com/ingenuitas/python-tesseract/blob/master/fmemopen.c). Ported by Jeff Verkoeyen under the Apache 2.0 License.
+
+From the fmemopen man page:
+
+> FILE *fmemopen(void *buf, size_t size, const char *mode);
+>
+> The fmemopen() function opens a stream that permits the access specified by mode. The stream
+> allows I/O to be performed on the string or memory buffer pointed to by buf. This buffer must be
+> at least size bytes long.
+
+Alas, this method does not exist on BSD operating systems (specifically Mac OS X and iOS). It is
+possible to recreate this functionality using a BSD-specific method called `funopen`.
+
+From the funopen man page:
+
+> FILE * funopen(const void *cookie, int (*readfn)(void *, char *, int),
+> int (*writefn)(void *, const char *, int), fpos_t (*seekfn)(void *, fpos_t, int),
+> int (*closefn)(void *));
+>
+> The funopen() function associates a stream with up to four ``I/O functions''. Either readfn or
+> writefn must be specified; the others can be given as an appropriately-typed NULL pointer. These
+> I/O functions will be used to read, write, seek and close the new stream.
+
+fmemopen.c provides a simple implementation of fmemopen using funopen so that you can create FILE
+pointers to blocks of memory.
+
+Adding it to your Project
+=========================
+
+Drag fmemopen.h and fmemopen.c to your project and add them to your target. `#include "fmemopen.h"`
+wherever you need to use `fmemopen`.
+
+Examples
+========
+
+```obj-c
+#import "fmemopen.h"
+
+NSString* string = @"fmemopen in Objective-C";
+const char* cstr = [string UTF8String];
+FILE* file = fmemopen((void *)cstr, sizeof(char) * (string.length + 1), "r");
+
+// fread on file will now read the contents of the NSString
+
+fclose(file);
+```
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/fmemopen.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/fmemopen.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/fmemopen.c
new file mode 100644
index 0000000..926ce36
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/fmemopen.c
@@ -0,0 +1,78 @@
+/*
+ * fmem.c : fmemopen() on top of BSD's funopen()
+ * 20081017 AF
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef linux
+struct fmem {
+ size_t pos;
+ size_t size;
+ char *buffer;
+};
+typedef struct fmem fmem_t;
+
+static int readfn(void *handler, char *buf, int size)
+{
+ int count = 0;
+ fmem_t *mem = handler;
+ size_t available = mem->size - mem->pos;
+
+ if(size > available) size = available;
+ for(count=0; count < size; mem->pos++, count++)
+ buf[count] = mem->buffer[mem->pos];
+
+ return count;
+}
+
+static int writefn(void *handler, const char *buf, int size)
+{
+ int count = 0;
+ fmem_t *mem = handler;
+ size_t available = mem->size - mem->pos;
+
+ if(size > available) size = available;
+ for(count=0; count < size; mem->pos++, count++)
+ mem->buffer[mem->pos] = buf[count];
+
+ return count; // ? count : size;
+}
+
+static fpos_t seekfn(void *handler, fpos_t offset, int whence)
+{
+ size_t pos;
+ fmem_t *mem = handler;
+
+ switch(whence) {
+ case SEEK_SET: pos = offset; break;
+ case SEEK_CUR: pos = mem->pos + offset; break;
+ case SEEK_END: pos = mem->size + offset; break;
+ default: return -1;
+ }
+
+ if(pos < 0 || pos > mem->size) return -1;
+
+ mem->pos = pos;
+ return (fpos_t) pos;
+}
+
+static int closefn(void *handler)
+{
+ free(handler);
+ return 0;
+}
+
+/* simple, but portable version of fmemopen for OS X / BSD */
+FILE *fmemopen(void *buf, size_t size, const char *mode)
+{
+ fmem_t *mem = (fmem_t *) malloc(sizeof(fmem_t));
+
+ memset(mem, 0, sizeof(fmem_t));
+ mem->size = size, mem->buffer = buf;
+ return funopen(mem, readfn, writefn, seekfn, closefn);
+}
+#endif
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/fmemopen.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/fmemopen.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/fmemopen.h
new file mode 100644
index 0000000..3d06b20
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/fmemopen.h
@@ -0,0 +1,52 @@
+//
+// Copyright 2012 Jeff Verkoeyen
+// Originally ported from https://github.com/ingenuitas/python-tesseract/blob/master/fmemopen.c
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef FMEMOPEN_H_
+#define FMEMOPEN_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * A BSD port of the fmemopen Linux method using funopen.
+ *
+ * man docs for fmemopen:
+ * http://linux.die.net/man/3/fmemopen
+ *
+ * man docs for funopen:
+ * https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/funopen.3.html
+ *
+ * This method is ported from ingenuitas' python-tesseract project.
+ *
+ * You must call fclose on the returned file pointer or memory will be leaked.
+ *
+ * @param buf The data that will be used to back the FILE* methods. Must be at least
+ * @c size bytes.
+ * @param size The size of the @c buf data.
+ * @param mode The permitted stream operation modes.
+ * @returns A pointer that can be used in the fread/fwrite/fseek/fclose family of methods.
+ * If a failure occurred NULL will be returned.
+ */
+FILE *fmemopen(void *buf, size_t size, const char *mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef FMEMOPEN_H_
http://git-wip-us.apache.org/repos/asf/celix/blob/bf76d213/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/open_memstream.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/open_memstream.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/open_memstream.c
new file mode 100644
index 0000000..6bc4f01
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/memstream/open_memstream.c
@@ -0,0 +1,130 @@
+/* Use funopen(3) to provide open_memstream(3) like functionality. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+struct memstream {
+ char **cp;
+ size_t *lenp;
+ size_t offset;
+};
+
+static void
+memstream_grow(struct memstream *ms, size_t newsize)
+{
+ char *buf;
+
+ if (newsize > *ms->lenp) {
+ buf = realloc(*ms->cp, newsize + 1);
+ if (buf != NULL) {
+#ifdef DEBUG
+ fprintf(stderr, "MS: %p growing from %zd to %zd\n",
+ ms, *ms->lenp, newsize);
+#endif
+ memset(buf + *ms->lenp + 1, 0, newsize - *ms->lenp);
+ *ms->cp = buf;
+ *ms->lenp = newsize;
+ }
+ }
+}
+
+static int
+memstream_read(void *cookie, char *buf, int len)
+{
+ struct memstream *ms;
+ int tocopy;
+
+ ms = cookie;
+ memstream_grow(ms, ms->offset + len);
+ tocopy = *ms->lenp - ms->offset;
+ if (len < tocopy)
+ tocopy = len;
+ memcpy(buf, *ms->cp + ms->offset, tocopy);
+ ms->offset += tocopy;
+#ifdef DEBUG
+ fprintf(stderr, "MS: read(%p, %d) = %d\n", ms, len, tocopy);
+#endif
+ return (tocopy);
+}
+
+static int
+memstream_write(void *cookie, const char *buf, int len)
+{
+ struct memstream *ms;
+ int tocopy;
+
+ ms = cookie;
+ memstream_grow(ms, ms->offset + len);
+ tocopy = *ms->lenp - ms->offset;
+ if (len < tocopy)
+ tocopy = len;
+ memcpy(*ms->cp + ms->offset, buf, tocopy);
+ ms->offset += tocopy;
+#ifdef DEBUG
+ fprintf(stderr, "MS: write(%p, %d) = %d\n", ms, len, tocopy);
+#endif
+ return (tocopy);
+}
+
+static fpos_t
+memstream_seek(void *cookie, fpos_t pos, int whence)
+{
+ struct memstream *ms;
+#ifdef DEBUG
+ size_t old;
+#endif
+
+ ms = cookie;
+#ifdef DEBUG
+ old = ms->offset;
+#endif
+ switch (whence) {
+ case SEEK_SET:
+ ms->offset = pos;
+ break;
+ case SEEK_CUR:
+ ms->offset += pos;
+ break;
+ case SEEK_END:
+ ms->offset = *ms->lenp + pos;
+ break;
+ }
+#ifdef DEBUG
+ fprintf(stderr, "MS: seek(%p, %zd, %d) %zd -> %zd\n", ms, pos, whence,
+ old, ms->offset);
+#endif
+ return (ms->offset);
+}
+
+static int
+memstream_close(void *cookie)
+{
+
+ free(cookie);
+ return (0);
+}
+
+FILE *
+open_memstream(char **cp, size_t *lenp)
+{
+ struct memstream *ms;
+ int save_errno;
+ FILE *fp;
+
+ *cp = NULL;
+ *lenp = 0;
+ ms = malloc(sizeof(*ms));
+ ms->cp = cp;
+ ms->lenp = lenp;
+ ms->offset = 0;
+ fp = funopen(ms, memstream_read, memstream_write, memstream_seek,
+ memstream_close);
+ if (fp == NULL) {
+ save_errno = errno;
+ free(ms);
+ errno = save_errno;
+ }
+ return (fp);
+}
\ No newline at end of file