summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWill Thompson <will.thompson@collabora.co.uk>2012-11-27 10:27:40 +0000
committerWill Thompson <will.thompson@collabora.co.uk>2012-12-06 17:30:53 +0000
commitdbe5edf811d8585866eb4ac605676963a7f19601 (patch)
tree242a406b8e10e7e4f76b49318b7c9ce7c5f19cd2 /src
parent1327065e89774ae1f7ffe07dcc473f21d4bdac60 (diff)
vcard-manager: represent new node tree as a node tree.
Diffstat (limited to 'src')
-rw-r--r--src/conn-avatars.c4
-rw-r--r--src/vcard-manager.c165
2 files changed, 72 insertions, 97 deletions
diff --git a/src/conn-avatars.c b/src/conn-avatars.c
index b74af5d92..a90555113 100644
--- a/src/conn-avatars.c
+++ b/src/conn-avatars.c
@@ -854,8 +854,8 @@ gabble_connection_set_avatar (TpSvcConnectionInterfaceAvatars *iface,
edit_info = gabble_vcard_manager_edit_info_new ("PHOTO",
NULL, GABBLE_VCARD_EDIT_REPLACE,
- "TYPE", mime_type,
- "BINVAL", base64,
+ '(', "TYPE", '$', mime_type, ')',
+ '(', "BINVAL", '$', base64, ')',
NULL);
g_free (base64);
diff --git a/src/vcard-manager.c b/src/vcard-manager.c
index 963548ae7..1c09ff367 100644
--- a/src/vcard-manager.c
+++ b/src/vcard-manager.c
@@ -48,53 +48,29 @@ static guint request_wait_delay = 5 * 60;
static const gchar *NO_ALIAS = "none";
-typedef struct {
- gchar *key;
- gchar *value;
-} GabbleVCardChild;
-
-static GabbleVCardChild *
-gabble_vcard_child_new (const gchar *key,
- const gchar *value)
-{
- GabbleVCardChild *child = g_slice_new (GabbleVCardChild);
-
- child->key = g_strdup (key);
- child->value = g_strdup (value);
- return child;
-}
-
-static void
-gabble_vcard_child_free (GabbleVCardChild *child)
-{
- g_free (child->key);
- g_free (child->value);
- g_slice_free (GabbleVCardChild, child);
-}
-
struct _GabbleVCardManagerEditInfo {
/* name of element to edit */
gchar *element_name;
- /* value of element to edit or NULL if no value should be used */
- gchar *element_value;
-
- /* list of GabbleVCardChild */
- GList *children;
-
/* If REPLACE, the first element with this name (if any) will be updated;
* if APPEND, an element with this name will be added;
* if DELETE, all elements with this name will be removed;
* if CLEAR, everything except PHOTO and NICKNAME will be deleted, in
* preparation for a SetContactInfo operation
- * if SET_ALIAS and element_value is NULL, set the best alias we have
+ * if SET_ALIAS and new_alias is NULL, set the best alias we have
* as the NICKNAME or FN (as appropriate) if that field doesn't already
* have a value
- * if SET_ALIAS and element_value is non-NULL, set that
+ * if SET_ALIAS and new_alias is non-NULL, set that
* as the NICKNAME or FN (as appropriate), overriding anything already
* there
*/
GabbleVCardEditType edit_type;
+
+ /* the element to fill in, if edit_type is REPLACE or APPEND. */
+ WockyNodeTree *element;
+
+ /* only meaningful if edit_type is SET_ALIAS; see above. */
+ gchar *new_alias;
};
/* signal enum */
@@ -978,7 +954,10 @@ gabble_vcard_manager_replace_is_significant (GabbleVCardManagerEditInfo *info,
{
gboolean seen = FALSE;
WockyNodeIter i;
- WockyNode *node;
+ WockyNode *node, *replacement_node;
+
+ g_return_val_if_fail (info->element != NULL, FALSE);
+ replacement_node = wocky_node_tree_get_top_node (info->element);
/* Find the first node matching the one we want to edit */
wocky_node_iter_init (&i, old_vcard, info->element_name, NULL);
@@ -997,7 +976,7 @@ gabble_vcard_manager_replace_is_significant (GabbleVCardManagerEditInfo *info,
/* consider NULL and "" to be different representations for the
* same thing */
value = node->content;
- new_value = info->element_value;
+ new_value = replacement_node->content;
if (value == NULL)
value = "";
@@ -1017,19 +996,17 @@ gabble_vcard_manager_replace_is_significant (GabbleVCardManagerEditInfo *info,
* about avoiding unnecessary edits: assume that the PHOTO on
* the server doesn't have extra children, and that one matching
* child is enough. */
- GList *child_iter;
+ WockyNodeIter child_iter;
+ WockyNode *new_child_node;
- for (child_iter = info->children;
- child_iter != NULL;
- child_iter = child_iter->next)
+ wocky_node_iter_init (&child_iter, replacement_node, NULL, NULL);
+ while (wocky_node_iter_next (&child_iter, &new_child_node))
{
- GabbleVCardChild *child = child_iter->data;
- WockyNode *child_node = wocky_node_get_child (node,
- child->key);
+ WockyNode *old_child_node = wocky_node_get_child (node,
+ new_child_node->name);
- if (child_node == NULL ||
- tp_strdiff (child_node->content,
- child->value))
+ if (old_child_node == NULL ||
+ tp_strdiff (old_child_node->content, new_child_node->content))
{
return TRUE;
}
@@ -1037,7 +1014,7 @@ gabble_vcard_manager_replace_is_significant (GabbleVCardManagerEditInfo *info,
}
else
{
- if (info->children != NULL)
+ if (replacement_node->children != NULL)
return TRUE;
}
}
@@ -1066,25 +1043,6 @@ remove_all_children_named (
return changed;
}
-static void
-add_new_child (
- GabbleVCardManagerEditInfo *info,
- WockyNode *vcard_node)
-{
- WockyNode *node;
- GList *iter;
-
- node = wocky_node_add_child_with_content (vcard_node,
- info->element_name, info->element_value);
-
- for (iter = info->children; iter != NULL; iter = iter->next)
- {
- GabbleVCardChild *child = iter->data;
-
- wocky_node_add_child_with_content (node, child->key, child->value);
- }
-}
-
static gboolean
gabble_vcard_manager_edit_info_apply_replace (
GabbleVCardManagerEditInfo *info,
@@ -1113,7 +1071,7 @@ gabble_vcard_manager_edit_info_apply_replace (
}
remove_all_children_named (vcard_node, info->element_name);
- add_new_child (info, vcard_node);
+ wocky_node_add_node_tree (vcard_node, info->element);
return TRUE;
}
@@ -1132,7 +1090,7 @@ gabble_vcard_manager_edit_info_apply_append (
return FALSE;
}
- add_new_child (info, vcard_node);
+ wocky_node_add_node_tree (vcard_node, info->element);
return TRUE;
}
@@ -1195,7 +1153,7 @@ gabble_vcard_manager_edit_info_apply_set_alias (
info->element_name = g_strdup ("FN");
}
- if (info->element_value == NULL)
+ if (info->new_alias == NULL)
{
/* We're just trying to fix a possibly-incomplete SetContactInfo() */
WockyNode *node = wocky_node_get_child (old_vcard, info->element_name);
@@ -1215,9 +1173,11 @@ gabble_vcard_manager_edit_info_apply_set_alias (
return FALSE;
}
- info->element_value = alias;
+ info->new_alias = alias;
}
+ info->element = wocky_node_tree_new (info->element_name, NS_VCARD_TEMP,
+ '$', info->new_alias, NULL);
info->edit_type = GABBLE_VCARD_EDIT_REPLACE;
return gabble_vcard_manager_edit_info_apply_replace (info, old_vcard,
vcard_manager);
@@ -1797,36 +1757,49 @@ gabble_vcard_manager_edit_info_new (const gchar *element_name,
{
GabbleVCardManagerEditInfo *info;
va_list ap;
- const gchar *key;
- const gchar *value;
-
- if (edit_type == GABBLE_VCARD_EDIT_DELETE)
- {
- const gchar *first_edit = NULL;
-
- g_return_val_if_fail (element_value == NULL, NULL);
-
- va_start (ap, edit_type);
- first_edit = va_arg (ap, const gchar *);
- va_end (ap);
- g_return_val_if_fail (first_edit == NULL, NULL);
- }
- info = g_slice_new (GabbleVCardManagerEditInfo);
+ info = g_slice_new0 (GabbleVCardManagerEditInfo);
info->element_name = g_strdup (element_name);
- info->element_value = g_strdup (element_value);
info->edit_type = edit_type;
- info->children = NULL;
va_start (ap, edit_type);
- while ((key = va_arg (ap, const gchar *)))
+ switch (edit_type)
{
- value = va_arg (ap, const gchar *);
- gabble_vcard_manager_edit_info_add_child (info, key, value);
- }
+ case GABBLE_VCARD_EDIT_REPLACE:
+ case GABBLE_VCARD_EDIT_APPEND:
+ g_return_val_if_fail (element_name != NULL, NULL);
+
+ info->element = wocky_node_tree_new_va (element_name, NS_VCARD_TEMP,
+ ap);
+ va_end (ap);
+
+ if (element_value != NULL)
+ wocky_node_set_content (wocky_node_tree_get_top_node (info->element),
+ element_value);
+
+ break;
+
+ case GABBLE_VCARD_EDIT_SET_ALIAS:
+ g_return_val_if_fail (element_name == NULL, NULL);
- va_end (ap);
+ info->new_alias = g_strdup (element_value);
+ element_value = NULL;
+
+ /* deliberate fall-through to check the varargs... */
+ case GABBLE_VCARD_EDIT_DELETE:
+ case GABBLE_VCARD_EDIT_CLEAR:
+ {
+ const gchar *first_edit = NULL;
+
+ g_return_val_if_fail (element_value == NULL, NULL);
+
+ first_edit = va_arg (ap, const gchar *);
+ va_end (ap);
+ g_return_val_if_fail (first_edit == NULL, NULL);
+ break;
+ }
+ }
return info;
}
@@ -1837,17 +1810,19 @@ gabble_vcard_manager_edit_info_add_child (
const gchar *key,
const gchar *value)
{
- edit_info->children = g_list_append (edit_info->children,
- gabble_vcard_child_new (key, value));
+ g_return_if_fail (edit_info->element != NULL);
+
+ wocky_node_add_child_with_content (
+ wocky_node_tree_get_top_node (edit_info->element),
+ key, value);
}
void
gabble_vcard_manager_edit_info_free (GabbleVCardManagerEditInfo *info)
{
g_free (info->element_name);
- g_free (info->element_value);
- g_list_foreach (info->children, (GFunc) gabble_vcard_child_free, NULL);
- g_list_free (info->children);
+ g_free (info->new_alias);
+ g_clear_object (&info->element);
g_slice_free (GabbleVCardManagerEditInfo, info);
}