diff --git a/legacy/ecore/src/bin/ecore_dbus_receiver_test.c b/legacy/ecore/src/bin/ecore_dbus_receiver_test.c index 170d72759a..86de5bc29a 100644 --- a/legacy/ecore/src/bin/ecore_dbus_receiver_test.c +++ b/legacy/ecore/src/bin/ecore_dbus_receiver_test.c @@ -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 diff --git a/legacy/ecore/src/bin/ecore_dbus_test.c b/legacy/ecore/src/bin/ecore_dbus_test.c index 1972d54f66..a7b54c5463 100644 --- a/legacy/ecore/src/bin/ecore_dbus_test.c +++ b/legacy/ecore/src/bin/ecore_dbus_test.c @@ -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) diff --git a/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_marshal.c b/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_marshal.c index 269a6dc6b7..c2e4866235 100644 --- a/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_marshal.c +++ b/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_marshal.c @@ -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; + } diff --git a/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_message.c b/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_message.c index 97198b283c..81de4c6c8a 100644 --- a/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_message.c +++ b/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_message.c @@ -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 */ diff --git a/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_private.h b/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_private.h index 9957e5fbb5..5c34cbf7d6 100644 --- a/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_private.h +++ b/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_private.h @@ -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); diff --git a/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_unmarshal.c b/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_unmarshal.c index 4312a4ec36..b7985a9fa3 100644 --- a/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_unmarshal.c +++ b/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_unmarshal.c @@ -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) diff --git a/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_utils.c b/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_utils.c index eeae221e0f..c62be502b7 100644 --- a/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_utils.c +++ b/legacy/ecore/src/lib/ecore_dbus/ecore_dbus_utils.c @@ -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++; + } +}