[libvirt] [libvirt-glib 20/37] Improve gvir_config_object_new_child

Christophe Fergeau cfergeau at redhat.com
Thu Nov 10 20:33:52 UTC 2011


Add an "overwrite" boolean argument to indicate what to do when
the child we are about to create already exists.
---
 libvirt-gconfig/libvirt-gconfig-clock.c  |    3 +-
 libvirt-gconfig/libvirt-gconfig-domain.c |    2 +-
 libvirt-gconfig/libvirt-gconfig-object.c |   39 +++++++++++++++++++++++------
 libvirt-gconfig/libvirt-gconfig-object.h |    3 +-
 libvirt-gconfig/libvirt-gconfig-os.c     |   11 +++++---
 5 files changed, 43 insertions(+), 15 deletions(-)

diff --git a/libvirt-gconfig/libvirt-gconfig-clock.c b/libvirt-gconfig/libvirt-gconfig-clock.c
index 3deb725..7cf35bb 100644
--- a/libvirt-gconfig/libvirt-gconfig-clock.c
+++ b/libvirt-gconfig/libvirt-gconfig-clock.c
@@ -119,7 +119,8 @@ void gvir_config_clock_set_variable_offset(GVirConfigClock *klock,
     xmlNodePtr node;
     char *offset_str;
 
-    node = gvir_config_object_new_child(GVIR_CONFIG_OBJECT(klock), "clock");
+    node = gvir_config_object_new_child(GVIR_CONFIG_OBJECT(klock),
+                                        "clock", TRUE);
     if (node == NULL)
         return;
 
diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c
index 41390bd..88b46fb 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain.c
@@ -256,7 +256,7 @@ void gvir_config_domain_set_features(GVirConfigDomain *domain,
     GStrv it;
 
     features_node = gvir_config_object_new_child(GVIR_CONFIG_OBJECT(domain),
-                                                 "features");
+                                                 "features", TRUE);
     for (it = features; *it != NULL; it++) {
         xmlNodePtr node;
 
diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c
index 598ac0c..fd7d2d8 100644
--- a/libvirt-gconfig/libvirt-gconfig-object.c
+++ b/libvirt-gconfig/libvirt-gconfig-object.c
@@ -294,34 +294,57 @@ char *gvir_config_object_get_node_content(GVirConfigObject *object,
     return gvir_config_xml_get_child_element_content_glib(node, node_name);
 }
 
-void
-gvir_config_object_set_child(GVirConfigObject *object, xmlNodePtr child)
+static xmlNodePtr
+gvir_config_object_set_child_internal(GVirConfigObject *object,
+                                      xmlNodePtr child,
+                                      gboolean overwrite)
 {
     xmlNodePtr parent_node;
     xmlNodePtr old_node;
 
     parent_node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(object));
-    g_return_if_fail (parent_node != NULL);
+    g_return_val_if_fail (parent_node != NULL, 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, child);
-        xmlFreeNode(old_node);
+        if (overwrite) {
+            old_node = xmlReplaceNode(old_node, child);
+            xmlFreeNode(old_node);
+        } else {
+            return old_node;
+        }
     } else {
         xmlAddChild(parent_node, child);
     }
+
+    return NULL;
+}
+
+void
+gvir_config_object_set_child(GVirConfigObject *object, xmlNodePtr child)
+{
+    gvir_config_object_set_child_internal(object, child, TRUE);
 }
 
 xmlNodePtr
-gvir_config_object_new_child(GVirConfigObject *object, const char *child_name)
+gvir_config_object_new_child(GVirConfigObject *object,
+                             const char *child_name,
+                             gboolean overwrite)
 {
     xmlNodePtr new_node;
+    xmlNodePtr old_node;
 
     new_node = xmlNewDocNode(NULL, NULL, (xmlChar *)child_name, NULL);
-    gvir_config_object_set_child(object, new_node);
+    old_node = gvir_config_object_set_child_internal(object, new_node,
+                                                     overwrite);
+    if ((old_node != NULL) && !overwrite) {
+        xmlFreeNode(new_node);
+        return old_node;
+    }
+
     return new_node;
 }
 
@@ -332,7 +355,7 @@ void gvir_config_object_set_node_content(GVirConfigObject *object,
     xmlNodePtr node;
     xmlChar *encoded_data;
 
-    node = gvir_config_object_new_child(object, node_name);
+    node = gvir_config_object_new_child(object, node_name, TRUE);
     g_return_if_fail(node != NULL);
     encoded_data = xmlEncodeEntitiesReentrant(node->doc,
                                               (xmlChar *)value);
diff --git a/libvirt-gconfig/libvirt-gconfig-object.h b/libvirt-gconfig/libvirt-gconfig-object.h
index 8e67b92..096cefb 100644
--- a/libvirt-gconfig/libvirt-gconfig-object.h
+++ b/libvirt-gconfig/libvirt-gconfig-object.h
@@ -79,7 +79,8 @@ char *gvir_config_object_get_node_content(GVirConfigObject *object,
 guint64 gvir_config_object_get_node_content_uint64(GVirConfigObject *object,
                                                    const char *node_name);
 xmlNodePtr gvir_config_object_new_child(GVirConfigObject *object,
-                                        const char *child_name);
+                                        const char *child_name,
+                                        gboolean overwrite);
 void gvir_config_object_set_child(GVirConfigObject *object,
                                   xmlNodePtr child);
 void gvir_config_object_set_node_content(GVirConfigObject *object,
diff --git a/libvirt-gconfig/libvirt-gconfig-os.c b/libvirt-gconfig/libvirt-gconfig-os.c
index 3e23493..394bef5 100644
--- a/libvirt-gconfig/libvirt-gconfig-os.c
+++ b/libvirt-gconfig/libvirt-gconfig-os.c
@@ -85,7 +85,7 @@ void gvir_config_os_set_os_type(GVirConfigOs *os, GVirConfigOsType type)
     xmlNodePtr node;
     const char *type_str;
 
-    node = gvir_config_object_new_child(GVIR_CONFIG_OBJECT(os), "type");
+    node = gvir_config_object_new_child(GVIR_CONFIG_OBJECT(os), "type", TRUE);
     if (node == NULL)
         return;
     type_str = gvir_config_genum_get_nick(GVIR_TYPE_CONFIG_OS_TYPE, type);
@@ -103,7 +103,8 @@ void gvir_config_os_enable_boot_menu(GVirConfigOs *os, gboolean enable)
 {
     xmlNodePtr node;
 
-    node = gvir_config_object_new_child(GVIR_CONFIG_OBJECT(os), "bootmenu");
+    node = gvir_config_object_new_child(GVIR_CONFIG_OBJECT(os),
+                                        "bootmenu", TRUE);
     if (node == NULL)
         return;
     if (enable)
@@ -116,7 +117,8 @@ void gvir_config_os_bios_enable_serial(GVirConfigOs *os, gboolean enable)
 {
     xmlNodePtr node;
 
-    node = gvir_config_object_new_child(GVIR_CONFIG_OBJECT(os), "bios");
+    node = gvir_config_object_new_child(GVIR_CONFIG_OBJECT(os),
+                                        "bios", TRUE);
     if (node == NULL)
         return;
     if (enable)
@@ -131,7 +133,8 @@ void gvir_config_os_set_smbios_mode(GVirConfigOs *os,
     xmlNodePtr node;
     const char *mode_str;
 
-    node = gvir_config_object_new_child(GVIR_CONFIG_OBJECT(os), "smbios");
+    node = gvir_config_object_new_child(GVIR_CONFIG_OBJECT(os),
+                                        "smbios", TRUE);
     if (node == NULL)
         return;
     mode_str = gvir_config_genum_get_nick(GVIR_TYPE_CONFIG_OS_SM_BIOS_MODE,
-- 
1.7.7




More information about the libvir-list mailing list