[telepathy-gabble/master] Make GabbleCapabilitySet opaque
Simon McVittie
simon.mcvittie at collabora.co.uk
Tue Sep 8 04:10:08 PDT 2009
---
src/capabilities.c | 45 ++++++++++++++++++++++++++-------------
src/capabilities.h | 6 +++-
src/caps-hash.c | 14 +++++++++++-
src/connection.c | 9 +++----
src/private-tubes-factory.c | 49 +++++++++++++++++++++++++-----------------
5 files changed, 80 insertions(+), 43 deletions(-)
diff --git a/src/capabilities.c b/src/capabilities.c
index a291d24..d21cef6 100644
--- a/src/capabilities.c
+++ b/src/capabilities.c
@@ -141,6 +141,10 @@ omits_content_creators (LmMessageNode *identity)
}
}
+struct _GabbleCapabilitySet {
+ GPtrArray *strings;
+};
+
GabblePresenceCapabilities
capabilities_parse (GabbleCapabilitySet *cap_set,
LmMessageNode *query_result)
@@ -161,9 +165,9 @@ capabilities_parse (GabbleCapabilitySet *cap_set,
ret |= PRESENCE_CAP_JINGLE_OMITS_CONTENT_CREATOR;
}
- for (j = 0; j < cap_set->len; j++)
+ for (j = 0; j < cap_set->strings->len; j++)
{
- var = g_ptr_array_index (cap_set, j);
+ var = g_ptr_array_index (cap_set->strings, j);
for (i = self_advertised_features; i->ns != NULL; i++)
{
@@ -222,7 +226,10 @@ const CapabilityConversionData capabilities_conversions[] =
GabbleCapabilitySet *
gabble_capability_set_new (void)
{
- return g_ptr_array_new ();
+ GabbleCapabilitySet *ret = g_slice_new0 (GabbleCapabilitySet);
+
+ ret->strings = g_ptr_array_new ();
+ return ret;
}
GabbleCapabilitySet *
@@ -294,8 +301,8 @@ gabble_capability_set_update (GabbleCapabilitySet *target,
g_return_if_fail (target != NULL);
g_return_if_fail (source != NULL);
- for (i = 0; i < source->len; i++)
- gabble_capability_set_add (target, g_ptr_array_index (source, i));
+ for (i = 0; i < source->strings->len; i++)
+ gabble_capability_set_add (target, g_ptr_array_index (source->strings, i));
}
void
@@ -306,7 +313,7 @@ gabble_capability_set_add (GabbleCapabilitySet *caps,
g_return_if_fail (cap != NULL);
if (!gabble_capability_set_has (caps, cap))
- g_ptr_array_add (caps, g_strdup (cap));
+ g_ptr_array_add (caps->strings, g_strdup (cap));
}
void
@@ -316,10 +323,10 @@ gabble_capability_set_clear (GabbleCapabilitySet *caps)
g_return_if_fail (caps != NULL);
- for (i = 0; i < caps->len; i++)
- g_free (g_ptr_array_index (caps, i));
+ for (i = 0; i < caps->strings->len; i++)
+ g_free (g_ptr_array_index (caps->strings, i));
- g_ptr_array_set_size (caps, 0);
+ g_ptr_array_set_size (caps->strings, 0);
}
void
@@ -328,7 +335,8 @@ gabble_capability_set_free (GabbleCapabilitySet *caps)
g_return_if_fail (caps != NULL);
gabble_capability_set_clear (caps);
- g_ptr_array_free (caps, TRUE);
+ g_ptr_array_free (caps->strings, TRUE);
+ g_slice_free (GabbleCapabilitySet, caps);
}
gboolean
@@ -340,8 +348,8 @@ gabble_capability_set_has (const GabbleCapabilitySet *caps,
g_return_val_if_fail (caps != NULL, FALSE);
g_return_val_if_fail (cap != NULL, FALSE);
- for (i = 0; i < caps->len; i++)
- if (!tp_strdiff (g_ptr_array_index (caps, i), cap))
+ for (i = 0; i < caps->strings->len; i++)
+ if (!tp_strdiff (g_ptr_array_index (caps->strings, i), cap))
return TRUE;
return FALSE;
@@ -356,12 +364,19 @@ gabble_capability_set_equals (const GabbleCapabilitySet *a,
g_return_val_if_fail (a != NULL, FALSE);
g_return_val_if_fail (b != NULL, FALSE);
- if (a->len != b->len)
+ if (a->strings->len != b->strings->len)
return FALSE;
- for (i = 0; i < a->len; i++)
- if (!gabble_capability_set_has (b, g_ptr_array_index (a, i)))
+ for (i = 0; i < a->strings->len; i++)
+ if (!gabble_capability_set_has (b, g_ptr_array_index (a->strings, i)))
return FALSE;
return TRUE;
}
+
+void
+gabble_capability_set_foreach (const GabbleCapabilitySet *caps,
+ GFunc func, gpointer user_data)
+{
+ g_ptr_array_foreach (caps->strings, func, user_data);
+}
diff --git a/src/capabilities.h b/src/capabilities.h
index fb11476..aafe364 100644
--- a/src/capabilities.h
+++ b/src/capabilities.h
@@ -43,9 +43,9 @@ struct _Feature
/**
* GabbleCapabilitySet:
*
- * A GPtrArray of gchar *, treated as a set.
+ * A set of capabilities.
*/
-typedef GPtrArray GabbleCapabilitySet;
+typedef struct _GabbleCapabilitySet GabbleCapabilitySet;
GabbleCapabilitySet *gabble_capability_set_new (void);
GabbleCapabilitySet *gabble_capability_set_new_from_stanza (
@@ -64,6 +64,8 @@ gboolean gabble_capability_set_equals (const GabbleCapabilitySet *a,
const GabbleCapabilitySet *b);
void gabble_capability_set_clear (GabbleCapabilitySet *caps);
void gabble_capability_set_free (GabbleCapabilitySet *caps);
+void gabble_capability_set_foreach (const GabbleCapabilitySet *caps,
+ GFunc func, gpointer user_data);
/* XEP-0115 version 1.3:
*
diff --git a/src/caps-hash.c b/src/caps-hash.c
index 21d96f1..2eeb15d 100644
--- a/src/caps-hash.c
+++ b/src/caps-hash.c
@@ -349,6 +349,12 @@ caps_hash_compute_from_lm_node (LmMessageNode *node)
return str;
}
+static void
+ptr_array_strdup (gpointer str,
+ gpointer array)
+{
+ g_ptr_array_add (array, g_strdup (str));
+}
/**
* Compute our hash as defined by the XEP-0115.
@@ -359,7 +365,8 @@ gchar *
caps_hash_compute_from_self_presence (GabbleConnection *self)
{
GabblePresence *presence = self->self_presence;
- GPtrArray *features = gabble_presence_get_caps (presence);
+ GabbleCapabilitySet *cap_set;
+ GPtrArray *features = g_ptr_array_new ();
GPtrArray *identities = g_ptr_array_new ();
GPtrArray *dataforms = g_ptr_array_new ();
gchar *str;
@@ -369,6 +376,11 @@ caps_hash_compute_from_self_presence (GabbleConnection *self)
/* Gabble does not use dataforms, let 'dataforms' be empty */
+ /* FIXME: somehow allow iteration over this without copying twice */
+ cap_set = gabble_presence_get_caps (presence);
+ gabble_capability_set_foreach (cap_set, ptr_array_strdup, features);
+ gabble_capability_set_free (cap_set);
+
str = caps_hash_compute (features, identities, dataforms);
gabble_presence_free_xep0115_hash (features, identities, dataforms);
diff --git a/src/connection.c b/src/connection.c
index 4d3c576..da6f020 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -1623,8 +1623,8 @@ _gabble_connection_send_iq_error (GabbleConnection *conn,
}
static void
-add_feature_node (LmMessageNode *result_query,
- const gchar *namespace)
+add_feature_node (gpointer namespace,
+ gpointer result_query)
{
LmMessageNode *feature_node;
@@ -1650,7 +1650,6 @@ connection_iq_disco_cb (LmMessageHandler *handler,
LmMessageNode *iq, *result_iq, *query, *result_query, *identity;
const gchar *node, *suffix;
GabbleCapabilitySet *features;
- guint i;
gchar *caps_hash;
if (lm_message_get_sub_type (message) != LM_MESSAGE_SUB_TYPE_GET)
@@ -1726,8 +1725,8 @@ connection_iq_disco_cb (LmMessageHandler *handler,
}
else
{
- for (i = 0; i < features->len; i++)
- add_feature_node (result_query, g_ptr_array_index (features, i));
+ gabble_capability_set_foreach (features, add_feature_node,
+ result_query);
NODE_DEBUG (result_iq, "sending disco response");
diff --git a/src/private-tubes-factory.c b/src/private-tubes-factory.c
index 209cc0f..c4bfb18 100644
--- a/src/private-tubes-factory.c
+++ b/src/private-tubes-factory.c
@@ -517,6 +517,31 @@ add_generic_tube_caps (GPtrArray *arr)
#define STREAM_CAP_PREFIX (NS_TUBES "/stream#")
#define DBUS_CAP_PREFIX (NS_TUBES "/dbus#")
+typedef struct {
+ gboolean supports_tubes;
+ GPtrArray *arr;
+ TpHandle handle;
+} GetContactCapsClosure;
+
+static void
+get_contact_caps_foreach (gpointer ns,
+ gpointer user_data)
+{
+ GetContactCapsClosure *closure = user_data;
+
+ if (!g_str_has_prefix (ns, NS_TUBES))
+ return;
+
+ closure->supports_tubes = TRUE;
+
+ if (g_str_has_prefix (ns, STREAM_CAP_PREFIX))
+ add_service_to_array (ns + strlen (STREAM_CAP_PREFIX), closure->arr,
+ TP_TUBE_TYPE_STREAM, closure->handle);
+ else if (g_str_has_prefix (ns, DBUS_CAP_PREFIX))
+ add_service_to_array (ns + strlen (DBUS_CAP_PREFIX), closure->arr,
+ TP_TUBE_TYPE_DBUS, closure->handle);
+}
+
static void
gabble_private_tubes_factory_get_contact_caps (
GabbleCapsChannelManager *manager,
@@ -525,30 +550,14 @@ gabble_private_tubes_factory_get_contact_caps (
GPtrArray *arr)
{
GabblePrivateTubesFactory *self = GABBLE_PRIVATE_TUBES_FACTORY (manager);
- gboolean supports_tubes;
- guint i;
+ GetContactCapsClosure closure = { FALSE, arr, handle };
/* Always claim that we support tubes. */
- supports_tubes = (handle == self->priv->conn->parent.self_handle);
-
- for (i = 0; i < caps->len; i++)
- {
- const gchar *ns = g_ptr_array_index (caps, i);
+ closure.supports_tubes = (handle == self->priv->conn->parent.self_handle);
- if (!g_str_has_prefix (ns, NS_TUBES))
- continue;
-
- supports_tubes = TRUE;
-
- if (g_str_has_prefix (ns, STREAM_CAP_PREFIX))
- add_service_to_array (ns + strlen (STREAM_CAP_PREFIX), arr,
- TP_TUBE_TYPE_STREAM, handle);
- else if (g_str_has_prefix (ns, DBUS_CAP_PREFIX))
- add_service_to_array (ns + strlen (DBUS_CAP_PREFIX), arr,
- TP_TUBE_TYPE_DBUS, handle);
- }
+ gabble_capability_set_foreach (caps, get_contact_caps_foreach, &closure);
- if (supports_tubes)
+ if (closure.supports_tubes)
add_generic_tube_caps (arr);
}
--
1.5.6.5
More information about the telepathy-commits
mailing list