[Telepathy-commits] [telepathy-glib/master] contacts_got_attributes, contacts_get_attributes: refactor so we work correctly if the method is not by_handle
Simon McVittie
simon.mcvittie at collabora.co.uk
Mon Dec 1 03:13:57 PST 2008
We want to ref the handles if and only if we started from handles - if
we started from IDs, RequestHandles refs them, and if we started from
contacts, they're already referenced anyway.
---
telepathy-glib/contact.c | 185 ++++++++++++++++++++++++++--------------------
1 files changed, 106 insertions(+), 79 deletions(-)
diff --git a/telepathy-glib/contact.c b/telepathy-glib/contact.c
index e6ab7e4..66b348c 100644
--- a/telepathy-glib/contact.c
+++ b/telepathy-glib/contact.c
@@ -1604,104 +1604,128 @@ contacts_got_attributes (TpConnection *connection,
i = 0;
- while (i < c->handles->len)
+ if (c->signature == CB_BY_HANDLE)
{
- TpHandle handle = g_array_index (c->handles, guint, i);
- GHashTable *asv = g_hash_table_lookup (attributes,
- GUINT_TO_POINTER (handle));
+ g_assert (c->contacts->len == 0);
- if (asv == NULL)
- {
- /* not in the hash table => not valid */
- g_array_append_val (c->invalid, handle);
- g_array_remove_index_fast (c->handles, i);
- }
- else
+ while (i < c->handles->len)
{
- TpContact *contact = NULL;
- guint j;
- const gchar *s;
- gpointer boxed;
-
- /* we might already have consumed the only reference we have to
- * the handle - if we have, we must recycle the same object rather
- * than calling tp_contact_ensure again */
- for (j = 0; j < i; j++)
+ TpHandle handle = g_array_index (c->handles, guint, i);
+ GHashTable *asv = g_hash_table_lookup (attributes,
+ GUINT_TO_POINTER (handle));
+
+ if (asv == NULL)
+ {
+ /* not in the hash table => not valid */
+ g_array_append_val (c->invalid, handle);
+ g_array_remove_index_fast (c->handles, i);
+ }
+ else
{
- if (handle == g_array_index (c->handles, guint, j))
+ TpContact *contact = NULL;
+ guint j;
+
+ /* we might already have consumed the only reference we have to
+ * the handle - if we have, we must recycle the same object
+ * rather than calling tp_contact_ensure again */
+ for (j = 0; j < i; j++)
{
- contact = g_object_ref (g_ptr_array_index (c->contacts, j));
+ if (handle == g_array_index (c->handles, guint, j))
+ {
+ contact = g_object_ref (g_ptr_array_index (c->contacts,
+ j));
+ }
}
- }
- if (contact == NULL)
- contact = tp_contact_ensure (connection, handle);
+ if (contact == NULL)
+ contact = tp_contact_ensure (connection, handle);
- /* set up the contact with its attributes */
+ g_ptr_array_add (c->contacts, contact);
- s = tp_asv_get_string (asv,
- TP_IFACE_CONNECTION "/contact-id");
+ /* save the contact and move on to the next handle */
+ i++;
+ }
+ }
+ }
- if (s == NULL)
- {
- GError *e = g_error_new (TP_DBUS_ERRORS,
- TP_DBUS_ERROR_INCONSISTENT,
- "Connection manager %s is broken: contact #%u in "
- "the GetContactAttributes result has no contact-id",
- tp_proxy_get_bus_name (connection), handle);
+ g_assert (c->contacts->len == c->handles->len);
- contacts_context_fail (c, e);
- g_error_free (e);
- g_object_unref (contact);
- return;
- }
- else if (contact->priv->identifier == NULL)
- {
- contact->priv->identifier = g_strdup (s);
- }
- else if (tp_strdiff (contact->priv->identifier, s))
- {
- GError *e = g_error_new (TP_DBUS_ERRORS,
- TP_DBUS_ERROR_INCONSISTENT,
- "Connection manager %s is broken: contact #%u "
- "identifier changed from %s to %s",
- tp_proxy_get_bus_name (connection), handle,
- contact->priv->identifier, s);
+ for (i = 0; i < c->handles->len; i++)
+ {
+ TpContact *contact = g_ptr_array_index (c->contacts, i);
+ const gchar *s;
+ gpointer boxed;
+ GHashTable *asv = g_hash_table_lookup (attributes,
+ GUINT_TO_POINTER (contact->priv->handle));
- contacts_context_fail (c, e);
- g_error_free (e);
- g_object_unref (contact);
- return;
- }
+ if (asv == NULL)
+ {
+ GError *e = g_error_new (TP_DBUS_ERRORS, TP_DBUS_ERROR_INCONSISTENT,
+ "We hold a ref to handle #%u but it appears to be invalid",
+ contact->priv->handle);
- s = tp_asv_get_string (asv,
- TP_IFACE_CONNECTION_INTERFACE_ALIASING "/alias");
+ contacts_context_fail (c, e);
+ g_error_free (e);
+ return;
+ }
- if (s != NULL)
- {
- contact->priv->has_features |= CONTACT_FEATURE_FLAG_ALIAS;
- g_free (contact->priv->alias);
- contact->priv->alias = g_strdup (s);
- g_object_notify ((GObject *) contact, "alias");
- }
+ /* set up the contact with its attributes */
- s = tp_asv_get_string (asv,
- TP_IFACE_CONNECTION_INTERFACE_AVATARS "/token");
+ s = tp_asv_get_string (asv, TP_IFACE_CONNECTION "/contact-id");
- if (s != NULL)
- contacts_avatar_updated (connection, handle, s, NULL, NULL);
+ if (s == NULL)
+ {
+ GError *e = g_error_new (TP_DBUS_ERRORS, TP_DBUS_ERROR_INCONSISTENT,
+ "Connection manager %s is broken: contact #%u in the "
+ "GetContactAttributes result has no contact-id",
+ tp_proxy_get_bus_name (connection), contact->priv->handle);
- boxed = tp_asv_get_boxed (asv,
- TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE "/presence",
- TP_STRUCT_TYPE_SIMPLE_PRESENCE);
- contact_maybe_set_simple_presence (contact, boxed);
+ contacts_context_fail (c, e);
+ g_error_free (e);
+ return;
+ }
- /* FIXME: TP_IFACE_CONNECTION_INTERFACE_CAPABILITIES "/caps" */
+ if (contact->priv->identifier == NULL)
+ {
+ contact->priv->identifier = g_strdup (s);
+ }
+ else if (tp_strdiff (contact->priv->identifier, s))
+ {
+ GError *e = g_error_new (TP_DBUS_ERRORS, TP_DBUS_ERROR_INCONSISTENT,
+ "Connection manager %s is broken: contact #%u identifier "
+ "changed from %s to %s",
+ tp_proxy_get_bus_name (connection), contact->priv->handle,
+ contact->priv->identifier, s);
+
+ contacts_context_fail (c, e);
+ g_error_free (e);
+ return;
+ }
- /* save the contact and move on to the next handle */
- g_ptr_array_add (c->contacts, contact);
- i++;
+ s = tp_asv_get_string (asv,
+ TP_IFACE_CONNECTION_INTERFACE_ALIASING "/alias");
+
+ if (s != NULL)
+ {
+ contact->priv->has_features |= CONTACT_FEATURE_FLAG_ALIAS;
+ g_free (contact->priv->alias);
+ contact->priv->alias = g_strdup (s);
+ g_object_notify ((GObject *) contact, "alias");
}
+
+ s = tp_asv_get_string (asv,
+ TP_IFACE_CONNECTION_INTERFACE_AVATARS "/token");
+
+ if (s != NULL)
+ contacts_avatar_updated (connection, contact->priv->handle, s,
+ NULL, NULL);
+
+ boxed = tp_asv_get_boxed (asv,
+ TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE "/presence",
+ TP_STRUCT_TYPE_SIMPLE_PRESENCE);
+ contact_maybe_set_simple_presence (contact, boxed);
+
+ /* FIXME: TP_IFACE_CONNECTION_INTERFACE_CAPABILITIES "/caps" */
}
contacts_context_continue (c);
@@ -1758,10 +1782,13 @@ contacts_get_attributes (ContactsContext *context)
g_ptr_array_add (array, NULL);
supported_interfaces = (const gchar **) g_ptr_array_free (array, FALSE);
+ /* we want to hold the handles if and only if the call is by_handle -
+ * for the other modes, we already have handles */
context->refcount++;
tp_connection_get_contact_attributes (context->connection, -1,
context->handles->len, (const TpHandle *) context->handles->data,
- supported_interfaces, TRUE, contacts_got_attributes,
+ supported_interfaces, (context->signature == CB_BY_HANDLE),
+ contacts_got_attributes,
context, contacts_context_unref, context->weak_object);
g_free (supported_interfaces);
}
--
1.5.6.5
More information about the Telepathy-commits
mailing list