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);
/* useful */
int appclient_call(AppClient * appclient, Variable ** ret,
char const * method, ...);
int appclient_call(AppClient * appclient,
void ** result, char const * method, ...);
int appclient_call_variable(AppClient * appclient,
Variable * result, char const * method, ...);
#endif /* !LIBAPP_APP_APPCLIENT_H */

View File

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

View File

@ -388,18 +388,21 @@ int appinterface_get_args_count(AppInterface * appinterface, size_t * count,
/* useful */
/* appinterface_callv */
int appinterface_callv(AppInterface * appinterface, void ** result,
char const * method, size_t argc, Variable ** argv)
char const * method, va_list args)
{
int ret;
AppInterfaceCall * call;
Variable * r = NULL;
Variable * r;
if((call = _appinterface_get_call(appinterface, method)) == NULL)
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;
if((ret = marshall_call(call->type.type, &r, call->func, argc, argv))
== 0 && r != NULL)
if((ret = marshall_call(call->type.type, r, call->func, call->args_cnt,
NULL)) == 0 && r != NULL)
{
if(result != NULL)
/* 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 */
/* appinterface_get_call */
static AppInterfaceCall * _appinterface_get_call(AppInterface * appinterface,

View File

@ -42,6 +42,8 @@ int appinterface_get_args_count(AppInterface * appinterface, size_t * count,
/* useful */
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);
#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))
/* XXX report errors */
return -1;
ret = appinterface_callv(appserver->interface, &result, method, 0,
NULL);
ret = appinterface_call_variablev(appserver->interface, result, method,
0, NULL);
if(result != NULL)
variable_delete(result);
return ret;

View File

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

View File

@ -23,7 +23,7 @@
/* Marshall */
/* functions */
int marshall_call(VariableType type, Variable ** result, void * func,
int marshall_call(VariableType type, Variable * result, void * func,
size_t argc, Variable ** argv);
#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)
{
int ret = 0;
Variable * v = NULL;
Variable * v;
int res;
#ifdef DEBUG
@ -100,6 +100,8 @@ static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
if(verbose != 0)
printf("Calling %s() with %lu arguments\n", call->name,
(unsigned long)call->args_cnt);
if((v = variable_new(VT_NULL, NULL)) == NULL)
return -1;
/* FIXME may segfault (check interface), use appclient_callv? */
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__,
call->name, res);
#endif
ret = appclient_call(ac, &v, call->name, NULL);
ret = appclient_call_variable(ac, v, call->name, NULL);
break;
case 1:
#ifdef DEBUG
@ -116,16 +118,16 @@ static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
call->name, call->args[0].integer);
#endif
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);
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);
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);
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);
else
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[1].integer);
#endif
ret = appclient_call(ac, &v, call->name,
ret = appclient_call_variable(ac, v, call->name,
call->args[0].integer,
call->args[1].integer);
break;
@ -154,7 +156,7 @@ static int _appclient_call(int verbose, AppClient * ac, AppClientCall * call)
call->args[1]._float,
call->args[2]._float);
#endif
ret = appclient_call(ac, &v, call->name,
ret = appclient_call_variable(ac, v, call->name,
call->args[0]._float,
call->args[1]._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[2].integer);
#endif
ret = appclient_call(ac, &v, call->name,
ret = appclient_call_variable(ac, v, call->name,
call->args[0].integer,
call->args[1].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[3]._float);
#endif
ret = appclient_call(ac, &v, call->name,
ret = appclient_call_variable(ac, v, call->name,
call->args[0]._float,
call->args[1]._float,
call->args[2]._float,