diff options
| author | Colin Walters <walters@verbum.org> | 2005-02-17 17:41:30 +0000 | 
|---|---|---|
| committer | Colin Walters <walters@verbum.org> | 2005-02-17 17:41:30 +0000 | 
| commit | 03f6615eaccc2c1f84d4252e5a627a2ac86d41d9 (patch) | |
| tree | 6b7867f43ae7858f2aae4a208e01d10dd3d752a3 /test | |
| parent | 9e4450872a6861bd93a01dabe14d2d16f6c84d3f (diff) | |
2005-02-17  Colin Walters  <walters@verbum.org>
	This patch is based on initial work from
	Paul Kuliniewicz <kuliniew@purdue.edu>.
	* glib/dbus-gvalue.c (dbus_gvalue_init): New function; move
	initialization of GValue from dbus type to here.
	(dbus_gvalue_genmarshal_name_from_type): New function; generates a string
	for the "glib-genmarshal" program from a DBus type.
	(dbus_gvalue_binding_type_from_type): New function; turns a DBus type
	into the C name for it we use in the glib bindings.
	(dbus_gvalue_ctype_from_type): New function; maps a DBus type into a
	glib C type (not GValue).
	(dbus_gvalue_demarshal): invoke dbus_gvalue_init.
	* glib/dbus-gutils.c (_dbus_gutils_wincaps_to_uscore): Moved here
	from dbus-gobject.c.
	* glib/dbus-gutils.h: Prototype it.
	* glib/dbus-gproxy.c: Include new dbus-gobject.h.
	(marshal_dbus_message_to_g_marshaller): Use new shared function
	dbus_glib_marshal_dbus_message_to_gvalue_array.
	* glib/dbus-gparser.c (parse_interface, parse_method): Handle c_name attribute.
	Will be changed once we have annotations.
	* glib/dbus-gobject.c: Change info_hash_mutex from GStaticMutex to
	GStaticRWLock.  Callers updated.
	(wincaps_to_uscore): Move to dbus-gutils.c.  Callers updated.
	(string_table_next): New function for iterating over zero-terminated
	string value array.
	(string_table_lookup): New function; retrieves specific entry in
	array.
	(get_method_data): New function; look up method data in object data chunk.
	(object_error_domain_prefix_from_object_info)
	(object_error_code_from_object_info): New functions, but not implemented yet.
	(method_interface_from_object_info): New function; retrieve interface name.
	(method_name_from_object_info): New function; retrieve method name.
	(method_arg_info_from_object_info): New function; retrieve argument data.
	(arg_iterate): New function; iterates over serialized argument data.
	(method_dir_signature_from_object_info): New function; returns a
	GString holding type signature for arguments for just one
	direction (input or output).
	(method_input_signature_from_object_info)
	(method_output_signature_from_object_info): New functions.
	(dbus_glib_marshal_dbus_message_to_gvalue_array): New shared function;
	converts dbus message arguments into a GValue array.  Used for both
	signal handling and method invocation.
	(struct DBusGlibWriteIterfaceData): New utility structure.
	(write_interface): New function; generate introspection XML for
	an interface.
	(introspect_interfaces): New function; gathers all interface->methods,
	generates introspection XML for them.
	(handle_introspect): Invoke introspect_interfaces.
	(get_object_property): Be sure to zero-initalize stack-allocated GValue.
	(lookup_object_and_method): New function; examines an incoming message
	and attempts to match it up (via interface, method name, and argument
	signature) with a known object and method.
	(gerror_domaincode_to_dbus_error_name): New function; converts a
	GError domain and code into a DBus error name.  Needs GError data
	added to object introspection to work well.
	(gerror_to_dbus_error_message): Creates a DBusMessage error return from
	GError.
	(invoke_object_method): New function to invoke an object method
	looked up via lookup_object_and_method.  Parses the incoming
	message, turns it into a GValue array, then invokes the marshaller
	specified in the DBusGMethodInfo.  Creates a new message with
	either return values or error message as appropriate.
	(gobject_message_function): Invoke lookup_object_and_method and
	invoke_object_method.
	* glib/dbus-glib-tool.c: Include dbus-binding-tool-glib.h.
	(enum DBusBindingOutputMode): New enum for binding output modes.
	(pretty_print): Print binding names.
	(dbus_binding_tool_error_quark): GError bits.
	(version): Fix typo.
	(main): Create GIOChannel for output.  Parse new --mode argument,
	possible values are "pretty-print", "glib-server", "glib-client".
	Use mode to invoke appropriate function.
	* glib/dbus-gobject.h: Prototype dbus_glib_marshal_dbus_message_to_gvalue_array.
	* glib/dbus-glib-tool.h: New header, just includes GError bits
	for now.
	* glib/dbus-gidl.c (struct InterfaceInfo): Add bindings hashtable;
	maps binding style to name.
	(struct MethodInfo): Ditto.
	(get_hash_keys, get_hash_key): Utility function, returns keys for
	a GHashTable.
	(interface_info_new, method_info_new): Initialize bindings.
	(interface_info_unref, method_info_unref): Destroy bindings.
	(method_info_get_binding_names, method_info_get_binding_name)
	(interface_info_get_binding_names, interface_info_get_binding_name):
	Functions for retrieving binding names.
	(method_info_set_binding_name, interface_info_set_binding_name):
	Functions for setting binding names.
	* glib/dbus-binding-tool-glib.h: New file, has prototypes
	for glib binding generation.
	* glib/dbus-binding-tool-glib.c: New file, implements server-side
	and client-side glib glue generation.
	* glib/Makefile.am (dbus_binding_tool_SOURCES): Add
	dbus-binding-tool-glib.c, dbus-binding-tool-glib.h,
	dbus-glib-tool.h.
	* dbus/dbus-glib.h (struct DBusGMethodMarshaller): Remove in favor
	of using GClosureMarshal directly.
	(struct DBusGObjectInfo): Add n_infos member.
	* test/glib/test-service-glib.xml: New file; contains introspection data
	for MyTestObject used in test-service-glib.c.
	* test/glib/test-service-glib.c (enum MyObjectError): New GError enum.
	(my_object_do_nothing, my_object_increment, my_object_throw_error)
	(my_object_uppercase, my_object_many_args): New test methods.
	(main): Use dbus_g_object_class_install_info to include generated object
	info.
	* test/glib/Makefile.am: Generate server-side glue for test-service-glib.c,
	as well as client-side bindings.
	* test/glib/test-dbus-glib.c: Include test-service-glib-bindings.h.
	(main): Activate TestSuiteGLibService; test invoke a bunch of its methods
	using both the dbus_gproxy stuff directly as well as the generated bindings.
Diffstat (limited to 'test')
| -rw-r--r-- | test/glib/Makefile.am | 15 | ||||
| -rw-r--r-- | test/glib/test-dbus-glib.c | 203 | ||||
| -rw-r--r-- | test/glib/test-service-glib.c | 76 | ||||
| -rw-r--r-- | test/glib/test-service-glib.xml | 33 | 
4 files changed, 323 insertions, 4 deletions
diff --git a/test/glib/Makefile.am b/test/glib/Makefile.am index a679bcc1..0a246252 100644 --- a/test/glib/Makefile.am +++ b/test/glib/Makefile.am @@ -40,7 +40,20 @@ test_dbus_glib_SOURCES=				\  test_dbus_glib_LDADD= $(top_builddir)/glib/libdbus-glib-1.la  test_service_glib_SOURCES=				\ -	test-service-glib.c +	test-service-glib.c				\ +	test-service-glib-glue.h + +BUILT_SOURCES = test-service-glib-glue.h test-service-glib-bindings.h + +test-service-glib-glue.h: $(top_builddir)/glib/dbus-binding-tool test-service-glib.xml +	$(top_builddir)/glib/dbus-binding-tool --mode=glib-server $(srcdir)/test-service-glib.xml > test-service-glib-glue.h.tmp +	mv test-service-glib-glue.h.tmp test-service-glib-glue.h + +test-service-glib-bindings.h: $(top_builddir)/glib/dbus-binding-tool test-service-glib.xml +	$(top_builddir)/glib/dbus-binding-tool --mode=glib-client $(srcdir)/test-service-glib.xml > test-service-glib-bindings.h.tmp +	mv test-service-glib-bindings.h.tmp test-service-glib-bindings.h + +CLEANFILES = test-service-glib-glue.h test-service-glib-glue.h.tmp test-service-glib-bindings.h test-service-glib-bindings.h.tmp  test_service_glib_LDADD= $(top_builddir)/glib/libdbus-glib-1.la diff --git a/test/glib/test-dbus-glib.c b/test/glib/test-dbus-glib.c index cee9316b..ca36af1f 100644 --- a/test/glib/test-dbus-glib.c +++ b/test/glib/test-dbus-glib.c @@ -3,6 +3,7 @@  #include <stdio.h>  #include <stdlib.h>  #include <string.h> +#include "test-service-glib-bindings.h"  static GMainLoop *loop = NULL;  static int n_times_foo_received = 0; @@ -37,7 +38,11 @@ main (int argc, char **argv)    int i;    guint32 result;    const char *v_STRING; +  char *v_STRING_2;    guint32 v_UINT32; +  guint32 v_UINT32_2; +  double v_DOUBLE; +  double v_DOUBLE_2;    g_type_init (); @@ -220,10 +225,204 @@ main (int argc, char **argv)                    n_times_foo_received);        exit (1);      } -   -  g_object_unref (G_OBJECT (driver)); + +  /* Activate test servie */  +  g_print ("Activating TestSuiteGLibService\n"); +  v_STRING = "org.freedesktop.DBus.TestSuiteGLibService"; +  v_UINT32 = 0; +  call = dbus_g_proxy_begin_call (driver, "StartServiceByName", +                                  DBUS_TYPE_STRING, +                                  &v_STRING, +                                  DBUS_TYPE_UINT32, +                                  &v_UINT32, +                                  DBUS_TYPE_INVALID); + +  error = NULL; +  if (!dbus_g_proxy_end_call (driver, call, &error, +                             DBUS_TYPE_UINT32, &result, +                             DBUS_TYPE_INVALID)) +    { +      g_printerr ("Failed to complete Activate call: %s\n", +                  error->message); +      g_error_free (error); +      exit (1); +    } +    g_object_unref (G_OBJECT (proxy)); + +  proxy = dbus_g_proxy_new_for_name_owner (connection, +                                           "org.freedesktop.DBus.TestSuiteGLibService", +                                           "/org/freedesktop/DBus/Tests/MyTestObject", +                                           "org.freedesktop.DBus.Tests.MyObject", +                                           &error); +  if (proxy == NULL) +    { +      g_printerr ("Failed to create proxy for name owner: %s\n", +                  error->message); +      g_error_free (error); +      exit (1);       +    } + +  call = dbus_g_proxy_begin_call (proxy, "DoNothing", +                                  DBUS_TYPE_INVALID); +  error = NULL; +  if (!dbus_g_proxy_end_call (proxy, call, &error, DBUS_TYPE_INVALID)) +    { +      g_printerr ("Failed to complete DoNothing call: %s\n", +                  error->message); +      g_error_free (error); +      exit (1); +    } + +  v_UINT32 = 42; +  call = dbus_g_proxy_begin_call (proxy, "Increment", +				  DBUS_TYPE_UINT32, &v_UINT32, +                                  DBUS_TYPE_INVALID); +  error = NULL; +  if (!dbus_g_proxy_end_call (proxy, call, &error, +			      DBUS_TYPE_UINT32, &v_UINT32_2, +			      DBUS_TYPE_INVALID)) +    { +      g_printerr ("Failed to complete Increment call: %s\n", +                  error->message); +      g_error_free (error); +      exit (1); +    } + +  if (v_UINT32_2 != v_UINT32 + 1) +    { +      g_printerr ("Increment call returned %d, should be 43\n", v_UINT32_2); +      exit (1); +    } + +  call = dbus_g_proxy_begin_call (proxy, "ThrowError", DBUS_TYPE_INVALID); +  error = NULL; +  if (dbus_g_proxy_end_call (proxy, call, &error, DBUS_TYPE_INVALID) != FALSE) +    { +      g_printerr ("ThrowError call unexpectedly succeeded!\n"); +      exit (1); +    } + +  g_print ("ThrowError failed (as expected) returned error: %s\n", error->message); +  g_error_free (error); + +  v_STRING = "foobar"; +  call = dbus_g_proxy_begin_call (proxy, "Uppercase", +				  DBUS_TYPE_STRING, &v_STRING, +				  DBUS_TYPE_INVALID); +  error = NULL; +  if (!dbus_g_proxy_end_call (proxy, call, &error, +			      DBUS_TYPE_STRING, &v_STRING_2, +			      DBUS_TYPE_INVALID)) +    { +      g_printerr ("Failed to complete Uppercase call: %s\n", +                  error->message); +      g_error_free (error); +      exit (1); +    } +  if (strcmp ("FOOBAR", v_STRING_2) != 0) +    { +      g_printerr ("Uppercase call returned unexpected string %s\n", v_STRING_2); +      exit (1); +    } + +  v_STRING = "bazwhee"; +  v_UINT32 = 26; +  v_DOUBLE = G_PI; +  call = dbus_g_proxy_begin_call (proxy, "ManyArgs", +				  DBUS_TYPE_UINT32, &v_UINT32, +				  DBUS_TYPE_STRING, &v_STRING, +				  DBUS_TYPE_DOUBLE, &v_DOUBLE, +				  DBUS_TYPE_INVALID); +  error = NULL; +  if (!dbus_g_proxy_end_call (proxy, call, &error, +			      DBUS_TYPE_DOUBLE, &v_DOUBLE_2, +			      DBUS_TYPE_STRING, &v_STRING_2, +			      DBUS_TYPE_INVALID)) +    { +      g_printerr ("Failed to complete ManyArgs call: %s\n", +                  error->message); +      g_error_free (error); +      exit (1); +    } +  if (v_DOUBLE_2 < 55 || v_DOUBLE_2 > 56) +    { +      g_printerr ("ManyArgs call returned unexpected double value %f\n", v_DOUBLE_2); +      exit (1); +    } +  if (strcmp ("BAZWHEE", v_STRING_2) != 0) +    { +      g_printerr ("ManyArgs call returned unexpected string %s\n", v_STRING_2); +      exit (1); +    } + +  if (!org_freedesktop_DBus_Tests_MyObject_do_nothing (proxy, &error)) +    { +      g_printerr ("Failed to complete (wrapped) DoNothing call: %s\n", +                  error->message); +      g_error_free (error); +      exit (1); +    } + +  if (!org_freedesktop_DBus_Tests_MyObject_increment (proxy, 42, &v_UINT32_2, &error)) +    { +      g_printerr ("Failed to complete (wrapped) Increment call: %s\n", +                  error->message); +      g_error_free (error); +      exit (1); +    } + +  if (v_UINT32_2 != 43) +    { +      g_printerr ("(wrapped) increment call returned %d, should be 43\n", v_UINT32_2); +      exit (1); +    } + +  if (org_freedesktop_DBus_Tests_MyObject_throw_error (proxy, &error) != FALSE) +    { +      g_printerr ("(wrapped) ThrowError call unexpectedly succeeded!\n"); +      exit (1); +    } + +  g_print ("(wrapped) ThrowError failed (as expected) returned error: %s\n", error->message); +  g_error_free (error); + +  if (!org_freedesktop_DBus_Tests_MyObject_uppercase (proxy, "foobar", &v_STRING_2, &error))  +    { +      g_printerr ("Failed to complete (wrapped) Uppercase call: %s\n", +                  error->message); +      g_error_free (error); +      exit (1); +    } +  if (strcmp ("FOOBAR", v_STRING_2) != 0) +    { +      g_printerr ("(wrapped) Uppercase call returned unexpected string %s\n", v_STRING_2); +      exit (1); +    } + +  if (!org_freedesktop_DBus_Tests_MyObject_many_args (proxy, 26, "bazwhee", G_PI, +						      &v_DOUBLE_2, &v_STRING_2, &error)) +    { +      g_printerr ("Failed to complete (wrapped) ManyArgs call: %s\n", +                  error->message); +      g_error_free (error); +      exit (1); +    } +  if (v_DOUBLE_2 < 55 || v_DOUBLE_2 > 56) +    { +      g_printerr ("(wrapped) ManyArgs call returned unexpected double value %f\n", v_DOUBLE_2); +      exit (1); +    } +  if (strcmp ("BAZWHEE", v_STRING_2) != 0) +    { +      g_printerr ("(wrapped) ManyArgs call returned unexpected string %s\n", v_STRING_2); +      exit (1); +    } + +  g_object_unref (G_OBJECT (proxy)); +  g_object_unref (G_OBJECT (driver)); +    g_print ("Successfully completed %s\n", argv[0]);    return 0; diff --git a/test/glib/test-service-glib.c b/test/glib/test-service-glib.c index 2fa3095c..81cb556f 100644 --- a/test/glib/test-service-glib.c +++ b/test/glib/test-service-glib.c @@ -4,6 +4,8 @@  #include <stdlib.h>  #include <string.h>  #include <glib/gi18n.h> +#include <glib-object.h> +#include <glib/gquark.h>  typedef struct MyObject MyObject;  typedef struct MyObjectClass MyObjectClass; @@ -30,6 +32,28 @@ struct MyObjectClass  G_DEFINE_TYPE(MyObject, my_object, G_TYPE_OBJECT) +typedef enum +{ +  MY_OBJECT_ERROR_FOO, +  MY_OBJECT_ERROR_BAR +} MyObjectError; + +#define MY_OBJECT_ERROR my_object_error_quark () + +gboolean my_object_do_nothing (MyObject *obj, GError **error); + +gboolean my_object_increment (MyObject *obj, gint32 x, int *ret, GError **error); + +gboolean my_object_throw_error (MyObject *obj, GError **error); + +gboolean my_object_uppercase (MyObject *obj, const char *str, char **ret, GError **error); + +gboolean my_object_many_args (MyObject *obj, guint32 x, const char *str, double trouble, double *d_ret, char **str_ret, GError **error); + +#include "test-service-glib-glue.h" + +GQuark my_object_error_quark (void); +  /* Properties */  enum  { @@ -115,6 +139,54 @@ my_object_class_init (MyObjectClass *mobject_class)                                                          "default value",                                                          G_PARAM_READWRITE));  } + +GQuark +my_object_error_quark (void) +{ +  static GQuark quark = 0; +  if (!quark) +    quark = g_quark_from_static_string ("my_object_error"); + +  return quark; +} + +gboolean +my_object_do_nothing (MyObject *obj, GError **error) +{ +  return TRUE; +} + +gboolean +my_object_increment (MyObject *obj, gint32 x, int *ret, GError **error) +{ +  *ret = x +1; +  return TRUE; +} + +gboolean +my_object_throw_error (MyObject *obj, GError **error) +{ +  g_set_error (error, +	       MY_OBJECT_ERROR, +	       MY_OBJECT_ERROR_FOO, +	       "this method always loses"); +  return FALSE; +} + +gboolean +my_object_uppercase (MyObject *obj, const char *str, char **ret, GError **error) +{ +  *ret = g_ascii_strup (str, -1); +  return TRUE; +} + +gboolean +my_object_many_args (MyObject *obj, guint32 x, const char *str, double trouble, double *d_ret, char **str_ret, GError **error) +{ +  *d_ret = trouble + (x * 2); +  *str_ret = g_ascii_strup (str, -1); +  return TRUE; +}  static GMainLoop *loop; @@ -148,8 +220,10 @@ main (int argc, char **argv)    obj = g_object_new (MY_TYPE_OBJECT, NULL); +  dbus_g_object_class_install_info (G_OBJECT_GET_CLASS (obj), +				    &dbus_glib_my_object_object_info);    dbus_g_connection_register_g_object (connection, -                                       "/org/freedesktop/my_test_object", +                                       "/org/freedesktop/DBus/Tests/MyTestObject",                                         obj);    driver_proxy = dbus_g_proxy_new_for_name (connection, diff --git a/test/glib/test-service-glib.xml b/test/glib/test-service-glib.xml new file mode 100644 index 00000000..223bf67f --- /dev/null +++ b/test/glib/test-service-glib.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<node name="/org/freedesktop/DBus/Tests/MyTestObject"> + +  <interface name="org.freedesktop.DBus.Tests.MyObject" c_name="my_object"> + +    <method name="DoNothing" c_name="my_object_do_nothing"> +    </method> + +    <method name="Increment" c_name="my_object_increment"> +      <arg type="uint32" name="x" /> +      <arg type="uint32" direction="out" /> +    </method> + +    <method name="ThrowError" c_name="my_object_throw_error"> +    </method> + +    <method name="Uppercase" c_name="my_object_uppercase"> +      <arg type="string" direction="in" /> +      <arg type="string" direction="out" /> +    </method> + +    <method name="ManyArgs" c_name="my_object_many_args"> +      <arg type="uint32" name="x" direction="in" /> +      <arg type="string" name="str" direction="in" /> +      <arg type="double" name="trouble" direction="in" /> +      <arg type="double" name="d_ret" direction="out" /> +      <arg type="string" name="str_ret" direction="out" /> +    </method> + +  </interface> + +</node>  | 
