[telepathy-gabble/master] Represent PRESENCE_CAP_JINGLE_OMITS_CONTENT_CREATOR as a pseudo-namespace
Simon McVittie
simon.mcvittie at collabora.co.uk
Tue Sep 8 04:10:05 PDT 2009
---
src/capabilities.c | 82 ++++++++++++++++++++++++++++++++++---------------
src/capabilities.h | 10 +++++-
src/presence-cache.c | 2 +-
3 files changed, 66 insertions(+), 28 deletions(-)
diff --git a/src/capabilities.c b/src/capabilities.c
index 35c4dcc..5c7a6bd 100644
--- a/src/capabilities.c
+++ b/src/capabilities.c
@@ -75,6 +75,12 @@ static const Feature self_advertised_features[] =
{ 0, NULL, 0}
};
+static const Feature quirks[] = {
+ { 0, QUIRK_OMITS_CONTENT_CREATORS,
+ PRESENCE_CAP_JINGLE_OMITS_CONTENT_CREATOR },
+ { 0, NULL, 0 }
+};
+
const GabbleCapabilitySet *
gabble_capabilities_get_bundle_voice_v1 ()
{
@@ -110,9 +116,6 @@ omits_content_creators (LmMessageNode *identity)
gchar *end;
int ver;
- if (tp_strdiff (identity->name, "identity"))
- return FALSE;
-
name = lm_message_node_get_attribute (identity, "name");
if (name == NULL)
@@ -183,27 +186,14 @@ struct _GabbleCapabilitySet {
};
GabblePresenceCapabilities
-capabilities_parse (GabbleCapabilitySet *cap_set,
- LmMessageNode *query_result)
+capabilities_parse (GabbleCapabilitySet *cap_set)
{
GabblePresenceCapabilities ret = PRESENCE_CAP_NONE;
const gchar *var;
const Feature *i;
- NodeIter ni;
TpIntSetIter iter;
g_return_val_if_fail (cap_set != NULL, 0);
- g_return_val_if_fail (query_result != NULL, 0);
-
- /* 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 (ni);
-
- if (omits_content_creators (child))
- ret |= PRESENCE_CAP_JINGLE_OMITS_CONTENT_CREATOR;
- }
tp_intset_iter_init (&iter, tp_handle_set_peek (cap_set->handles));
@@ -211,17 +201,34 @@ capabilities_parse (GabbleCapabilitySet *cap_set,
{
var = tp_handle_inspect (feature_handles, iter.element);
- for (i = self_advertised_features; i->ns != NULL; i++)
+ if (var[0] == QUIRK_PREFIX_CHAR)
{
- if (!tp_strdiff (var, i->ns))
+ for (i = quirks; i->ns != NULL; i++)
{
- ret |= i->caps;
- break;
+ if (!tp_strdiff (var, i->ns))
+ {
+ ret |= i->caps;
+ break;
+ }
}
+
+ if (i->ns == NULL)
+ g_warning ("unknown quirk: %s", var + 1);
}
+ else
+ {
+ for (i = self_advertised_features; i->ns != NULL; i++)
+ {
+ if (!tp_strdiff (var, i->ns))
+ {
+ ret |= i->caps;
+ break;
+ }
+ }
- if (i->ns == NULL)
- DEBUG ("ignoring unknown capability %s", var);
+ if (i->ns == NULL)
+ DEBUG ("ignoring unknown capability %s", var);
+ }
}
return ret;
@@ -290,6 +297,16 @@ gabble_capability_set_new_from_stanza (LmMessageNode *query_result)
{
LmMessageNode *child = node_iter_data (ni);
+ if (!tp_strdiff (child->name, "identity"))
+ {
+ if (omits_content_creators (child))
+ {
+ gabble_capability_set_add (ret, QUIRK_OMITS_CONTENT_CREATORS);
+ }
+
+ continue;
+ }
+
if (tp_strdiff (child->name, "feature"))
continue;
@@ -298,6 +315,12 @@ gabble_capability_set_new_from_stanza (LmMessageNode *query_result)
if (NULL == var)
continue;
+ if (G_UNLIKELY (var[0] == QUIRK_PREFIX_CHAR))
+ {
+ /* I think not! (It's not allowed in XML...) */
+ continue;
+ }
+
/* TODO: only store namespaces we understand. */
gabble_capability_set_add (ret, var);
}
@@ -318,6 +341,10 @@ gabble_capability_set_new_from_flags (GabblePresenceCapabilities caps)
if ((i->caps & caps) == i->caps)
gabble_capability_set_add (ret, i->ns);
+ for (i = quirks; NULL != i->ns; i++)
+ if ((i->caps & caps) == i->caps)
+ gabble_capability_set_add (ret, i->ns);
+
return ret;
}
@@ -434,6 +461,7 @@ gabble_capability_set_equals (const GabbleCapabilitySet *a,
tp_handle_set_peek (b->handles));
}
+/* Does not iterate over quirks, only real features. */
void
gabble_capability_set_foreach (const GabbleCapabilitySet *caps,
GFunc func, gpointer user_data)
@@ -447,7 +475,11 @@ gabble_capability_set_foreach (const GabbleCapabilitySet *caps,
while (tp_intset_iter_next (&iter))
{
- func ((gchar *) tp_handle_inspect (feature_handles, iter.element),
- user_data);
+ const gchar *var = tp_handle_inspect (feature_handles, iter.element);
+
+ g_return_if_fail (var != NULL);
+
+ if (var[0] != QUIRK_PREFIX_CHAR)
+ func ((gchar *) var, user_data);
}
}
diff --git a/src/capabilities.h b/src/capabilities.h
index 74972a8..039b888 100644
--- a/src/capabilities.h
+++ b/src/capabilities.h
@@ -40,6 +40,13 @@ struct _Feature
GabblePresenceCapabilities caps;
};
+/* Pseudo-capabilities for buggy or strange implementations, represented as
+ * strings starting with a character not allowed in XML (the ASCII beep :-) */
+#define QUIRK_PREFIX_CHAR '\x07'
+#define QUIRK_PREFIX "\x07"
+/* Gabble 0.7.x with 16 <= x < 29 omits @creator on <content/> */
+#define QUIRK_OMITS_CONTENT_CREATORS "\x07omits-content-creators"
+
/**
* GabbleCapabilitySet:
*
@@ -108,8 +115,7 @@ void capabilities_fill_cache (GabblePresenceCache *cache);
*/
GabblePresenceCapabilities capabilities_get_initial_caps (void);
-GabblePresenceCapabilities capabilities_parse (GabbleCapabilitySet *cap_set,
- LmMessageNode *query_result);
+GabblePresenceCapabilities capabilities_parse (GabbleCapabilitySet *cap_set);
typedef GabblePresenceCapabilities (*TypeFlagsToCapsFunc) (guint typeflags);
typedef guint (*CapsToTypeFlagsFunc) (GabblePresenceCapabilities caps);
diff --git a/src/presence-cache.c b/src/presence-cache.c
index ad131f8..fee574f 100644
--- a/src/presence-cache.c
+++ b/src/presence-cache.c
@@ -955,7 +955,7 @@ _caps_disco_cb (GabbleDisco *disco,
}
cap_set = gabble_capability_set_new_from_stanza (query_result);
- caps = capabilities_parse (cap_set, query_result);
+ caps = capabilities_parse (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
--
1.5.6.5
More information about the telepathy-commits
mailing list