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:
rephorm 2006-09-29 02:04:06 +00:00 committed by rephorm
parent b1d7ba8071
commit f32284778e
7 changed files with 172 additions and 28 deletions

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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)

View File

@ -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++;
}
}