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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list