Associations and types of elements for arrays and hash tables
Submitted by David Zeuthen
Link to original bug (#581106)
Description
Hi,
One really neat thing about the base object class is that you can associate data with pointers, e.g. g_object_set_data() and g_object_get_data() and thereby hook into the finalization process through a GDestroyNotify.
This latter is extremely useful in mid-layer library code where you take objects from the library user, attach some stuff to them and return later with a callback.
It would be nice to have similar constructs on GArray, GPtrArray and GHashTable since these are (unfortunately) not based on GObject, e.g.
g_array_set_data() g_array_get_data() g_array_steal_data()
and ditto for GPtrArray and GHashTable
In addition, it would be useful to know about the types of elements stored in these three container classes, e.g.
GType g_array_get_element_type() GType g_ptr_array_get_element_type() GType g_hash_table_get_key_type() GType g_hash_table_get_value_type()
so you can write safer code like in [1].
Another example is where you e.g. want to return a collection to the user where you point into data that is already allocated. In that case you want to unref the allocated data when the user unrefs his reference to the collection. For example
p = g_ptr_array_new (); g_ptr_array_set_element_type (p, G_TYPE_STRING); // add pointers to p that point into a DBusMessage g_ptr_array_set_data (p, "dbus-1-message", dbus_message_ref (message), (GDestroyNotify) dbus_message_unref); // drop our ref, message will be unreffed, when p is unreffed dbus_message_unref (message); // return p to user, user will call g_ptr_array_unref() when done
Again, this is not specific to D-Bus; it's just to illustrate the general idea.
I'll attach a patch that does this for GArray - the idea is similar for GPtrArray and GHashTable but I thought I'd float the idea before doing that.
[1] : This is an example of where I want to use this for the proposed GDBus work but it's generally useful anyway.
static void on_get_ata_smart_data_attrs_cb (DevkitDisksDevice *proxy, GAsyncResult *result, gpointer user_data) { GPtrArray *ata_smart_attrs; GError **error;
error = NULL; if (!devkit_disks_device_invoke_get_ata_smart_data_attrs_finish ( proxy, &ata_smart_attrs, &error)) goto fail_and_stuff;
g_assert (g_ptr_array_get_element_type (ata_smart_attrs) == DEVKIT_DISKS_TYPE_ATA_SMART_ATTR);
/* do stuff with ata_smart_attrs */
g_ptr_array_free (&ata_smart_attrs);
<....> }