diff options
| -rw-r--r-- | ChangeLog | 52 | ||||
| -rw-r--r-- | glib/dbus-gtest.c | 4 | ||||
| -rw-r--r-- | glib/dbus-gtest.h | 1 | ||||
| -rw-r--r-- | glib/dbus-gtype-specialized.c | 13 | ||||
| -rw-r--r-- | glib/dbus-gtype-specialized.h | 15 | ||||
| -rw-r--r-- | glib/dbus-gvalue-utils.c | 116 | ||||
| -rw-r--r-- | glib/dbus-gvalue.c | 402 | ||||
| -rw-r--r-- | glib/examples/statemachine/statemachine-client.c | 192 | ||||
| -rw-r--r-- | glib/examples/statemachine/statemachine-server.c | 27 | ||||
| -rw-r--r-- | glib/examples/statemachine/statemachine.c | 44 | ||||
| -rw-r--r-- | test/glib/test-dbus-glib.c | 60 | ||||
| -rw-r--r-- | test/glib/test-service-glib.c | 34 | ||||
| -rw-r--r-- | test/glib/test-service-glib.xml | 5 | 
13 files changed, 706 insertions, 259 deletions
| @@ -1,3 +1,55 @@ +2005-07-08  Colin Walters  <walters@verbum.org> + +	* test/glib/test-service-glib.xml:  +	* test/glib/test-service-glib.c: +	* test/glib/test-dbus-glib.c: Test a{sv}. + +	* glib/examples/statemachine/statemachine.c: +	* glib/examples/statemachine/statemachine-server.c: +	* glib/examples/statemachine/statemachine-client.c: Fix some bugs, +	add progress bar, etc. + +	* glib/dbus-gvalue.c (register_array, register_dict): Delete; not +	needed anymore due to generic array/map marshalling. +	(dbus_g_value_types_init): Don't register basic arrays or the +	string/string hash. +	(dbus_gtype_from_signature_iter): Don't try to recurse into +	variants. +	(dbus_gtype_to_signature): Check collection/map before type +	metadata. +	(demarshal_garray_basic): Renamed to demarshal_collection_array. +	(demarshal_ghashtable): Renamed to demarshal_map; fix to use new +	generic map creation/append functions instead of hash table +	specifically. +	(get_type_demarshaller): Handle maps. +	(demarshal_collection): Dispatch on collection type to either +	demarshal_collection_ptrarray or demarshal_collection_array. +	(get_type_marshaller): Handle maps. +	(marshal_collection): Dispatch collection type to either +	marshal_collection_ptrarray or marshal_collection_array. +	(_dbus_gvalue_test): New test. + +	* glib/dbus-gvalue-utils.c (unset_and_free_g_value): New function. +	(hash_free_from_gtype): Use it to free GValues. +	(hashtable_append): New function. +	(ptrarray_append): Fix prototype. +	(slist_append): Ditto. +	(_dbus_gvalue_utils_test): Extend tests. + +	* glib/dbus-gtype-specialized.c +	(dbus_g_type_specialized_init_append): Renamed from +	dbus_g_type_specialized_collection_init_append.  Remove const from +	value, since we steal it. +	(dbus_g_type_specialized_map_append): New function. + +	* glib/dbus-gtype-specialized.h: Update prototypes. +	Add DBusGTypeSpecializedMapAppendFunc. + +	* glib/dbus-gtest.c (dbus_glib_internal_do_not_use_run_tests): Run +	_dbus_gvalue_test. +	 +	* glib/dbus-gtest.h: Prototype it. +  2005-07-08  Ross Burton  <ross@openedhand.com>  	* dbus/dbus-glib.h: diff --git a/glib/dbus-gtest.c b/glib/dbus-gtest.c index 2b79feb4..e5c2e8b9 100644 --- a/glib/dbus-gtest.c +++ b/glib/dbus-gtest.c @@ -63,6 +63,10 @@ dbus_glib_internal_do_not_use_run_tests (const char *test_data_dir)    if (!_dbus_gvalue_utils_test (test_data_dir))      die ("gvalue utils"); +  printf ("%s: running GValue tests\n", "dbus-glib-test"); +  if (!_dbus_gvalue_test (test_data_dir)) +    die ("gvalue utils"); +    printf ("%s: running glib tests\n", "dbus-glib-test");    if (!_dbus_glib_test (test_data_dir))      die ("glib"); diff --git a/glib/dbus-gtest.h b/glib/dbus-gtest.h index 73bf0dda..75633ea7 100644 --- a/glib/dbus-gtest.h +++ b/glib/dbus-gtest.h @@ -30,6 +30,7 @@ gboolean _dbus_gmain_test   (const char *test_data_dir);  gboolean _dbus_gobject_test (const char *test_data_dir);  gboolean _dbus_gutils_test  (const char *test_data_dir);  gboolean _dbus_glib_test    (const char *test_data_dir); +gboolean _dbus_gvalue_test  (const char *test_data_dir);  gboolean _dbus_gvalue_utils_test    (const char *test_data_dir);  void dbus_glib_internal_do_not_use_run_tests (const char *test_data_dir); diff --git a/glib/dbus-gtype-specialized.c b/glib/dbus-gtype-specialized.c index d588fa86..ccf65eef 100644 --- a/glib/dbus-gtype-specialized.c +++ b/glib/dbus-gtype-specialized.c @@ -427,7 +427,7 @@ typedef struct {  } DBusGTypeSpecializedAppendContextReal;  void -dbus_g_type_specialized_collection_init_append (GValue *value, DBusGTypeSpecializedAppendContext *ctx) +dbus_g_type_specialized_init_append (GValue *value, DBusGTypeSpecializedAppendContext *ctx)  {    DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;    GType gtype; @@ -446,7 +446,7 @@ dbus_g_type_specialized_collection_init_append (GValue *value, DBusGTypeSpeciali  void  dbus_g_type_specialized_collection_append (DBusGTypeSpecializedAppendContext *ctx, -					   const GValue *elt) +					   GValue                            *elt)  {    DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;    ((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->append_func (ctx, elt); @@ -461,6 +461,15 @@ dbus_g_type_specialized_collection_end_append (DBusGTypeSpecializedAppendContext  }  void +dbus_g_type_specialized_map_append (DBusGTypeSpecializedAppendContext *ctx, +				    GValue                            *key, +				    GValue                            *val) +{ +  DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx; +  ((DBusGTypeSpecializedMapVtable *) realctx->specdata->klass->vtable)->append_func (ctx, key, val); +} + +void  dbus_g_type_map_value_iterate (const GValue                           *value,  			       DBusGTypeSpecializedMapIterator         iterator,  			       gpointer                                user_data) diff --git a/glib/dbus-gtype-specialized.h b/glib/dbus-gtype-specialized.h index 8e47db98..e95af3e5 100644 --- a/glib/dbus-gtype-specialized.h +++ b/glib/dbus-gtype-specialized.h @@ -58,12 +58,17 @@ typedef struct {    gpointer d;  } DBusGTypeSpecializedAppendContext; -void           dbus_g_type_specialized_collection_init_append  (GValue *val, DBusGTypeSpecializedAppendContext *ctx); +void           dbus_g_type_specialized_init_append             (GValue *val, DBusGTypeSpecializedAppendContext *ctx); -void           dbus_g_type_specialized_collection_append       (DBusGTypeSpecializedAppendContext *ctx, const GValue *elt); +void           dbus_g_type_specialized_collection_append       (DBusGTypeSpecializedAppendContext *ctx, GValue *elt);  void           dbus_g_type_specialized_collection_end_append   (DBusGTypeSpecializedAppendContext *ctx); +void           dbus_g_type_specialized_map_append              (DBusGTypeSpecializedAppendContext *ctx, +								GValue                            *key, +								GValue                            *val); +								 +  gboolean       dbus_g_type_collection_get_fixed             (GValue                                 *value,  							     gpointer                               *data,  							     guint                                  *len); @@ -90,8 +95,8 @@ typedef struct {  } DBusGTypeSpecializedVtable;  typedef gboolean (*DBusGTypeSpecializedCollectionFixedAccessorFunc) (GType type, gpointer instance, gpointer *values, guint *len); -typedef void (*DBusGTypeSpecializedCollectionIteratorFunc)          (GType type, gpointer instance, DBusGTypeSpecializedCollectionIterator iterator, gpointer user_data); -typedef void     (*DBusGTypeSpecializedCollectionAppendFunc)        (DBusGTypeSpecializedAppendContext *ctx, const GValue *val); +typedef void     (*DBusGTypeSpecializedCollectionIteratorFunc)      (GType type, gpointer instance, DBusGTypeSpecializedCollectionIterator iterator, gpointer user_data); +typedef void     (*DBusGTypeSpecializedCollectionAppendFunc)        (DBusGTypeSpecializedAppendContext *ctx, GValue *val);  typedef void     (*DBusGTypeSpecializedCollectionEndAppendFunc)     (DBusGTypeSpecializedAppendContext *ctx);  typedef struct { @@ -103,10 +108,12 @@ typedef struct {  } DBusGTypeSpecializedCollectionVtable;  typedef void (*DBusGTypeSpecializedMapIteratorFunc) (GType type, gpointer instance, DBusGTypeSpecializedMapIterator iterator, gpointer user_data); +typedef void (*DBusGTypeSpecializedMapAppendFunc)   (DBusGTypeSpecializedAppendContext *ctx, GValue *key, GValue *val);  typedef struct {    DBusGTypeSpecializedVtable                        base_vtable;    DBusGTypeSpecializedMapIteratorFunc               iterator; +  DBusGTypeSpecializedMapAppendFunc                 append_func;  } DBusGTypeSpecializedMapVtable;  void           dbus_g_type_specialized_init           (void); diff --git a/glib/dbus-gvalue-utils.c b/glib/dbus-gvalue-utils.c index b281f6ee..b17eee16 100644 --- a/glib/dbus-gvalue-utils.c +++ b/glib/dbus-gvalue-utils.c @@ -226,6 +226,15 @@ hash_func_from_gtype (GType gtype, GHashFunc *func)      }  } +static void +unset_and_free_g_value (gpointer val) +{ +  GValue *value = val; + +  g_value_unset (value); +  g_free (value); +} +  static gboolean  hash_free_from_gtype (GType gtype, GDestroyNotify *func)  { @@ -244,7 +253,7 @@ hash_free_from_gtype (GType gtype, GDestroyNotify *func)      default:        if (gtype == G_TYPE_VALUE)  	{ -	  *func = (GDestroyNotify) g_value_unset; +	  *func = unset_and_free_g_value;  	  return TRUE;  	}        return FALSE; @@ -441,6 +450,17 @@ dbus_g_hash_table_insert_steal_values (GHashTable *table,    g_hash_table_insert (table, key, val);  } +static void +hashtable_append (DBusGTypeSpecializedAppendContext *ctx, +		  GValue                            *key, +		  GValue                            *val) +{ +  GHashTable *table; + +  table = g_value_get_boxed (ctx->val); +  dbus_g_hash_table_insert_steal_values (table, key, val); +} +  static gpointer  hashtable_constructor (GType type)  { @@ -667,7 +687,7 @@ ptrarray_copy (GType type, gpointer src)  }  static void -ptrarray_append (DBusGTypeSpecializedAppendContext *ctx, const GValue *value) +ptrarray_append (DBusGTypeSpecializedAppendContext *ctx, GValue *value)  {    GPtrArray *array; @@ -740,7 +760,7 @@ slist_copy (GType type, gpointer src)  }  static void -slist_append (DBusGTypeSpecializedAppendContext *ctx, const GValue *value) +slist_append (DBusGTypeSpecializedAppendContext *ctx, GValue *value)  {    GSList *list; @@ -822,7 +842,8 @@ dbus_g_type_specialized_builtins_init (void)        NULL,        NULL      }, -    hashtable_iterator +    hashtable_iterator, +    hashtable_append    };    dbus_g_type_register_map ("GHashTable", &hashtable_vtable, 0); @@ -860,6 +881,35 @@ test_specialized_hash (const GValue *key, const GValue *val, gpointer user_data)      }  } +static void +test_specialized_hash_2 (const GValue *key, const GValue *val, gpointer user_data) +{ +  TestSpecializedHashData *data = user_data; +  const GValue *realval; + +  g_assert (G_VALUE_HOLDS_STRING (key)); +  g_assert (G_VALUE_TYPE (val) == G_TYPE_VALUE); + +  realval = g_value_get_boxed (val); + +  if (!strcmp (g_value_get_string (key), "foo")) +    { +      data->seen_foo = TRUE; +      g_assert (G_VALUE_HOLDS_UINT (realval)); +      g_assert (g_value_get_uint (realval) == 20); +    } +  else if (!strcmp (g_value_get_string (key), "baz")) +    { +      data->seen_baz = TRUE; +      g_assert (G_VALUE_HOLDS_STRING (realval)); +      g_assert (!strcmp ("bar", g_value_get_string (realval))); +    } +  else +    { +      g_assert_not_reached (); +    } +} +  gboolean  _dbus_gvalue_utils_test (const char *datadir)  { @@ -911,6 +961,62 @@ _dbus_gvalue_utils_test (const char *datadir)      g_value_unset (&val);    } +  type = dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE); +  g_assert (dbus_g_type_is_map (type)); +  g_assert (dbus_g_type_get_map_key_specialization (type) == G_TYPE_STRING); +  g_assert (dbus_g_type_get_map_value_specialization (type) == G_TYPE_VALUE); +  { +    GHashTable *instance; +    GValue val = { 0, }; +    TestSpecializedHashData hashdata; +    DBusGTypeSpecializedAppendContext ctx; +    GValue *eltval; + +    instance = dbus_g_type_specialized_construct (type); +    g_value_init (&val, type); +    g_value_set_boxed_take_ownership (&val, instance); + +    dbus_g_type_specialized_init_append (&val, &ctx); + +    { +      GValue keyval = { 0, }; +      GValue valval = { 0, }; +      g_value_init (&keyval, G_TYPE_STRING); +      g_value_set_string (&keyval, "foo");  + +      g_value_init (&valval, G_TYPE_VALUE); +      eltval = g_new0 (GValue, 1); +      g_value_init (eltval, G_TYPE_UINT); +      g_value_set_uint (eltval, 20); +      g_value_set_boxed_take_ownership (&valval, eltval); +      dbus_g_type_specialized_map_append (&ctx, &keyval, &valval); +    } + +    { +      GValue keyval = { 0, }; +      GValue valval = { 0, }; +      g_value_init (&keyval, G_TYPE_STRING); +      g_value_set_string (&keyval, "baz");  +      g_value_init (&valval, G_TYPE_VALUE); +      eltval = g_new0 (GValue, 1); +      g_value_init (eltval, G_TYPE_STRING); +      g_value_set_string (eltval, "bar"); +      g_value_set_boxed_take_ownership (&valval, eltval); +      dbus_g_type_specialized_map_append (&ctx, &keyval, &valval); +    } + +    hashdata.seen_foo = FALSE; +    hashdata.seen_baz = FALSE; +    dbus_g_type_map_value_iterate (&val, +				   test_specialized_hash_2,  +				   &hashdata); +     +    g_assert (hashdata.seen_foo); +    g_assert (hashdata.seen_baz); + +    g_value_unset (&val); +  } +    type = dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING);    g_assert (dbus_g_type_is_collection (type));    g_assert (dbus_g_type_get_collection_specialization (type) == G_TYPE_STRING); @@ -927,7 +1033,7 @@ _dbus_gvalue_utils_test (const char *datadir)      g_value_init (&val, type);      g_value_set_boxed_take_ownership (&val, instance); -    dbus_g_type_specialized_collection_init_append (&val, &ctx); +    dbus_g_type_specialized_init_append (&val, &ctx);      g_value_init (&eltval, G_TYPE_STRING);      g_value_set_static_string (&eltval, "foo"); diff --git a/glib/dbus-gvalue.c b/glib/dbus-gvalue.c index 4e7495c7..88397731 100644 --- a/glib/dbus-gvalue.c +++ b/glib/dbus-gvalue.c @@ -22,6 +22,8 @@   *   */ +#include "config.h" +#include "dbus-gtest.h"  #include "dbus-gvalue.h"  #include "dbus-gobject.h"  #include "dbus-gvalue-utils.h" @@ -76,12 +78,6 @@ static gboolean demarshal_variant               (DBusGValueMarshalCtx      *cont  						 DBusMessageIter           *iter,  						 GValue                    *value,  						 GError                   **error); -static gboolean marshal_garray_basic            (DBusMessageIter           *iter, -						 const GValue              *value); -static gboolean demarshal_garray_basic          (DBusGValueMarshalCtx      *context, -						 DBusMessageIter           *iter, -						 GValue                    *value, -						 GError                   **error);  static gboolean marshal_proxy                   (DBusMessageIter           *iter,  						 const GValue             *value);  static gboolean demarshal_proxy                 (DBusGValueMarshalCtx      *context, @@ -102,17 +98,29 @@ static gboolean demarshal_object                (DBusGValueMarshalCtx      *cont  						 GError                   **error);  static gboolean marshal_map                     (DBusMessageIter           *iter,  						 const GValue              *value); -static gboolean demarshal_ghashtable            (DBusGValueMarshalCtx      *context, +static gboolean demarshal_map                   (DBusGValueMarshalCtx      *context,  						 DBusMessageIter           *iter,  						 GValue                    *value,  						 GError                   **error);  static gboolean marshal_collection              (DBusMessageIter           *iter,  						 const GValue              *value); +static gboolean marshal_collection_ptrarray     (DBusMessageIter           *iter, +						 const GValue              *value); +static gboolean marshal_collection_array        (DBusMessageIter           *iter, +						 const GValue              *value);  static gboolean demarshal_collection            (DBusGValueMarshalCtx      *context,  						 DBusMessageIter           *iter,  						 GValue                    *value,  						 GError                   **error); +static gboolean demarshal_collection_ptrarray   (DBusGValueMarshalCtx      *context, +						 DBusMessageIter           *iter, +						 GValue                    *value, +						 GError                   **error); +static gboolean demarshal_collection_array      (DBusGValueMarshalCtx      *context, +						 DBusMessageIter           *iter, +						 GValue                    *value, +						 GError                   **error);  static gboolean marshal_recurse                 (DBusMessageIter           *iter,  						 const GValue              *value); @@ -198,30 +206,6 @@ register_basic (int typecode, const DBusGTypeMarshalData *typedata)    set_type_metadata (basic_typecode_to_gtype (typecode), typedata);  } -static void -register_array (int typecode, const DBusGTypeMarshalData *typedata) -{ -  GType elt_gtype; -  GType gtype; - -  elt_gtype = basic_typecode_to_gtype (typecode);  -  gtype = dbus_g_type_get_collection ("GArray", elt_gtype); -  set_type_metadata (gtype, typedata);  -} - -static void -register_dict (int key_type, int value_type, const DBusGTypeMarshalData *typedata) -{ -  GType key_gtype; -  GType value_gtype; -  GType gtype; - -  key_gtype = basic_typecode_to_gtype (key_type);  -  value_gtype = basic_typecode_to_gtype (value_type);  -  gtype = dbus_g_type_get_map ("GHashTable", key_gtype, value_gtype); -  set_type_metadata (gtype, typedata);  -} -  void  dbus_g_value_types_init (void)  { @@ -240,14 +224,6 @@ dbus_g_value_types_init (void)      marshal_basic,      demarshal_basic    }; -  static const DBusGTypeMarshalVtable garray_basic_vtable = { -    marshal_garray_basic, -    demarshal_garray_basic -  }; -  static const DBusGTypeMarshalVtable ghashtable_vtable = { -    marshal_map, -    demarshal_ghashtable -  };    /* Register basic types */    { @@ -374,56 +350,8 @@ dbus_g_value_types_init (void)      set_type_metadata (G_TYPE_STRV, &typedata);    }; -  {  -    static const DBusGTypeMarshalData typedata = { -      DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BOOLEAN_AS_STRING, -      &garray_basic_vtable -    }; -    register_array (DBUS_TYPE_BOOLEAN, &typedata); -  } -  {  -    static const DBusGTypeMarshalData typedata = { -      DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING, -      &garray_basic_vtable -    }; -    register_array (DBUS_TYPE_BYTE, &typedata); -  } -  {  -    static const DBusGTypeMarshalData typedata = { -      DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT32_AS_STRING, -      &garray_basic_vtable -    }; -    register_array (DBUS_TYPE_UINT32, &typedata); -  } -  {  -    static const DBusGTypeMarshalData typedata = { -      DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING, -      &garray_basic_vtable -    }; -    register_array (DBUS_TYPE_INT32, &typedata); -  } -  {  -    static const DBusGTypeMarshalData typedata = { -      DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT64_AS_STRING, -      &garray_basic_vtable -    }; -    register_array (DBUS_TYPE_UINT64, &typedata); -  } -  {  -    static const DBusGTypeMarshalData typedata = { -      DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT64_AS_STRING, -      &garray_basic_vtable -    }; -    register_array (DBUS_TYPE_INT64, &typedata); -  } -  {  -    static const DBusGTypeMarshalData typedata = { -      DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, -      &ghashtable_vtable, -    }; -    register_dict (DBUS_TYPE_STRING, DBUS_TYPE_STRING, &typedata); -  } +  /* Register some types specific to the D-BUS GLib bindings */    {      static const DBusGTypeMarshalVtable vtable = {        marshal_proxy, @@ -535,6 +463,7 @@ dbus_g_value_iterator_get_values (DBusGValueIterator *iter,        context.gconnection = (iterval->value.recurse.toplevel)->value.toplevel.connection;        context.proxy = (iterval->value.recurse.toplevel)->value.toplevel.proxy; +        if (!dbus_gvalue_demarshal (&context,  				  &(iterval->value.recurse.iterator),  				  value, @@ -661,6 +590,10 @@ dbus_gtype_from_signature_iter (DBusSignatureIter *iter, gboolean is_client)        DBusSignatureIter subiter;        g_assert (dbus_type_is_container (current_type)); + +      if (current_type == DBUS_TYPE_VARIANT) +	return g_value_get_type (); +              dbus_signature_iter_recurse (iter, &subiter);        if (current_type == DBUS_TYPE_ARRAY) @@ -673,8 +606,6 @@ dbus_gtype_from_signature_iter (DBusSignatureIter *iter, gboolean is_client)  	}        else if (current_type == DBUS_TYPE_STRUCT)  	return signature_iter_to_g_type_struct (&subiter, is_client); -      else if (current_type == DBUS_TYPE_VARIANT) -	return g_value_get_type ();        else if (current_type == DBUS_TYPE_DICT_ENTRY)  	return G_TYPE_INVALID;        else @@ -721,10 +652,6 @@ dbus_gtype_to_signature (GType gtype)    char *ret;    DBusGTypeMarshalData *typedata; -  typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ()); -  if (typedata == NULL) -    return NULL; -    if (dbus_g_type_is_collection (gtype))      {        GType elt_gtype; @@ -751,7 +678,12 @@ dbus_gtype_to_signature (GType gtype)        g_free (val_subsig);      }    else -    ret = g_strdup (typedata->sig); +    { +      typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ()); +      if (typedata == NULL) +	return NULL; +      ret = g_strdup (typedata->sig); +    }    return ret;  } @@ -1066,53 +998,18 @@ demarshal_strv (DBusGValueMarshalCtx    *context,  }  static gboolean -demarshal_garray_basic (DBusGValueMarshalCtx    *context, -			DBusMessageIter         *iter, -			GValue                  *value, -			GError                 **error) -{ -  DBusMessageIter subiter; -  GArray *ret; -  GType elt_gtype; -  int elt_size; -  void *msgarray; -  int msgarray_len; - -  dbus_message_iter_recurse (iter, &subiter); - -  elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value)); -  g_assert (elt_gtype != G_TYPE_INVALID); -  g_assert (dbus_g_type_is_fixed (elt_gtype)); - -  elt_size = dbus_g_type_fixed_get_size (elt_gtype); -   -  ret = g_array_new (FALSE, TRUE, elt_size); - -  msgarray = NULL; -  dbus_message_iter_get_fixed_array (&subiter, -				     &msgarray, -				     &msgarray_len); -  g_assert (msgarray != NULL); -  g_assert (msgarray_len >= 0); -  g_array_append_vals (ret, msgarray, (guint) msgarray_len); - -  g_value_set_boxed_take_ownership (value, ret); -   -  return TRUE; -} - -static gboolean -demarshal_ghashtable (DBusGValueMarshalCtx    *context, -		      DBusMessageIter         *iter, -		      GValue                  *value, -		      GError                 **error) +demarshal_map (DBusGValueMarshalCtx    *context, +	       DBusMessageIter         *iter, +	       GValue                  *value, +	       GError                 **error)  {    GType gtype;    DBusMessageIter subiter;    int current_type; -  GHashTable *ret; +  gpointer ret;    GType key_gtype;    GType value_gtype; +  DBusGTypeSpecializedAppendContext appendctx;    current_type = dbus_message_iter_get_arg_type (iter);    if (current_type != DBUS_TYPE_ARRAY) @@ -1140,14 +1037,12 @@ demarshal_ghashtable (DBusGValueMarshalCtx    *context,      }    key_gtype = dbus_g_type_get_map_key_specialization (gtype); -  g_assert (dbus_gtype_is_valid_hash_key (key_gtype));    value_gtype = dbus_g_type_get_map_value_specialization (gtype); -  g_assert (dbus_gtype_is_valid_hash_value (value_gtype)); -  ret = g_hash_table_new_full (dbus_g_hash_func_from_gtype (key_gtype), -			       dbus_g_hash_equal_from_gtype (key_gtype), -			       dbus_g_hash_free_from_gtype (key_gtype), -			       dbus_g_hash_free_from_gtype (value_gtype)); +  ret = dbus_g_type_specialized_construct (gtype); +  g_value_set_boxed_take_ownership (value, ret); + +  dbus_g_type_specialized_init_append (value, &appendctx);    while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)      { @@ -1176,14 +1071,11 @@ demarshal_ghashtable (DBusGValueMarshalCtx    *context,  				  error))  	return FALSE; -      dbus_g_hash_table_insert_steal_values (ret, -					     &key_value, -					     &value_value); -      /* Ownership of values passes to hash table, don't unset */ +      dbus_g_type_specialized_map_append (&appendctx, &key_value, &value_value); +      /* Ownership of values passes to map, don't unset */        dbus_message_iter_next (&subiter);      } -  g_value_set_boxed_take_ownership (value, ret);    return TRUE;  } @@ -1200,6 +1092,8 @@ get_type_demarshaller (GType type)  	return demarshal_recurse;        if (dbus_g_type_is_collection (type))  	return demarshal_collection; +      if (dbus_g_type_is_map (type)) +	return demarshal_map;        g_warning ("No demarshaller registered for type \"%s\"", g_type_name (type));        return NULL; @@ -1216,6 +1110,24 @@ demarshal_collection (DBusGValueMarshalCtx    *context,  {    GType coltype;    GType subtype; +   +  coltype = G_VALUE_TYPE (value); +  subtype = dbus_g_type_get_collection_specialization (coltype); + +  if (dbus_g_type_is_fixed (subtype)) +    return demarshal_collection_array (context, iter, value, error); +  else +    return demarshal_collection_ptrarray (context, iter, value, error); +} + +static gboolean +demarshal_collection_ptrarray (DBusGValueMarshalCtx    *context, +			       DBusMessageIter         *iter, +			       GValue                  *value, +			       GError                 **error) +{ +  GType coltype; +  GType subtype;    gpointer instance;    DBusGTypeSpecializedAppendContext ctx;    DBusGValueDemarshalFunc demarshaller; @@ -1254,7 +1166,7 @@ demarshal_collection (DBusGValueMarshalCtx    *context,    instance = dbus_g_type_specialized_construct (coltype);    g_value_set_boxed_take_ownership (value, instance); -  dbus_g_type_specialized_collection_init_append (value, &ctx); +  dbus_g_type_specialized_init_append (value, &ctx);    while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)      { @@ -1278,6 +1190,42 @@ demarshal_collection (DBusGValueMarshalCtx    *context,  }  static gboolean +demarshal_collection_array (DBusGValueMarshalCtx    *context, +			    DBusMessageIter         *iter, +			    GValue                  *value, +			    GError                 **error) +{ +  DBusMessageIter subiter; +  GArray *ret; +  GType elt_gtype; +  int elt_size; +  void *msgarray; +  int msgarray_len; + +  dbus_message_iter_recurse (iter, &subiter); + +  elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value)); +  g_assert (elt_gtype != G_TYPE_INVALID); +  g_assert (dbus_g_type_is_fixed (elt_gtype)); + +  elt_size = dbus_g_type_fixed_get_size (elt_gtype); +   +  ret = g_array_new (FALSE, TRUE, elt_size); + +  msgarray = NULL; +  dbus_message_iter_get_fixed_array (&subiter, +				     &msgarray, +				     &msgarray_len); +  g_assert (msgarray != NULL); +  g_assert (msgarray_len >= 0); +  g_array_append_vals (ret, msgarray, (guint) msgarray_len); + +  g_value_set_boxed_take_ownership (value, ret); +   +  return TRUE; +} + +static gboolean  demarshal_recurse (DBusGValueMarshalCtx    *context,  		   DBusMessageIter         *iter,  		   GValue                  *value, @@ -1545,50 +1493,6 @@ marshal_strv (DBusMessageIter   *iter,  }  static gboolean -marshal_garray_basic (DBusMessageIter   *iter, -		      const GValue      *value) -{ -  GType elt_gtype; -  DBusMessageIter subiter; -  GArray *array; -  guint elt_size; -  char *subsignature_str; - -  elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value)); -  /* FIXME - this means we can't send an array of DBusGValue right now... */ -  subsignature_str = dbus_gtype_to_signature (elt_gtype); -  g_assert (subsignature_str != NULL); -   -  elt_size = dbus_g_type_fixed_get_size (elt_gtype); - -  array = g_value_get_boxed (value); - -  if (!dbus_message_iter_open_container (iter, -					 DBUS_TYPE_ARRAY, -					 subsignature_str, -					 &subiter)) -    goto oom; - -  /* TODO - This assumes that basic values are the same size -   * is this always true?  If it is we can probably avoid -   * a lot of the overhead in _marshal_basic_instance... -   */ -  if (!dbus_message_iter_append_fixed_array (&subiter, -					     subsignature_str[0], -					     &(array->data), -					     array->len)) -    goto oom; - -  if (!dbus_message_iter_close_container (iter, &subiter)) -    goto oom; -  g_free (subsignature_str); -  return TRUE; - oom: -  g_error ("out of memory"); -  return FALSE; -} - -static gboolean  marshal_proxy (DBusMessageIter         *iter,  	       const GValue            *value)  { @@ -1791,6 +1695,8 @@ get_type_marshaller (GType type)  	return marshal_recurse;        if (dbus_g_type_is_collection (type))  	return marshal_collection; +      if (dbus_g_type_is_map (type)) +	return marshal_map;        g_warning ("No marshaller registered for type \"%s\"", g_type_name (type));        return NULL; @@ -1824,6 +1730,22 @@ marshal_collection (DBusMessageIter         *iter,  		    const GValue            *value)  {    GType coltype; +  GType subtype; +   +  coltype = G_VALUE_TYPE (value); +  subtype = dbus_g_type_get_collection_specialization (coltype); + +  if (dbus_g_type_is_fixed (subtype)) +    return marshal_collection_array (iter, value); +  else +    return marshal_collection_ptrarray (iter, value); +} + +static gboolean +marshal_collection_ptrarray (DBusMessageIter         *iter, +			     const GValue            *value) +{ +  GType coltype;    GType elt_gtype;    DBusGValueCollectionMarshalData data;    DBusMessageIter subiter; @@ -1861,6 +1783,51 @@ marshal_collection (DBusMessageIter         *iter,    return FALSE;  } + +static gboolean +marshal_collection_array (DBusMessageIter   *iter, +			  const GValue      *value) +{ +  GType elt_gtype; +  DBusMessageIter subiter; +  GArray *array; +  guint elt_size; +  char *subsignature_str; + +  elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value)); +  g_assert (dbus_g_type_is_fixed (elt_gtype)); +  subsignature_str = dbus_gtype_to_signature (elt_gtype); +  g_assert (subsignature_str != NULL); +   +  elt_size = dbus_g_type_fixed_get_size (elt_gtype); + +  array = g_value_get_boxed (value); + +  if (!dbus_message_iter_open_container (iter, +					 DBUS_TYPE_ARRAY, +					 subsignature_str, +					 &subiter)) +    goto oom; + +  /* TODO - This assumes that basic values are the same size +   * is this always true?  If it is we can probably avoid +   * a lot of the overhead in _marshal_basic_instance... +   */ +  if (!dbus_message_iter_append_fixed_array (&subiter, +					     subsignature_str[0], +					     &(array->data), +					     array->len)) +    goto oom; + +  if (!dbus_message_iter_close_container (iter, &subiter)) +    goto oom; +  g_free (subsignature_str); +  return TRUE; + oom: +  g_error ("out of memory"); +  return FALSE; +} +  static gboolean  marshal_recurse (DBusMessageIter         *iter,  		 const GValue            *value) @@ -1882,3 +1849,54 @@ dbus_gvalue_marshal (DBusMessageIter         *iter,      return FALSE;    return marshaller (iter, value);  } + +#ifdef DBUS_BUILD_TESTS + +static void +assert_type_maps_to (GType gtype, const char *expected_sig) +{ +  char *sig; +  sig = dbus_gtype_to_signature (gtype); +  g_assert (sig != NULL); +  g_assert (!strcmp (expected_sig, sig)); +  g_free (sig); +} + +static void +assert_signature_maps_to (const char *sig, GType expected_gtype) +{ +  g_assert (dbus_gtype_from_signature (sig, TRUE) == expected_gtype); +} + +static void +assert_bidirectional_mapping (GType gtype, const char *expected_sig) +{ +  assert_type_maps_to (gtype, expected_sig); +  assert_signature_maps_to (expected_sig, gtype); +} + +/** + * @ingroup DBusGLibInternals + * Unit test for general glib stuff + * @returns #TRUE on success. + */ +gboolean +_dbus_gvalue_test (const char *test_data_dir) +{ +  dbus_g_value_types_init (); +   +  assert_bidirectional_mapping (G_TYPE_STRING, DBUS_TYPE_STRING_AS_STRING); +  assert_bidirectional_mapping (G_TYPE_UCHAR, DBUS_TYPE_BYTE_AS_STRING); +  assert_bidirectional_mapping (G_TYPE_UINT, DBUS_TYPE_UINT32_AS_STRING); + +  assert_bidirectional_mapping (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), +				DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING); +  assert_bidirectional_mapping (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), +				DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING); +  assert_bidirectional_mapping (dbus_g_type_get_collection ("GArray", G_TYPE_INT), +				DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING); + +  return TRUE; +} + +#endif /* DBUS_BUILD_TESTS */ diff --git a/glib/examples/statemachine/statemachine-client.c b/glib/examples/statemachine/statemachine-client.c index 54c630ff..88b21847 100644 --- a/glib/examples/statemachine/statemachine-client.c +++ b/glib/examples/statemachine/statemachine-client.c @@ -59,8 +59,9 @@ typedef struct  {    char *name;    char *state; +  gdouble progress;    DBusGProxy *proxy; -  DBusGProxyCall *get_initial_state_call; +  DBusGProxyCall *get_progress_call;  } MachineInfo;  typedef struct @@ -91,6 +92,15 @@ proxy_to_iter (GtkTreeModel *model, DBusGProxy *proxy, GtkTreeIter *iter)  }  static void +signal_row_change (ClientState *state, GtkTreeIter *iter) +{ +  GtkTreePath *path; +  path = gtk_tree_model_get_path (state->store, iter); +  gtk_tree_model_row_changed (state->store, path, iter); +  gtk_tree_path_free (path); +} + +static void  get_machine_info_cb (DBusGProxy *proxy,  		     DBusGProxyCall *call,  		     gpointer data) @@ -115,13 +125,67 @@ get_machine_info_cb (DBusGProxy *proxy,    info->name = name;    g_free (info->state);    info->state = statename; -  { -    GtkTreePath *path; -    path = gtk_tree_model_get_path (state->store, &iter); -    gtk_tree_model_row_changed (state->store, path, &iter); -    gtk_tree_path_free (path); -  } -  info->get_initial_state_call = NULL; +  signal_row_change (state, &iter); +} + +static void +set_proxy_acquisition_progress (ClientState *state, +				DBusGProxy *proxy, +				double progress) +{ +  MachineInfo *info; +  GtkTreeIter iter; + +  if (!proxy_to_iter (state->store, proxy, &iter)) +    g_assert_not_reached (); +  gtk_tree_model_get (state->store, &iter, 0, &info, -1); + +  /* Ignore machines in unknown state */ +  if (!info->state) +    return; +   +  if (strcmp (info->state, "Acquired")) +    lose ("Got AcquisitionProgress signal in bad state %s", +	  info->state); + +  g_print ("Got acquisition progress change for %p (%s) to %f\n", proxy, info->name ? info->name : "(unknown)", progress); + +  info->progress = progress; + +  signal_row_change (state, &iter); +} + +static void +proxy_acquisition_changed_cb (DBusGProxy *proxy, +			      double progress, +			      gpointer user_data) +{ +  set_proxy_acquisition_progress (user_data, proxy, progress); +} + +static void +get_acquiring_progress_cb (DBusGProxy *proxy, +			   DBusGProxyCall *call, +			   gpointer user_data) +{ +  GError *error = NULL; +  MachineInfo *info; +  GtkTreeIter iter; +  ClientState *state = user_data; +  gdouble progress; + +  if (!proxy_to_iter (state->store, proxy, &iter)) +    g_assert_not_reached (); +  gtk_tree_model_get (state->store, &iter, 0, &info, -1); + +  g_assert (info->get_progress_call == call); + +  if (!dbus_g_proxy_end_call (proxy, call, &error, +			      G_TYPE_DOUBLE, &progress, G_TYPE_INVALID)) +    lose_gerror ("Failed to complete GetAcquiringProgress call", error); +  info->get_progress_call = NULL; + +  set_proxy_acquisition_progress (state, proxy, progress);  }  static void @@ -139,25 +203,27 @@ proxy_state_changed_cb (DBusGProxy *proxy,    g_print ("Got state change for %p (%s) to %s\n", proxy, info->name ? info->name : "(unknown)", statename); -  /* If we got a signal for the state, we shouldn't update -   * based on the (possibly stale) call -   */ -  if (info->get_initial_state_call != NULL) -    { -      g_print ("Cancelling outstanding GetInfo call for %p due to signal\n", proxy); -      dbus_g_proxy_cancel_call (proxy, info->get_initial_state_call); -      info->get_initial_state_call = NULL; -    } -    g_free (info->state);    info->state = g_strdup (statename); -  { -    GtkTreePath *path; -    path = gtk_tree_model_get_path (state->store, &iter); -    gtk_tree_model_row_changed (state->store, path, &iter); -    gtk_tree_path_free (path); -  } +  if (!strcmp (info->state, "Acquired")) +    { +      g_print ("Starting GetAcquiringProgress call for %p\n", info->proxy); +      if (info->get_progress_call != NULL) +	{ +	  dbus_g_proxy_cancel_call (info->proxy, info->get_progress_call); +	  info->get_progress_call = NULL; +	} +      info->get_progress_call =  +	dbus_g_proxy_begin_call (info->proxy, "GetAcquiringProgress", +				 get_acquiring_progress_cb, +				 state, NULL, +				 G_TYPE_INVALID); +    } +  else +    info->progress = 0.0; + +  signal_row_change (state, &iter);  }  static void @@ -172,6 +238,7 @@ add_machine (ClientState *state,    info = g_new0 (MachineInfo, 1);    info->name = g_strdup (name);    info->state = g_strdup (mstate); +  info->progress = 0.0;    info->proxy = dbus_g_proxy_new_for_name (state->bus,  					   "com.example.StateServer", @@ -181,14 +248,11 @@ add_machine (ClientState *state,    if (!info->state)      {        g_print ("Starting GetInfo call for %p\n", info->proxy); -      info->get_initial_state_call -	= dbus_g_proxy_begin_call (info->proxy, "GetInfo", -				   get_machine_info_cb, -				   state, NULL, -				   G_TYPE_INVALID); +      dbus_g_proxy_begin_call (info->proxy, "GetInfo", +			       get_machine_info_cb, +			       state, NULL, +			       G_TYPE_INVALID);      } -  else -    info->get_initial_state_call = NULL;    /* Watch for state changes */    dbus_g_proxy_add_signal (info->proxy, "StateChanged", @@ -200,6 +264,15 @@ add_machine (ClientState *state,  			       state,  			       NULL); +  dbus_g_proxy_add_signal (info->proxy, "AcquisitionProgress", +			   G_TYPE_DOUBLE, G_TYPE_INVALID); +   +  dbus_g_proxy_connect_signal (info->proxy, +			       "AcquisitionProgress",  +			       G_CALLBACK (proxy_acquisition_changed_cb), +			       state, +			       NULL); +    gtk_list_store_prepend (GTK_LIST_STORE (state->store), &iter);    gtk_list_store_set (GTK_LIST_STORE (state->store), &iter, 0, info, -1); @@ -306,6 +379,12 @@ do_a_state_change (ClientState *state)        g_print ("Sending Start request to machine %s\n", info->name);        dbus_g_proxy_call_no_reply (info->proxy, "Start", G_TYPE_INVALID);      } +  else if (!strcmp (info->state, "Loading")) +    { +       +      g_print ("Sending Reacquire request to machine %s\n", info->name); +      dbus_g_proxy_call_no_reply (info->proxy, "Reacquire", G_TYPE_INVALID); +    }    else      {        g_print ("Sending Shutdown request to machine %s\n", info->name); @@ -318,7 +397,7 @@ do_something_random_2 (gpointer data)  {    ClientState *state = data;    do_a_state_change (state); -  g_timeout_add (g_random_int_range (500, 3000), do_something_random_2, state); +  g_timeout_add (g_random_int_range (2000, 5000), do_something_random_2, state);    return FALSE;  } @@ -328,12 +407,13 @@ do_something_random (gpointer data)    ClientState *state = data;    gint n_children; -  switch (g_random_int_range (0, 2)) +  switch (g_random_int_range (0, 3))      {      case 0:        send_create_machine (state);        break;      case 1: +    case 2:        do_a_state_change (state);        break;      default: @@ -341,8 +421,11 @@ do_something_random (gpointer data)      }    n_children = gtk_tree_model_iter_n_children (state->store, NULL); -  if (n_children >= 8) -    g_timeout_add (g_random_int_range (500, 3000), do_something_random_2, state); +  if (n_children >= 5) +    { +      g_print ("MAX children reached, switching to state changes only\n"); +      g_timeout_add (g_random_int_range (500, 3000), do_something_random_2, state); +    }    else      g_timeout_add (g_random_int_range (500, 3000), do_something_random, state);    return FALSE; @@ -406,6 +489,34 @@ sort_by_state (GtkTreeModel *model,  		 info_b ? info_b->state : "");  } +static void  +set_cell_progress (GtkTreeViewColumn *tree_column, +		   GtkCellRenderer   *cell, +		   GtkTreeModel      *tree_model, +		   GtkTreeIter       *iter, +		   gpointer           data) +{ +  MachineInfo *info; +   +  gtk_tree_model_get (tree_model, iter, 0, &info, -1); +   +  g_object_set (cell, "value", (int) (info->progress * 100), NULL); +} + +static gint +sort_by_progress (GtkTreeModel *model, +		  GtkTreeIter  *a, +		  GtkTreeIter  *b, +		  gpointer      user_data) +{ +  MachineInfo *info_a, *info_b; + +  gtk_tree_model_get (model, a, 0, &info_a, -1); +  gtk_tree_model_get (model, b, 0, &info_b, -1); + +  return info_a->progress > info_b->progress ? 1 : -1; +} +  static void  get_machines_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer data)  { @@ -458,6 +569,17 @@ get_machines_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer data)  				   0, sort_by_state, NULL, NULL);    gtk_tree_view_column_set_sort_column_id (col, 0);    gtk_tree_view_append_column (GTK_TREE_VIEW (state->view), col); + +  rend = gtk_cell_renderer_progress_new (); +  col = gtk_tree_view_column_new_with_attributes (_("Progress"),  +						  rend,  +						  NULL); +  gtk_tree_view_column_set_cell_data_func (col, rend, set_cell_progress, NULL, NULL); +  gtk_tree_view_column_set_resizable (col, TRUE); +  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (state->store),  +				   0, sort_by_progress, NULL, NULL); +  gtk_tree_view_column_set_sort_column_id (col, 0); +  gtk_tree_view_append_column (GTK_TREE_VIEW (state->view), col);    for (i = 0; i < objs->len; i++)      { diff --git a/glib/examples/statemachine/statemachine-server.c b/glib/examples/statemachine/statemachine-server.c index 7cadf1fe..2cbf39fe 100644 --- a/glib/examples/statemachine/statemachine-server.c +++ b/glib/examples/statemachine/statemachine-server.c @@ -104,6 +104,26 @@ sm_server_get_property (GObject *object,      }  } +static void +machine_state_changed_cb (SMObject *obj, const char *state, gpointer data) +{ +  char *name; + +  g_object_get (obj, "name", &name, NULL); +  g_print ("Machine %s switching to state %s\n", name, state); +  g_free (name); +} + +static void +machine_acquisition_changed_cb (SMObject *obj, gdouble progress, gpointer data) +{ +  char *name; + +  g_object_get (obj, "name", &name, NULL); +  g_print ("Machine %s got progress %f\n", name, progress); +  g_free (name); +} +  gboolean  sm_server_create_machine (SMServer *server, const char *name, GError **error)  { @@ -130,6 +150,13 @@ sm_server_create_machine (SMServer *server, const char *name, GError **error)    g_print ("Created state machine with name %s at %s\n", name, path); +  g_signal_connect_object (machine, "state-changed", +			   G_CALLBACK (machine_state_changed_cb), +			   NULL, 0); +  g_signal_connect_object (machine, "acquisition-progress", +			   G_CALLBACK (machine_acquisition_changed_cb), +			   NULL, 0); +    g_signal_emit (server, sm_server_signals[MACHINE_CREATED], 0, name, path);    return TRUE; diff --git a/glib/examples/statemachine/statemachine.c b/glib/examples/statemachine/statemachine.c index 2bde0058..c94e2945 100644 --- a/glib/examples/statemachine/statemachine.c +++ b/glib/examples/statemachine/statemachine.c @@ -103,8 +103,8 @@ sm_object_state_get_type (void)  	  ENUM_ENTRY (SM_OBJECT_STATE_SHUTDOWN, "Shutdown"),  	  ENUM_ENTRY (SM_OBJECT_STATE_INITIALIZED, "Loading"), -	  ENUM_ENTRY (SM_OBJECT_STATE_ACQUIRED, "Resource acquired"), -	  ENUM_ENTRY (SM_OBJECT_STATE_OPERATING, "Operating normally"), +	  ENUM_ENTRY (SM_OBJECT_STATE_ACQUIRED, "Acquired"), +	  ENUM_ENTRY (SM_OBJECT_STATE_OPERATING, "Operating"),  	  { 0, 0, 0 }  	}; @@ -175,6 +175,21 @@ sm_object_get_property (GObject *object,      }  } +static const char * +state_to_string (SMObjectState state) +{ +  GEnumValue *value; +  GEnumClass *prop_class; +  const char *ret; +   +  prop_class = g_type_class_ref (SM_TYPE_OBJECT_STATE); +  value = g_enum_get_value (prop_class, state); +  ret = value->value_nick; + +  g_type_class_unref (prop_class); +  return ret; +} +  static void  queue_task (SMObject *object, guint delay, GSourceFunc func)  { @@ -188,6 +203,8 @@ idle_state_change (gpointer data)  {    SMObject *object = data; +  g_print ("doing idle state change for %s to %s\n", +	   object->name, state_to_string (object->requested_state));    state_change (object, object->requested_state);    return FALSE;  } @@ -197,7 +214,8 @@ idle_further_acquire (gpointer data)  {    SMObject *object = data; -  object->acquisition_progress += g_random_double_range (0.05, 0.5); +  g_print ("doing idle acquisition for machine %s\n", object->name); +  object->acquisition_progress += g_random_double_range (0.20, 0.7);    if (object->acquisition_progress > 1.0)      {        object->acquisition_progress = 1.0; @@ -220,26 +238,10 @@ clear_pending_tasks (SMObject *object)    object->pending_tasks = NULL;  } -static const char * -state_to_string (SMObjectState state) -{ -  GEnumValue *value; -  GEnumClass *prop_class; -  const char *ret; -   -  prop_class = g_type_class_ref (SM_TYPE_OBJECT_STATE); -  value = g_enum_get_value (prop_class, state); -  ret = value->value_nick; - -  g_type_class_unref (prop_class); -  return ret; -} -  static void  state_change (SMObject *object, SMObjectState new_state)  {    g_signal_emit (object, sm_object_signals[STATE_CHANGED], 0, -		 state_to_string (object->state),  		 state_to_string (new_state));    clear_pending_tasks (object); @@ -288,7 +290,7 @@ sm_object_start (SMObject *object, GError **error)  gboolean  sm_object_shutdown (SMObject *object, GError **error)  { -  if (object->state != SM_OBJECT_STATE_INITIALIZED) +  if (object->state == SM_OBJECT_STATE_SHUTDOWN)      {        g_set_error (error,  		   SM_ERROR, @@ -321,7 +323,7 @@ sm_object_reinitialize (SMObject *object, GError **error)  gboolean  sm_object_reacquire (SMObject *object, GError **error)  { -  if (object->state != SM_OBJECT_STATE_ACQUIRED) +  if (object->state == SM_OBJECT_STATE_ACQUIRED)      {        g_set_error (error,  		   SM_ERROR, diff --git a/test/glib/test-dbus-glib.c b/test/glib/test-dbus-glib.c index 15cd769a..4fbe797e 100644 --- a/test/glib/test-dbus-glib.c +++ b/test/glib/test-dbus-glib.c @@ -26,6 +26,13 @@ static gboolean proxy_destroy_and_nameowner_complete = FALSE;  static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2);  static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; +static void +unset_and_free_gvalue (gpointer val) +{ +  g_value_unset (val); +  g_free (val); +} +  static gboolean  timed_exit (gpointer loop)  { @@ -40,6 +47,7 @@ proxy_destroyed_cb (DBusGProxy *proxy, gpointer user_data)    proxy_destroyed = TRUE;    if (proxy_destroy_and_nameowner && !proxy_destroy_and_nameowner_complete && await_terminating_service == NULL)      { +      g_source_remove (exit_timeout);        g_main_loop_quit (loop);        proxy_destroy_and_nameowner_complete = TRUE;      }  @@ -62,11 +70,13 @@ name_owner_changed (DBusGProxy *proxy,        await_terminating_service = NULL;        if (proxy_destroy_and_nameowner && !proxy_destroy_and_nameowner_complete && proxy_destroyed)  	{ +	  g_source_remove (exit_timeout);  	  g_main_loop_quit (loop);  	  proxy_destroy_and_nameowner_complete = TRUE;  	}         else if (!proxy_destroy_and_nameowner)  	{ +	  g_source_remove (exit_timeout);  	  g_main_loop_quit (loop);  	}      } @@ -838,6 +848,50 @@ main (int argc, char **argv)    run_mainloop ();    { +    GValue *val; +    GHashTable *table; +    GHashTable *ret_table; + +    table = g_hash_table_new_full (g_str_hash, g_str_equal, +				   g_free, unset_and_free_gvalue); +     +    val = g_new0 (GValue, 1); +    g_value_init (val, G_TYPE_UINT); +    g_value_set_uint (val, 42); +    g_hash_table_insert (table, g_strdup ("foo"), val); + +    val = g_new0 (GValue, 1); +    g_value_init (val, G_TYPE_STRING); +    g_value_set_string (val, "hello"); +    g_hash_table_insert (table, g_strdup ("bar"), val); + +    ret_table = NULL; +    g_print ("Calling ManyStringify\n"); +    if (!dbus_g_proxy_call (proxy, "ManyStringify", &error, +			    dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), table, +			    G_TYPE_INVALID, +			    dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &ret_table, +			    G_TYPE_INVALID)) +      lose_gerror ("Failed to complete ManyStringify call", error); + +    g_assert (ret_table != NULL); +    g_assert (g_hash_table_size (ret_table) == 2); + +    val = g_hash_table_lookup (ret_table, "foo"); +    g_assert (val != NULL); +    g_assert (G_VALUE_HOLDS_STRING (val)); +    g_assert (!strcmp ("42", g_value_get_string (val))); + +    val = g_hash_table_lookup (ret_table, "bar"); +    g_assert (val != NULL); +    g_assert (G_VALUE_HOLDS_STRING (val)); +    g_assert (!strcmp ("hello", g_value_get_string (val))); + +    g_hash_table_destroy (table); +    g_hash_table_destroy (ret_table); +  } + +  {      guint val;      char *ret_path;      DBusGProxy *ret_proxy; @@ -1135,6 +1189,9 @@ main (int argc, char **argv)      lose_gerror ("Failed to complete Uppercase call", error);    g_free (v_STRING_2); +  if (getenv ("DBUS_GLIB_TEST_SLEEP_AFTER_ACTIVATION1")) +    g_usleep (8 * G_USEC_PER_SEC); +    dbus_g_proxy_add_signal (proxy, "Frobnicate", G_TYPE_INT, G_TYPE_INVALID);    dbus_g_proxy_connect_signal (proxy, "Frobnicate", @@ -1175,6 +1232,9 @@ main (int argc, char **argv)  			  G_TYPE_INVALID, G_TYPE_INVALID))      lose_gerror ("Failed to complete EmitFrobnicate call", error); +  if (getenv ("DBUS_GLIB_TEST_SLEEP_AFTER_ACTIVATION2")) +    g_usleep (8 * G_USEC_PER_SEC); +    dbus_g_connection_flush (connection);    exit_timeout = g_timeout_add (5000, timed_exit, loop);    g_main_loop_run (loop); diff --git a/test/glib/test-service-glib.c b/test/glib/test-service-glib.c index a9e57926..580eb107 100644 --- a/test/glib/test-service-glib.c +++ b/test/glib/test-service-glib.c @@ -63,6 +63,8 @@ gboolean my_object_many_return (MyObject *obj, guint32 *arg0, char **arg1, gint3  gboolean my_object_recursive1 (MyObject *obj, GArray *array, guint32 *len_ret, GError **error);  gboolean my_object_recursive2 (MyObject *obj, guint32 reqlen, GArray **array, GError **error); +gboolean my_object_many_stringify (MyObject *obj, GHashTable *vals, GHashTable **ret, GError **error); +  gboolean my_object_objpath (MyObject *obj, const char *in, char **arg1, GError **error);  gboolean my_object_get_objs (MyObject *obj, GPtrArray **objs, GError **error); @@ -397,6 +399,38 @@ my_object_many_uppercase (MyObject *obj, const char * const *in, char ***out, GE    return TRUE;  } +static void +hash_foreach_stringify (gpointer key, gpointer val, gpointer user_data) +{ +  const char *keystr = key; +  const GValue *value = val; +  GValue *sval; +  GHashTable *ret = user_data; + +  sval = g_new0 (GValue, 1); +  g_value_init (sval, G_TYPE_STRING); +  if (!g_value_transform (value, sval)) +    g_assert_not_reached (); + +  g_hash_table_insert (ret, g_strdup (keystr), sval); +} + +static void +unset_and_free_gvalue (gpointer val) +{ +  g_value_unset (val); +  g_free (val); +} + +gboolean +my_object_many_stringify (MyObject *obj, GHashTable /* char * -> GValue * */ *vals, GHashTable /* char * -> GValue * */ **ret, GError **error) +{ +  *ret = g_hash_table_new_full (g_str_hash, g_str_equal, +				g_free, unset_and_free_gvalue); +  g_hash_table_foreach (vals, hash_foreach_stringify, *ret); +  return TRUE; +} +  gboolean  my_object_objpath (MyObject *obj, const char *incoming, char **outgoing, GError **error)  { diff --git a/test/glib/test-service-glib.xml b/test/glib/test-service-glib.xml index 272f7b23..c299a80c 100644 --- a/test/glib/test-service-glib.xml +++ b/test/glib/test-service-glib.xml @@ -95,6 +95,11 @@        <arg type="u" direction="out" />      </method> +    <method name="ManyStringify"> +      <arg type="a{sv}" direction="in"/> +      <arg type="a{sv}" direction="out"/> +    </method> +      <method name="EmitFrobnicate">      </method> | 
