X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbind%2Fdbind-any.c;h=30d8adddf106d9e14fa024f904240e08e6329feb;hb=a80c880b92e4947c011c46ebdac122023ed0ea6b;hp=1f784e5e2dc6e55f17a72a9b19863740f5fed6c3;hpb=28d2e961940e5b242e008f23bf9b2d68ab555cfa;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/dbind/dbind-any.c b/dbind/dbind-any.c index 1f784e5..30d8add 100644 --- a/dbind/dbind-any.c +++ b/dbind/dbind-any.c @@ -1,22 +1,20 @@ /* type driven marshalling */ -#include "config.h" -#include "dbind-config.h" -#define DBUS_API_SUBJECT_TO_CHANGE #include #include + +#include "config.h" +#include "dbind-config.h" #include "dbind-any.h" #undef DEBUG -/* Align a value upward to a boundary, expressed as a number of bytes. - E.g. align to an 8-byte boundary with argument of 8. */ - -/* +/* Align a value upward to a boundary, expressed as a number of bytes. + * E.g. align to an 8-byte boundary with argument of 8. + * * (this + boundary - 1) * & * ~(boundary - 1) */ - #define ALIGN_VALUE(this, boundary) \ (( ((gulong)(this)) + (((gulong)(boundary)) -1)) & (~(((gulong)(boundary))-1))) @@ -24,10 +22,20 @@ ((gpointer)ALIGN_VALUE(this, boundary)) #define PTR_PLUS(ptr, offset) \ - ((gpointer) (((guchar *)(ptr)) + (offset))) + ((gpointer) (((guchar *)(ptr)) + (offset))) -unsigned int dbind_find_c_alignment_r (char **type); -unsigned int dbind_find_c_alignment (char *type); +#define DBIND_POD_CASES \ + DBUS_TYPE_BYTE: \ + case DBUS_TYPE_INT16: \ + case DBUS_TYPE_UINT16: \ + case DBUS_TYPE_INT32: \ + case DBUS_TYPE_UINT32: \ + case DBUS_TYPE_BOOLEAN: \ + case DBUS_TYPE_INT64: \ + case DBUS_TYPE_UINT64: \ + case DBUS_TYPE_DOUBLE + +/*---------------------------------------------------------------------------*/ static void warn_braces () @@ -36,26 +44,89 @@ warn_braces () " an explicit type member of 'struct'\n"); } -/* gather immediate allocation information for this type */ -size_t dbind_gather_alloc_info_r (char **type) +/*---------------------------------------------------------------------------*/ + +static unsigned int +dbind_find_c_alignment_r (const char **type) { + unsigned int retval = 1; + char t = **type; (*type)++; - if (t == DBUS_TYPE_ARRAY) { - switch (**type) { - case DBUS_STRUCT_BEGIN_CHAR: - while (**type != DBUS_STRUCT_END_CHAR && **type != '\0') (*type)++; - if (**type != '\0') (*type)++; - break; - case '\0': - break; - default: - (*type)++; - break; - } - } - - switch (t) { + +#ifdef DEBUG + fprintf (stderr, "\tfind align for %c (0x%x)\n", t, t); +#endif + + switch (t) { + case DBUS_TYPE_BYTE: + return DBIND_ALIGNOF_CHAR; + case DBUS_TYPE_BOOLEAN: + return DBIND_ALIGNOF_DBUS_BOOL_T; + case DBUS_TYPE_INT16: + case DBUS_TYPE_UINT16: + return DBIND_ALIGNOF_DBUS_INT16_T; + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: + return DBIND_ALIGNOF_DBUS_INT32_T; + case DBUS_TYPE_INT64: + case DBUS_TYPE_UINT64: + return DBIND_ALIGNOF_DBUS_INT64_T; + case DBUS_TYPE_DOUBLE: + return DBIND_ALIGNOF_DOUBLE; + /* ptr types */ + case DBUS_TYPE_STRING: + case DBUS_TYPE_OBJECT_PATH: + case DBUS_TYPE_SIGNATURE: + case DBUS_TYPE_ARRAY: + return DBIND_ALIGNOF_DBIND_POINTER; + case DBUS_STRUCT_BEGIN_CHAR: +#if DBIND_ALIGNOF_DBIND_STRUCT > 1 + retval = MAX (retval, DBIND_ALIGNOF_DBIND_STRUCT); +#endif + while (**type != DBUS_STRUCT_END_CHAR) { + int elem_align = dbind_find_c_alignment_r (type); + retval = MAX (retval, elem_align); + } + (*type)++; + return retval; + case DBUS_TYPE_STRUCT: + case DBUS_TYPE_DICT_ENTRY: + warn_braces (); + return DBIND_ALIGNOF_DBIND_POINTER; + case '\0': + g_assert_not_reached(); + break; + default: + return 1; + } +} + +/*---------------------------------------------------------------------------*/ + +/* gather immediate allocation information for this type */ +static size_t +dbind_gather_alloc_info_r (const char **type) +{ + char t = **type; + (*type)++; + if (t == DBUS_TYPE_ARRAY) + { + switch (**type) + { + case DBUS_STRUCT_BEGIN_CHAR: + while (**type != DBUS_STRUCT_END_CHAR && **type != '\0') (*type)++; + if (**type != '\0') (*type)++; + break; + case '\0': + break; + default: + (*type)++; + break; + } + } + + switch (t) { case DBUS_TYPE_BYTE: return sizeof (char); case DBUS_TYPE_BOOLEAN: @@ -78,110 +149,116 @@ size_t dbind_gather_alloc_info_r (char **type) case DBUS_TYPE_ARRAY: return sizeof (void *); case DBUS_STRUCT_BEGIN_CHAR: { - int sum = 0, stralign; + int sum = 0, stralign; stralign = dbind_find_c_alignment (*type - 1); while (**type != DBUS_STRUCT_END_CHAR) { - sum = ALIGN_VALUE (sum, dbind_find_c_alignment (*type)); - sum += dbind_gather_alloc_info_r (type); + sum = ALIGN_VALUE (sum, dbind_find_c_alignment (*type)); + sum += dbind_gather_alloc_info_r (type); } - sum = ALIGN_VALUE (sum, stralign); + sum = ALIGN_VALUE (sum, stralign); g_assert (**type == DBUS_STRUCT_END_CHAR); (*type)++; - return sum; + return sum; } case DBUS_TYPE_STRUCT: case DBUS_TYPE_DICT_ENTRY: warn_braces (); - default: - return 0; - } + default: + return 0; + } } -size_t dbind_gather_alloc_info (char *type) +static size_t +dbind_gather_alloc_info (const char *type) { - return dbind_gather_alloc_info_r (&type); + return dbind_gather_alloc_info_r (&type); } -unsigned int -dbind_find_c_alignment_r (char **type) -{ - unsigned int retval = 1; - - char t = **type; - (*type)++; +/*---------------------------------------------------------------------------*/ +static void +dbind_any_free_r (const char **type, void **data) +{ #ifdef DEBUG - fprintf (stderr, "\tfind align for %c (0x%x)\n", t, t); + fprintf (stderr, "any free '%c' to %p\n", **type, *data); #endif - switch (t) { - case DBUS_TYPE_BYTE: - return DBIND_ALIGNOF_CHAR; - case DBUS_TYPE_BOOLEAN: - return DBIND_ALIGNOF_DBUS_BOOL_T; - case DBUS_TYPE_INT16: - case DBUS_TYPE_UINT16: - return DBIND_ALIGNOF_DBUS_INT16_T; - case DBUS_TYPE_INT32: - case DBUS_TYPE_UINT32: - return DBIND_ALIGNOF_DBUS_INT32_T; - case DBUS_TYPE_INT64: - case DBUS_TYPE_UINT64: - return DBIND_ALIGNOF_DBUS_INT64_T; - case DBUS_TYPE_DOUBLE: - return DBIND_ALIGNOF_DOUBLE; - /* ptr types */ + switch (**type) { + case DBIND_POD_CASES: + *data = ((guchar *)*data) + dbind_gather_alloc_info (*type); + (*type)++; + break; case DBUS_TYPE_STRING: case DBUS_TYPE_OBJECT_PATH: case DBUS_TYPE_SIGNATURE: - case DBUS_TYPE_ARRAY: - return DBIND_ALIGNOF_DBIND_POINTER; - case DBUS_STRUCT_BEGIN_CHAR: -#if DBIND_ALIGNOF_DBIND_STRUCT > 1 - retval = MAX (retval, DBIND_ALIGNOF_DBIND_STRUCT); +#ifdef DEBUG + fprintf (stderr, "string free %p\n", **(void ***)data); #endif + g_free (**(void ***)data); + *data = ((guchar *)*data) + dbind_gather_alloc_info (*type); + (*type)++; + break; + case DBUS_TYPE_ARRAY: { + int i; + GArray *vals = **(void ***)data; + size_t elem_size, elem_align; + const char *saved_child_type; + + (*type)++; + saved_child_type = *type; + + elem_size = dbind_gather_alloc_info (*type); + elem_align = dbind_find_c_alignment_r (type); + + for (i = 0; i < vals->len; i++) { + void *ptr = vals->data + elem_size * i; + *type = saved_child_type; /* rewind type info */ + ptr = ALIGN_ADDRESS (ptr, elem_align); + dbind_any_free_r (type, &ptr); + } + g_array_free (vals, TRUE); + break; + } + case DBUS_STRUCT_BEGIN_CHAR: { + gconstpointer data0 = *data; + int offset = 0, stralign; + + stralign = dbind_find_c_alignment (*type); + (*type)++; + + offset = 0 ; while (**type != DBUS_STRUCT_END_CHAR) { - int elem_align = dbind_find_c_alignment_r (type); - retval = MAX (retval, elem_align); + const char *subt = *type; + offset = ALIGN_VALUE (offset, dbind_find_c_alignment (*type)); + *data = PTR_PLUS (data0, offset); + dbind_any_free_r (type, data); + offset += dbind_gather_alloc_info (subt); } + + offset = ALIGN_VALUE (offset, stralign); + *data = PTR_PLUS (data0, offset); + + g_assert (**type == DBUS_STRUCT_END_CHAR); (*type)++; - return retval; + + break; + } case DBUS_TYPE_STRUCT: case DBUS_TYPE_DICT_ENTRY: warn_braces (); - return DBIND_ALIGNOF_DBIND_POINTER; - case '\0': - g_assert_not_reached(); break; - default: - return 1; - } + } } -unsigned int -dbind_find_c_alignment (char *type) -{ - return dbind_find_c_alignment_r (&type); -} - -#define DBIND_POD_CASES \ - DBUS_TYPE_BYTE: \ - case DBUS_TYPE_INT16: \ - case DBUS_TYPE_UINT16: \ - case DBUS_TYPE_INT32: \ - case DBUS_TYPE_UINT32: \ - case DBUS_TYPE_BOOLEAN: \ - case DBUS_TYPE_INT64: \ - case DBUS_TYPE_UINT64: \ - case DBUS_TYPE_DOUBLE +/*---------------------------------------------------------------------------*/ void dbind_any_marshal (DBusMessageIter *iter, - char **type, + const char **type, void **data) { size_t len; @@ -205,7 +282,8 @@ dbind_any_marshal (DBusMessageIter *iter, GArray *vals = **(void ***)data; size_t elem_size, elem_align; DBusMessageIter sub; - char *saved_child_type, *child_type_string; + const char *saved_child_type; + char *child_type_string; (*type)++; saved_child_type = *type; @@ -215,7 +293,7 @@ dbind_any_marshal (DBusMessageIter *iter, /* wow this part of the API sucks too ... */ child_type_string = g_strndup (saved_child_type, *type - saved_child_type); -/* fprintf (stderr, "array child type '%s'\n", child_type_string); */ + /* fprintf (stderr, "array child type '%s'\n", child_type_string); */ dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, child_type_string, &sub); for (i = 0; i < vals->len; i++) { @@ -230,8 +308,8 @@ dbind_any_marshal (DBusMessageIter *iter, break; } case DBUS_STRUCT_BEGIN_CHAR: { - gconstpointer data0 = *data; - int offset = 0, stralign; + gconstpointer data0 = *data; + int offset = 0, stralign; DBusMessageIter sub; stralign = dbind_find_c_alignment (*type); @@ -242,15 +320,15 @@ dbind_any_marshal (DBusMessageIter *iter, offset = 0 ; while (**type != DBUS_STRUCT_END_CHAR) { - char *subt = *type; - offset = ALIGN_VALUE (offset, dbind_find_c_alignment (*type)); - *data = PTR_PLUS (data0, offset); + const char *subt = *type; + offset = ALIGN_VALUE (offset, dbind_find_c_alignment (*type)); + *data = PTR_PLUS (data0, offset); dbind_any_marshal (&sub, type, data); offset += dbind_gather_alloc_info (subt); } - offset = ALIGN_VALUE (offset, stralign); - *data = PTR_PLUS (data0, offset); + offset = ALIGN_VALUE (offset, stralign); + *data = PTR_PLUS (data0, offset); dbus_message_iter_close_container (iter, &sub); @@ -266,9 +344,83 @@ dbind_any_marshal (DBusMessageIter *iter, } } +/*---------------------------------------------------------------------------*/ + +void +dbind_any_marshal_va (DBusMessageIter *iter, + const char **arg_types, + va_list args) +{ + const char *p = *arg_types; + + /* Guard against null arg types + Fix for - http://bugs.freedesktop.org/show_bug.cgi?id=23027 + */ + if (p == NULL) + p = ""; + + { + /* special case base-types since we need to walk the stack worse-luck */ + for (;*p != '\0' && *p != '=';) { + int intarg; + void *ptrarg; + double doublearg; + dbus_int64_t int64arg; + void *arg = NULL; + + switch (*p) { + case DBUS_TYPE_BYTE: + case DBUS_TYPE_BOOLEAN: + case DBUS_TYPE_INT16: + case DBUS_TYPE_UINT16: + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: + intarg = va_arg (args, int); + arg = &intarg; + break; + case DBUS_TYPE_INT64: + case DBUS_TYPE_UINT64: + int64arg = va_arg (args, dbus_int64_t); + arg = &int64arg; + break; + case DBUS_TYPE_DOUBLE: + doublearg = va_arg (args, double); + arg = &doublearg; + break; + /* ptr types */ + case DBUS_TYPE_STRING: + case DBUS_TYPE_OBJECT_PATH: + case DBUS_TYPE_SIGNATURE: + case DBUS_TYPE_ARRAY: + case DBUS_TYPE_DICT_ENTRY: + ptrarg = va_arg (args, void *); + arg = &ptrarg; + break; + case DBUS_STRUCT_BEGIN_CHAR: + ptrarg = va_arg (args, void *); + arg = ptrarg; + break; + + case DBUS_TYPE_VARIANT: + fprintf (stderr, "No variant support yet - very toolkit specific\n"); + ptrarg = va_arg (args, void *); + arg = &ptrarg; + break; + default: + fprintf (stderr, "Unknown / invalid arg type %c\n", *p); + break; + } + if (arg != NULL) + dbind_any_marshal (iter, &p, &arg); + } + } +} + +/*---------------------------------------------------------------------------*/ + void dbind_any_demarshal (DBusMessageIter *iter, - char **type, + const char **type, void **data) { size_t len; @@ -300,23 +452,23 @@ dbind_any_demarshal (DBusMessageIter *iter, GArray *vals; DBusMessageIter child; size_t elem_size, elem_align; - char *stored_child_type; + const char *stored_child_type; int i; (*type)++; stored_child_type = *type; - + elem_size = dbind_gather_alloc_info (*type); elem_align = dbind_find_c_alignment_r (type); vals = g_array_new (FALSE, FALSE, elem_size); (**(void ***)data) = vals; *data = ((guchar *)*data) + sizeof (void *); - + i = 0; dbus_message_iter_recurse (iter, &child); while (dbus_message_iter_get_arg_type (&child) != DBUS_TYPE_INVALID) { void *ptr; - char *subt = stored_child_type; + const char *subt = stored_child_type; g_array_set_size (vals, i + 1); ptr = vals->data + elem_size * i; ptr = ALIGN_ADDRESS (ptr, elem_align); @@ -326,8 +478,8 @@ dbind_any_demarshal (DBusMessageIter *iter, break; } case DBUS_STRUCT_BEGIN_CHAR: { - gconstpointer data0 = *data; - int offset = 0, stralign; + gconstpointer data0 = *data; + int offset = 0, stralign; DBusMessageIter child; stralign = dbind_find_c_alignment (*type); @@ -337,15 +489,15 @@ dbind_any_demarshal (DBusMessageIter *iter, dbus_message_iter_recurse (iter, &child); while (**type != DBUS_STRUCT_END_CHAR) { - char *subt = *type; - offset = ALIGN_VALUE (offset, dbind_find_c_alignment (*type)); - *data = PTR_PLUS (data0, offset); + const char *subt = *type; + offset = ALIGN_VALUE (offset, dbind_find_c_alignment (*type)); + *data = PTR_PLUS (data0, offset); dbind_any_demarshal (&child, type, data); offset += dbind_gather_alloc_info (subt); } - offset = ALIGN_VALUE (offset, stralign); - *data = PTR_PLUS (data0, offset); + offset = ALIGN_VALUE (offset, stralign); + *data = PTR_PLUS (data0, offset); g_assert (**type == DBUS_STRUCT_END_CHAR); (*type)++; @@ -360,85 +512,25 @@ dbind_any_demarshal (DBusMessageIter *iter, dbus_message_iter_next (iter); } -static void -dbind_any_free_r (char **type, void **data) -{ - size_t len; +/*---------------------------------------------------------------------------*/ -#ifdef DEBUG - fprintf (stderr, "any free '%c' to %p\n", **type, *data); -#endif - - switch (**type) { - case DBIND_POD_CASES: - *data = ((guchar *)*data) + dbind_gather_alloc_info (*type); - (*type)++; - break; - case DBUS_TYPE_STRING: - case DBUS_TYPE_OBJECT_PATH: - case DBUS_TYPE_SIGNATURE: -#ifdef DEBUG - fprintf (stderr, "string free %p\n", **(void ***)data); -#endif - g_free (**(void ***)data); - *data = ((guchar *)*data) + dbind_gather_alloc_info (*type); - (*type)++; - break; - case DBUS_TYPE_ARRAY: { - int i; - GArray *vals = **(void ***)data; - size_t elem_size, elem_align; - char *saved_child_type, *child_type_string; - - (*type)++; - saved_child_type = *type; - - elem_size = dbind_gather_alloc_info (*type); - elem_align = dbind_find_c_alignment_r (type); - - for (i = 0; i < vals->len; i++) { - void *ptr = vals->data + elem_size * i; - *type = saved_child_type; /* rewind type info */ - ptr = ALIGN_ADDRESS (ptr, elem_align); - dbind_any_free_r (type, &ptr); - } - g_array_free (vals, TRUE); - break; - } - case DBUS_STRUCT_BEGIN_CHAR: { - gconstpointer data0 = *data; - int offset = 0, stralign; - - stralign = dbind_find_c_alignment (*type); - (*type)++; - - offset = 0 ; - while (**type != DBUS_STRUCT_END_CHAR) { - char *subt = *type; - offset = ALIGN_VALUE (offset, dbind_find_c_alignment (*type)); - *data = PTR_PLUS (data0, offset); - dbind_any_free_r (type, data); - offset += dbind_gather_alloc_info (subt); - } - - offset = ALIGN_VALUE (offset, stralign); - *data = PTR_PLUS (data0, offset); - - g_assert (**type == DBUS_STRUCT_END_CHAR); - (*type)++; - - break; - } - case DBUS_TYPE_STRUCT: - case DBUS_TYPE_DICT_ENTRY: - warn_braces (); - break; +void +dbind_any_demarshal_va (DBusMessageIter *iter, + const char **arg_types, + va_list args) +{ + const char *p = *arg_types; + for (;*p != '\0';) { + void *arg = va_arg (args, void *); + dbind_any_demarshal (iter, &p, &arg); } } +/*---------------------------------------------------------------------------*/ + /* nice deep free ... */ void -dbind_any_free (char *type, +dbind_any_free (const char *type, void *ptr) { dbind_any_free_r (&type, &ptr); @@ -446,7 +538,17 @@ dbind_any_free (char *type, /* should this be the default normalization ? */ void -dbind_any_free_ptr (char *type, void *ptr) +dbind_any_free_ptr (const char *type, void *ptr) { dbind_any_free (type, &ptr); } + +/*---------------------------------------------------------------------------*/ + +unsigned int +dbind_find_c_alignment (const char *type) +{ + return dbind_find_c_alignment_r (&type); +} + +/*END------------------------------------------------------------------------*/