[libvirt] [libvirt-gconfig PATCHv2 04/32] Add gvir_config_object_replace_child helper

Christophe Fergeau cfergeau at redhat.com
Mon Nov 21 18:04:01 UTC 2011


This allows us to factor the code to add an XML node to a config
object.

--
v2: use g_return_if_fail to test function args for sanity

replace object
---
 libvirt-gconfig/libvirt-gconfig-object-private.h |    5 +
 libvirt-gconfig/libvirt-gconfig-object.c         |  105 +++++++++++++++-------
 libvirt-gconfig/libvirt-gconfig.h                |    2 +-
 3 files changed, 80 insertions(+), 32 deletions(-)

diff --git a/libvirt-gconfig/libvirt-gconfig-object-private.h b/libvirt-gconfig/libvirt-gconfig-object-private.h
index aec88bf..a14a792 100644
--- a/libvirt-gconfig/libvirt-gconfig-object-private.h
+++ b/libvirt-gconfig/libvirt-gconfig-object-private.h
@@ -35,6 +35,11 @@ void gvir_config_object_set_node_content(GVirConfigObject *object,
 void gvir_config_object_set_node_content_uint64(GVirConfigObject *object,
                                                 const char *node_name,
                                                 guint64 value);
+xmlNodePtr gvir_config_object_replace_child(GVirConfigObject *object,
+                                            const char *child_name);
+void gvir_config_object_set_child(GVirConfigObject *object,
+                                  xmlNodePtr child);
+
 
 G_END_DECLS
 
diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c
index 276be8c..ac10e88 100644
--- a/libvirt-gconfig/libvirt-gconfig-object.c
+++ b/libvirt-gconfig/libvirt-gconfig-object.c
@@ -297,34 +297,89 @@ gvir_config_object_get_node_content(GVirConfigObject *object,
     return gvir_config_xml_get_child_element_content_glib(node, node_name);
 }
 
-/* FIXME: if there are multiple nodes with the same name, this function
- * won't behave as expected. Should we get rid of the duplicated node names
- * here?
- */
-G_GNUC_INTERNAL void
-gvir_config_object_set_node_content(GVirConfigObject *object,
-                                    const char *node_name,
-                                    const char *value)
+static xmlNodePtr
+gvir_config_object_set_child_internal(GVirConfigObject *object,
+                                      xmlNodePtr child,
+                                      gboolean overwrite)
 {
     xmlNodePtr parent_node;
     xmlNodePtr old_node;
-    xmlNodePtr new_node;
-    xmlChar *encoded_name;
 
     parent_node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(object));
-    encoded_name = xmlEncodeEntitiesReentrant(parent_node->doc,
-                                              (xmlChar *)value);
-    new_node = xmlNewDocNode(parent_node->doc, NULL,
-                             (xmlChar *)node_name, encoded_name);
-    xmlFree(encoded_name);
+    g_return_val_if_fail (parent_node != NULL, NULL);
 
-    old_node = gvir_config_xml_get_element(parent_node, node_name, NULL);
+    old_node = gvir_config_xml_get_element(parent_node, child->name, NULL);
+    /* FIXME: should we make sure there are no multiple occurrences
+     * of this node?
+     */
     if (old_node) {
-        old_node = xmlReplaceNode(old_node, new_node);
-        xmlFreeNode(old_node);
+        if (overwrite) {
+            old_node = xmlReplaceNode(old_node, child);
+            xmlFreeNode(old_node);
+        } else {
+            return old_node;
+        }
     } else {
-        xmlAddChild(parent_node, new_node);
+        xmlAddChild(parent_node, child);
     }
+
+    return NULL;
+}
+
+G_GNUC_INTERNAL void
+gvir_config_object_set_child(GVirConfigObject *object, xmlNodePtr child)
+{
+    gvir_config_object_set_child_internal(object, child, TRUE);
+}
+
+G_GNUC_INTERNAL xmlNodePtr
+gvir_config_object_replace_child(GVirConfigObject *object,
+                                 const char *child_name)
+{
+    xmlNodePtr new_node;
+
+    g_return_val_if_fail(GVIR_IS_CONFIG_OBJECT(object), NULL);
+    g_return_val_if_fail(child_name != NULL, NULL);
+
+    new_node = xmlNewDocNode(NULL, NULL, (xmlChar *)child_name, NULL);
+    gvir_config_object_set_child_internal(object, new_node, TRUE);
+
+    return new_node;
+}
+
+G_GNUC_INTERNAL void
+gvir_config_object_set_node_content(GVirConfigObject *object,
+                                    const char *node_name,
+                                    const char *value)
+{
+    xmlNodePtr node;
+    xmlChar *encoded_data;
+
+    g_return_if_fail(GVIR_IS_CONFIG_OBJECT(object));
+    g_return_if_fail(node_name != NULL);
+    g_return_if_fail(value != NULL);
+
+    node = gvir_config_object_replace_child(object, node_name);
+    g_return_if_fail(node != NULL);
+    encoded_data = xmlEncodeEntitiesReentrant(node->doc,
+                                              (xmlChar *)value);
+    xmlNodeSetContent(node, encoded_data);
+    xmlFree(encoded_data);
+}
+
+G_GNUC_INTERNAL void
+gvir_config_object_set_node_content_uint64(GVirConfigObject *object,
+                                           const char *node_name,
+                                           guint64 value)
+{
+    char *str;
+
+    g_return_if_fail(GVIR_IS_CONFIG_OBJECT(object));
+    g_return_if_fail(node_name != NULL);
+
+    str = g_strdup_printf("%"G_GUINT64_FORMAT, value);
+    gvir_config_object_set_node_content(object, node_name, str);
+    g_free(str);
 }
 
 /* FIXME: how to notify of errors/node not found? */
@@ -350,18 +405,6 @@ gvir_config_object_get_node_content_uint64(GVirConfigObject *object,
     return value;
 }
 
-
-G_GNUC_INTERNAL void
-gvir_config_object_set_node_content_uint64(GVirConfigObject *object,
-                                           const char *node_name,
-                                           guint64 value)
-{
-    char *str;
-    str = g_strdup_printf("%"G_GUINT64_FORMAT, value);
-    gvir_config_object_set_node_content(object, node_name, str);
-    g_free(str);
-}
-
 GVirConfigObject *gvir_config_object_new_from_xml(GType type,
                                                   const char *root_name,
                                                   const char *schema,
diff --git a/libvirt-gconfig/libvirt-gconfig.h b/libvirt-gconfig/libvirt-gconfig.h
index fdc78a4..4e23f0d 100644
--- a/libvirt-gconfig/libvirt-gconfig.h
+++ b/libvirt-gconfig/libvirt-gconfig.h
@@ -26,11 +26,11 @@
 #include <glib-object.h>
 #include <libxml/tree.h>
 
-#include <libvirt-gconfig/libvirt-gconfig-helpers.h>
 #include <libvirt-gconfig/libvirt-gconfig-object.h>
 #include <libvirt-gconfig/libvirt-gconfig-capabilities.h>
 #include <libvirt-gconfig/libvirt-gconfig-domain.h>
 #include <libvirt-gconfig/libvirt-gconfig-domain-snapshot.h>
+#include <libvirt-gconfig/libvirt-gconfig-helpers.h>
 #include <libvirt-gconfig/libvirt-gconfig-interface.h>
 #include <libvirt-gconfig/libvirt-gconfig-network.h>
 #include <libvirt-gconfig/libvirt-gconfig-node-device.h>
-- 
1.7.7.3




More information about the libvir-list mailing list