summaryrefslogtreecommitdiff
path: root/gio/gdbusinterface.c
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2011-04-08 15:14:47 -0400
committerDavid Zeuthen <davidz@redhat.com>2011-04-08 15:48:28 -0400
commit94b907134426e26393a86630dae5ce53baee6ae6 (patch)
treec768a5ec5e82c0d5a19c5e687e28d033472af8d2 /gio/gdbusinterface.c
parent0729260141bb585943ad1c6efa8ab7ee9058b0aa (diff)
Start merging gdbus-codegen code
Signed-off-by: David Zeuthen <davidz@redhat.com>
Diffstat (limited to 'gio/gdbusinterface.c')
-rw-r--r--gio/gdbusinterface.c410
1 files changed, 410 insertions, 0 deletions
diff --git a/gio/gdbusinterface.c b/gio/gdbusinterface.c
new file mode 100644
index 000000000..d8f85943b
--- /dev/null
+++ b/gio/gdbusinterface.c
@@ -0,0 +1,410 @@
+/* GDBus - GLib D-Bus Library
+ *
+ * Copyright (C) 2008-2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz@redhat.com>
+ */
+
+#include "config.h"
+
+#include "gdbusobject.h"
+#include "gdbusinterface.h"
+#include "gio-marshal.h"
+
+#include "glibintl.h"
+
+/**
+ * SECTION:gdbusinterface
+ * @short_description: Base type for D-Bus interfaces
+ * @include: gio/gio.h
+ *
+ * The #GDBusInterface type is the base type for D-Bus interfaces both
+ * on the service side (see #GDBusInterfaceStub) and client side (see
+ * #GDBusProxy).
+ */
+
+typedef GDBusInterfaceIface GDBusInterfaceInterface;
+G_DEFINE_INTERFACE (GDBusInterface, g_dbus_interface, G_TYPE_OBJECT)
+
+static void
+g_dbus_interface_default_init (GDBusInterfaceIface *iface)
+{
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_dbus_interface_get_info:
+ * @interface: An exported D-Bus interface.
+ *
+ * Gets D-Bus introspection information for the D-Bus interface
+ * implemented by @interface.
+ *
+ * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.
+ */
+GDBusInterfaceInfo *
+g_dbus_interface_get_info (GDBusInterface *interface)
+{
+ g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface), NULL);
+ return G_DBUS_INTERFACE_GET_IFACE (interface)->get_info (interface);
+}
+
+/**
+ * g_dbus_interface_get_object:
+ * @interface: An exported D-Bus interface.
+ *
+ * Gets the #GDBusObject that @interface belongs to, if any.
+ *
+ * Returns: (transfer none): A #GDBusObject or %NULL. The returned
+ * reference belongs to @interface and should not be freed.
+ */
+GDBusObject *
+g_dbus_interface_get_object (GDBusInterface *interface)
+{
+ g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface), NULL);
+ return G_DBUS_INTERFACE_GET_IFACE (interface)->get_object (interface);
+}
+
+/**
+ * g_dbus_interface_set_object:
+ * @interface: An exported D-Bus interface.
+ * @object: A #GDBusObject or %NULL.
+ *
+ * Sets the #GDBusObject for @interface to @object.
+ *
+ * Note that @interface will hold a weak reference to @object.
+ */
+void
+g_dbus_interface_set_object (GDBusInterface *interface,
+ GDBusObject *object)
+{
+ g_return_if_fail (G_IS_DBUS_INTERFACE (interface));
+ g_return_if_fail (object == NULL || G_IS_DBUS_OBJECT (object));
+ G_DBUS_INTERFACE_GET_IFACE (interface)->set_object (interface, object);
+}
+
+/* Keep it here for now. TODO: move */
+
+#include <string.h>
+
+/**
+ * g_dbus_gvariant_to_gvalue:
+ * @value: A #GVariant.
+ * @out_gvalue: Return location for the #GValue.
+ *
+ * Convert a #GVariant to a #GValue. If @value is floating, it is consumed.
+ *
+ * Note that the passed @out_gvalue does not have to have a #GType set.
+ *
+ * Returns: %TRUE if the conversion succeeded, %FALSE otherwise.
+ */
+gboolean
+g_dbus_gvariant_to_gvalue (GVariant *value,
+ GValue *out_gvalue)
+{
+ gboolean ret;
+ const GVariantType *type;
+ gchar **array;
+
+ g_return_val_if_fail (value != NULL, FALSE);
+ g_return_val_if_fail (out_gvalue != NULL, FALSE);
+
+ ret = FALSE;
+
+ memset (out_gvalue, '\0', sizeof (GValue));
+
+ switch (g_variant_classify (value))
+ {
+ case G_VARIANT_CLASS_BOOLEAN:
+ g_value_init (out_gvalue, G_TYPE_BOOLEAN);
+ g_value_set_boolean (out_gvalue, g_variant_get_boolean (value));
+ break;
+
+ case G_VARIANT_CLASS_BYTE:
+ g_value_init (out_gvalue, G_TYPE_UCHAR);
+ g_value_set_uchar (out_gvalue, g_variant_get_byte (value));
+ break;
+
+ case G_VARIANT_CLASS_INT16:
+ g_value_init (out_gvalue, G_TYPE_INT);
+ g_value_set_int (out_gvalue, g_variant_get_int16 (value));
+ break;
+
+ case G_VARIANT_CLASS_UINT16:
+ g_value_init (out_gvalue, G_TYPE_UINT);
+ g_value_set_uint (out_gvalue, g_variant_get_uint16 (value));
+ break;
+
+ case G_VARIANT_CLASS_INT32:
+ g_value_init (out_gvalue, G_TYPE_INT);
+ g_value_set_int (out_gvalue, g_variant_get_int32 (value));
+ break;
+
+ case G_VARIANT_CLASS_UINT32:
+ g_value_init (out_gvalue, G_TYPE_UINT);
+ g_value_set_uint (out_gvalue, g_variant_get_uint32 (value));
+ break;
+
+ case G_VARIANT_CLASS_INT64:
+ g_value_init (out_gvalue, G_TYPE_INT64);
+ g_value_set_int64 (out_gvalue, g_variant_get_int64 (value));
+ break;
+
+ case G_VARIANT_CLASS_UINT64:
+ g_value_init (out_gvalue, G_TYPE_UINT64);
+ g_value_set_uint64 (out_gvalue, g_variant_get_uint64 (value));
+ break;
+
+ case G_VARIANT_CLASS_HANDLE:
+ g_value_init (out_gvalue, G_TYPE_INT);
+ g_value_set_int (out_gvalue, g_variant_get_int32 (value));
+ break;
+
+ case G_VARIANT_CLASS_DOUBLE:
+ g_value_init (out_gvalue, G_TYPE_DOUBLE);
+ g_value_set_double (out_gvalue, g_variant_get_double (value));
+ break;
+
+ case G_VARIANT_CLASS_STRING:
+ g_value_init (out_gvalue, G_TYPE_STRING);
+ g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
+ break;
+
+ case G_VARIANT_CLASS_OBJECT_PATH:
+ g_value_init (out_gvalue, G_TYPE_STRING);
+ g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
+ break;
+
+ case G_VARIANT_CLASS_SIGNATURE:
+ g_value_init (out_gvalue, G_TYPE_STRING);
+ g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
+ break;
+
+ case G_VARIANT_CLASS_ARRAY:
+ type = g_variant_get_type (value);
+ switch (g_variant_type_peek_string (type)[1])
+ {
+ case G_VARIANT_CLASS_BYTE:
+ g_value_init (out_gvalue, G_TYPE_STRING);
+ g_value_set_string (out_gvalue, g_variant_get_bytestring (value));
+ break;
+
+ case G_VARIANT_CLASS_STRING:
+ g_value_init (out_gvalue, G_TYPE_STRV);
+ array = g_variant_dup_strv (value, NULL);
+ g_value_take_boxed (out_gvalue, array);
+ break;
+
+ case G_VARIANT_CLASS_ARRAY:
+ switch (g_variant_type_peek_string (type)[2])
+ {
+ case G_VARIANT_CLASS_BYTE:
+ g_value_init (out_gvalue, G_TYPE_STRV);
+ array = g_variant_dup_bytestring_array (value, NULL);
+ g_value_take_boxed (out_gvalue, array);
+ break;
+
+ default:
+ g_value_init (out_gvalue, G_TYPE_VARIANT);
+ g_value_set_variant (out_gvalue, value);
+ break;
+ }
+ break;
+
+ default:
+ g_value_init (out_gvalue, G_TYPE_VARIANT);
+ g_value_set_variant (out_gvalue, value);
+ break;
+ }
+ break;
+
+ case G_VARIANT_CLASS_VARIANT:
+ case G_VARIANT_CLASS_MAYBE:
+ case G_VARIANT_CLASS_TUPLE:
+ case G_VARIANT_CLASS_DICT_ENTRY:
+ g_value_init (out_gvalue, G_TYPE_VARIANT);
+ g_value_set_variant (out_gvalue, value);
+ break;
+ }
+
+ ret = TRUE;
+
+ return ret;
+}
+
+
+/**
+ * g_dbus_gvalue_to_gvariant:
+ * @gvalue: A #GValue to convert to a #GVariant.
+ * @expected_type: The #GVariantType to create.
+ *
+ * Convert a #GValue to #GVariant.
+ *
+ * Returns: A #GVariant (never floating) holding the data from @gvalue
+ * or %NULL in case of error. Free with g_variant_unref().
+ */
+GVariant *
+g_dbus_gvalue_to_gvariant (const GValue *gvalue,
+ const GVariantType *expected_type)
+{
+ GVariant *ret;
+ const gchar *s;
+ const gchar * const *as;
+ const gchar *empty_strv[1] = {NULL};
+
+ g_return_val_if_fail (gvalue != NULL, NULL);
+ g_return_val_if_fail (expected_type != NULL, NULL);
+
+ ret = NULL;
+
+ /* The expected type could easily be e.g. "s" with the GValue holding a string.
+ * because of the UseGVariant annotation
+ */
+ if (G_VALUE_TYPE (gvalue) == G_TYPE_VARIANT)
+ {
+ ret = g_value_dup_variant (gvalue);
+ }
+ else
+ {
+ switch (g_variant_type_peek_string (expected_type)[0])
+ {
+ case G_VARIANT_CLASS_BOOLEAN:
+ ret = g_variant_ref_sink (g_variant_new_boolean (g_value_get_boolean (gvalue)));
+ break;
+
+ case G_VARIANT_CLASS_BYTE:
+ ret = g_variant_ref_sink (g_variant_new_byte (g_value_get_uchar (gvalue)));
+ break;
+
+ case G_VARIANT_CLASS_INT16:
+ ret = g_variant_ref_sink (g_variant_new_int16 (g_value_get_int (gvalue)));
+ break;
+
+ case G_VARIANT_CLASS_UINT16:
+ ret = g_variant_ref_sink (g_variant_new_uint16 (g_value_get_uint (gvalue)));
+ break;
+
+ case G_VARIANT_CLASS_INT32:
+ ret = g_variant_ref_sink (g_variant_new_int32 (g_value_get_int (gvalue)));
+ break;
+
+ case G_VARIANT_CLASS_UINT32:
+ ret = g_variant_ref_sink (g_variant_new_uint32 (g_value_get_uint (gvalue)));
+ break;
+
+ case G_VARIANT_CLASS_INT64:
+ ret = g_variant_ref_sink (g_variant_new_int64 (g_value_get_int64 (gvalue)));
+ break;
+
+ case G_VARIANT_CLASS_UINT64:
+ ret = g_variant_ref_sink (g_variant_new_uint64 (g_value_get_uint64 (gvalue)));
+ break;
+
+ case G_VARIANT_CLASS_HANDLE:
+ ret = g_variant_ref_sink (g_variant_new_handle (g_value_get_int (gvalue)));
+ break;
+
+ case G_VARIANT_CLASS_DOUBLE:
+ ret = g_variant_ref_sink (g_variant_new_double (g_value_get_double (gvalue)));
+ break;
+
+ case G_VARIANT_CLASS_STRING:
+ s = g_value_get_string (gvalue);
+ if (s == NULL)
+ s = "";
+ ret = g_variant_ref_sink (g_variant_new_string (s));
+ break;
+
+ case G_VARIANT_CLASS_OBJECT_PATH:
+ s = g_value_get_string (gvalue);
+ if (s == NULL)
+ s = "/";
+ ret = g_variant_ref_sink (g_variant_new_object_path (s));
+ break;
+
+ case G_VARIANT_CLASS_SIGNATURE:
+ s = g_value_get_string (gvalue);
+ if (s == NULL)
+ s = "";
+ ret = g_variant_ref_sink (g_variant_new_signature (s));
+ break;
+
+ case G_VARIANT_CLASS_ARRAY:
+ switch (g_variant_type_peek_string (expected_type)[1])
+ {
+ case G_VARIANT_CLASS_BYTE:
+ s = g_value_get_string (gvalue);
+ if (s == NULL)
+ s = "";
+ ret = g_variant_ref_sink (g_variant_new_bytestring (s));
+ break;
+
+ case G_VARIANT_CLASS_STRING:
+ as = g_value_get_boxed (gvalue);
+ if (as == NULL)
+ as = empty_strv;
+ ret = g_variant_ref_sink (g_variant_new_strv (as, -1));
+ break;
+
+ case G_VARIANT_CLASS_ARRAY:
+ switch (g_variant_type_peek_string (expected_type)[2])
+ {
+ case G_VARIANT_CLASS_BYTE:
+ as = g_value_get_boxed (gvalue);
+ if (as == NULL)
+ as = empty_strv;
+ ret = g_variant_ref_sink (g_variant_new_bytestring_array (as, -1));
+ break;
+
+ default:
+ ret = g_value_dup_variant (gvalue);
+ break;
+ }
+ break;
+
+ default:
+ ret = g_value_dup_variant (gvalue);
+ break;
+ }
+ break;
+
+ default:
+ case G_VARIANT_CLASS_VARIANT:
+ case G_VARIANT_CLASS_MAYBE:
+ case G_VARIANT_CLASS_TUPLE:
+ case G_VARIANT_CLASS_DICT_ENTRY:
+ ret = g_value_dup_variant (gvalue);
+ break;
+ }
+ }
+
+ /* Could be that the GValue is holding a NULL GVariant - in that case,
+ * we return an "empty" GVariant instead of a NULL GVariant
+ */
+ if (ret == NULL)
+ {
+ GVariant *untrusted_empty;
+ untrusted_empty = g_variant_new_from_data (expected_type, NULL, 0, FALSE, NULL, NULL);
+ ret = g_variant_ref_sink (g_variant_get_normal_form (untrusted_empty));
+ g_variant_unref (untrusted_empty);
+ }
+
+ g_assert (!g_variant_is_floating (ret));
+
+ return ret;
+}