summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2008-12-17 14:35:04 -0500
committerDavid Zeuthen <davidz@redhat.com>2008-12-17 14:35:04 -0500
commitbe92ac30da13698e0ccaa90801caf490cfe6f696 (patch)
treefb2a85b2c937e378936adbf6fccd444167883a9d
parent9f7a46b0e675aaa8b0b60507b4b4654013131502 (diff)
minor changes to ArraySeq
-rw-r--r--src/eggdbus/eggdbusarrayseq.c735
-rw-r--r--src/eggdbus/eggdbusarrayseq.h68
-rw-r--r--src/tests/testclient.c238
3 files changed, 519 insertions, 522 deletions
diff --git a/src/eggdbus/eggdbusarrayseq.c b/src/eggdbus/eggdbusarrayseq.c
index 6e5e010..2df4876 100644
--- a/src/eggdbus/eggdbusarrayseq.c
+++ b/src/eggdbus/eggdbusarrayseq.c
@@ -32,110 +32,52 @@
* @title: EggDBusArraySeq
* @short_description: Arrays
*
- * An array type that can store elements of (virtually) any type known by the GObject
- * library. See egg_dbus_array_seq_new() for details.
+ * An array type that can store elements of a given #GType. See egg_dbus_array_seq_new() for details.
*
* The array will automatically grow when elements are added and all accessor functions
* dealing with index-based access checks if the index is within bounds. If an index
* is not within the bounds of the array a warning is issued using g_error() (causing
* program termination).
*
- * When possible type checking will be performed to ensure an inserted element is compatible
- * element type of the array. If the check fails, a warning is issued using g_error() (causing
- * program termination).
- *
- * The array type has a notion of <emphasis>static elements</emphasis> that can be used
- * to do away with copying/freeing data if certain assumptions can be made about the
- * data passed in. See #EGG_DBUS_ARRAY_SEQ_FLAGS_STATIC for details.
+ * When possible (when the elements are derived from #GObject) type checking will be performed to
+ * ensure an inserted element is compatible with the element type of the array. If the check fails,
+ * a warning is issued using g_error() (causing program termination).
*
- * For implementing operations that involve comparing if two elements are equal (such
- * as egg_dbus_array_seq_contains()), a #GEqualFunc is needed. For most types (such as
- * #G_TYPE_STRING and #G_TYPE_INT), the default one is used but for e.g. #G_TYPE_OBJECT
- * derived types one will need to be provided. Note that said operations are
- * <emphasis>optional</emphasis> in the sense that if a #GEqualFunc is not provided
- * other operations will still work; the operations needing the equality function
+ * For implementing operations that involve comparing elements (such as egg_dbus_array_seq_contains()),
+ * a #GEqualFunc is needed. For most types (such as #G_TYPE_STRING and #G_TYPE_INT), the natural
+ * #GEqualFunc is used but for e.g. #G_TYPE_OBJECT derived types one will need to be provided.
+ * Note that said operations are <emphasis>optional</emphasis> in the sense that if a #GEqualFunc
+ * is not provided other operations will still work; the operations needing the equal function
* will just fail and call g_error() (causing program termination).
*
- * By default, the array takes ownership when inserting elements meaning that the
- * programmer gives up his reference. In addition, there is convenience API to
- * make the array insert a copy of the element; see egg_dbus_array_seq_add_dup() for
- * example.
- *
- * Items extracted from the array are owned by the array. There is also convenience
- * API to get a copy of the item, see egg_dbus_array_seq_get_dup() for an example.
+ * By default, the array takes ownership when inserting elements meaning that the programmer gives
+ * up his reference. Elements extracted from the array are owned by the array. There is also convenience
+ * API to get a copy of the item, see egg_dbus_array_seq_get_copy().
*
* Note that this class exposes a number of implementation details directly in the class
* instance structure for efficient and convenient access when used from the C programming
* language. Use with caution. For the same reasons, this class also provides a number of
- * convenience functions such as egg_dbus_array_seq_add_int(), egg_dbus_array_seq_set_int(),
- * egg_dbus_array_seq_get_int() and egg_dbus_array_seq_new_for_int().
- *
- * TODO:
- *
- * Want to have the notion of a read-only array; for example, in a modern world
- * #GVolumeMonitor would pass out read-only arrays of volumes (since the user
- * can't add anything to them). Can easily be implemented with #EggDBusArraySeqFlags.
- * Then need to document that write-ops can fail with warnings (which is fine
- * too). In constrast, libgee has #GeeReadOnlyList etc. This will not scale for the
- * reasons outlined in <ulink url="http://java.sun.com/j2se/1.5.0/docs/guide/collections/designfaq.html">Java Collections API Design FAQ</ulink>. Also want a convenience method that constructs a
- * read-only array from a given array.
- *
- * Maybe we want convenience constructors that take a #GSList and #GList. No need for
- * constructors for #GPtrArray and #GArray, the user can do this just as easily
- * by using the regular constructors.
- *
- * Also want minor convenience like add_all() etc.; I'm probably missing something.
- * See Java and .NET collection APIs for details.
- *
- * Maybe we want convenience methods that constructs #GList, #GSList, #GPtrArray
- * and #GArray from the given data.
- *
- * We also want to have proper GInterfaces like in libgee (#EggDBusArraySeq is designed
- * to very easily implement #GeeCollection and #GeeList), see
- * <ulink url="http://bugzilla.gnome.org/show_bug.cgi?id=560061">bgo 560061</ulink>
- * for the gory detalis and prospect of having that in GLib. It doesn't make
- * sense, however, to make #EggDBusArraySeq implement any interfaces shipped with
- * the EggDBus package; the point of having collection interfaces is that everyone
- * should be using the same stuff (and we'd also want those interfaces to support
- * e.g. #EggDBusArraySeqFlags or similar since it's an useful thing). And at this
- * point it's fine; we'll always be handing out arrays _anyway_ (due to how the
- * D-Bus protocol); however it would perhaps be useful for the user to pass in,
- * say, a #EggDBusListSeq since it might be easier on his side to construct
- * a doubly-linked list than an array. So there.
- *
- * Want to implement at least a few algorithms like for_each() and sort(). This
- * should probably wait until we have proper GInterfaces. And then some concerted
- * effort around that.
+ * convenience functions for dealing with fixed-size integral and floating point numbers.
*/
typedef struct
{
/* if element_type is a fixed-size type, these are both NULL */
- gpointer (*copy_func) (EggDBusArraySeq *array_seq, gconstpointer element);
- void (*free_func) (EggDBusArraySeq *array_seq, gpointer element);
+ gpointer (*copy_func) (EggDBusArraySeq *array_seq, gconstpointer element);
+ GDestroyNotify free_func;
+ GEqualFunc equal_func;
+ GBoxedCopyFunc user_copy_func;
guint capacity;
/* cached value of G_IS_OBJECT_TYPE() to avoid overhead on every insertion */
gboolean element_type_is_gobject_derived;
- GEqualFunc equal_func;
-
- EggDBusArraySeqFlags flags;
-
+ /* cached value to determine if it's a fixed size array */
+ gboolean element_type_is_fixed_size;
} EggDBusArraySeqPrivate;
-enum
-{
- PROP_0,
- PROP_FLAGS,
- PROP_ELEMENT_TYPE,
- PROP_SIZE,
- PROP_ELEMENTS,
- PROP_ELEMENT_SIZE,
-};
-
#define EGG_DBUS_ARRAY_SEQ_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_DBUS_TYPE_ARRAY_SEQ, EggDBusArraySeqPrivate))
G_DEFINE_TYPE (EggDBusArraySeq, egg_dbus_array_seq, G_TYPE_OBJECT);
@@ -160,7 +102,8 @@ egg_dbus_array_seq_finalize (GObject *object)
if (priv->free_func != NULL)
for (n = 0; n < array_seq->size; n++)
- priv->free_func (array_seq, array_seq->data.v_ptr[n]);
+ if (array_seq->data.v_ptr[n] != NULL)
+ priv->free_func (array_seq->data.v_ptr[n]);
g_free (array_seq->data.data);
G_OBJECT_CLASS (egg_dbus_array_seq_parent_class)->finalize (object);
@@ -169,21 +112,23 @@ egg_dbus_array_seq_finalize (GObject *object)
/* ---------------------------------------------------------------------------------------------------- */
static gpointer
-copy_elem_object (EggDBusArraySeq *array_seq,
- gconstpointer element)
+copy_via_user_copy_func (EggDBusArraySeq *array_seq,
+ gconstpointer element)
{
- return element == NULL ? NULL : g_object_ref ((gpointer) element);
+ EggDBusArraySeqPrivate *priv;
+
+ priv = EGG_DBUS_ARRAY_SEQ_GET_PRIVATE (array_seq);
+
+ return element == NULL ? NULL : priv->user_copy_func ((gpointer) element);
}
-static void
-free_elem_object (EggDBusArraySeq *array_seq,
- gpointer element)
+static gpointer
+copy_elem_object (EggDBusArraySeq *array_seq,
+ gconstpointer element)
{
- if (element != NULL)
- g_object_unref (element);
+ return element == NULL ? NULL : g_object_ref ((gpointer) element);
}
-
static gpointer
copy_elem_string (EggDBusArraySeq *array_seq,
gconstpointer element)
@@ -191,13 +136,6 @@ copy_elem_string (EggDBusArraySeq *array_seq,
return g_strdup (element);
}
-static void
-free_elem_string (EggDBusArraySeq *array_seq,
- gpointer element)
-{
- g_free (element);
-}
-
static gpointer
copy_elem_boxed (EggDBusArraySeq *array_seq,
gconstpointer element)
@@ -205,14 +143,6 @@ copy_elem_boxed (EggDBusArraySeq *array_seq,
return element == NULL ? NULL : g_boxed_copy (array_seq->element_type, element);
}
-static void
-free_elem_boxed (EggDBusArraySeq *array_seq,
- gpointer element)
-{
- if (element != NULL)
- g_boxed_free (array_seq->element_type, element);
-}
-
static gpointer
copy_elem_param_spec (EggDBusArraySeq *array_seq,
gconstpointer element)
@@ -220,28 +150,6 @@ copy_elem_param_spec (EggDBusArraySeq *array_seq,
return element == NULL ? NULL : g_param_spec_ref ((gpointer) element);
}
-static void
-free_elem_param_spec (EggDBusArraySeq *array_seq,
- gpointer element)
-{
- if (element != NULL)
- g_param_spec_unref (element);
-}
-
-static gpointer
-copy_elem_static (EggDBusArraySeq *array_seq,
- gconstpointer element)
-{
- return (gpointer) element;
-}
-
-static void
-free_elem_static (EggDBusArraySeq *array_seq,
- gpointer element)
-{
- /* intentionally left blank */
-}
-
/* ---------------------------------------------------------------------------------------------------- */
#define IMPL_EQUAL_FUNC(type) \
@@ -273,10 +181,13 @@ ensure_size (EggDBusArraySeq *array_seq,
guint old_capacity;
guint old_size;
+ if (array_seq->size >= minimum_size)
+ return;
+
priv = EGG_DBUS_ARRAY_SEQ_GET_PRIVATE (array_seq);
- /* always allocated in 8-element increments */
- minimum_capacity = (guint) (((((guint64) minimum_size) * G_GINT64_CONSTANT (8)) + G_GINT64_CONSTANT (8)) / G_GINT64_CONSTANT (8));
+ /* always allocate 8 elements at a time */
+ minimum_capacity = (guint) ((minimum_size + 7) / 8) * 8;
old_capacity = priv->capacity;
old_size = array_seq->size;
@@ -311,116 +222,122 @@ egg_dbus_array_seq_class_init (EggDBusArraySeqClass *klass)
g_type_class_add_private (klass, sizeof (EggDBusArraySeqPrivate));
}
-
/**
* egg_dbus_array_seq_new:
* @element_type: The type of the elements in the array.
+ * @free_func: Function to be used to free elements or %NULL.
+ * @copy_func: Function to be used to copy elements or %NULL to use the default copy function.
+ * @equal_func: Function to be used for comparing equality or %NULL to use the default equality function.
*
- * Creates a new array that holds elements of @element_type with the default (if any) function
- * for comparing equality.
+ * Creates a new array that holds elements of @element_type and uses @free_func to free
+ * elements when they are no longer in use (e.g. when removed from the array either directly
+ * by calling e.g. egg_dbus_array_seq_remove_at() or if replaced by another element through
+ * egg_dbus_array_seq_set()). If @free_func is %NULL, then it is the responsibility of the owner
+ * of the array to free the elements when they are no longer used.
*
- * Allowed values for @element_type include the types #EGG_DBUS_TYPE_INT16, #EGG_DBUS_TYPE_UINT16
- * as well as any fundamental type known by the GObject library, and any type derived from any
- * of the aforementioned types. Note that for #G_TYPE_INTERFACE, only instances deriving from
- * #G_TYPE_OBJECT are supported.
- *
- * See egg_dbus_array_seq_new() for a variant of this function with more complicated options.
- *
- * Returns: A new #EggDBusArraySeq. Free with g_object_unref().
- **/
-EggDBusArraySeq *
-egg_dbus_array_seq_new (GType element_type)
-{
- return egg_dbus_array_seq_new_full (element_type,
- EGG_DBUS_ARRAY_SEQ_FLAGS_NONE,
- NULL,
- 0,
- NULL);
-}
-
-/**
- * egg_dbus_array_seq_new_full:
- * @element_type: The type of the elements in the array.
- * @flags: A combination of flags from #EggDBusArraySeqFlags.
- * @equal_func: A function that compares whether to elements are equal or %NULL to use default if one such exists.
- * @size: The number of elements in the @data parameter or 0 if @data is %NULL.
- * @data: Either %NULL (in which case @size must be 0) or raw memory to initialize the array with.
- *
- * Creates a new array and optionally initializes with it with @size elements copied from @data.
- * See egg_dbus_array_seq_new() for details on allowed values of @element_type and required memory
- * layout of @data.
+ * If @copy_func is %NULL, the default copy function is used if one exists for @element_type
+ * (for example there is no default copy function if @element_type is #G_TYPE_POINTER). Note
+ * that <emphasis>optional</emphasis> methods such as egg_dbus_array_seq_get_copy() won't
+ * work if there is no copy function.
*
* If @equal_func is %NULL, the default equality function is used if one exists for @element_type
- * (there is no natural equality function if @element_type is a subtype of #G_TYPE_OBJECT, #G_TYPE_INTERFACE
- * or #G_TYPE_BOXED). Note that if the elements holds a fixed-size type (such as #G_TYPE_INT), the
- * parameters passed to @equal_func will be the address of the element (e.g. a #gint<!-- -->*). Otherwise
- * (for arrays holding non-fixed sizes) the pointer stored in the array is passed (e.g. a #GFile<!-- -->*
- * if the array holds elements of #G_TYPE_FILE).
- *
- * If #EGG_DBUS_ARRAY_SEQ_FLAGS_STATIC is set in @flags, then elements are never copied (and methods like
- * e.g. egg_dbus_array_seq_add_dup() will behave like egg_dbus_array_seq_add()) which can help with
- * performance. On the other hand, if this flag is passed, you must guarantee that any elements inserted
- * into the returned array are alive for the lifetime of the returned array. Use with caution.
+ * (for example there is no default equality function if @element_type is a subtype of
+ * #G_TYPE_OBJECT, #G_TYPE_INTERFACE or #G_TYPE_BOXED). Note that <emphasis>optional</emphasis>
+ * methods such as egg_dbus_array_seq_contains() won't work if there is no equality function.
+ *
+ * If the type of elements is not a fixed-size type (such as #GObject derived types), the array
+ * will store pointers and all value pointers to and from this class are to the actual elements
+ * (the array is simply an array of pointers). For example, to implement @equal_func when
+ * @element_type is #G_TYPE_FILE, one would do the following:
+ *
+ * <programlisting>
+ * static gboolean
+ * my_file_equal_func (gconstpointer _a, gconstpointer _b)
+ * {
+ * GVolume *a = G_FILE (_a);
+ * GVolume *b = G_FILE (_b)
+ * gboolean is_equal;
+ *
+ * /<!-- -->* compute is_equal by comparing a and b *<!-- -->/
+ *
+ * return is_equal;
+ * }
+ * </programlisting>
+ *
+ * or, in this specific case, just pass g_file_equal() as @equal_func.
+ *
+ * If the type of the elements is a fixed-size type (such as #G_TYPE_INT, #G_TYPE_DOUBLE or a
+ * #G_TYPE_ENUM derived type), all value pointers used throughout this class is for the address
+ * of where the fixed-size value is stored inside the array. This is because the raw value are stored
+ * in the array; as such no pointers to elements are ever used (in addition, this means that @free_func
+ * and @copy_func are never used on such arrays). For example, for #G_TYPE_DOUBLE, you'd define
+ * @equal_func like this:
+ *
+ * <programlisting>
+ * static gboolean
+ * my_double_equal_func (gconstpointer _a, gconstpointer _b)
+ * {
+ * gdouble a = *((gdouble *) _a);
+ * gdouble b = *((gdouble *) _b);
+ * gboolean is_equal;
+ *
+ * /<!-- -->* compute is_equal by comparing a and b *<!-- -->/
+ *
+ * return is_equal;
+ * }
+ * </programlisting>
+ *
+ * Note that the default equality functions for integral and floating point types should
+ * be good enough for all but exotic corner cases.
*
* Returns: A new #EggDBusArraySeq. Free with g_object_unref().
**/
EggDBusArraySeq *
-egg_dbus_array_seq_new_full (GType element_type,
- EggDBusArraySeqFlags flags,
- GEqualFunc equal_func,
- guint size,
- gconstpointer data)
+egg_dbus_array_seq_new (GType element_type,
+ GDestroyNotify free_func,
+ GBoxedCopyFunc copy_func,
+ GEqualFunc equal_func)
{
GType fundamental_type;
EggDBusArraySeq *array_seq;
EggDBusArraySeqPrivate *priv;
gboolean not_supported;
- gpointer *given_data;
- guint n;
array_seq = EGG_DBUS_ARRAY_SEQ (g_object_new (EGG_DBUS_TYPE_ARRAY_SEQ, NULL));
priv = EGG_DBUS_ARRAY_SEQ_GET_PRIVATE (array_seq);
- priv->flags = flags;
- array_seq->size = size;
array_seq->element_type = element_type;
priv->equal_func = equal_func;
+ priv->free_func = free_func;
not_supported = FALSE;
fundamental_type = G_TYPE_FUNDAMENTAL (array_seq->element_type);
- if (flags & EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC)
- g_error ("You cannot pass EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC in flags");
-
/* first compute copy_func, free_func, element_size and equal_func */
switch (fundamental_type)
{
case G_TYPE_OBJECT:
case G_TYPE_INTERFACE:
priv->copy_func = copy_elem_object;
- priv->free_func = free_elem_object;
array_seq->element_size = sizeof (gpointer);
priv->element_type_is_gobject_derived = TRUE;
break;
case G_TYPE_BOXED:
priv->copy_func = copy_elem_boxed;
- priv->free_func = free_elem_boxed;
array_seq->element_size = sizeof (gpointer);
break;
case G_TYPE_PARAM:
priv->copy_func = copy_elem_param_spec;
- priv->free_func = free_elem_param_spec;
array_seq->element_size = sizeof (gpointer);
break;
case G_TYPE_STRING:
priv->copy_func = copy_elem_string;
- priv->free_func = free_elem_string;
array_seq->element_size = sizeof (gpointer);
if (priv->equal_func == NULL)
@@ -430,6 +347,7 @@ egg_dbus_array_seq_new_full (GType element_type,
case G_TYPE_UCHAR:
case G_TYPE_CHAR:
+ priv->element_type_is_fixed_size = TRUE;
array_seq->element_size = sizeof (guchar);
if (priv->equal_func == NULL)
priv->equal_func = _guchar_equal;
@@ -437,6 +355,7 @@ egg_dbus_array_seq_new_full (GType element_type,
case G_TYPE_INT:
case G_TYPE_UINT:
+ priv->element_type_is_fixed_size = TRUE;
array_seq->element_size = sizeof (gint);
if (priv->equal_func == NULL)
priv->equal_func = _gint_equal;
@@ -444,18 +363,21 @@ egg_dbus_array_seq_new_full (GType element_type,
case G_TYPE_INT64:
case G_TYPE_UINT64:
+ priv->element_type_is_fixed_size = TRUE;
array_seq->element_size = sizeof (gint64);
if (priv->equal_func == NULL)
priv->equal_func = _gint64_equal;
break;
case G_TYPE_BOOLEAN:
+ priv->element_type_is_fixed_size = TRUE;
array_seq->element_size = sizeof (gboolean);
if (priv->equal_func == NULL)
priv->equal_func = _gboolean_equal;
break;
case G_TYPE_DOUBLE:
+ priv->element_type_is_fixed_size = TRUE;
array_seq->element_size = sizeof (gdouble);
if (priv->equal_func == NULL)
priv->equal_func = _gdouble_equal;
@@ -463,12 +385,14 @@ egg_dbus_array_seq_new_full (GType element_type,
case G_TYPE_LONG:
case G_TYPE_ULONG:
+ priv->element_type_is_fixed_size = TRUE;
array_seq->element_size = sizeof (glong);
if (priv->equal_func == NULL)
priv->equal_func = _glong_equal;
break;
case G_TYPE_FLOAT:
+ priv->element_type_is_fixed_size = TRUE;
array_seq->element_size = sizeof (gfloat);
if (priv->equal_func == NULL)
priv->equal_func = _gfloat_equal;
@@ -476,6 +400,7 @@ egg_dbus_array_seq_new_full (GType element_type,
case G_TYPE_ENUM:
case G_TYPE_FLAGS:
+ priv->element_type_is_fixed_size = TRUE;
array_seq->element_size = sizeof (gint);
if (priv->equal_func == NULL)
priv->equal_func = _gint_equal;
@@ -487,11 +412,12 @@ egg_dbus_array_seq_new_full (GType element_type,
default:
/* can't have 16bit types in the switch since they're not constant
- * (Thanks GObject for not have GType for these)
+ * (Thanks GObject for not having a GType for these)
*/
if (array_seq->element_type == EGG_DBUS_TYPE_INT16 ||
array_seq->element_type == EGG_DBUS_TYPE_UINT16)
{
+ priv->element_type_is_fixed_size = TRUE;
array_seq->element_size = sizeof (gint16);
if (priv->equal_func == NULL)
priv->equal_func = _gint16_equal;
@@ -503,96 +429,63 @@ egg_dbus_array_seq_new_full (GType element_type,
break;
}
- /* warn/abort if STATIC was passed but element is a fixed-size type; this is a programmer-error */
- if (priv->copy_func == NULL && (priv->flags & EGG_DBUS_ARRAY_SEQ_FLAGS_STATIC))
+ if (priv->element_type_is_fixed_size && free_func != NULL)
{
- g_error ("Using EGG_DBUS_ARRAY_SEQ_FLAGS_STATIC doesn't make sense for "
- "fixed-size type %s.",
+ g_error ("Meaningless to specify free_func for EggDBusArraySeq<%s>.",
g_type_name (array_seq->element_type));
}
- /* sort out equal function */
- if (priv->equal_func != NULL)
- priv->flags |= EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC;
-
- if (not_supported)
+ if (priv->element_type_is_fixed_size && copy_func != NULL)
{
- /* didn't recognize type; this is a programmer/user error; contract says we can only manage
- * boxed or GObject-derived types
- */
- g_error ("Unsupported type %s used as element type for EggDBusArraySeq.",
+ g_error ("Meaningless to specify copy_func for EggDBusArraySeq<%s>.",
g_type_name (array_seq->element_type));
}
- /* if the passed in objects are static; use non-op copy(), free() implementations */
- if (priv->flags & EGG_DBUS_ARRAY_SEQ_FLAGS_STATIC)
+ if (copy_func != NULL)
{
- priv->copy_func = copy_elem_static;
- priv->free_func = free_elem_static;
+ priv->user_copy_func = copy_func;
+ priv->copy_func = copy_via_user_copy_func;
}
- /* take the passed in elements */
- given_data = (gpointer *) data;
- array_seq->data.v_ptr = NULL;
-
- /* ... allocate data to store element copies */
- ensure_size (array_seq, array_seq->size);
-
- /* ... and copy the passed in data if applicable */
- if (given_data != NULL && array_seq->size > 0)
+ if (not_supported)
{
- if (priv->copy_func != NULL)
- {
- /* elements are pointers; have to copy them one by one */
- for (n = 0; n < array_seq->size; n++)
- {
- array_seq->data.v_ptr[n] = priv->copy_func (array_seq, given_data[n]);
- }
- }
- else
- {
- /* for arrays of fixed size, copy the whole lot at once */
- memcpy (array_seq->data.v_ptr, given_data, array_seq->size * array_seq->element_size);
- }
+ /* didn't recognize type; this is a programmer/user error; contract says we can only manage
+ * boxed or GObject-derived types
+ */
+ g_error ("Unsupported type %s used as element type for EggDBusArraySeq.",
+ g_type_name (array_seq->element_type));
}
return array_seq;
}
-/**
- * egg_dbus_array_seq_set_equal_func:
- * @array_seq: A #EggDBusArraySeq.
- * @equal_func: A #GEqualFunc or %NULL.
- *
- * Sets the function for comparing equality.
- **/
-void
-egg_dbus_array_seq_set_equal_func (EggDBusArraySeq *array_seq,
- GEqualFunc equal_func)
+static gboolean
+check_have_equal_func (EggDBusArraySeq *array_seq)
{
EggDBusArraySeqPrivate *priv;
priv = EGG_DBUS_ARRAY_SEQ_GET_PRIVATE (array_seq);
- priv->equal_func = equal_func;
+ if (G_LIKELY (priv->equal_func != NULL))
+ return TRUE;
- if (equal_func == NULL)
- priv->flags &= ~EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC;
- else
- priv->flags |= EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC;
+ g_error ("no equal_func set for EggDBusArraySeq<%s>",
+ g_type_name (array_seq->element_type));
+
+ return FALSE;
}
static gboolean
-check_have_equal_func (EggDBusArraySeq *array_seq)
+check_have_copy_func (EggDBusArraySeq *array_seq)
{
EggDBusArraySeqPrivate *priv;
priv = EGG_DBUS_ARRAY_SEQ_GET_PRIVATE (array_seq);
- if (G_LIKELY (priv->equal_func != NULL))
+ if (G_LIKELY (priv->copy_func != NULL))
return TRUE;
- g_error ("no equal_func set for EggDBusArraySeq<%s>",
+ g_error ("no copy_func set for EggDBusArraySeq<%s>",
g_type_name (array_seq->element_type));
return FALSE;
@@ -633,25 +526,7 @@ check_element_type (EggDBusArraySeq *array_seq,
}
/**
- * egg_dbus_array_seq_get_flags:
- * @array_seq: A #EggDBusArraySeq.
- *
- * Gets the flags that specify the behavior of @array_seq.
- *
- * Returns: Flags from #EggDBusArraySeqFlags that specify the behavior of @array_seq.
- **/
-EggDBusArraySeqFlags
-egg_dbus_array_seq_get_flags (EggDBusArraySeq *array_seq)
-{
- EggDBusArraySeqPrivate *priv;
-
- priv = EGG_DBUS_ARRAY_SEQ_GET_PRIVATE (array_seq);
-
- return priv->flags;
-}
-
-/**
- * egg_dbus_array_seq_size:
+ * egg_dbus_array_seq_get_size:
* @array_seq: A #EggDBusArraySeq.
*
* Gets the size of @array_seq.
@@ -659,7 +534,7 @@ egg_dbus_array_seq_get_flags (EggDBusArraySeq *array_seq)
* Returns: The number of elements in @array_seq.
**/
guint
-egg_dbus_array_seq_size (EggDBusArraySeq *array_seq)
+egg_dbus_array_seq_get_size (EggDBusArraySeq *array_seq)
{
EggDBusArraySeqPrivate *priv;
@@ -704,7 +579,8 @@ egg_dbus_array_seq_set_size (EggDBusArraySeq *array_seq,
if (priv->free_func != NULL)
{
for (n = size; n < old_size; n++)
- priv->free_func (array_seq, array_seq->data.v_ptr[n]);
+ if (array_seq->data.v_ptr[n] != NULL)
+ priv->free_func (array_seq->data.v_ptr[n]);
}
/* set new size */
@@ -726,7 +602,7 @@ egg_dbus_array_seq_set_size (EggDBusArraySeq *array_seq,
* If @array_seq contains elements on non-fixed size, <literal>sizeof</literal> #gpointer
* is returned.
*
- * Returns: The size, in byes, of each element.
+ * Returns: The size, in bytes, of each element.
**/
gsize
egg_dbus_array_seq_get_element_size (EggDBusArraySeq *array_seq)
@@ -753,32 +629,42 @@ egg_dbus_array_seq_get_element_type (EggDBusArraySeq *array_seq)
}
/**
- * egg_dbus_array_seq_steal_data:
+ * egg_dbus_array_seq_have_copy_func:
* @array_seq: A #EggDBusArraySeq.
*
- * Steals the data backing @array_seq. The effect is the same as calling
- * egg_dbus_array_seq_clear(), e.g. no elements will remain in the array
- * when this function returns. Use with caution.
+ * Checks if @array_seq have a copy function.
*
- * Returns: A pointer to the elements of @array_seq. It is your
- * responsibility to free the returned data depending on the element
- * type of @array_seq.
+ * Returns: %TRUE only if there is a copy function for @array_seq.
**/
-gpointer
-egg_dbus_array_seq_steal_data (EggDBusArraySeq *array_seq)
+gboolean
+egg_dbus_array_seq_have_copy_func (EggDBusArraySeq *array_seq)
{
EggDBusArraySeqPrivate *priv;
- gpointer result;
priv = EGG_DBUS_ARRAY_SEQ_GET_PRIVATE (array_seq);
- result = array_seq->data.v_ptr;
- array_seq->data.v_ptr = NULL;
- array_seq->size = 0;
+ return priv->copy_func != NULL;
+}
- return result;
+/**
+ * egg_dbus_array_seq_get_equal_func:
+ * @array_seq: A #EggDBusArraySeq.
+ *
+ * Gets the #GEqualFunc used for comparing equality of elements.
+ *
+ * Returns: A #GEqualFunc.
+ **/
+GEqualFunc
+egg_dbus_array_seq_get_equal_func (EggDBusArraySeq *array_seq)
+{
+ EggDBusArraySeqPrivate *priv;
+
+ priv = EGG_DBUS_ARRAY_SEQ_GET_PRIVATE (array_seq);
+
+ return priv->equal_func;
}
+
/**
* egg_dbus_array_seq_remove_at:
* @array_seq: A #EggDBusArraySeq.
@@ -823,7 +709,8 @@ egg_dbus_array_seq_remove_range_at (EggDBusArraySeq *array_seq,
if (priv->free_func != NULL)
{
for (n = index; n < index + size; n++)
- priv->free_func (array_seq, array_seq->data.v_ptr[n]);
+ if (array_seq->data.v_ptr[n] != NULL)
+ priv->free_func (array_seq->data.v_ptr[n]);
}
/* move data (this works for both pointers and primitive types) */
@@ -864,8 +751,8 @@ egg_dbus_array_seq_clear (EggDBusArraySeq *array_seq)
* Gets the element at @index from @array_seq.
*
* Note that the returned element is owned by @array_seq and may be invalid if
- * later removed from the array. If you want your own reference use
- * egg_dbus_array_seq_get_dup().
+ * later removed from the array. If you want a copy, use egg_dbus_array_seq_get_copy()
+ * instead.
*
* This is a constant-time operation.
*
@@ -884,25 +771,31 @@ egg_dbus_array_seq_get (EggDBusArraySeq *array_seq,
priv = EGG_DBUS_ARRAY_SEQ_GET_PRIVATE (array_seq);
- if (priv->copy_func != NULL)
+ if (! priv->element_type_is_fixed_size)
return array_seq->data.v_ptr[index];
else
return array_seq->data.v_byte + index * array_seq->element_size;
}
/**
- * egg_dbus_array_seq_get_dup:
+ * egg_dbus_array_seq_get_copy:
* @array_seq: A #EggDBusArraySeq.
* @index: Zero-based index of element.
*
- * Gets a copy/reference of the element at @index from @array_seq. If you don't want your
- * own copy/reference use egg_dbus_array_seq_get().
+ * Gets a copy of the element at @index from @array_seq. If you don't want your
+ * own copy use egg_dbus_array_seq_get() instead.
*
- * Returns: A copy/reference of the requested element. Free with the appropriate
+ * This method is <emphasis>optional</emphasis> as some element types (for example #G_TYPE_POINTER
+ * and derived types) have no natural copy function and one might not have been set when @array_seq
+ * was constructed. It is a programming error to call this method on @array_seq if there
+ * is no copy function on @array_seq (a warning will be printed using g_error() causing program
+ * termination).
+ *
+ * Returns: A copy of the requested element. Free with the appropriate
* function depending on the element type of @array_seq.
**/
gpointer
-egg_dbus_array_seq_get_dup (EggDBusArraySeq *array_seq,
+egg_dbus_array_seq_get_copy (EggDBusArraySeq *array_seq,
gint index)
{
EggDBusArraySeqPrivate *priv;
@@ -912,20 +805,38 @@ egg_dbus_array_seq_get_dup (EggDBusArraySeq *array_seq,
if (!check_index (array_seq, index))
return NULL;
+ if (!check_have_copy_func (array_seq))
+ return NULL;
+
priv = EGG_DBUS_ARRAY_SEQ_GET_PRIVATE (array_seq);
- if (priv->copy_func != NULL)
- return priv->copy_func (array_seq, array_seq->data.v_ptr[index]);
+ if (! priv->element_type_is_fixed_size)
+ {
+ return priv->copy_func (array_seq, array_seq->data.v_ptr[index]);
+ }
else
- return g_memdup (array_seq->data.v_byte + index * array_seq->element_size,
- array_seq->element_size);
+ {
+ return g_memdup (array_seq->data.v_byte + index * array_seq->element_size,
+ array_seq->element_size);
+ }
}
-static void
-egg_dbus_array_seq_set_internal (EggDBusArraySeq *array_seq,
- gint index,
- gconstpointer value,
- gboolean steal_value)
+/**
+ * egg_dbus_array_seq_set:
+ * @array_seq: A #EggDBusArraySeq.
+ * @index: Zero-based index of element.
+ * @value: The value to insert.
+ *
+ * Replaces the element at @index in @array_seq with @value.
+ *
+ * Note that this function <emphasis>steals</emphasis> your reference to @value.
+ *
+ * This is a constant-time operation.
+ **/
+void
+egg_dbus_array_seq_set (EggDBusArraySeq *array_seq,
+ gint index,
+ gconstpointer value)
{
EggDBusArraySeqPrivate *priv;
@@ -942,15 +853,13 @@ egg_dbus_array_seq_set_internal (EggDBusArraySeq *array_seq,
/* out with the old... */
if (priv->free_func != NULL)
- priv->free_func (array_seq, array_seq->data.v_ptr[index]);
+ if (array_seq->data.v_ptr[index] != NULL)
+ priv->free_func (array_seq->data.v_ptr[index]);
/* and in with the new.. */
- if (priv->copy_func != NULL)
+ if (! priv->element_type_is_fixed_size)
{
- if (steal_value)
- array_seq->data.v_ptr[index] = (gpointer) value;
- else
- array_seq->data.v_ptr[index] = priv->copy_func (array_seq, value);
+ array_seq->data.v_ptr[index] = (gpointer) value;
}
else
{
@@ -961,58 +870,13 @@ egg_dbus_array_seq_set_internal (EggDBusArraySeq *array_seq,
}
/**
- * egg_dbus_array_seq_set:
- * @array_seq: A #EggDBusArraySeq.
- * @index: Zero-based index of element.
- * @value: The value to insert.
- *
- * Replaces the element at @index in @array_seq with @value.
- *
- * Note that this function <emphasis>steals</emphasis> your reference to @value to
- * avoid copying/reffing it. If this is unwanted use egg_dbus_array_seq_set_dup() to
- * hold on to your reference.
- *
- * This is a constant-time operation.
- **/
-void
-egg_dbus_array_seq_set (EggDBusArraySeq *array_seq,
- gint index,
- gconstpointer value)
-{
- egg_dbus_array_seq_set_internal (array_seq, index, value, TRUE);
-}
-
-/**
- * egg_dbus_array_seq_set_dup:
- * @array_seq: A #EggDBusArraySeq.
- * @index: Zero-based index of element.
- * @value: The value to insert.
- *
- * Replaces the element at @index in @array_seq with a copy/reference of @value.
- *
- * Note that @value is copied/reffed and you still own a reference to @value that
- * you must free yourself. If this is unwanted use egg_dbus_array_seq_set() instead.
- *
- * This is a constant-time operation.
- **/
-void
-egg_dbus_array_seq_set_dup (EggDBusArraySeq *array_seq,
- gint index,
- gconstpointer value)
-{
- egg_dbus_array_seq_set_internal (array_seq, index, value, FALSE);
-}
-
-/**
* egg_dbus_array_seq_add:
* @array_seq: A #EggDBusArraySeq.
* @value: The value to append.
*
* Appends @value to the end of @array_seq. The size of @array_seq will grow by one.
*
- * Note that this function <emphasis>steals</emphasis> your reference to @value to
- * avoid copying/reffing it. If this is unwanted use egg_dbus_array_seq_add_dup() to
- * hold on to your reference.
+ * Note that this function <emphasis>steals</emphasis> your reference to @value.
*
* This is a constant time operation.
*
@@ -1024,34 +888,53 @@ egg_dbus_array_seq_add (EggDBusArraySeq *array_seq,
{
/* grow, then add a copy of the element */
ensure_size (array_seq, array_seq->size + 1);
- egg_dbus_array_seq_set_dup (array_seq,
- array_seq->size - 1,
- value);
+ egg_dbus_array_seq_set (array_seq,
+ array_seq->size - 1,
+ value);
return TRUE;
}
/**
- * egg_dbus_array_seq_add_dup:
+ * egg_dbus_array_seq_insert:
* @array_seq: A #EggDBusArraySeq.
+ * @index: Zero-based index of element.
* @value: The value to append.
*
- * Appends a copy of @value to the end of @array_seq. The size of @array_seq will grow by one.
- *
- * Note that @value is copied/reffed and you still own a reference to @value that
- * you must free yourself. If this is unwanted use egg_dbus_array_seq_add() instead.
+ * Inserts @value at @index of @array_seq. All elements currently at or after @index will
+ * be shifted up by one and the size of @array_seq will grow by one.
*
- * Returns: Always %TRUE.
+ * Note that this function <emphasis>steals</emphasis> your reference to @value.
**/
-gboolean
-egg_dbus_array_seq_add_dup (EggDBusArraySeq *array_seq,
- gconstpointer value)
+void
+egg_dbus_array_seq_insert (EggDBusArraySeq *array_seq,
+ gint index,
+ gconstpointer value)
{
- /* grow, then add stolen element */
+ EggDBusArraySeqPrivate *priv;
+ guint old_size;
+
+ if (!check_index (array_seq, index))
+ return;
+
+ priv = EGG_DBUS_ARRAY_SEQ_GET_PRIVATE (array_seq);
+
+ old_size = array_seq->size;
ensure_size (array_seq, array_seq->size + 1);
- egg_dbus_array_seq_set_dup (array_seq,
- array_seq->size - 1,
- value);
- return TRUE;
+
+ if (old_size - index > 0)
+ {
+ g_memmove (array_seq->data.v_byte + (index + 1) * array_seq->element_size, /* dst */
+ array_seq->data.v_byte + index * array_seq->element_size, /* src */
+ (old_size - index) * array_seq->element_size);
+ }
+
+ memset (array_seq->data.v_byte + index * array_seq->element_size,
+ 0,
+ array_seq->element_size);
+
+ egg_dbus_array_seq_set (array_seq,
+ index,
+ value);
}
/**
@@ -1061,8 +944,9 @@ egg_dbus_array_seq_add_dup (EggDBusArraySeq *array_seq,
*
* Find the first occurence of an element equal to @value in @array_seq.
*
- * This method is optional. It is a programing error to call this method on @array_seq
- * if the flag #EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC isn't set.
+ * This method is <emphasis>optional</emphasis>. It is a programing error to call this
+ * method on @array_seq if there is no #GEqualFunc set for @array_seq (a warning will be
+ * printed using g_error() causing program termination).
*
* Returns: The index of the first occurence of an element equal to @value
* in @array_seq or -1 if no such elements exist.
@@ -1083,7 +967,7 @@ egg_dbus_array_seq_index_of (EggDBusArraySeq *array_seq,
{
gboolean found;
- if (priv->copy_func != NULL)
+ if (! priv->element_type_is_fixed_size)
found = priv->equal_func (array_seq->data.v_ptr[n], value);
else
found = priv->equal_func (array_seq->data.v_byte + n * array_seq->element_size, value);
@@ -1102,8 +986,9 @@ egg_dbus_array_seq_index_of (EggDBusArraySeq *array_seq,
*
* Check if @array_seq contains an element equal to @value.
*
- * This method is optional. It is a programing error to call this method on @array_seq
- * if the flag #EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC isn't set.
+ * This method is <emphasis>optional</emphasis>. It is a programing error to call this
+ * method on @array_seq if there is no #GEqualFunc set for @array_seq (a warning will be
+ * printed using g_error() causing program termination).
*
* Returns: %TRUE if @array_seq contains one or more elements equal to @value.
**/
@@ -1121,8 +1006,9 @@ egg_dbus_array_seq_contains (EggDBusArraySeq *array_seq,
*
* Remove the first occurence of elements equal to @value from @array_seq.
*
- * This method is optional. It is a programing error to call this method on @array_seq
- * if the flag #EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC isn't set.
+ * This method is <emphasis>optional</emphasis>. It is a programing error to call this method
+ * on @array_seq if there is no #GEqualFunc set for @array_seq (a warning will be
+ * printed using g_error() causing program termination).
*
* Returns: %TRUE if an element was removed.
**/
@@ -1176,7 +1062,7 @@ egg_dbus_array_seq_add_fixed (EggDBusArraySeq *array_seq,
case G_TYPE_INT:
case G_TYPE_UINT:
v_int = value;
- egg_dbus_array_seq_add (array_seq, &v_int16);
+ egg_dbus_array_seq_add (array_seq, &v_int);
break;
case G_TYPE_INT64:
@@ -1346,6 +1232,107 @@ egg_dbus_array_seq_set_float (EggDBusArraySeq *array_seq,
}
/**
+ * egg_dbus_array_seq_insert_fixed:
+ * @array_seq: A #EggDBusArraySeq.
+ * @index: Zero-based index of element.
+ * @value: The value to append.
+ *
+ * Inserts @value at @index of @array_seq. All elements currently at or after @index will
+ * be shifted up by one and the size of @array_seq will grow by one.
+ *
+ * This is a C convenience function for fixed-size integral types such as #G_TYPE_UCHAR, #G_TYPE_INT and so on.
+ **/
+void
+egg_dbus_array_seq_insert_fixed (EggDBusArraySeq *array_seq,
+ gint index,
+ guint64 value)
+{
+ guchar v_byte;
+ guint16 v_int16;
+ guint v_int;
+ gulong v_long;
+
+ switch (array_seq->element_type)
+ {
+ case G_TYPE_UCHAR:
+ case G_TYPE_CHAR:
+ v_byte = value;
+ egg_dbus_array_seq_insert (array_seq, index, &v_byte);
+ break;
+
+ case G_TYPE_INT:
+ case G_TYPE_UINT:
+ v_int = value;
+ egg_dbus_array_seq_insert (array_seq, index, &v_int);
+ break;
+
+ case G_TYPE_INT64:
+ case G_TYPE_UINT64:
+ egg_dbus_array_seq_insert (array_seq, index, &value);
+ break;
+
+ case G_TYPE_LONG:
+ case G_TYPE_ULONG:
+ v_long = value;
+ egg_dbus_array_seq_insert (array_seq, index, &v_long);
+ break;
+
+ default:
+ /* can't have 16bit types in the switch since they're not constant
+ */
+ if (array_seq->element_type == EGG_DBUS_TYPE_INT16 ||
+ array_seq->element_type == EGG_DBUS_TYPE_UINT16)
+ {
+ v_int16 = value;
+ egg_dbus_array_seq_insert (array_seq, index, &v_int16);
+ }
+ else
+ {
+ g_error ("Cannot use egg_dbus_array_seq_insert_fixed() on EggDBusArraySeq<%s>",
+ g_type_name (array_seq->element_type));
+ }
+ break;
+ }
+}
+
+/**
+ * egg_dbus_array_seq_insert_float:
+ * @array_seq: A #EggDBusArraySeq.
+ * @index: Zero-based index of element.
+ * @value: The value to append.
+ *
+ * Inserts @value at @index of @array_seq. All elements currently at or after @index will
+ * be shifted up by one and the size of @array_seq will grow by one.
+ *
+ * This is a C convenience function for the floating point types #G_TYPE_FLOAT and #G_TYPE_DOUBLE.
+ **/
+void
+egg_dbus_array_seq_insert_float (EggDBusArraySeq *array_seq,
+ gint index,
+ gdouble value)
+{
+ gfloat v_float;
+
+ switch (array_seq->element_type)
+ {
+ case G_TYPE_FLOAT:
+ v_float = value;
+ egg_dbus_array_seq_insert (array_seq, index, &v_float);
+ break;
+
+ case G_TYPE_DOUBLE:
+ egg_dbus_array_seq_insert (array_seq, index, &value);
+ break;
+
+ default:
+ g_error ("Cannot use egg_dbus_array_seq_insert_float() on EggDBusArraySeq<%s>",
+ g_type_name (array_seq->element_type));
+ break;
+ }
+}
+
+
+/**
* egg_dbus_array_seq_get_fixed:
* @array_seq: A #EggDBusArraySeq.
* @index: Zero-based index of element.
diff --git a/src/eggdbus/eggdbusarrayseq.h b/src/eggdbus/eggdbusarrayseq.h
index 830cc4c..d51d390 100644
--- a/src/eggdbus/eggdbusarrayseq.h
+++ b/src/eggdbus/eggdbusarrayseq.h
@@ -40,21 +40,6 @@ G_BEGIN_DECLS
typedef struct _EggDBusArraySeqClass EggDBusArraySeqClass;
/**
- * EggDBusArraySeqFlags:
- * @EGG_DBUS_ARRAY_SEQ_FLAGS_NONE: No flags set.
- * @EGG_DBUS_ARRAY_SEQ_FLAGS_STATIC: Elements are never copied; users of the array must ensure that inserted elements are alive for the duration of the lifetime of the array.
- * @EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC: Is set only if there's an equal function for comparing elements. If this flag is not set, certain operations such as egg_dbus_array_seq_contains() on the array are not supported. You can not pass this flag in any of the constructors.
- *
- * Flags that specify the behavior of an #EggDBusArraySeq instance.
- */
-typedef enum
-{
- EGG_DBUS_ARRAY_SEQ_FLAGS_NONE = 0,
- EGG_DBUS_ARRAY_SEQ_FLAGS_STATIC = (1<<0),
- EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC = (1<<1),
-} EggDBusArraySeqFlags;
-
-/**
* EggDBusArraySeq:
* @size: Number of elements in the array.
* @element_type: The #GType of the elements in the array.
@@ -129,55 +114,48 @@ struct _EggDBusArraySeqClass
GType egg_dbus_array_seq_get_type (void) G_GNUC_CONST;
-EggDBusArraySeq *egg_dbus_array_seq_new (GType element_type) G_GNUC_WARN_UNUSED_RESULT;
+EggDBusArraySeq *egg_dbus_array_seq_new (GType element_type,
+ GDestroyNotify free_func,
+ GBoxedCopyFunc copy_func,
+ GEqualFunc equal_func) G_GNUC_WARN_UNUSED_RESULT;
+gsize egg_dbus_array_seq_get_element_size (EggDBusArraySeq *array_seq);
-EggDBusArraySeq *egg_dbus_array_seq_new_full (GType element_type,
- EggDBusArraySeqFlags flags,
- GEqualFunc equal_func,
- guint size,
- gconstpointer data) G_GNUC_WARN_UNUSED_RESULT;
+GType egg_dbus_array_seq_get_element_type (EggDBusArraySeq *array_seq) G_GNUC_WARN_UNUSED_RESULT;
-EggDBusArraySeqFlags egg_dbus_array_seq_get_flags (EggDBusArraySeq *array_seq) G_GNUC_WARN_UNUSED_RESULT;
+GEqualFunc egg_dbus_array_seq_get_equal_func (EggDBusArraySeq *array_seq) G_GNUC_WARN_UNUSED_RESULT;
-void egg_dbus_array_seq_set_equal_func (EggDBusArraySeq *array_seq,
- GEqualFunc equal_func);
+gboolean egg_dbus_array_seq_have_copy_func (EggDBusArraySeq *array_seq) G_GNUC_WARN_UNUSED_RESULT;
-guint egg_dbus_array_seq_size (EggDBusArraySeq *array_seq) G_GNUC_WARN_UNUSED_RESULT;
+guint egg_dbus_array_seq_get_size (EggDBusArraySeq *array_seq) G_GNUC_WARN_UNUSED_RESULT;
void egg_dbus_array_seq_set_size (EggDBusArraySeq *array_seq,
guint size);
-gsize egg_dbus_array_seq_get_element_size (EggDBusArraySeq *array_seq);
-
-GType egg_dbus_array_seq_get_element_type (EggDBusArraySeq *array_seq) G_GNUC_WARN_UNUSED_RESULT;
-
-void egg_dbus_array_seq_remove_at (EggDBusArraySeq *array_seq,
- gint index);
-
-void egg_dbus_array_seq_remove_range_at (EggDBusArraySeq *array_seq,
- gint index,
- guint size);
-
void egg_dbus_array_seq_clear (EggDBusArraySeq *array_seq);
gpointer egg_dbus_array_seq_get (EggDBusArraySeq *array_seq,
gint index) G_GNUC_WARN_UNUSED_RESULT;
-gpointer egg_dbus_array_seq_get_dup (EggDBusArraySeq *array_seq,
+gpointer egg_dbus_array_seq_get_copy (EggDBusArraySeq *array_seq,
gint index) G_GNUC_WARN_UNUSED_RESULT;
void egg_dbus_array_seq_set (EggDBusArraySeq *array_seq,
gint index,
gconstpointer value);
-void egg_dbus_array_seq_set_dup (EggDBusArraySeq *array_seq,
+void egg_dbus_array_seq_insert (EggDBusArraySeq *array_seq,
gint index,
gconstpointer value);
gboolean egg_dbus_array_seq_add (EggDBusArraySeq *array_seq,
gconstpointer value);
-gboolean egg_dbus_array_seq_add_dup (EggDBusArraySeq *array_seq,
- gconstpointer value);
+
+void egg_dbus_array_seq_remove_at (EggDBusArraySeq *array_seq,
+ gint index);
+
+void egg_dbus_array_seq_remove_range_at (EggDBusArraySeq *array_seq,
+ gint index,
+ guint size);
gint egg_dbus_array_seq_index_of (EggDBusArraySeq *array_seq,
gconstpointer value);
@@ -190,9 +168,6 @@ gboolean egg_dbus_array_seq_remove (EggDBusArraySeq
/* C convenience functions */
-gpointer egg_dbus_array_seq_steal_data (EggDBusArraySeq *array_seq) G_GNUC_WARN_UNUSED_RESULT;
-
-
gboolean egg_dbus_array_seq_add_fixed (EggDBusArraySeq *array_seq,
guint64 value);
gboolean egg_dbus_array_seq_add_float (EggDBusArraySeq *array_seq,
@@ -205,6 +180,13 @@ void egg_dbus_array_seq_set_float (EggDBusArraySeq
gint index,
gdouble value);
+void egg_dbus_array_seq_insert_fixed (EggDBusArraySeq *array_seq,
+ gint index,
+ guint64 value);
+void egg_dbus_array_seq_insert_float (EggDBusArraySeq *array_seq,
+ gint index,
+ gdouble value);
+
guint64 egg_dbus_array_seq_get_fixed (EggDBusArraySeq *array_seq,
gint index) G_GNUC_WARN_UNUSED_RESULT;
gdouble egg_dbus_array_seq_get_float (EggDBusArraySeq *array_seq,
diff --git a/src/tests/testclient.c b/src/tests/testclient.c
index 4853b52..39844a6 100644
--- a/src/tests/testclient.c
+++ b/src/tests/testclient.c
@@ -3565,18 +3565,16 @@ test_egg_dbus_array_seq (void)
GFile *file_3;
guint64 some_uint64_numbers[3] = {G_MAXINT64 - 10, G_MAXINT * G_GINT64_CONSTANT (2), G_GINT64_CONSTANT (42)};
guchar some_prime_numbers[7] = {1, 2, 3, 5, 7, 11, 13};
-
+ guint n;
/*
* First, check that all EggDBusArraySeq operations work
*/
- a = egg_dbus_array_seq_new_full (G_TYPE_STRING,
- 0,
- NULL,
- 5,
- some_strings);
+ a = egg_dbus_array_seq_new (G_TYPE_STRING, g_free, NULL, NULL);
+ for (n = 0; n < 5; n++)
+ egg_dbus_array_seq_add (a, g_strdup (some_strings[n]));
g_assert_cmpuint (egg_dbus_array_seq_get_element_type (a), ==, G_TYPE_STRING);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 5);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 5);
g_assert_cmpstr (egg_dbus_array_seq_get (a, 0), ==, "zero");
g_assert_cmpstr (egg_dbus_array_seq_get (a, 1), ==, "one");
g_assert_cmpstr (egg_dbus_array_seq_get (a, 2), ==, "two");
@@ -3584,14 +3582,30 @@ test_egg_dbus_array_seq (void)
g_assert_cmpstr (egg_dbus_array_seq_get (a, 4), ==, "four");
/* address SHOULDN'T be the same since it's a copy */
g_assert (egg_dbus_array_seq_get (a, 0) != some_strings[0]);
- /* try adding elements; this will automatically grow the array */
- egg_dbus_array_seq_add_dup (a, "five");
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 6);
+ /* try inserting elements, that should shift elements up */
+ egg_dbus_array_seq_insert (a, 3, g_strdup ("two-and-a-half"));
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 6);
+ g_assert_cmpstr (egg_dbus_array_seq_get (a, 0), ==, "zero");
+ g_assert_cmpstr (egg_dbus_array_seq_get (a, 1), ==, "one");
+ g_assert_cmpstr (egg_dbus_array_seq_get (a, 2), ==, "two");
+ g_assert_cmpstr (egg_dbus_array_seq_get (a, 3), ==, "two-and-a-half");
+ g_assert_cmpstr (egg_dbus_array_seq_get (a, 4), ==, "three");
+ g_assert_cmpstr (egg_dbus_array_seq_get (a, 5), ==, "four");
+ egg_dbus_array_seq_remove_at (a, 3);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 5);
+ g_assert_cmpstr (egg_dbus_array_seq_get (a, 0), ==, "zero");
+ g_assert_cmpstr (egg_dbus_array_seq_get (a, 1), ==, "one");
+ g_assert_cmpstr (egg_dbus_array_seq_get (a, 2), ==, "two");
+ g_assert_cmpstr (egg_dbus_array_seq_get (a, 3), ==, "three");
+ g_assert_cmpstr (egg_dbus_array_seq_get (a, 4), ==, "four");
+ /* Try adding elements; this will automatically grow the array */
+ egg_dbus_array_seq_add (a, g_strdup ("five"));
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 6);
g_assert_cmpstr (egg_dbus_array_seq_get (a, 5), ==, "five");
/* this would be a buffer overflow; verify that we catch it and warn/abort */
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
{
- egg_dbus_array_seq_set_dup (a, 7, "seven");
+ egg_dbus_array_seq_set (a, 7, g_strdup ("seven"));
}
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*index 7 is out of bounds on EggDBusArraySeq<gchararray> of size 6*");
@@ -3600,15 +3614,15 @@ test_egg_dbus_array_seq (void)
* Note that this creates a hole at index 6. Also check that.
*/
egg_dbus_array_seq_set_size (a, 8);
- egg_dbus_array_seq_set_dup (a, 7, "seven");
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 8);
+ egg_dbus_array_seq_set (a, 7, g_strdup ("seven"));
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 8);
g_assert (egg_dbus_array_seq_get (a, 6) == NULL);
g_assert_cmpstr (egg_dbus_array_seq_get (a, 7), ==, "seven");
/* replace elements */
- egg_dbus_array_seq_set_dup (a, 1, "better one"); /* get it? ;-) */
+ egg_dbus_array_seq_set (a, 1, g_strdup ("better one")); /* get it? ;-) */
/* removing elements */
egg_dbus_array_seq_remove_at (a, 2);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 7);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 7);
g_assert_cmpstr (egg_dbus_array_seq_get (a, 0), ==, "zero");
g_assert_cmpstr (egg_dbus_array_seq_get (a, 1), ==, "better one");
g_assert_cmpstr (egg_dbus_array_seq_get (a, 2), ==, "three");
@@ -3617,13 +3631,13 @@ test_egg_dbus_array_seq (void)
g_assert (egg_dbus_array_seq_get (a, 5) == NULL);
g_assert_cmpstr (egg_dbus_array_seq_get (a, 6), ==, "seven");
egg_dbus_array_seq_remove_range_at (a, 1, 3);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 4);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 4);
g_assert_cmpstr (egg_dbus_array_seq_get (a, 0), ==, "zero");
g_assert_cmpstr (egg_dbus_array_seq_get (a, 1), ==, "five");
g_assert (egg_dbus_array_seq_get (a, 2) == NULL);
g_assert_cmpstr (egg_dbus_array_seq_get (a, 3), ==, "seven");
egg_dbus_array_seq_remove_at (a, 2);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 3);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 3);
g_assert_cmpstr (egg_dbus_array_seq_get (a, 0), ==, "zero");
g_assert_cmpstr (egg_dbus_array_seq_get (a, 1), ==, "five");
g_assert_cmpstr (egg_dbus_array_seq_get (a, 2), ==, "seven");
@@ -3644,24 +3658,20 @@ test_egg_dbus_array_seq (void)
g_test_trap_assert_stderr ("*index -2 is out of bounds on EggDBusArraySeq<gchararray> of size 3*");
/* check we that downsizing the array works */
egg_dbus_array_seq_set_size (a, 2);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 2);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 2);
/* check that clear works */
egg_dbus_array_seq_clear (a);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 0);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 0);
g_object_unref (a);
/* -------------------------------------------------------------------------------- */
- /* now, check that EGG_DBUS_ARRAY_SEQ_FLAGS_STATIC is honored; e.g. that
- * no copies elements are ever made
- */
- a = egg_dbus_array_seq_new_full (G_TYPE_STRING,
- EGG_DBUS_ARRAY_SEQ_FLAGS_STATIC,
- NULL,
- 5,
- some_strings);
+ /* now, check the same without a free function */
+ a = egg_dbus_array_seq_new (G_TYPE_STRING, NULL, NULL, NULL);
+ for (n = 0; n < 5; n++)
+ egg_dbus_array_seq_add (a, some_strings[n]);
g_assert_cmpuint (egg_dbus_array_seq_get_element_type (a), ==, G_TYPE_STRING);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 5);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 5);
g_assert_cmpstr (egg_dbus_array_seq_get (a, 0), ==, "zero");
g_assert_cmpstr (egg_dbus_array_seq_get (a, 1), ==, "one");
g_assert_cmpstr (egg_dbus_array_seq_get (a, 2), ==, "two");
@@ -3669,35 +3679,16 @@ test_egg_dbus_array_seq (void)
g_assert_cmpstr (egg_dbus_array_seq_get (a, 4), ==, "four");
/* address SHOULD be the same since it's not a copy */
g_assert (egg_dbus_array_seq_get (a, 0) == some_strings[0]);
- /* elements inserted after constuction shouldn't be copied either even if _dup() is used */
- egg_dbus_array_seq_set_dup (a, 1, some_strings[0]);
- g_assert_cmpstr (egg_dbus_array_seq_get (a, 1), ==, "zero");
- g_assert (egg_dbus_array_seq_get (a, 1) == some_strings[0]);
- /* check we can steal the data; first terminate with NULL so g_strv_length() works */
- egg_dbus_array_seq_add (a, NULL);
- string_array = (gchar **) egg_dbus_array_seq_steal_data (a);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 0);
g_object_unref (a);
- /* no need to free strings in the array, these are static strings */
- g_assert_cmpuint (g_strv_length (string_array), ==, 5);
- g_assert_cmpstr (string_array[0], ==, "zero");
- g_assert_cmpstr (string_array[1], ==, "zero");
- g_assert_cmpstr (string_array[2], ==, "two");
- g_assert_cmpstr (string_array[3], ==, "three");
- g_assert_cmpstr (string_array[4], ==, "four");
- g_assert (string_array[4] == some_strings[4]);
- g_free (string_array);
/* -------------------------------------------------------------------------------- */
/* check that fixed size types work (through C convenience interface) */
- a = egg_dbus_array_seq_new_full (G_TYPE_UCHAR,
- 0, /* flags */
- NULL,
- 7,
- some_prime_numbers);
+ a = egg_dbus_array_seq_new (G_TYPE_UCHAR, NULL, NULL, NULL);
+ for (n = 0; n < 7; n++)
+ egg_dbus_array_seq_add_fixed (a, some_prime_numbers[n]);
g_assert_cmpuint (egg_dbus_array_seq_get_element_type (a), ==, G_TYPE_UCHAR);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 7);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 7);
/* check that direct access works */
g_assert_cmpint (a->data.v_byte[0], ==, 1);
g_assert_cmpint (a->data.v_byte[1], ==, 2);
@@ -3714,6 +3705,26 @@ test_egg_dbus_array_seq (void)
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 4), ==, 7);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 5), ==, 11);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 6), ==, 13);
+ /* check we can insert items in the middle */
+ egg_dbus_array_seq_insert_fixed (a, 5, 9);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 8);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 0), ==, 1);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 1), ==, 2);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 2), ==, 3);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 3), ==, 5);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 4), ==, 7);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 5), ==, 9);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 6), ==, 11);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 7), ==, 13);
+ egg_dbus_array_seq_remove_at (a, 5);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 7);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 0), ==, 1);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 1), ==, 2);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 2), ==, 3);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 3), ==, 5);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 4), ==, 7);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 5), ==, 11);
+ g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 6), ==, 13);
/* check that we're getting runtime errors / abort for out-of-bounds access */
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
{
@@ -3724,7 +3735,7 @@ test_egg_dbus_array_seq (void)
g_test_trap_assert_stderr ("*index 10 is out of bounds on EggDBusArraySeq<guchar> of size 7*");
/* check we can set elements */
egg_dbus_array_seq_set_fixed (a, 4, 9); /* prime intruder! */
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 7);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 7);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 0), ==, 1);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 1), ==, 2);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 2), ==, 3);
@@ -3735,7 +3746,7 @@ test_egg_dbus_array_seq (void)
/* check that we can remove elements */
egg_dbus_array_seq_remove_at (a, 2);
egg_dbus_array_seq_remove_at (a, 4);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 5);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 5);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 0), ==, 1);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 1), ==, 2);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 2), ==, 5);
@@ -3743,18 +3754,18 @@ test_egg_dbus_array_seq (void)
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 4), ==, 13);
/* check we can add stuff */
egg_dbus_array_seq_add_fixed (a, 0xff);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 6);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 6);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 5), ==, 0xff);
g_object_unref (a);
+ /* -------------------------------------------------------------------------------- */
+
/* check another fixed size type just for kicks */
- a = egg_dbus_array_seq_new_full (G_TYPE_INT64,
- 0, /* flags */
- NULL,
- 3,
- some_uint64_numbers);
+ a = egg_dbus_array_seq_new (G_TYPE_INT64, NULL, NULL, NULL);
+ for (n = 0; n < 3; n++)
+ egg_dbus_array_seq_add_fixed (a, some_uint64_numbers[n]);
g_assert_cmpuint (egg_dbus_array_seq_get_element_type (a), ==, G_TYPE_INT64);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 3);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 3);
/* check that direct access works */
g_assert_cmpint (a->data.v_int64[0], ==, G_MAXINT64 - 10);
g_assert_cmpint (a->data.v_int64[1], ==, G_MAXINT * G_GINT64_CONSTANT (2));
@@ -3762,12 +3773,12 @@ test_egg_dbus_array_seq (void)
/* check we can remove stuff */
egg_dbus_array_seq_remove_at (a, 1);
/* check that C convenience getters work */
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 2);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 2);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 0), ==, G_MAXINT64 - 10);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 1), ==, 42);
/* check we can add stuff */
egg_dbus_array_seq_add_fixed (a, G_MAXINT * G_GINT64_CONSTANT (3));
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 3);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 3);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 0), ==, G_MAXINT64 - 10);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 1), ==, 42);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 2), ==, G_MAXINT * G_GINT64_CONSTANT (3));
@@ -3776,11 +3787,11 @@ test_egg_dbus_array_seq (void)
/* -------------------------------------------------------------------------------- */
/* now check that boxed types works */
- a = egg_dbus_array_seq_new (G_TYPE_STRV);
+ a = egg_dbus_array_seq_new (G_TYPE_STRV, (GDestroyNotify) g_strfreev, NULL, NULL);
egg_dbus_array_seq_add (a, g_strsplit ("a test string", " ", 0));
egg_dbus_array_seq_add (a, g_strsplit ("another string", " ", 0));
- egg_dbus_array_seq_add_dup (a, some_strings);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 3);
+ egg_dbus_array_seq_add (a, g_strdupv ((gchar **) some_strings));
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 3);
g_assert_cmpuint (g_strv_length (egg_dbus_array_seq_get (a, 0)), ==, 3);
g_assert_cmpstr (a->data.v_strv[0][0], ==, "a");
g_assert_cmpstr (a->data.v_strv[0][1], ==, "test");
@@ -3795,14 +3806,6 @@ test_egg_dbus_array_seq (void)
g_assert_cmpstr (a->data.v_strv[2][3], ==, "three");
g_assert_cmpstr (a->data.v_strv[2][4], ==, "four");
/* adding stuff of a wrong type should cause a run-time warning / abort; check that
- *
- * (Unfortunately we can't check types if the the regular array_seq_add()
- * is used (a boxed instance or string could be passed) though the program
- * is very likely to crash if this happens.
- *
- * One way to get around this is to abolish array_seq_add() completely and
- * replace it with the types we care about (str, strv, object, boxed)...
- * TODO: consider if that's a good idea.
*/
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
{
@@ -3812,13 +3815,13 @@ test_egg_dbus_array_seq (void)
g_test_trap_assert_stderr ("*Cannot use egg_dbus_array_seq_add_fixed() on EggDBusArraySeq<GStrv>*");
/* check we can remove stuff; we only bother check the first element this time */
egg_dbus_array_seq_remove_at (a, 1);
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 2);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 2);
g_assert_cmpuint (g_strv_length (egg_dbus_array_seq_get (a, 0)), ==, 3);
g_assert_cmpstr (a->data.v_strv[0][0], ==, "a");
g_assert_cmpuint (g_strv_length (egg_dbus_array_seq_get (a, 1)), ==, 5);
g_assert_cmpstr (a->data.v_strv[1][0], ==, "zero");
- /* check that dup works */
- string_array = egg_dbus_array_seq_get_dup (a, 1);
+ /* check that copying works */
+ string_array = egg_dbus_array_seq_get_copy (a, 1);
g_assert_cmpuint (g_strv_length (string_array), ==, 5);
g_assert_cmpstr (string_array[0], ==, "zero");
g_assert_cmpstr (string_array[1], ==, "one");
@@ -3831,10 +3834,10 @@ test_egg_dbus_array_seq (void)
/* -------------------------------------------------------------------------------- */
/* check that types deriving from boxed types work */
- a = egg_dbus_array_seq_new (EGG_DBUS_TYPE_OBJECT_PATH_ARRAY);
+ a = egg_dbus_array_seq_new (EGG_DBUS_TYPE_OBJECT_PATH_ARRAY, (GDestroyNotify) g_strfreev, NULL, NULL);
egg_dbus_array_seq_add (a, g_strsplit ("/a/test/path", "/", 0));
egg_dbus_array_seq_add (a, g_strsplit ("/another/path", "/", 0));
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 2);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 2);
g_assert_cmpuint (g_strv_length (egg_dbus_array_seq_get (a, 0)), ==, 4);
g_assert_cmpstr (a->data.v_strv[0][0], ==, "");
g_assert_cmpstr (a->data.v_strv[0][1], ==, "a");
@@ -3853,10 +3856,10 @@ test_egg_dbus_array_seq (void)
* arrays of boxed instances. However, there's one additional check that is done; namely
* type checking:
*/
- a = egg_dbus_array_seq_new (TEST_TYPE_SUBJECT);
+ a = egg_dbus_array_seq_new (TEST_TYPE_SUBJECT, g_object_unref, NULL, NULL);
egg_dbus_array_seq_add (a, test_subject_new (TEST_SUBJECT_KIND_HUMAN, "davidz", "eggs", "blue"));
egg_dbus_array_seq_add (a, test_subject_new (TEST_SUBJECT_KIND_HUMAN, "krh", "<undisclosed>", "<classified>"));
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 2);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 2);
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
{
egg_dbus_array_seq_add_fixed (a, 0xcafebabe);
@@ -3878,26 +3881,26 @@ test_egg_dbus_array_seq (void)
* (implemented by GLocalFile and (if gvfs is installed) and GDaemonFile) use that for
* our test case.
*/
- a = egg_dbus_array_seq_new (G_TYPE_FILE);
+ a = egg_dbus_array_seq_new (G_TYPE_FILE, g_object_unref, NULL, NULL);
egg_dbus_array_seq_add (a, g_file_new_for_path ("a.txt"));
egg_dbus_array_seq_add (a, g_file_new_for_path ("b.txt"));
egg_dbus_array_seq_add (a, g_file_new_for_path ("c.txt"));
- g_assert_cmpuint (egg_dbus_array_seq_size (a), ==, 3);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 3);
g_object_unref (a);
/* -------------------------------------------------------------------------------- */
/* check that equal_func is properly inferred and works */
- a = egg_dbus_array_seq_new (G_TYPE_STRING);
- g_assert (egg_dbus_array_seq_get_flags (a) & EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC);
- egg_dbus_array_seq_add_dup (a, "zero");
- egg_dbus_array_seq_add_dup (a, "one");
- egg_dbus_array_seq_add_dup (a, "two");
- egg_dbus_array_seq_add_dup (a, "three");
- egg_dbus_array_seq_add_dup (a, "two");
- egg_dbus_array_seq_add_dup (a, "four");
- egg_dbus_array_seq_add_dup (a, "two");
- egg_dbus_array_seq_add_dup (a, "five");
+ a = egg_dbus_array_seq_new (G_TYPE_STRING, g_free, NULL, NULL);
+ g_assert (egg_dbus_array_seq_get_equal_func (a) != NULL);
+ egg_dbus_array_seq_add (a, g_strdup ("zero"));
+ egg_dbus_array_seq_add (a, g_strdup ("one"));
+ egg_dbus_array_seq_add (a, g_strdup ("two"));
+ egg_dbus_array_seq_add (a, g_strdup ("three"));
+ egg_dbus_array_seq_add (a, g_strdup ("two"));
+ egg_dbus_array_seq_add (a, g_strdup ("four"));
+ egg_dbus_array_seq_add (a, g_strdup ("two"));
+ egg_dbus_array_seq_add (a, g_strdup ("five"));
g_assert_cmpint (egg_dbus_array_seq_index_of (a, "three"), ==, 3);
g_assert_cmpint (egg_dbus_array_seq_index_of (a, "two"), ==, 2);
g_assert (egg_dbus_array_seq_remove (a, "two"));
@@ -3911,12 +3914,11 @@ test_egg_dbus_array_seq (void)
/* -------------------------------------------------------------------------------- */
- /* try for a fixed-size type as well (we don't provide C convenience for these (yet?)) */
- a = egg_dbus_array_seq_new_full (G_TYPE_INT,
- 0,
- NULL,
- 8,
- some_ints);
+ /* try for a fixed-size type as well */
+ a = egg_dbus_array_seq_new (G_TYPE_INT, NULL, NULL, NULL);
+ for (n = 0; n < 8; n++)
+ egg_dbus_array_seq_add_fixed (a, some_ints[n]);
+ g_assert_cmpuint (egg_dbus_array_seq_get_size (a), ==, 8);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 0), ==, 0);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 1), ==, 1);
g_assert_cmpint (egg_dbus_array_seq_get_fixed (a, 2), ==, 2);
@@ -3939,8 +3941,8 @@ test_egg_dbus_array_seq (void)
/* -------------------------------------------------------------------------------- */
/* check there is no equal_func by default for GObject types */
- a = egg_dbus_array_seq_new (G_TYPE_FILE);
- g_assert (! (egg_dbus_array_seq_get_flags (a) & EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC));
+ a = egg_dbus_array_seq_new (G_TYPE_FILE, g_object_unref, NULL, NULL);
+ g_assert (egg_dbus_array_seq_get_equal_func (a) == NULL);
egg_dbus_array_seq_add (a, g_file_new_for_path ("0.txt"));
egg_dbus_array_seq_add (a, g_file_new_for_path ("1.txt"));
egg_dbus_array_seq_add (a, g_file_new_for_path ("2.txt"));
@@ -3959,9 +3961,18 @@ test_egg_dbus_array_seq (void)
}
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*no equal_func set for EggDBusArraySeq<GFile>*");
- /* check we can set an equal_func post construction and that the equal func works*/
- egg_dbus_array_seq_set_equal_func (a, (GEqualFunc) g_file_equal);
- g_assert (egg_dbus_array_seq_get_flags (a) & EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC);
+ g_object_unref (a);
+ /* now check again with an equal func */
+ a = egg_dbus_array_seq_new (G_TYPE_FILE, g_object_unref, NULL, (GEqualFunc) g_file_equal);
+ g_assert (egg_dbus_array_seq_get_equal_func (a) != NULL);
+ egg_dbus_array_seq_add (a, g_file_new_for_path ("0.txt"));
+ egg_dbus_array_seq_add (a, g_file_new_for_path ("1.txt"));
+ egg_dbus_array_seq_add (a, g_file_new_for_path ("2.txt"));
+ egg_dbus_array_seq_add (a, g_file_new_for_path ("3.txt"));
+ egg_dbus_array_seq_add (a, g_file_new_for_path ("2.txt"));
+ egg_dbus_array_seq_add (a, g_file_new_for_path ("4.txt"));
+ egg_dbus_array_seq_add (a, g_file_new_for_path ("2.txt"));
+ egg_dbus_array_seq_add (a, g_file_new_for_path ("5.txt"));
file_2 = g_file_new_for_path ("2.txt");
file_3 = g_file_new_for_path ("3.txt");
g_assert_cmpint (egg_dbus_array_seq_index_of (a, file_3), ==, 3);
@@ -3975,8 +3986,25 @@ test_egg_dbus_array_seq (void)
g_assert (!egg_dbus_array_seq_remove (a, file_2));
g_object_unref (file_2);
g_object_unref (file_3);
- egg_dbus_array_seq_set_equal_func (a, NULL);
- g_assert (! (egg_dbus_array_seq_get_flags (a) & EGG_DBUS_ARRAY_SEQ_FLAGS_HAVE_EQUAL_FUNC));
+ g_object_unref (a);
+
+ /* -------------------------------------------------------------------------------- */
+
+ /* check we can handle raw pointer types */
+ a = egg_dbus_array_seq_new (G_TYPE_POINTER, NULL, NULL, NULL);
+ g_assert (egg_dbus_array_seq_get_equal_func (a) == NULL);
+ egg_dbus_array_seq_add (a, g_file_new_for_path ("0.txt"));
+ egg_dbus_array_seq_add (a, g_file_new_for_path ("1.txt"));
+ g_object_unref (a->data.v_ptr[0]);
+ g_object_unref (a->data.v_ptr[1]);
+ /* check that attempting to copy items will cause a runtime error */
+ if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
+ {
+ gpointer ptr;
+ ptr = egg_dbus_array_seq_get_copy (a, 0);
+ }
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("*no copy_func set for EggDBusArraySeq<gpointer>*");
g_object_unref (a);
}