Ironing out the remote calling interface

This commit is contained in:
Pierre Pronchery 2014-04-26 00:22:46 +08:00
parent 7dec2e7e3b
commit 11b9e434f9
8 changed files with 96 additions and 50 deletions

View File

@ -35,7 +35,9 @@ AppClient * appclient_new_event(char const * app, char const * name,
void appclient_delete(AppClient * appclient); void appclient_delete(AppClient * appclient);
/* useful */ /* useful */
int appclient_call(AppClient * appclient, Variable ** ret, int appclient_call(AppClient * appclient,
char const * method, ...); void ** result, char const * method, ...);
int appclient_call_variable(AppClient * appclient,
Variable * result, char const * method, ...);
#endif /* !LIBAPP_APP_APPCLIENT_H */ #endif /* !LIBAPP_APP_APPCLIENT_H */

View File

@ -115,7 +115,21 @@ char const * appclient_get_app(AppClient * appclient)
/* useful */ /* useful */
/* appclient_call */ /* appclient_call */
int appclient_call(AppClient * appclient, int appclient_call(AppClient * appclient,
void ** result, char const * function, ...) void ** result, char const * method, ...)
{
int ret;
va_list ap;
va_start(ap, method);
ret = appinterface_callv(appclient->interface, result, method, ap);
va_end(ap);
return ret;
}
/* appclient_call_variable */
int appclient_call_variable(AppClient * appclient,
Variable * result, char const * method, ...)
{ {
int ret; int ret;
size_t cnt; size_t cnt;
@ -123,17 +137,16 @@ int appclient_call(AppClient * appclient,
va_list ap; va_list ap;
Variable ** argv; Variable ** argv;
if(appinterface_get_args_count(appclient->interface, &cnt, function) if(appinterface_get_args_count(appclient->interface, &cnt, method) != 0)
!= 0)
return -1; return -1;
if((argv = malloc(sizeof(*argv) * cnt)) == NULL) if((argv = malloc(sizeof(*argv) * cnt)) == NULL)
return error_set_code(-errno, "%s", strerror(errno)); return error_set_code(-errno, "%s", strerror(errno));
va_start(ap, function); va_start(ap, method);
for(i = 0; i < cnt; i++) for(i = 0; i < cnt; i++)
argv[i] = va_arg(ap, Variable *); argv[i] = va_arg(ap, Variable *);
va_end(ap); va_end(ap);
ret = appinterface_callv(appclient->interface, result, function, cnt, ret = appinterface_call_variablev(appclient->interface, result, method,
argv); cnt, argv);
free(argv); free(argv);
return ret; return ret;
} }

View File

@ -388,18 +388,21 @@ int appinterface_get_args_count(AppInterface * appinterface, size_t * count,
/* useful */ /* useful */
/* appinterface_callv */ /* appinterface_callv */
int appinterface_callv(AppInterface * appinterface, void ** result, int appinterface_callv(AppInterface * appinterface, void ** result,
char const * method, size_t argc, Variable ** argv) char const * method, va_list args)
{ {
int ret; int ret;
AppInterfaceCall * call; AppInterfaceCall * call;
Variable * r = NULL; Variable * r;
if((call = _appinterface_get_call(appinterface, method)) == NULL) if((call = _appinterface_get_call(appinterface, method)) == NULL)
return -1; return -1;
if(argc != call->args_cnt) /* FIXME implement argv */
if(call->type.type == VT_NULL)
r = NULL;
else if((r = variable_new(call->type.type, NULL)) == NULL)
return -1; return -1;
if((ret = marshall_call(call->type.type, &r, call->func, argc, argv)) if((ret = marshall_call(call->type.type, r, call->func, call->args_cnt,
== 0 && r != NULL) NULL)) == 0 && r != NULL)
{ {
if(result != NULL) if(result != NULL)
/* XXX return 0 anyway? */ /* XXX return 0 anyway? */
@ -410,6 +413,21 @@ int appinterface_callv(AppInterface * appinterface, void ** result,
} }
/* appinterface_call_variablev */
int appinterface_call_variablev(AppInterface * appinterface, Variable * result,
char const * method, size_t argc, Variable ** argv)
{
AppInterfaceCall * call;
if((call = _appinterface_get_call(appinterface, method)) == NULL)
return -1;
if(argc != call->args_cnt)
return -1;
/* FIXME implement argv */
return marshall_call(call->type.type, result, call->func, argc, NULL);
}
/* private */ /* private */
/* appinterface_get_call */ /* appinterface_get_call */
static AppInterfaceCall * _appinterface_get_call(AppInterface * appinterface, static AppInterfaceCall * _appinterface_get_call(AppInterface * appinterface,

View File

@ -42,6 +42,8 @@ int appinterface_get_args_count(AppInterface * appinterface, size_t * count,
/* useful */ /* useful */
int appinterface_callv(AppInterface * appinterface, void ** result, int appinterface_callv(AppInterface * appinterface, void ** result,
char const * method, va_list args);
int appinterface_call_variablev(AppInterface * appinterface, Variable * result,
char const * method, size_t argc, Variable ** argv); char const * method, size_t argc, Variable ** argv);
#endif /* !LIBAPP_APPINTERFACE_H */ #endif /* !LIBAPP_APPINTERFACE_H */

View File

@ -158,8 +158,8 @@ static int _helper_message_call(AppServer * appserver, AppTransport * transport,
if(!appinterface_can_call(appserver->interface, name, method)) if(!appinterface_can_call(appserver->interface, name, method))
/* XXX report errors */ /* XXX report errors */
return -1; return -1;
ret = appinterface_callv(appserver->interface, &result, method, 0, ret = appinterface_call_variablev(appserver->interface, result, method,
NULL); 0, NULL);
if(result != NULL) if(result != NULL)
variable_delete(result); variable_delete(result);
return ret; return ret;

View File

@ -15,16 +15,18 @@
#include <stddef.h> #include <string.h>
#include <errno.h>
#include <System/error.h>
#include "marshall.h" #include "marshall.h"
/* Marshall */ /* Marshall */
/* public */ /* public */
/* functions */ /* functions */
static int _call0(VariableType type, Variable ** result, void * func); static int _call0(VariableType type, Variable * result, void * func);
int marshall_call(VariableType type, Variable ** result, void * func, int marshall_call(VariableType type, Variable * result, void * func,
size_t argc, Variable ** argv) size_t argc, Variable ** argv)
{ {
if(argc == 0) if(argc == 0)
@ -33,9 +35,9 @@ int marshall_call(VariableType type, Variable ** result, void * func,
return -1; return -1;
} }
static int _call0(VariableType type, Variable ** result, void * func) static int _call0(VariableType type, Variable * result, void * func)
{ {
Variable * v; int ret = 0;
union union
{ {
void * call; void * call;
@ -54,7 +56,7 @@ static int _call0(VariableType type, Variable ** result, void * func)
} f; } f;
union union
{ {
uint8_t bool; uint8_t b;
int8_t i8; int8_t i8;
uint8_t u8; uint8_t u8;
int16_t i16; int16_t i16;
@ -69,61 +71,68 @@ static int _call0(VariableType type, Variable ** result, void * func)
/* FIXME implement through the generic marshaller instead */ /* FIXME implement through the generic marshaller instead */
f.call = func; f.call = func;
if((v = variable_new(type, NULL)) == NULL)
return -1;
switch(type) switch(type)
{ {
case VT_NULL: case VT_NULL:
f.call_null(); f.call_null();
break; break;
case VT_BOOL: case VT_BOOL:
res.bool = (f.call_bool() != 0) ? 1 : 0; res.b = (f.call_bool() != 0) ? 1 : 0;
variable_set_from(v, type, &res.bool); if(result != NULL)
ret = variable_set_from(result, type, &res.b);
break; break;
case VT_INT8: case VT_INT8:
res.i8 = f.call_i8(); res.i8 = f.call_i8();
variable_set_from(v, type, &res.i8); if(result != NULL)
ret = variable_set_from(result, type, &res.i8);
break; break;
case VT_UINT8: case VT_UINT8:
res.u8 = f.call_u8(); res.u8 = f.call_u8();
variable_set_from(v, type, &res.u8); if(result != NULL)
ret = variable_set_from(result, type, &res.u8);
break; break;
case VT_INT16: case VT_INT16:
res.i16 = f.call_i16(); res.i16 = f.call_i16();
variable_set_from(v, type, &res.i16); if(result != NULL)
ret = variable_set_from(result, type, &res.i16);
break; break;
case VT_UINT16: case VT_UINT16:
res.u16 = f.call_u16(); res.u16 = f.call_u16();
variable_set_from(v, type, &res.u16); if(result != NULL)
ret = variable_set_from(result, type, &res.u16);
break; break;
case VT_INT32: case VT_INT32:
res.i32 = f.call_i32(); res.i32 = f.call_i32();
variable_set_from(v, type, &res.i32); if(result != NULL)
ret = variable_set_from(result, type, &res.i32);
break; break;
case VT_UINT32: case VT_UINT32:
res.u32 = f.call_u32(); res.u32 = f.call_u32();
variable_set_from(v, type, &res.u32); if(result != NULL)
ret = variable_set_from(result, type, &res.u32);
break; break;
case VT_INT64: case VT_INT64:
res.i64 = f.call_i64(); res.i64 = f.call_i64();
variable_set_from(v, type, &res.i64); if(result != NULL)
ret = variable_set_from(result, type, &res.i64);
break; break;
case VT_UINT64: case VT_UINT64:
res.u64 = f.call_u64(); res.u64 = f.call_u64();
variable_set_from(v, type, &res.u64); if(result != NULL)
ret = variable_set_from(result, type, &res.u64);
break; break;
case VT_FLOAT: case VT_FLOAT:
res.f = f.call_f(); res.f = f.call_f();
variable_set_from(v, type, &res.f); if(result != NULL)
ret = variable_set_from(result, type, &res.f);
break; break;
case VT_DOUBLE: case VT_DOUBLE:
res.d = f.call_d(); res.d = f.call_d();
variable_set_from(v, type, &res.d); if(result != NULL)
ret = variable_set_from(result, type, &res.d);
break; break;
default: default:
variable_delete(v); return -error_set_code(1, "%s", strerror(ENOSYS));
return -1;
} }
*result = v; return ret;
return 0;
} }

View File

@ -23,7 +23,7 @@
/* Marshall */ /* Marshall */
/* functions */ /* functions */
int marshall_call(VariableType type, Variable ** result, void * func, int marshall_call(VariableType type, Variable * result, void * func,
size_t argc, Variable ** argv); size_t argc, Variable ** argv);
#endif /* !LIBAPP_MARSHALL_H */ #endif /* !LIBAPP_MARSHALL_H */

View File

@ -91,7 +91,7 @@ static int _appclient(int verbose, char const * app, char const * name,
static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call) static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
{ {
int ret = 0; int ret = 0;
Variable * v = NULL; Variable * v;
int res; int res;
#ifdef DEBUG #ifdef DEBUG
@ -100,6 +100,8 @@ static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
if(verbose != 0) if(verbose != 0)
printf("Calling %s() with %lu arguments\n", call->name, printf("Calling %s() with %lu arguments\n", call->name,
(unsigned long)call->args_cnt); (unsigned long)call->args_cnt);
if((v = variable_new(VT_NULL, NULL)) == NULL)
return -1;
/* FIXME may segfault (check interface), use appclient_callv? */ /* FIXME may segfault (check interface), use appclient_callv? */
switch(call->args_cnt) switch(call->args_cnt)
{ {
@ -108,7 +110,7 @@ static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
fprintf(stderr, "DEBUG: %s() %s() res=%d\n", __func__, fprintf(stderr, "DEBUG: %s() %s() res=%d\n", __func__,
call->name, res); call->name, res);
#endif #endif
ret = appclient_call(ac, &v, call->name, NULL); ret = appclient_call_variable(ac, v, call->name, NULL);
break; break;
case 1: case 1:
#ifdef DEBUG #ifdef DEBUG
@ -116,16 +118,16 @@ static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
call->name, call->args[0].integer); call->name, call->args[0].integer);
#endif #endif
if(call->args[0].type == ACCAT_DOUBLE) if(call->args[0].type == ACCAT_DOUBLE)
ret = appclient_call(ac, &v, call->name, ret = appclient_call_variable(ac, v, call->name,
call->args[0]._double); call->args[0]._double);
else if(call->args[0].type == ACCAT_FLOAT) else if(call->args[0].type == ACCAT_FLOAT)
ret = appclient_call(ac, &v, call->name, ret = appclient_call_variable(ac, v, call->name,
call->args[0]._float); call->args[0]._float);
else if(call->args[0].type == ACCAT_INTEGER) else if(call->args[0].type == ACCAT_INTEGER)
ret = appclient_call(ac, &v, call->name, ret = appclient_call_variable(ac, v, call->name,
call->args[0].integer); call->args[0].integer);
else if(call->args[0].type == ACCAT_STRING) else if(call->args[0].type == ACCAT_STRING)
ret = appclient_call(ac, &v, call->name, ret = appclient_call_variable(ac, v, call->name,
call->args[0].string); call->args[0].string);
else else
ret = error_set_code(1, "%s", ret = error_set_code(1, "%s",
@ -139,7 +141,7 @@ static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
call->args[0].integer, call->args[0].integer,
call->args[1].integer); call->args[1].integer);
#endif #endif
ret = appclient_call(ac, &v, call->name, ret = appclient_call_variable(ac, v, call->name,
call->args[0].integer, call->args[0].integer,
call->args[1].integer); call->args[1].integer);
break; break;
@ -154,7 +156,7 @@ static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
call->args[1]._float, call->args[1]._float,
call->args[2]._float); call->args[2]._float);
#endif #endif
ret = appclient_call(ac, &v, call->name, ret = appclient_call_variable(ac, v, call->name,
call->args[0]._float, call->args[0]._float,
call->args[1]._float, call->args[1]._float,
call->args[2]._float); call->args[2]._float);
@ -168,7 +170,7 @@ static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
call->args[1].integer, call->args[1].integer,
call->args[2].integer); call->args[2].integer);
#endif #endif
ret = appclient_call(ac, &v, call->name, ret = appclient_call_variable(ac, v, call->name,
call->args[0].integer, call->args[0].integer,
call->args[1].integer, call->args[1].integer,
call->args[2].integer); call->args[2].integer);
@ -182,7 +184,7 @@ static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
call->args[2]._float, call->args[2]._float,
call->args[3]._float); call->args[3]._float);
#endif #endif
ret = appclient_call(ac, &v, call->name, ret = appclient_call_variable(ac, v, call->name,
call->args[0]._float, call->args[0]._float,
call->args[1]._float, call->args[1]._float,
call->args[2]._float, call->args[2]._float,