diff src/dbus-server.c @ 11187:744c0708d11f

[gaim-migrate @ 13303] gaim-remote.py implements the functionality of standard gaim-remote, but using DBus. It can also call all gaim functions exported via DBus. dbus-analize-function.py can now produce dbus bindings for GHashTable arguments. committer: Tailor Script <tailor@pidgin.im>
author Piotr Zielinski <zielaj>
date Wed, 03 Aug 2005 23:54:37 +0000
parents 57af14280b5f
children 421a8523ad04
line wrap: on
line diff
--- a/src/dbus-server.c	Wed Aug 03 22:58:06 2005 +0000
+++ b/src/dbus-server.c	Wed Aug 03 23:54:37 2005 +0000
@@ -96,7 +96,7 @@
 
 gint gaim_dbus_pointer_to_id(gpointer node) {
     gint id = GPOINTER_TO_INT(g_hash_table_lookup(map_node_id, node));
-    g_return_val_if_fail(id, 0);
+    g_return_val_if_fail(id || node == NULL, 0);
     return id;
 }
 	
@@ -136,7 +136,109 @@
     
     return ptr;
 }
+
+
+/**************************************************************************/
+/** @name Modified versions of some DBus functions                        */
+/**************************************************************************/
+
+dbus_bool_t
+gaim_dbus_message_get_args (DBusMessage     *message,
+                       DBusError       *error,
+		       int              first_arg_type,
+		       ...)
+{
+  dbus_bool_t retval;
+  va_list var_args;
+
+  va_start (var_args, first_arg_type);
+  retval = gaim_dbus_message_get_args_valist (message, error, first_arg_type, var_args);
+  va_end (var_args);
+
+  return retval;
+}
+
+dbus_bool_t
+gaim_dbus_message_get_args_valist (DBusMessage     *message,
+				   DBusError       *error,
+				   int              first_arg_type,
+				   va_list          var_args)
+{
+  DBusMessageIter iter;
+
+  dbus_message_iter_init (message, &iter);
+  return gaim_dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
+}
+
+dbus_bool_t
+gaim_dbus_message_iter_get_args(DBusMessageIter *iter,
+				DBusError       *error,
+				int              first_arg_type,
+				...)
+{
+  dbus_bool_t retval;
+  va_list var_args;
+
+  va_start (var_args, first_arg_type);
+  retval = gaim_dbus_message_iter_get_args_valist(iter, error, first_arg_type, var_args);
+  va_end (var_args);
+
+  return retval;
+}
+
+#define TYPE_IS_CONTAINER(typecode)             \
+    ((typecode) == DBUS_TYPE_STRUCT ||          \
+     (typecode) == DBUS_TYPE_DICT_ENTRY ||      \
+     (typecode) == DBUS_TYPE_VARIANT ||         \
+     (typecode) == DBUS_TYPE_ARRAY)
+
+
+dbus_bool_t
+gaim_dbus_message_iter_get_args_valist (DBusMessageIter *iter,
+					DBusError       *error,
+					int              first_arg_type,
+					va_list          var_args)
+{
+    int spec_type, msg_type, i;
+
+    spec_type = first_arg_type;
+    
+    for(i=0; spec_type != DBUS_TYPE_INVALID; i++) {
+	msg_type = dbus_message_iter_get_arg_type (iter);
+
+	if (msg_type != spec_type) {
+	    dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+			    "Argument %d is specified to be of type \"%i\", but "
+			    "is actually of type \"%i\"\n", i,
+			    spec_type, msg_type);
+          return FALSE;
+	}
+
+	if (!TYPE_IS_CONTAINER(spec_type)) {
+	    gpointer ptr;
+	    ptr = va_arg (var_args, gpointer);
+	    dbus_message_iter_get_basic(iter, ptr);
+	}
+	else {
+	    DBusMessageIter *sub;
+	    sub = va_arg (var_args, DBusMessageIter*);
+	    dbus_message_iter_recurse(iter, sub);
+	    g_print("subiter %i:%i\n", (int) sub, * (int*) sub);
+	    break;		/* for testing only! */
+	}
 	
+	spec_type = va_arg (var_args, int);
+	if (!dbus_message_iter_next(iter) && spec_type != DBUS_TYPE_INVALID) {
+	    dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+			    "Message has only %d arguments, but more were expected", i);
+	    return FALSE;
+        }
+    }
+  return TRUE;
+}
+
+
+
 /**************************************************************************/
 /** @name Useful functions                                                */
 /**************************************************************************/
@@ -155,9 +257,6 @@
 		return "";
 }
 
-
-
-
 dbus_int32_t* gaim_dbusify_GList(GList *list, gboolean free_memory,
 				 dbus_int32_t *len)
  {
@@ -194,6 +293,78 @@
 	return array;
 }
 
+gpointer* gaim_GList_to_array(GList *list, gboolean free_memory,
+			      dbus_int32_t *len)
+{
+	gpointer *array;
+	int i;
+	GList *elem;
+
+	*len = g_list_length(list);
+	array = g_new0(gpointer, g_list_length(list));
+	for(i = 0, elem = list; elem != NULL; elem = elem->next, i++) 
+		array[i] = elem->data;
+
+	if (free_memory)
+		g_list_free(list);
+
+	return array;
+}
+
+gpointer* gaim_GSList_to_array(GSList *list, gboolean free_memory,
+			      dbus_int32_t *len)
+{
+	gpointer *array;
+	int i;
+	GSList *elem;
+
+	*len = g_slist_length(list);
+	array = g_new0(gpointer, g_slist_length(list));
+	for(i = 0, elem = list; elem != NULL; elem = elem->next, i++) 
+		array[i] = elem->data;
+
+	if (free_memory)
+		g_slist_free(list);
+
+	return array;
+}
+
+GHashTable *gaim_dbus_iter_hash_table(DBusMessageIter *iter, DBusError *error) {
+    GHashTable *hash;
+
+    /* we do not need to destroy strings because they are part of the message */
+    hash = g_hash_table_new(g_str_hash, g_str_equal); 
+
+    do {
+	char *key, *value;
+	DBusMessageIter subiter;
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY) 
+	    goto error;		/* With all due respect to Dijkstra,
+				   this goto is for exception
+				   handling, and it is ok because it
+				   avoids duplication of the code
+				   responsible for destroying the hash
+				   table.  Exceptional instructions
+				   for exceptional situations. */	    
+
+	dbus_message_iter_recurse(iter, &subiter);
+	if (!gaim_dbus_message_iter_get_args(&subiter, error, 
+					     DBUS_TYPE_STRING, &key,
+					     DBUS_TYPE_STRING, &value,
+					     DBUS_TYPE_INVALID))
+	    goto error;		/* same here */
+
+	g_hash_table_insert(hash, key, value);
+    } while (dbus_message_iter_next(iter));
+    
+    return hash;
+
+ error:
+    g_hash_table_destroy(hash);
+    return NULL;
+}
+
 /**************************************************************/
 /* DBus bindings ...                                          */
 /**************************************************************/
@@ -260,7 +431,9 @@
 }
 
 
-/* Introspection */
+/**************************************************************************/
+/** @name Signals                                                         */
+/**************************************************************************/
 
 static const char *gettext(const char **ptr) {
     const char *text = *ptr;
@@ -307,9 +480,9 @@
 		type = gettext(&text);
 		name = gettext(&text);
 		
-	    g_string_append_printf(str, 
-				   "<arg name='%s' type='%s' direction='%s'/>\n",
-				   name, type, direction);
+		g_string_append_printf(str, 
+				       "<arg name='%s' type='%s' direction='%s'/>\n",
+				       name, type, direction);
 	    }
 	    g_string_append(str, "</method>\n");
 	}
@@ -535,7 +708,3 @@
 }
 
 
-/* Introspection support */
-
-
-