forked from enlightenment/efl
support arrays (via a more general marshal function)
add utility function to get length of a "complete type" in the signature this assumes the signature is valid. we should probably add a validator (and enfore the recursion limits in the spec) SVN revision: 26198
This commit is contained in:
parent
b1d7ba8071
commit
f32284778e
|
@ -101,21 +101,35 @@ _test_object_test(Ecore_DBus_Event_Method_Call *event)
|
|||
{
|
||||
Ecore_DBus_Message *msg;
|
||||
unsigned int *i;
|
||||
char *s;
|
||||
char *s1, *s2;
|
||||
Ecore_List *l;
|
||||
int first;
|
||||
|
||||
printf("received call to test!\n");
|
||||
msg = event->message;
|
||||
|
||||
i = (unsigned int *)ecore_dbus_message_body_field_get(msg, 0);
|
||||
s = (char *)ecore_dbus_message_body_field_get(msg, 1);
|
||||
s1 = (char *)ecore_dbus_message_body_field_get(msg, 1);
|
||||
l = (Ecore_List *)ecore_dbus_message_body_field_get(msg, 2);
|
||||
s2 = (char *)ecore_dbus_message_body_field_get(msg, 3);
|
||||
|
||||
if (!i || !s)
|
||||
if (!i || !s1 || !l || !s2)
|
||||
{
|
||||
/* XXX reply with error */
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" params: i = %d, s = \"%s\"\n", i ? *i : 0, s);
|
||||
printf(" params: i = %d, s1 = \"%s\", l = (", i ? *i : 0, s1);
|
||||
ecore_list_goto_first(l);
|
||||
first = 1;
|
||||
while(i = ecore_list_next(l))
|
||||
{
|
||||
if (!first) printf(", ");
|
||||
else first = 0;
|
||||
|
||||
printf("%d", i ? *i : 0);
|
||||
}
|
||||
printf("), s2: %s\n", s2);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -13,6 +13,7 @@ static void ecore_dbus_method_test_cb(void *data, Ecore_DBus_Method_Return *repl
|
|||
static void ecore_dbus_method_error_cb(void *data, const char *error);
|
||||
|
||||
static const char *event_type_get(Ecore_DBus_Message_Type type);
|
||||
static void _test_type_length();
|
||||
|
||||
static Ecore_DBus_Server *svr = NULL;
|
||||
|
||||
|
@ -21,6 +22,7 @@ main(int argc, char **argv)
|
|||
{
|
||||
ecore_dbus_init();
|
||||
|
||||
_test_type_length();
|
||||
svr = ecore_dbus_server_session_connect(NULL);
|
||||
if (!svr)
|
||||
{
|
||||
|
@ -53,12 +55,24 @@ static int
|
|||
ecore_dbus_event_server_add(void *udata, int ev_type, void *ev)
|
||||
{
|
||||
Ecore_DBus_Event_Server_Add *event;
|
||||
Ecore_List *ids;
|
||||
int i;
|
||||
|
||||
event = ev;
|
||||
printf("ecore_dbus_event_server_add\n");
|
||||
ecore_dbus_method_list_names(event->server,
|
||||
ecore_dbus_method_list_names_cb,
|
||||
ecore_dbus_method_error_cb, NULL);
|
||||
|
||||
ids = ecore_list_new();
|
||||
ecore_list_set_free_cb(ids, free);
|
||||
for(i = 0; i < 5; i++)
|
||||
{
|
||||
unsigned int *id;
|
||||
id = malloc(sizeof(int));
|
||||
*id = i * 2;
|
||||
ecore_list_append(ids, id);
|
||||
}
|
||||
ecore_dbus_message_new_method_call(event->server,
|
||||
"/org/enlightenment/test" /*path*/,
|
||||
"org.enlightenment.Test" /*interface*/,
|
||||
|
@ -66,8 +80,10 @@ ecore_dbus_event_server_add(void *udata, int ev_type, void *ev)
|
|||
"org.enlightenment.Test" /*destination*/,
|
||||
ecore_dbus_method_test_cb,
|
||||
ecore_dbus_method_error_cb, NULL,
|
||||
"us" /*fmt*/,
|
||||
5, "hello");
|
||||
"usaus" /*fmt*/,
|
||||
5, "hello", ids, "goodbye");
|
||||
|
||||
ecore_list_destroy(ids);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -141,6 +157,29 @@ event_type_get(Ecore_DBus_Message_Type type)
|
|||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
//int _ecore_dbus_complete_type_length(const char *);
|
||||
static void
|
||||
_test_type_length()
|
||||
{
|
||||
#define _NUM_TYPES 4
|
||||
struct { char *type; int len; } types[_NUM_TYPES] = {
|
||||
{ "us", 1 },
|
||||
{ "ads", 2 },
|
||||
{ "a(a(ai))su", 8 },
|
||||
{ "a{ss}u", 5 }
|
||||
};
|
||||
|
||||
int i;
|
||||
|
||||
printf("Test type length\n---------------\n");
|
||||
for (i = 0; i < _NUM_TYPES; i++)
|
||||
{
|
||||
int len = _ecore_dbus_complete_type_length_get(types[i].type);
|
||||
printf("\"%s\" => %d (expected %d) %s\n", types[i].type, len, types[i].len, len == types[i].len ? "PASS" : "FAIL");
|
||||
}
|
||||
printf("---------------\n");
|
||||
}
|
||||
|
||||
#else
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
|
|
|
@ -93,7 +93,7 @@ _ecore_dbus_message_marshal_array_begin(Ecore_DBus_Message *msg,
|
|||
_ecore_dbus_message_padding(msg, 4);
|
||||
|
||||
arr = _ecore_dbus_message_field_new(msg, ECORE_DBUS_DATA_TYPE_ARRAY);
|
||||
/* for the array length value */
|
||||
/* leave room for the array length value, gets filled in on array_end() */
|
||||
_ecore_dbus_message_append_uint32(msg, 0);
|
||||
arr->contained_type = contained_type;
|
||||
ecore_list_prepend(msg->recurse, arr);
|
||||
|
@ -113,6 +113,22 @@ _ecore_dbus_message_marshal_array_end(Ecore_DBus_Message *msg, Ecore_DBus_Messag
|
|||
*(unsigned int *)ECORE_DBUS_MESSAGE_FIELD(arr)->buffer = arr->end - arr->start;
|
||||
}
|
||||
|
||||
Ecore_DBus_Message_Field_Array *
|
||||
_ecore_dbus_message_marshal_array(Ecore_DBus_Message *msg, char *contained_type, Ecore_List *data)
|
||||
{
|
||||
Ecore_DBus_Message_Field_Array *arr;
|
||||
void *el;
|
||||
|
||||
printf("[ecore_dbus] marshal array %c\n", *contained_type);
|
||||
arr = _ecore_dbus_message_marshal_array_begin(msg, *contained_type);
|
||||
ecore_list_goto_first(data);
|
||||
while ((el = ecore_list_next(data)))
|
||||
_ecore_dbus_message_marshal(msg, contained_type, el);
|
||||
_ecore_dbus_message_marshal_array_end(msg, arr);
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
Ecore_DBus_Message_Field_Struct *
|
||||
_ecore_dbus_message_marshal_struct_begin(Ecore_DBus_Message *msg)
|
||||
{
|
||||
|
@ -146,22 +162,31 @@ _ecore_dbus_message_marshal_variant(Ecore_DBus_Message *msg, Ecore_DBus_Data_Typ
|
|||
_ecore_dbus_message_append_byte(msg, type);
|
||||
_ecore_dbus_message_append_byte(msg, '\0');
|
||||
|
||||
switch (type)
|
||||
f->value = _ecore_dbus_message_marshal(msg, &type, data);
|
||||
ecore_list_remove_first(msg->recurse);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Ecore_DBus_Message_Field *
|
||||
_ecore_dbus_message_marshal(Ecore_DBus_Message *msg, char *type, void *data)
|
||||
{
|
||||
|
||||
switch (*type)
|
||||
{
|
||||
case ECORE_DBUS_DATA_TYPE_UINT32:
|
||||
f->value = _ecore_dbus_message_marshal_uint32(msg, *(unsigned int *)data);
|
||||
break;
|
||||
return (Ecore_DBus_Message_Field *)_ecore_dbus_message_marshal_uint32(msg, *(unsigned int *)data);
|
||||
case ECORE_DBUS_DATA_TYPE_STRING:
|
||||
f->value = _ecore_dbus_message_marshal_string(msg, (char *)data);
|
||||
break;
|
||||
return (Ecore_DBus_Message_Field *)_ecore_dbus_message_marshal_string(msg, (char *)data);
|
||||
case ECORE_DBUS_DATA_TYPE_OBJECT_PATH:
|
||||
f->value = _ecore_dbus_message_marshal_object_path(msg, (char *)data);
|
||||
break;
|
||||
return (Ecore_DBus_Message_Field *)_ecore_dbus_message_marshal_object_path(msg, (char *)data);
|
||||
case ECORE_DBUS_DATA_TYPE_SIGNATURE:
|
||||
f->value = _ecore_dbus_message_marshal_signature(msg, (char *)data);
|
||||
break;
|
||||
case ECORE_DBUS_DATA_TYPE_INVALID:
|
||||
return (Ecore_DBus_Message_Field *)_ecore_dbus_message_marshal_signature(msg, (char *)data);
|
||||
case ECORE_DBUS_DATA_TYPE_BYTE:
|
||||
return (Ecore_DBus_Message_Field *)_ecore_dbus_message_marshal_byte(msg, *(char *)data);
|
||||
case ECORE_DBUS_DATA_TYPE_ARRAY:
|
||||
return (Ecore_DBus_Message_Field *)_ecore_dbus_message_marshal_array(msg, type + 1, (Ecore_List *)data); // we need to let the caller know how many fields were marshalled (e.g. how far to skip ahead in the type list)
|
||||
case ECORE_DBUS_DATA_TYPE_BOOLEAN:
|
||||
case ECORE_DBUS_DATA_TYPE_INT16:
|
||||
case ECORE_DBUS_DATA_TYPE_UINT16:
|
||||
|
@ -169,7 +194,6 @@ _ecore_dbus_message_marshal_variant(Ecore_DBus_Message *msg, Ecore_DBus_Data_Typ
|
|||
case ECORE_DBUS_DATA_TYPE_INT64:
|
||||
case ECORE_DBUS_DATA_TYPE_UINT64:
|
||||
case ECORE_DBUS_DATA_TYPE_DOUBLE:
|
||||
case ECORE_DBUS_DATA_TYPE_ARRAY:
|
||||
case ECORE_DBUS_DATA_TYPE_VARIANT:
|
||||
case ECORE_DBUS_DATA_TYPE_STRUCT:
|
||||
case ECORE_DBUS_DATA_TYPE_STRUCT_BEGIN:
|
||||
|
@ -177,12 +201,12 @@ _ecore_dbus_message_marshal_variant(Ecore_DBus_Message *msg, Ecore_DBus_Data_Typ
|
|||
case ECORE_DBUS_DATA_TYPE_DICT_ENTRY:
|
||||
case ECORE_DBUS_DATA_TYPE_DICT_ENTRY_BEGIN:
|
||||
case ECORE_DBUS_DATA_TYPE_DICT_ENTRY_END:
|
||||
#if 0
|
||||
case ECORE_DBUS_DATA_TYPE_INVALID:
|
||||
printf("[ecore_dbus] unhandled data type %c\n", *type);
|
||||
return NULL;
|
||||
default:
|
||||
#endif
|
||||
printf("[ecore_dbus] unknown/unhandled data type %c\n", type);
|
||||
break;
|
||||
printf("[ecore_dbus] unknown data type %c\n", *type);
|
||||
return NULL;
|
||||
}
|
||||
ecore_list_remove_first(msg->recurse);
|
||||
return f;
|
||||
|
||||
}
|
||||
|
|
|
@ -205,6 +205,9 @@ _ecore_dbus_message_body(Ecore_DBus_Message *msg, char *signature, va_list args)
|
|||
case ECORE_DBUS_DATA_TYPE_SIGNATURE:
|
||||
_ecore_dbus_message_marshal_signature(msg, (char *)va_arg(args, char *));
|
||||
break;
|
||||
case ECORE_DBUS_DATA_TYPE_ARRAY:
|
||||
_ecore_dbus_message_marshal_array(msg, signature + 1, (Ecore_List *)va_arg(args, Ecore_List *));
|
||||
break;
|
||||
case ECORE_DBUS_DATA_TYPE_INVALID:
|
||||
case ECORE_DBUS_DATA_TYPE_BOOLEAN:
|
||||
case ECORE_DBUS_DATA_TYPE_INT16:
|
||||
|
@ -213,7 +216,6 @@ _ecore_dbus_message_body(Ecore_DBus_Message *msg, char *signature, va_list args)
|
|||
case ECORE_DBUS_DATA_TYPE_INT64:
|
||||
case ECORE_DBUS_DATA_TYPE_UINT64:
|
||||
case ECORE_DBUS_DATA_TYPE_DOUBLE:
|
||||
case ECORE_DBUS_DATA_TYPE_ARRAY:
|
||||
case ECORE_DBUS_DATA_TYPE_VARIANT:
|
||||
case ECORE_DBUS_DATA_TYPE_STRUCT:
|
||||
case ECORE_DBUS_DATA_TYPE_STRUCT_BEGIN:
|
||||
|
@ -227,7 +229,7 @@ _ecore_dbus_message_body(Ecore_DBus_Message *msg, char *signature, va_list args)
|
|||
printf("[ecore_dbus] unknown/unhandled data type %c\n", *signature);
|
||||
break;
|
||||
}
|
||||
signature++;
|
||||
signature += _ecore_dbus_complete_type_length_get(signature);
|
||||
}
|
||||
}
|
||||
/* set body length */
|
||||
|
|
|
@ -237,8 +237,11 @@ unsigned char _ecore_dbus_message_read_byte(Ecore_DBus_Message *msg);
|
|||
unsigned int _ecore_dbus_message_read_uint32(Ecore_DBus_Message *msg);
|
||||
int _ecore_dbus_alignment_get(Ecore_DBus_Data_Type type);
|
||||
void *_ecore_dbus_message_field_value_get(Ecore_DBus_Message_Field *f);
|
||||
int _ecore_dbus_complete_type_length_get(const char *signature);
|
||||
|
||||
/* ecore_dbus_marshal.c */
|
||||
Ecore_DBus_Message_Field *
|
||||
_ecore_dbus_message_marshal(Ecore_DBus_Message *msg, char *type, void *data);
|
||||
Ecore_DBus_Message_Field_Byte *_ecore_dbus_message_marshal_byte(Ecore_DBus_Message *msg, unsigned char c);
|
||||
#if 0
|
||||
Ecore_DBus_Message_Field *_ecore_dbus_message_marshal_boolean(unsigned char **buf, unsigned int *old_length, uint32_t i);
|
||||
|
@ -257,6 +260,7 @@ Ecore_DBus_Message_Field_Object_Path *_ecore_dbus_message_marshal_object_path(Ec
|
|||
Ecore_DBus_Message_Field_Signature *_ecore_dbus_message_marshal_signature(Ecore_DBus_Message *msg, char *str);
|
||||
Ecore_DBus_Message_Field_Array *_ecore_dbus_message_marshal_array_begin(Ecore_DBus_Message *msg, Ecore_DBus_Data_Type contained_type);
|
||||
void _ecore_dbus_message_marshal_array_end(Ecore_DBus_Message *msg, Ecore_DBus_Message_Field_Array *arr);
|
||||
Ecore_DBus_Message_Field_Array *_ecore_dbus_message_marshal_array(Ecore_DBus_Message *msg, char *contained_type, Ecore_List *data);
|
||||
Ecore_DBus_Message_Field_Struct *_ecore_dbus_message_marshal_struct_begin(Ecore_DBus_Message *msg);
|
||||
void _ecore_dbus_message_marshal_struct_end(Ecore_DBus_Message *msg, Ecore_DBus_Message_Field_Struct *s);
|
||||
Ecore_DBus_Message_Field_Variant *_ecore_dbus_message_marshal_variant(Ecore_DBus_Message *msg, Ecore_DBus_Data_Type type, void *data);
|
||||
|
|
|
@ -387,7 +387,7 @@ _ecore_dbus_message_unmarshal(Ecore_DBus_Server *svr, unsigned char *message, in
|
|||
/* Parse header fields */
|
||||
if (!(arr = _ecore_dbus_message_unmarshal_array_begin(msg, ECORE_DBUS_DATA_TYPE_STRUCT, &size)))
|
||||
{
|
||||
printf("Could not parse custom header.\n");
|
||||
printf("Could not parse header fields.\n");
|
||||
goto error;
|
||||
}
|
||||
while (msg->length < arr->end)
|
||||
|
|
|
@ -140,7 +140,7 @@ _ecore_dbus_alignment_get(Ecore_DBus_Data_Type type)
|
|||
case ECORE_DBUS_DATA_TYPE_DICT_ENTRY:
|
||||
return 8;
|
||||
default:
|
||||
printf("Ecore_DBus: Alignment requested for invalid data type!\n");
|
||||
printf("[ecore_dbus] Alignment requested for invalid data type (%c)", type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -203,3 +203,64 @@ _ecore_dbus_message_field_value_get(Ecore_DBus_Message_Field *f)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the length of the complete type starting at signature.
|
||||
* signature should be a pointer within a signature string.
|
||||
*
|
||||
* e.g
|
||||
* uia -> 1 "u"
|
||||
* aus -> 2 "au"
|
||||
* (aus)s -> 5 "(aus)"
|
||||
*/
|
||||
int
|
||||
_ecore_dbus_complete_type_length_get(const char *signature)
|
||||
{
|
||||
int len = 0;
|
||||
int depth = 0;
|
||||
|
||||
while (*signature)
|
||||
{
|
||||
len++;
|
||||
switch (*signature)
|
||||
{
|
||||
case ECORE_DBUS_DATA_TYPE_BYTE:
|
||||
case ECORE_DBUS_DATA_TYPE_BOOLEAN:
|
||||
case ECORE_DBUS_DATA_TYPE_INT16:
|
||||
case ECORE_DBUS_DATA_TYPE_UINT16:
|
||||
case ECORE_DBUS_DATA_TYPE_INT32:
|
||||
case ECORE_DBUS_DATA_TYPE_UINT32:
|
||||
case ECORE_DBUS_DATA_TYPE_INT64:
|
||||
case ECORE_DBUS_DATA_TYPE_UINT64:
|
||||
case ECORE_DBUS_DATA_TYPE_DOUBLE:
|
||||
case ECORE_DBUS_DATA_TYPE_STRING:
|
||||
case ECORE_DBUS_DATA_TYPE_OBJECT_PATH:
|
||||
case ECORE_DBUS_DATA_TYPE_SIGNATURE:
|
||||
case ECORE_DBUS_DATA_TYPE_VARIANT:
|
||||
/* these types are complete on their own */
|
||||
if (!depth) return len;
|
||||
break;
|
||||
case ECORE_DBUS_DATA_TYPE_ARRAY:
|
||||
/* this takes one complete type after it. */
|
||||
break;
|
||||
case ECORE_DBUS_DATA_TYPE_STRUCT_BEGIN:
|
||||
case ECORE_DBUS_DATA_TYPE_DICT_ENTRY_BEGIN:
|
||||
depth++;
|
||||
break;
|
||||
case ECORE_DBUS_DATA_TYPE_STRUCT_END:
|
||||
case ECORE_DBUS_DATA_TYPE_DICT_ENTRY_END:
|
||||
depth--;
|
||||
if (!depth) return len;
|
||||
break;
|
||||
case ECORE_DBUS_DATA_TYPE_STRUCT:
|
||||
case ECORE_DBUS_DATA_TYPE_DICT_ENTRY:
|
||||
case ECORE_DBUS_DATA_TYPE_INVALID:
|
||||
printf("[ecore_dbus] type '%c' not allowed in signature string", *signature);
|
||||
break;
|
||||
default:
|
||||
printf("[ecore_dbus] unknown type '%c' not allowed in signature string", *signature);
|
||||
break;
|
||||
}
|
||||
signature++;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue