[telepathy-gabble/master] Parse (Contact)Caps from a CapabilitySet
Simon McVittie
simon.mcvittie at collabora.co.uk
Tue Sep 8 04:09:59 PDT 2009
This reduces the duplication of code iterating across all the
<feature>s.
Patch originally by Will Thompson, but needed significant merging with
Guillaume's node_iter patches and Will's Gabble-version detection.
---
src/capabilities.c | 29 ++++++++--------
src/capabilities.h | 3 +-
src/caps-channel-manager.c | 4 +-
src/caps-channel-manager.h | 6 ++-
src/ft-manager.c | 23 +------------
src/presence-cache.c | 11 ++++--
src/private-tubes-factory.c | 77 +++++++++++++++++++------------------------
7 files changed, 65 insertions(+), 88 deletions(-)
diff --git a/src/capabilities.c b/src/capabilities.c
index 0d03579..424cabf 100644
--- a/src/capabilities.c
+++ b/src/capabilities.c
@@ -143,29 +143,28 @@ omits_content_creators (LmMessageNode *identity)
}
GabblePresenceCapabilities
-capabilities_parse (LmMessageNode *query_result)
+capabilities_parse (GabbleCapabilitySet *cap_set,
+ LmMessageNode *query_result)
{
GabblePresenceCapabilities ret = PRESENCE_CAP_NONE;
const gchar *var;
+ guint j;
const Feature *i;
- NodeIter j;
+ NodeIter ni;
- for (j = node_iter (query_result); j; j = node_iter_next (j))
+ /* special case: OMITS_CONTENT_CREATOR looks at the software version,
+ * not the actual features (sad face) */
+ for (ni = node_iter (query_result); ni != NULL; ni = node_iter_next (ni))
{
- LmMessageNode *child = node_iter_data (j);
+ LmMessageNode *child = node_iter_data (ni);
- if (tp_strdiff (child->name, "feature"))
- {
- if (omits_content_creators (child))
- ret |= PRESENCE_CAP_JINGLE_OMITS_CONTENT_CREATOR;
-
- continue;
- }
-
- var = lm_message_node_get_attribute (child, "var");
+ if (omits_content_creators (child))
+ ret |= PRESENCE_CAP_JINGLE_OMITS_CONTENT_CREATOR;
+ }
- if (NULL == var)
- continue;
+ for (j = 0; j < cap_set->len; j++)
+ {
+ var = g_ptr_array_index (cap_set, j);
for (i = self_advertised_features; i->ns != NULL; i++)
{
diff --git a/src/capabilities.h b/src/capabilities.h
index dd1ecd4..f481dc0 100644
--- a/src/capabilities.h
+++ b/src/capabilities.h
@@ -96,7 +96,8 @@ void capabilities_fill_cache (GabblePresenceCache *cache);
*/
GabblePresenceCapabilities capabilities_get_initial_caps (void);
-GabblePresenceCapabilities capabilities_parse (LmMessageNode *query_result);
+GabblePresenceCapabilities capabilities_parse (GabbleCapabilitySet *cap_set,
+ LmMessageNode *query_result);
typedef GabblePresenceCapabilities (*TypeFlagsToCapsFunc) (guint typeflags);
typedef guint (*CapsToTypeFlagsFunc) (GabblePresenceCapabilities caps);
diff --git a/src/caps-channel-manager.c b/src/caps-channel-manager.c
index 4b345c1..f6cc60d 100644
--- a/src/caps-channel-manager.c
+++ b/src/caps-channel-manager.c
@@ -95,7 +95,7 @@ void gabble_caps_channel_manager_get_feature_list (
gpointer gabble_caps_channel_manager_parse_capabilities (
GabbleCapsChannelManager *caps_manager,
- LmMessageNode *query_result)
+ GabbleCapabilitySet *cap_set)
{
GabbleCapsChannelManagerIface *iface =
GABBLE_CAPS_CHANNEL_MANAGER_GET_INTERFACE (caps_manager);
@@ -103,7 +103,7 @@ gpointer gabble_caps_channel_manager_parse_capabilities (
if (method != NULL)
{
- return method (caps_manager, query_result);
+ return method (caps_manager, cap_set);
}
/* ... else assume there is not caps for this kind of channels */
return NULL;
diff --git a/src/caps-channel-manager.h b/src/caps-channel-manager.h
index 6c6edb9..75b2e9a 100644
--- a/src/caps-channel-manager.h
+++ b/src/caps-channel-manager.h
@@ -28,6 +28,7 @@
#include <telepathy-glib/exportable-channel.h>
#include <telepathy-glib/handle.h>
+#include "capabilities.h"
#include "types.h"
G_BEGIN_DECLS
@@ -68,7 +69,7 @@ typedef void (*GabbleCapsChannelManagerGetFeatureListFunc) (
GSList **features);
typedef gpointer (*GabbleCapsChannelManagerParseCapsFunc) (
- GabbleCapsChannelManager *manager, LmMessageNode *children);
+ GabbleCapsChannelManager *manager, GabbleCapabilitySet *cap_set);
typedef void (*GabbleCapsChannelManagerFreeCapsFunc) (
GabbleCapsChannelManager *manager, gpointer specific_caps);
@@ -95,7 +96,8 @@ void gabble_caps_channel_manager_get_feature_list (
GSList **features);
gpointer gabble_caps_channel_manager_parse_capabilities (
- GabbleCapsChannelManager *manager, LmMessageNode *query_result);
+ GabbleCapsChannelManager *manager,
+ GabbleCapabilitySet *cap_set);
void gabble_caps_channel_manager_free_capabilities (GabbleCapsChannelManager *manager,
gpointer specific_caps);
diff --git a/src/ft-manager.c b/src/ft-manager.c
index c47f97c..a0d5d40 100644
--- a/src/ft-manager.c
+++ b/src/ft-manager.c
@@ -675,28 +675,9 @@ gabble_ft_manager_get_contact_caps (GabbleCapsChannelManager *manager,
static gpointer
gabble_ft_manager_parse_caps (GabbleCapsChannelManager *manager,
- LmMessageNode *query_result)
+ GabbleCapabilitySet *cap_set)
{
- NodeIter i;
-
- for (i = node_iter (query_result); i; i = node_iter_next (i))
- {
- LmMessageNode *child = node_iter_data (i);
- const gchar *var;
-
- if (0 != strcmp (child->name, "feature"))
- continue;
-
- var = lm_message_node_get_attribute (child, "var");
-
- if (NULL == var)
- continue;
-
- if (!tp_strdiff (var, NS_FILE_TRANSFER))
- return GINT_TO_POINTER (TRUE);
- }
-
- return GINT_TO_POINTER (FALSE);
+ return GINT_TO_POINTER (gabble_capability_set_has (cap_set, NS_FILE_TRANSFER));
}
static void
diff --git a/src/presence-cache.c b/src/presence-cache.c
index 81eaa4f..f5155a4 100644
--- a/src/presence-cache.c
+++ b/src/presence-cache.c
@@ -912,7 +912,7 @@ find_matching_waiter (GSList *waiters,
static GHashTable *
parse_contact_caps (TpBaseConnection *base_conn,
- LmMessageNode *query_result)
+ GabbleCapabilitySet *cap_set)
{
GHashTable *per_channel_manager_caps = g_hash_table_new (NULL, NULL);
TpChannelManagerIter iter;
@@ -928,7 +928,7 @@ parse_contact_caps (TpBaseConnection *base_conn,
g_assert (GABBLE_IS_CAPS_CHANNEL_MANAGER (manager));
factory_caps = gabble_caps_channel_manager_parse_capabilities (
- GABBLE_CAPS_CHANNEL_MANAGER (manager), query_result);
+ GABBLE_CAPS_CHANNEL_MANAGER (manager), cap_set);
if (factory_caps != NULL)
g_hash_table_insert (per_channel_manager_caps,
@@ -1009,6 +1009,7 @@ _caps_disco_cb (GabbleDisco *disco,
GabblePresenceCache *cache;
GabblePresenceCachePrivate *priv;
TpHandleRepoIface *contact_repo;
+ GabbleCapabilitySet *cap_set;
GabblePresenceCapabilities caps = 0;
GHashTable *per_channel_manager_caps;
guint trust;
@@ -1055,8 +1056,10 @@ _caps_disco_cb (GabbleDisco *disco,
goto OUT;
}
- caps = capabilities_parse (query_result);
- per_channel_manager_caps = parse_contact_caps (base_conn, query_result);
+ cap_set = gabble_capability_set_new_from_stanza (query_result);
+ caps = capabilities_parse (cap_set, query_result);
+ per_channel_manager_caps = parse_contact_caps (base_conn, cap_set);
+ gabble_capability_set_free (cap_set);
/* Only 'sha-1' is mandatory to implement by XEP-0115. If the remote contact
* uses another hash algorithm, don't check the hash and fallback to the old
diff --git a/src/private-tubes-factory.c b/src/private-tubes-factory.c
index 5a10640..f23a291 100644
--- a/src/private-tubes-factory.c
+++ b/src/private-tubes-factory.c
@@ -658,59 +658,50 @@ gabble_private_tubes_factory_free_feat (gpointer data)
g_free (feat);
}
+static void
+examine_node (const gchar *var,
+ TubesCapabilities *caps)
+{
+ gchar *service;
+
+ if (!g_str_has_prefix (var, NS_TUBES))
+ return;
+
+ /* tubes generic cap or service specific */
+ caps->tubes_supported = TRUE;
+
+ if (g_str_has_prefix (var, NS_TUBES "/"))
+ {
+ /* http://telepathy.freedesktop.org/xmpp/tubes/$type#$service */
+ var += strlen (NS_TUBES "/");
+ if (g_str_has_prefix (var, "stream#"))
+ {
+ var += strlen ("stream#");
+ service = g_strdup (var);
+ g_hash_table_insert (caps->stream_tube_caps, service, NULL);
+ }
+ else if (g_str_has_prefix (var, "dbus#"))
+ {
+ var += strlen ("dbus#");
+ service = g_strdup (var);
+ g_hash_table_insert (caps->dbus_tube_caps, service, NULL);
+ }
+ }
+}
+
static gpointer
gabble_private_tubes_factory_parse_caps (
GabbleCapsChannelManager *manager,
- LmMessageNode *query_result)
+ GabbleCapabilitySet *cap_set)
{
- TubesCapabilities *caps;
- NodeIter i;
+ TubesCapabilities *caps = g_new0 (TubesCapabilities, 1);
- caps = g_new0 (TubesCapabilities, 1);
caps->stream_tube_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, gabble_private_tubes_factory_free_feat);
caps->dbus_tube_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, gabble_private_tubes_factory_free_feat);
- for (i = node_iter (query_result); i; i = node_iter_next (i))
- {
- LmMessageNode *child = node_iter_data (i);
- const gchar *var;
-
- if (0 != strcmp (child->name, "feature"))
- continue;
-
- var = lm_message_node_get_attribute (child, "var");
-
- if (NULL == var)
- continue;
-
- if (!g_str_has_prefix (var, NS_TUBES))
- continue;
-
- /* tubes generic cap or service specific */
- caps->tubes_supported = TRUE;
-
- if (g_str_has_prefix (var, NS_TUBES "/"))
- {
- /* http://telepathy.freedesktop.org/xmpp/tubes/$type#$service */
- var += strlen (NS_TUBES "/");
- if (g_str_has_prefix (var, "stream#"))
- {
- gchar *service;
- var += strlen ("stream#");
- service = g_strdup (var);
- g_hash_table_insert (caps->stream_tube_caps, service, NULL);
- }
- else if (g_str_has_prefix (var, "dbus#"))
- {
- gchar *service;
- var += strlen ("dbus#");
- service = g_strdup (var);
- g_hash_table_insert (caps->dbus_tube_caps, service, NULL);
- }
- }
- }
+ g_ptr_array_foreach (cap_set, (GFunc) examine_node, caps);
return caps;
}
--
1.5.6.5
More information about the telepathy-commits
mailing list