[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