[Telepathy-commits] [telepathy-gabble/master] workaround for Loudmouth not handling xml namespaces

Senko Rasic senko.rasic at collabora.co.uk
Tue Dec 2 04:34:11 PST 2008


---
 src/jingle-content.c          |   21 +++++++-----
 src/jingle-media-rtp.c        |    4 ++-
 src/jingle-session.c          |   14 +++++---
 src/jingle-transport-google.c |    2 +-
 src/util.c                    |   69 ++++++++++++++++++++++++++++++++--------
 src/util.h                    |    5 +++
 6 files changed, 84 insertions(+), 31 deletions(-)

diff --git a/src/jingle-content.c b/src/jingle-content.c
index bdd0492..cc83ab8 100644
--- a/src/jingle-content.c
+++ b/src/jingle-content.c
@@ -454,8 +454,8 @@ gabble_jingle_content_parse_add (GabbleJingleContent *c,
 
   g_object_get (c->session, "dialect", &dialect, NULL);
 
-  desc_node = lm_message_node_get_child (content_node, "description");
-  trans_node = lm_message_node_get_child (content_node, "transport");
+  desc_node = lm_message_node_get_child_any_ns (content_node, "description");
+  trans_node = lm_message_node_get_child_any_ns (content_node, "transport");
   creator = lm_message_node_get_attribute (content_node, "creator");
   name = lm_message_node_get_attribute (content_node, "name");
   senders = lm_message_node_get_attribute (content_node, "senders");
@@ -497,7 +497,7 @@ gabble_jingle_content_parse_add (GabbleJingleContent *c,
   /* if we didn't set it to google-p2p implicitly already, detect it */
   if (transport_type == 0)
     {
-      const gchar *ns = lm_message_node_get_attribute (trans_node, "xmlns");
+      const gchar *ns = lm_message_node_get_namespace (trans_node);
 
       transport_type = GPOINTER_TO_INT (
           g_hash_table_lookup (c->conn->jingle_factory->transports, ns));
@@ -541,11 +541,14 @@ gabble_jingle_content_parse_add (GabbleJingleContent *c,
       (GCallback) new_transport_candidates_cb, c);
 
   /* Depending on transport, there may be initial candidates specified here */
-  gabble_jingle_transport_iface_parse_candidates (trans, trans_node, error);
-  if (*error)
+  if (trans_node != NULL)
     {
-      g_object_unref (trans);
-      return;
+      gabble_jingle_transport_iface_parse_candidates (trans, trans_node, error);
+      if (*error)
+        {
+          g_object_unref (trans);
+          return;
+        }
     }
 
   g_assert (priv->transport == NULL);
@@ -578,8 +581,8 @@ gabble_jingle_content_parse_accept (GabbleJingleContent *c,
   LmMessageNode *trans_node, *desc_node;
   JingleDialect dialect;
 
-  desc_node = lm_message_node_get_child (content_node, "description");
-  trans_node = lm_message_node_get_child (content_node, "transport");
+  desc_node = lm_message_node_get_child_any_ns (content_node, "description");
+  trans_node = lm_message_node_get_child_any_ns (content_node, "transport");
   senders = lm_message_node_get_attribute (content_node, "senders");
 
   g_object_get (c->session, "dialect", &dialect, NULL);
diff --git a/src/jingle-media-rtp.c b/src/jingle-media-rtp.c
index 147ee09..e26f500 100644
--- a/src/jingle-media-rtp.c
+++ b/src/jingle-media-rtp.c
@@ -238,6 +238,8 @@ parse_description (GabbleJingleContent *content,
   GList *codecs = NULL;
   LmMessageNode *node;
 
+  DEBUG ("node: %s", desc_node->name);
+
   if (lm_message_node_has_namespace (desc_node, NS_JINGLE_RTP, NULL))
     {
       const gchar *type = lm_message_node_get_attribute (desc_node, "media");
@@ -295,7 +297,7 @@ parse_description (GabbleJingleContent *content,
       guint clockrate, channels;
       guint i;
 
-      if (tp_strdiff (node->name, "payload-type"))
+      if (tp_strdiff (lm_message_node_get_name (node), "payload-type"))
           continue;
 
       txt = lm_message_node_get_attribute (node, "id");
diff --git a/src/jingle-session.c b/src/jingle-session.c
index 617a6fe..fbca3c0 100644
--- a/src/jingle-session.c
+++ b/src/jingle-session.c
@@ -480,7 +480,7 @@ _foreach_content (GabbleJingleSession *sess, LmMessageNode *node,
        NULL != content_node;
        content_node = content_node->next)
     {
-      if (tp_strdiff (content_node->name, "content"))
+      if (tp_strdiff (lm_message_node_get_name (content_node), "content"))
         continue;
 
       name = lm_message_node_get_attribute (content_node, "name");
@@ -599,13 +599,15 @@ _each_content_add (GabbleJingleSession *sess, GabbleJingleContent *c,
 {
   GabbleJingleSessionPrivate *priv = GABBLE_JINGLE_SESSION_GET_PRIVATE (sess);
   const gchar *name = lm_message_node_get_attribute (content_node, "name");
-  LmMessageNode *desc_node = lm_message_node_get_child (content_node, "description");
+  LmMessageNode *desc_node = lm_message_node_get_child_any_ns (content_node,
+      "description");
   GType content_type = 0;
   const gchar *content_ns = NULL;
 
   if (desc_node != NULL)
     {
-      content_ns = lm_message_node_get_attribute (desc_node, "xmlns");
+      content_ns = lm_message_node_get_namespace (desc_node);
+      DEBUG ("namespace: %s", content_ns);
       content_type =
           GPOINTER_TO_INT (g_hash_table_lookup (priv->conn->jingle_factory->content_types,
           content_ns));
@@ -878,7 +880,7 @@ on_transport_info (GabbleJingleSession *sess, LmMessageNode *node,
             }
           else
             {
-              node = lm_message_node_get_child (node, "transport");
+              node = lm_message_node_get_child_any_ns (node, "transport");
 
               if (node == NULL)
                 {
@@ -892,7 +894,7 @@ on_transport_info (GabbleJingleSession *sess, LmMessageNode *node,
     {
       const gchar *name;
 
-      node = lm_message_node_get_child (node, "content");
+      node = lm_message_node_get_child_any_ns (node, "content");
       name = lm_message_node_get_attribute (node, "name");
       c = g_hash_table_lookup (priv->contents, name);
 
@@ -903,7 +905,7 @@ on_transport_info (GabbleJingleSession *sess, LmMessageNode *node,
         }
 
       /* we need transport child of content node */
-      node = lm_message_node_get_child (node, "transport");
+      node = lm_message_node_get_child_any_ns (node, "transport");
     }
 
   gabble_jingle_content_parse_transport_info (c, node, error);
diff --git a/src/jingle-transport-google.c b/src/jingle-transport-google.c
index e1a64b0..a376986 100644
--- a/src/jingle-transport-google.c
+++ b/src/jingle-transport-google.c
@@ -250,7 +250,7 @@ parse_candidates (GabbleJingleTransportIface *obj,
       JingleCandidateType ctype;
       JingleCandidate *c;
 
-      if (tp_strdiff (node->name, "candidate"))
+      if (tp_strdiff (lm_message_node_get_name (node), "candidate"))
           continue;
 
       name = lm_message_node_get_attribute (node, "name");
diff --git a/src/util.c b/src/util.c
index 35fab78..d3d61f5 100644
--- a/src/util.c
+++ b/src/util.c
@@ -127,26 +127,67 @@ lm_message_node_steal_children (LmMessageNode *snatcher,
     baby->parent = snatcher;
 }
 
-gboolean
-lm_message_node_has_namespace (LmMessageNode *node,
-                               const gchar *ns,
-                               const gchar *tag)
+/* variant of lm_message_node_get_child() which ignores node namespace
+ * prefix */
+LmMessageNode *
+lm_message_node_get_child_any_ns (LmMessageNode *node, const gchar *name)
 {
-  gchar *attribute = NULL;
-  const gchar *node_ns;
-  gboolean ret;
+  LmMessageNode *child;
 
-  if (tag != NULL)
-    attribute = g_strconcat ("xmlns:", tag, NULL);
+  for (child = node->children; child != NULL; child = child->next)
+    {
+      if (!tp_strdiff (lm_message_node_get_name (child), name))
+          return child;
+    }
 
-  node_ns = lm_message_node_get_attribute (node,
-      tag != NULL ? attribute : "xmlns");
+  return NULL;
+}
 
-  ret = !tp_strdiff (node_ns, ns);
+const gchar *
+lm_message_node_get_namespace (LmMessageNode *node)
+{
+  const gchar *node_ns = NULL;
+  gchar *x = strchr (node->name, ':');
 
-  g_free (attribute);
+  if (x != NULL)
+    {
+      gchar *prefix = g_strndup (node->name, (x - node->name));
+      gchar *attr = g_strdup_printf ("xmlns:%s", prefix);
 
-  return ret;
+      /* find the namespace in this node or its parents */
+      for (node_ns = NULL; (node != NULL) && (node_ns == NULL); node = node->parent)
+        {
+          node_ns = lm_message_node_get_attribute (node, attr);
+        }
+
+      g_free (prefix);
+      g_free (attr);
+    }
+  else
+    {
+      node_ns = lm_message_node_get_attribute (node, "xmlns");
+    }
+
+  return node_ns;
+}
+
+const gchar *
+lm_message_node_get_name (LmMessageNode *node)
+{
+  gchar *x = strchr (node->name, ':');
+
+  if (x != NULL)
+    return x + 1;
+  else
+    return node->name;
+}
+
+gboolean
+lm_message_node_has_namespace (LmMessageNode *node,
+                               const gchar *ns,
+                               const gchar *tag)
+{
+  return (!tp_strdiff (lm_message_node_get_namespace (node), ns));
 }
 
 LmMessageNode *
diff --git a/src/util.h b/src/util.h
index fceebbf..20e51af 100644
--- a/src/util.h
+++ b/src/util.h
@@ -72,5 +72,10 @@ GHashTable *lm_message_node_extract_properties (LmMessageNode *node,
 void
 lm_message_node_add_children_from_properties (LmMessageNode *node,
     GHashTable *properties, const gchar *prop);
+const gchar * lm_message_node_get_namespace (LmMessageNode *node);
+const gchar * lm_message_node_get_name (LmMessageNode *node);
+LmMessageNode * lm_message_node_get_child_any_ns (LmMessageNode *node,
+    const gchar *name);
+
 
 #endif /* __GABBLE_UTIL_H__ */
-- 
1.5.6.5




More information about the Telepathy-commits mailing list