|
Packit |
a07778 |
/*
|
|
Packit |
a07778 |
* libvirt-gconfig-object.c: base object for XML configuration
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Copyright (C) 2008 Daniel P. Berrange
|
|
Packit |
a07778 |
* Copyright (C) 2010-2011 Red Hat, Inc.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
a07778 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
a07778 |
* License as published by the Free Software Foundation; either
|
|
Packit |
a07778 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
a07778 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a07778 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
a07778 |
* Lesser General Public License for more details.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
a07778 |
* License along with this library. If not, see
|
|
Packit |
a07778 |
* <http://www.gnu.org/licenses/>.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Author: Daniel P. Berrange <berrange@redhat.com>
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#include <config.h>
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#include <string.h>
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#include <libxml/relaxng.h>
|
|
Packit |
a07778 |
#include <glib/gi18n-lib.h>
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#include "libvirt-gconfig/libvirt-gconfig.h"
|
|
Packit |
a07778 |
#include "libvirt-gconfig/libvirt-gconfig-private.h"
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#define GVIR_CONFIG_OBJECT_GET_PRIVATE(obj) \
|
|
Packit |
a07778 |
(G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_CONFIG_TYPE_OBJECT, GVirConfigObjectPrivate))
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
struct _GVirConfigObjectPrivate
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
gchar *schema;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
GVirConfigXmlDoc *doc;
|
|
Packit |
a07778 |
xmlNodePtr node;
|
|
Packit |
a07778 |
};
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_DEFINE_TYPE_WITH_PRIVATE(GVirConfigObject, gvir_config_object, G_TYPE_OBJECT);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
enum {
|
|
Packit |
a07778 |
PROP_0,
|
|
Packit |
a07778 |
PROP_SCHEMA,
|
|
Packit |
a07778 |
PROP_NODE,
|
|
Packit |
a07778 |
PROP_DOC
|
|
Packit |
a07778 |
};
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_xml_generic_error_nop(void *userData G_GNUC_UNUSED,
|
|
Packit |
a07778 |
const char *msg G_GNUC_UNUSED,
|
|
Packit |
a07778 |
...)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_xml_structured_error_nop(void *userData G_GNUC_UNUSED,
|
|
Packit |
a07778 |
xmlErrorPtr error G_GNUC_UNUSED)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_config_object_get_property(GObject *object,
|
|
Packit |
a07778 |
guint prop_id,
|
|
Packit |
a07778 |
GValue *value,
|
|
Packit |
a07778 |
GParamSpec *pspec)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConfigObject *obj = GVIR_CONFIG_OBJECT(object);
|
|
Packit |
a07778 |
GVirConfigObjectPrivate *priv = obj->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
switch (prop_id) {
|
|
Packit |
a07778 |
case PROP_SCHEMA:
|
|
Packit |
a07778 |
g_value_set_string(value, priv->schema);
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
case PROP_NODE:
|
|
Packit |
a07778 |
g_value_set_pointer(value, gvir_config_object_get_xml_node(obj));
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
case PROP_DOC:
|
|
Packit |
a07778 |
g_value_set_object(value, obj->priv->doc);
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
default:
|
|
Packit |
a07778 |
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_config_object_set_property(GObject *object,
|
|
Packit |
a07778 |
guint prop_id,
|
|
Packit |
a07778 |
const GValue *value,
|
|
Packit |
a07778 |
GParamSpec *pspec)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConfigObject *obj = GVIR_CONFIG_OBJECT(object);
|
|
Packit |
a07778 |
GVirConfigObjectPrivate *priv = obj->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
switch (prop_id) {
|
|
Packit |
a07778 |
case PROP_SCHEMA:
|
|
Packit |
a07778 |
g_free(priv->schema);
|
|
Packit |
a07778 |
priv->schema = g_value_dup_string(value);
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
case PROP_NODE:
|
|
Packit |
a07778 |
priv->node =g_value_get_pointer(value);
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
case PROP_DOC:
|
|
Packit |
a07778 |
obj->priv->doc = g_value_dup_object(value);
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
default:
|
|
Packit |
a07778 |
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_config_object_finalize(GObject *object)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConfigObject *gvir_object = GVIR_CONFIG_OBJECT(object);
|
|
Packit |
a07778 |
GVirConfigObjectPrivate *priv = gvir_object->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_free(priv->schema);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (priv->doc != NULL) {
|
|
Packit |
a07778 |
g_object_unref(G_OBJECT(priv->doc));
|
|
Packit |
a07778 |
priv->node = NULL; /* node belongs to doc, make sure not to free it */
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
if (priv->node != NULL) {
|
|
Packit |
a07778 |
g_assert(priv->node->doc == NULL);
|
|
Packit |
a07778 |
xmlFreeNode(priv->node);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_OBJECT_CLASS(gvir_config_object_parent_class)->finalize(object);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_config_object_class_init(GVirConfigObjectClass *klass)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
object_class->finalize = gvir_config_object_finalize;
|
|
Packit |
a07778 |
object_class->get_property = gvir_config_object_get_property;
|
|
Packit |
a07778 |
object_class->set_property = gvir_config_object_set_property;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_object_class_install_property(object_class,
|
|
Packit |
a07778 |
PROP_SCHEMA,
|
|
Packit |
a07778 |
g_param_spec_string("schema",
|
|
Packit |
a07778 |
"Schema",
|
|
Packit |
a07778 |
"The doc RNG schema",
|
|
Packit |
a07778 |
NULL,
|
|
Packit |
a07778 |
G_PARAM_READABLE |
|
|
Packit |
a07778 |
G_PARAM_WRITABLE |
|
|
Packit |
a07778 |
G_PARAM_CONSTRUCT_ONLY |
|
|
Packit |
a07778 |
G_PARAM_STATIC_STRINGS));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_object_class_install_property(object_class,
|
|
Packit |
a07778 |
PROP_NODE,
|
|
Packit |
a07778 |
g_param_spec_pointer("node",
|
|
Packit |
a07778 |
"XML Node",
|
|
Packit |
a07778 |
"The XML node this config object corresponds to",
|
|
Packit |
a07778 |
G_PARAM_READWRITE |
|
|
Packit |
a07778 |
G_PARAM_CONSTRUCT_ONLY |
|
|
Packit |
a07778 |
G_PARAM_STATIC_STRINGS));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_object_class_install_property(object_class,
|
|
Packit |
a07778 |
PROP_DOC,
|
|
Packit |
a07778 |
g_param_spec_object("doc",
|
|
Packit |
a07778 |
"XML Doc",
|
|
Packit |
a07778 |
"The XML doc this config object corresponds to",
|
|
Packit |
a07778 |
GVIR_CONFIG_TYPE_XML_DOC,
|
|
Packit |
a07778 |
G_PARAM_READWRITE |
|
|
Packit |
a07778 |
G_PARAM_CONSTRUCT_ONLY |
|
|
Packit |
a07778 |
G_PARAM_STATIC_STRINGS));
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_config_object_init(GVirConfigObject *object)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
object->priv = GVIR_CONFIG_OBJECT_GET_PRIVATE(object);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
void gvir_config_object_validate(GVirConfigObject *config,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConfigObjectPrivate *priv;
|
|
Packit |
a07778 |
xmlRelaxNGParserCtxtPtr rngParser = NULL;
|
|
Packit |
a07778 |
xmlRelaxNGPtr rng = NULL;
|
|
Packit |
a07778 |
xmlRelaxNGValidCtxtPtr rngValid = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_CONFIG_IS_OBJECT(config));
|
|
Packit |
a07778 |
g_return_if_fail(err == NULL || *err == NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = config->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
xmlSetGenericErrorFunc(NULL, gvir_xml_generic_error_nop);
|
|
Packit |
a07778 |
xmlSetStructuredErrorFunc(NULL, gvir_xml_structured_error_nop);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!priv->node) {
|
|
Packit |
a07778 |
gvir_config_set_error_literal(err,
|
|
Packit |
a07778 |
GVIR_CONFIG_OBJECT_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("No XML document associated with this config object"));
|
|
Packit |
a07778 |
return;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!priv->schema) {
|
|
Packit |
a07778 |
gvir_config_set_error_literal(err,
|
|
Packit |
a07778 |
GVIR_CONFIG_OBJECT_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("No XML schema associated with this config object"));
|
|
Packit |
a07778 |
return;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
rngParser = xmlRelaxNGNewParserCtxt(priv->schema);
|
|
Packit |
a07778 |
if (!rngParser) {
|
|
Packit |
a07778 |
gvir_config_set_error(err,
|
|
Packit |
a07778 |
GVIR_CONFIG_OBJECT_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Unable to create RNG parser for %s"),
|
|
Packit |
a07778 |
priv->schema);
|
|
Packit |
a07778 |
return;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
rng = xmlRelaxNGParse(rngParser);
|
|
Packit |
a07778 |
if (!rng) {
|
|
Packit |
a07778 |
gvir_config_set_error(err,
|
|
Packit |
a07778 |
GVIR_CONFIG_OBJECT_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Unable to parse RNG %s"),
|
|
Packit |
a07778 |
priv->schema);
|
|
Packit |
a07778 |
xmlRelaxNGFreeParserCtxt(rngParser);
|
|
Packit |
a07778 |
return;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
xmlRelaxNGFreeParserCtxt(rngParser);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
rngValid = xmlRelaxNGNewValidCtxt(rng);
|
|
Packit |
a07778 |
if (!rngValid) {
|
|
Packit |
a07778 |
gvir_config_set_error(err,
|
|
Packit |
a07778 |
GVIR_CONFIG_OBJECT_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Unable to create RNG validation context %s"),
|
|
Packit |
a07778 |
priv->schema);
|
|
Packit |
a07778 |
xmlRelaxNGFree(rng);
|
|
Packit |
a07778 |
return;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (xmlRelaxNGValidateDoc(rngValid, priv->node->doc) != 0) {
|
|
Packit |
a07778 |
gvir_config_set_error_literal(err,
|
|
Packit |
a07778 |
GVIR_CONFIG_OBJECT_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Unable to validate doc"));
|
|
Packit |
a07778 |
xmlRelaxNGFreeValidCtxt(rngValid);
|
|
Packit |
a07778 |
xmlRelaxNGFree(rng);
|
|
Packit |
a07778 |
return;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
xmlRelaxNGFreeValidCtxt(rngValid);
|
|
Packit |
a07778 |
xmlRelaxNGFree(rng);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
gchar *gvir_config_object_to_xml(GVirConfigObject *config)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_CONFIG_IS_OBJECT(config), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return gvir_config_xml_node_to_string(config->priv->node);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
const gchar *gvir_config_object_get_schema(GVirConfigObject *config)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_CONFIG_IS_OBJECT(config), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return config->priv->schema;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL GVirConfigXmlDoc *
|
|
Packit |
a07778 |
gvir_config_object_get_xml_doc(GVirConfigObject *config)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
return config->priv->doc;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/* FIXME: will we always have one xmlNode per GConfig object? */
|
|
Packit |
a07778 |
/* FIXME: need to return the right node from subclasses */
|
|
Packit |
a07778 |
/* NB: the xmlNodePtr must not be freed by the caller */
|
|
Packit |
a07778 |
G_GNUC_INTERNAL xmlNodePtr
|
|
Packit |
a07778 |
gvir_config_object_get_xml_node(GVirConfigObject *config)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
return config->priv->node;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL const char *
|
|
Packit |
a07778 |
gvir_config_object_get_node_content(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *node_name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNodePtr node;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(object));
|
|
Packit |
a07778 |
if (node == NULL)
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return gvir_config_xml_get_child_element_content(node, node_name);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL const char *
|
|
Packit |
a07778 |
gvir_config_object_get_attribute(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *node_name,
|
|
Packit |
a07778 |
const char *attr_name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNodePtr node;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(attr_name != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(object));
|
|
Packit |
a07778 |
if (node == NULL)
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (node_name != NULL) {
|
|
Packit |
a07778 |
node = gvir_config_xml_get_element(node, node_name, NULL);
|
|
Packit |
a07778 |
if (node == NULL)
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return gvir_config_xml_get_attribute_content(node, attr_name);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static xmlNodePtr
|
|
Packit |
a07778 |
gvir_config_object_set_child_internal(GVirConfigObject *object,
|
|
Packit |
a07778 |
xmlNodePtr child,
|
|
Packit |
a07778 |
gboolean overwrite)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNodePtr parent_node;
|
|
Packit |
a07778 |
xmlNodePtr old_node;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
parent_node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(object));
|
|
Packit |
a07778 |
g_return_val_if_fail (parent_node != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
old_node = gvir_config_xml_get_element(parent_node, child->name, NULL);
|
|
Packit |
a07778 |
/* FIXME: should we make sure there are no multiple occurrences
|
|
Packit |
a07778 |
* of this node?
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
if (old_node) {
|
|
Packit |
a07778 |
if (overwrite) {
|
|
Packit |
a07778 |
old_node = xmlReplaceNode(old_node, child);
|
|
Packit |
a07778 |
xmlFreeNode(old_node);
|
|
Packit |
a07778 |
} else {
|
|
Packit |
a07778 |
return old_node;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
} else {
|
|
Packit |
a07778 |
xmlAddChild(parent_node, child);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_set_child(GVirConfigObject *object, xmlNodePtr child)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
gvir_config_object_set_child_internal(object, child, TRUE);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_foreach_child(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *parent_name,
|
|
Packit |
a07778 |
GVirConfigXmlNodeIterator iter_func,
|
|
Packit |
a07778 |
gpointer opaque)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNodePtr root_node;
|
|
Packit |
a07778 |
xmlNodePtr node;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_CONFIG_IS_OBJECT(object));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
root_node = gvir_config_object_get_xml_node(object);
|
|
Packit |
a07778 |
g_return_if_fail(root_node != NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
node = gvir_config_xml_get_element(root_node, parent_name, NULL);
|
|
Packit |
a07778 |
if (node == NULL)
|
|
Packit |
a07778 |
return;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
gvir_config_xml_foreach_child(node, iter_func, opaque);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL GVirConfigObject *
|
|
Packit |
a07778 |
gvir_config_object_add_child(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *child_name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNodePtr new_node;
|
|
Packit |
a07778 |
xmlNodePtr old_node;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_CONFIG_IS_OBJECT(object), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(child_name != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
new_node = xmlNewDocNode(NULL, NULL, (xmlChar *)child_name, NULL);
|
|
Packit |
a07778 |
old_node = gvir_config_object_set_child_internal(object, new_node,
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
if (old_node != NULL) {
|
|
Packit |
a07778 |
xmlFreeNode(new_node);
|
|
Packit |
a07778 |
return GVIR_CONFIG_OBJECT(g_object_new(GVIR_CONFIG_TYPE_OBJECT,
|
|
Packit |
a07778 |
"doc", object->priv->doc,
|
|
Packit |
a07778 |
"node", old_node,
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return GVIR_CONFIG_OBJECT(g_object_new(GVIR_CONFIG_TYPE_OBJECT,
|
|
Packit |
a07778 |
"doc", object->priv->doc,
|
|
Packit |
a07778 |
"node", new_node,
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_add_child_with_attribute(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *child_name,
|
|
Packit |
a07778 |
const char *attr_name,
|
|
Packit |
a07778 |
const char *attr_value)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConfigObject *child;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
child = gvir_config_object_add_child(object, child_name);
|
|
Packit |
a07778 |
gvir_config_object_set_attribute(child, attr_name, attr_value, NULL);
|
|
Packit |
a07778 |
g_object_unref(G_OBJECT(child));
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
void gvir_config_object_add_child_with_attribute_enum(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *child_name,
|
|
Packit |
a07778 |
const char *attr_name,
|
|
Packit |
a07778 |
GType attr_type,
|
|
Packit |
a07778 |
unsigned int attr_value)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConfigObject *child;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
child = gvir_config_object_add_child(object, child_name);
|
|
Packit |
a07778 |
gvir_config_object_set_attribute_with_type(child, attr_name, attr_type, attr_value, NULL);
|
|
Packit |
a07778 |
g_object_unref(G_OBJECT(child));
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL GVirConfigObject *
|
|
Packit |
a07778 |
gvir_config_object_replace_child(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *child_name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNodePtr new_node;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_CONFIG_IS_OBJECT(object), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(child_name != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
new_node = xmlNewDocNode(NULL, NULL, (xmlChar *)child_name, NULL);
|
|
Packit |
a07778 |
gvir_config_object_set_child_internal(object, new_node, TRUE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return GVIR_CONFIG_OBJECT(g_object_new(GVIR_CONFIG_TYPE_OBJECT,
|
|
Packit |
a07778 |
"doc", object->priv->doc,
|
|
Packit |
a07778 |
"node", new_node,
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_replace_child_with_attribute(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *child_name,
|
|
Packit |
a07778 |
const char *attr_name,
|
|
Packit |
a07778 |
const char *attr_value)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConfigObject *child;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
child = gvir_config_object_replace_child(object, child_name);
|
|
Packit |
a07778 |
gvir_config_object_set_attribute(child, attr_name, attr_value, NULL);
|
|
Packit |
a07778 |
g_object_unref(G_OBJECT(child));
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_replace_child_with_attribute_enum(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *child_name,
|
|
Packit |
a07778 |
const char *attr_name,
|
|
Packit |
a07778 |
GType attr_type,
|
|
Packit |
a07778 |
unsigned int attr_value)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConfigObject *child;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
child = gvir_config_object_replace_child(object, child_name);
|
|
Packit |
a07778 |
gvir_config_object_set_attribute_with_type(child, attr_name, attr_type, attr_value, NULL);
|
|
Packit |
a07778 |
g_object_unref(G_OBJECT(child));
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
struct NodeMatch {
|
|
Packit |
a07778 |
const char *name;
|
|
Packit |
a07778 |
const char *ns;
|
|
Packit |
a07778 |
};
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static gboolean maybe_unlink_node(xmlNodePtr node, void *opaque)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
gboolean dounlink = TRUE;
|
|
Packit |
a07778 |
struct NodeMatch *match = (struct NodeMatch *)opaque;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (match->ns != NULL) {
|
|
Packit |
a07778 |
dounlink = dounlink && (g_strcmp0(match->ns, (char *)node->ns->href) == 0);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (match->name != NULL) {
|
|
Packit |
a07778 |
dounlink = dounlink && (g_strcmp0(match->name, (char *)node->name) == 0);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
if (dounlink) {
|
|
Packit |
a07778 |
xmlUnlinkNode(node);
|
|
Packit |
a07778 |
xmlFreeNode(node);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return dounlink;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static gboolean remove_oneshot(xmlNodePtr node, gpointer opaque)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
return !maybe_unlink_node(node, opaque);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_delete_child(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *child_name,
|
|
Packit |
a07778 |
const char *ns_href)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
struct NodeMatch match;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_CONFIG_IS_OBJECT(object));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
match.name = child_name;
|
|
Packit |
a07778 |
match.ns = ns_href;
|
|
Packit |
a07778 |
gvir_config_object_foreach_child(object, NULL, remove_oneshot, &match);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static gboolean remove_always(xmlNodePtr node, gpointer opaque)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
maybe_unlink_node(node, opaque);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_delete_children(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *child_name,
|
|
Packit |
a07778 |
const char *ns_href)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
struct NodeMatch match;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_CONFIG_IS_OBJECT(object));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
match.name = child_name;
|
|
Packit |
a07778 |
match.ns = ns_href;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
gvir_config_object_foreach_child(object, NULL, remove_always, &match);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_set_node_content(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *node_name,
|
|
Packit |
a07778 |
const char *value)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlChar *encoded_data;
|
|
Packit |
a07778 |
GVirConfigObject *node;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_CONFIG_IS_OBJECT(object));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (value == NULL) {
|
|
Packit |
a07778 |
gvir_config_object_delete_child(object, node_name, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (node_name != NULL) {
|
|
Packit |
a07778 |
node = gvir_config_object_replace_child(object, node_name);
|
|
Packit |
a07778 |
g_return_if_fail(node != NULL);
|
|
Packit |
a07778 |
} else {
|
|
Packit |
a07778 |
node = g_object_ref(object);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
encoded_data = xmlEncodeEntitiesReentrant(node->priv->node->doc,
|
|
Packit |
a07778 |
(xmlChar *)value);
|
|
Packit |
a07778 |
xmlNodeSetContent(node->priv->node, encoded_data);
|
|
Packit |
a07778 |
xmlFree(encoded_data);
|
|
Packit |
a07778 |
g_object_unref(G_OBJECT(node));
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_set_node_content_uint64(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *node_name,
|
|
Packit |
a07778 |
guint64 value)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
char *str;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_CONFIG_IS_OBJECT(object));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
str = g_strdup_printf("%"G_GUINT64_FORMAT, value);
|
|
Packit |
a07778 |
gvir_config_object_set_node_content(object, node_name, str);
|
|
Packit |
a07778 |
g_free(str);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/* FIXME: how to notify of errors/node not found? */
|
|
Packit |
a07778 |
G_GNUC_INTERNAL guint64
|
|
Packit |
a07778 |
gvir_config_object_get_node_content_uint64(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *node_name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNodePtr node;
|
|
Packit |
a07778 |
const char *str;
|
|
Packit |
a07778 |
guint64 value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(object));
|
|
Packit |
a07778 |
if (node == NULL)
|
|
Packit |
a07778 |
return 0;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
str = gvir_config_xml_get_child_element_content(node, node_name);
|
|
Packit |
a07778 |
if (!str)
|
|
Packit |
a07778 |
return 0;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
value = g_ascii_strtoull(str, NULL, 0);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return value;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL gint
|
|
Packit |
a07778 |
gvir_config_object_get_node_content_genum(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *node_name,
|
|
Packit |
a07778 |
GType enum_type,
|
|
Packit |
a07778 |
gint default_value)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNodePtr node;
|
|
Packit |
a07778 |
const char *str;
|
|
Packit |
a07778 |
gint value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(object));
|
|
Packit |
a07778 |
if (node == NULL)
|
|
Packit |
a07778 |
return default_value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
str = gvir_config_xml_get_child_element_content(node, node_name);
|
|
Packit |
a07778 |
if (!str)
|
|
Packit |
a07778 |
return default_value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
value = gvir_config_genum_get_value(enum_type, str, default_value);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return value;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL gint
|
|
Packit |
a07778 |
gvir_config_object_get_attribute_genum(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *node_name,
|
|
Packit |
a07778 |
const char *attr_name,
|
|
Packit |
a07778 |
GType enum_type,
|
|
Packit |
a07778 |
gint default_value)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNodePtr node;
|
|
Packit |
a07778 |
const char *attr_val;
|
|
Packit |
a07778 |
gint value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(attr_name != NULL, default_value);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(object));
|
|
Packit |
a07778 |
if (node == NULL)
|
|
Packit |
a07778 |
return default_value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (node_name != NULL) {
|
|
Packit |
a07778 |
node = gvir_config_xml_get_element(node, node_name, NULL);
|
|
Packit |
a07778 |
if (node == NULL)
|
|
Packit |
a07778 |
return default_value;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
attr_val = gvir_config_xml_get_attribute_content(node, attr_name);
|
|
Packit |
a07778 |
if (attr_val == NULL)
|
|
Packit |
a07778 |
return default_value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
value = gvir_config_genum_get_value(enum_type, attr_val,
|
|
Packit |
a07778 |
default_value);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return value;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL guint64
|
|
Packit |
a07778 |
gvir_config_object_get_attribute_uint64(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *node_name,
|
|
Packit |
a07778 |
const char *attr_name,
|
|
Packit |
a07778 |
guint64 default_value)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
const char *str;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
str = gvir_config_object_get_attribute(object, node_name, attr_name);
|
|
Packit |
a07778 |
if (str == NULL)
|
|
Packit |
a07778 |
return default_value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_ascii_strtoull(str, NULL, 0);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL gboolean
|
|
Packit |
a07778 |
gvir_config_object_get_attribute_boolean(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *node_name,
|
|
Packit |
a07778 |
const char *attr_name,
|
|
Packit |
a07778 |
gboolean default_value)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
const char *str;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
str = gvir_config_object_get_attribute(object, node_name, attr_name);
|
|
Packit |
a07778 |
if (g_strcmp0(str, "yes") == 0) {
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
} else if (g_strcmp0(str, "no") == 0) {
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
} else {
|
|
Packit |
a07778 |
return default_value;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
GVirConfigObject *gvir_config_object_new_from_xml(GType type,
|
|
Packit |
a07778 |
const char *root_name,
|
|
Packit |
a07778 |
const char *schema,
|
|
Packit |
a07778 |
const gchar *xml,
|
|
Packit |
a07778 |
GError **error)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConfigObject *object;
|
|
Packit |
a07778 |
GVirConfigXmlDoc *doc;
|
|
Packit |
a07778 |
xmlNodePtr node;
|
|
Packit |
a07778 |
GError *tmp_error = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
node = gvir_config_xml_parse(xml, root_name, &tmp_error);
|
|
Packit |
a07778 |
if (tmp_error != NULL) {
|
|
Packit |
a07778 |
g_propagate_error(error, tmp_error);
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
doc = gvir_config_xml_doc_new(node->doc);
|
|
Packit |
a07778 |
object = GVIR_CONFIG_OBJECT(g_object_new(type,
|
|
Packit |
a07778 |
"doc", doc,
|
|
Packit |
a07778 |
"node", node,
|
|
Packit |
a07778 |
"schema", schema,
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
g_object_unref(G_OBJECT(doc));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return object;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL GVirConfigObject *
|
|
Packit |
a07778 |
gvir_config_object_new_from_tree(GType type, GVirConfigXmlDoc *doc,
|
|
Packit |
a07778 |
const char *schema, xmlNodePtr tree)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(g_type_is_a(type, GVIR_CONFIG_TYPE_OBJECT), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_CONFIG_IS_XML_DOC(doc), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(tree != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return GVIR_CONFIG_OBJECT(g_object_new(type,
|
|
Packit |
a07778 |
"doc", doc,
|
|
Packit |
a07778 |
"node", tree,
|
|
Packit |
a07778 |
"schema", schema,
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
GVirConfigObject *gvir_config_object_new(GType type,
|
|
Packit |
a07778 |
const char *root_name,
|
|
Packit |
a07778 |
const char *schema)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConfigObject *object;
|
|
Packit |
a07778 |
GVirConfigXmlDoc *doc;
|
|
Packit |
a07778 |
xmlDocPtr xml_doc;
|
|
Packit |
a07778 |
xmlNodePtr node;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
doc = gvir_config_xml_doc_new(NULL);
|
|
Packit |
a07778 |
g_object_get(G_OBJECT(doc), "doc", &xml_doc, NULL);
|
|
Packit |
a07778 |
g_assert(xml_doc != NULL);
|
|
Packit |
a07778 |
node = xmlNewDocNode(xml_doc, NULL, (xmlChar *)root_name, NULL);
|
|
Packit |
a07778 |
xmlDocSetRootElement(xml_doc, node);
|
|
Packit |
a07778 |
object = GVIR_CONFIG_OBJECT(g_object_new(type,
|
|
Packit |
a07778 |
"doc", doc,
|
|
Packit |
a07778 |
"node", node,
|
|
Packit |
a07778 |
"schema", schema,
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_object_unref(G_OBJECT(doc));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return object;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_set_attribute(GVirConfigObject *object, ...)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlDocPtr doc;
|
|
Packit |
a07778 |
va_list args;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_CONFIG_IS_OBJECT(object));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_object_get(G_OBJECT(object->priv->doc), "doc", &doc, NULL);
|
|
Packit |
a07778 |
va_start(args, object);
|
|
Packit |
a07778 |
while (TRUE) {
|
|
Packit |
a07778 |
const char *name;
|
|
Packit |
a07778 |
const char *value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
name = va_arg(args, const char *);
|
|
Packit |
a07778 |
if (name == NULL) {
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
gvir_config_object_remove_attribute(object, name);
|
|
Packit |
a07778 |
value = va_arg(args, const char *);
|
|
Packit |
a07778 |
if (value == NULL) {
|
|
Packit |
a07778 |
g_warn_if_reached();
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
xmlNewProp(object->priv->node, (xmlChar *)name, (xmlChar *)value);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
va_end(args);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_set_attribute_with_type(GVirConfigObject *object, ...)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
va_list args;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_CONFIG_IS_OBJECT(object));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
va_start(args, object);
|
|
Packit |
a07778 |
while (TRUE) {
|
|
Packit |
a07778 |
const char *name;
|
|
Packit |
a07778 |
GType attr_type;
|
|
Packit |
a07778 |
char *str;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
name = va_arg(args, const char *);
|
|
Packit |
a07778 |
if (name == NULL) {
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
gvir_config_object_remove_attribute(object, name);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
attr_type = va_arg(args, GType);
|
|
Packit |
a07778 |
if (G_TYPE_IS_ENUM(attr_type)) {
|
|
Packit |
a07778 |
int val;
|
|
Packit |
a07778 |
const char *enum_str;
|
|
Packit |
a07778 |
val = va_arg(args, int);
|
|
Packit |
a07778 |
enum_str = gvir_config_genum_get_nick(attr_type, val);
|
|
Packit |
a07778 |
if (enum_str != NULL) {
|
|
Packit |
a07778 |
str = g_strdup(enum_str);
|
|
Packit |
a07778 |
} else {
|
|
Packit |
a07778 |
str = NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
} else switch (attr_type) {
|
|
Packit |
a07778 |
case G_TYPE_UINT64: {
|
|
Packit |
a07778 |
guint64 val;
|
|
Packit |
a07778 |
val = va_arg(args, guint64);
|
|
Packit |
a07778 |
str = g_strdup_printf("%"G_GUINT64_FORMAT, val);
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
case G_TYPE_UINT: {
|
|
Packit |
a07778 |
guint val;
|
|
Packit |
a07778 |
val = va_arg(args, guint);
|
|
Packit |
a07778 |
str = g_strdup_printf("%u", val);
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
case G_TYPE_INT: {
|
|
Packit |
a07778 |
gint val;
|
|
Packit |
a07778 |
val = va_arg(args, gint);
|
|
Packit |
a07778 |
str = g_strdup_printf("%d", val);
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
case G_TYPE_STRING:
|
|
Packit |
a07778 |
str = va_arg(args, char *);
|
|
Packit |
a07778 |
xmlNewProp(object->priv->node, (xmlChar *)name, (xmlChar *)str);
|
|
Packit |
a07778 |
str = NULL;
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
case G_TYPE_BOOLEAN: {
|
|
Packit |
a07778 |
gboolean val;
|
|
Packit |
a07778 |
val = va_arg(args, gboolean);
|
|
Packit |
a07778 |
str = g_strdup_printf("%s", val?"yes":"no");
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
default:
|
|
Packit |
a07778 |
g_warning("Unhandled type: %s", g_type_name(attr_type));
|
|
Packit |
a07778 |
g_assert_not_reached();
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (str != NULL) {
|
|
Packit |
a07778 |
xmlNewProp(object->priv->node, (xmlChar *)name, (xmlChar *)str);
|
|
Packit |
a07778 |
g_free(str);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
va_end(args);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_config_object_attach(GVirConfigObject *parent, GVirConfigObject *child, gboolean replace)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_CONFIG_IS_OBJECT(parent));
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_CONFIG_IS_OBJECT(child));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (replace) {
|
|
Packit |
a07778 |
gvir_config_object_delete_children(parent,
|
|
Packit |
a07778 |
(char *)child->priv->node->name,
|
|
Packit |
a07778 |
NULL);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
xmlUnlinkNode(child->priv->node);
|
|
Packit |
a07778 |
xmlAddChild(parent->priv->node, child->priv->node);
|
|
Packit |
a07778 |
if (child->priv->doc != NULL) {
|
|
Packit |
a07778 |
g_object_unref(G_OBJECT(child->priv->doc));
|
|
Packit |
a07778 |
child->priv->doc = NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
if (parent->priv->doc != NULL) {
|
|
Packit |
a07778 |
child->priv->doc = g_object_ref(parent->priv->doc);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_attach_replace(GVirConfigObject *parent,
|
|
Packit |
a07778 |
const char *child_name,
|
|
Packit |
a07778 |
GVirConfigObject *child)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_if_fail(child_name != NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (child == NULL)
|
|
Packit |
a07778 |
gvir_config_object_delete_children(parent, child_name, NULL);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
gvir_config_object_attach(parent, child, TRUE);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_attach_add(GVirConfigObject *parent, GVirConfigObject *child)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
gvir_config_object_attach(parent, child, FALSE);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL void
|
|
Packit |
a07778 |
gvir_config_object_remove_attribute(GVirConfigObject *object,
|
|
Packit |
a07778 |
const char *attr_name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
int status;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
do {
|
|
Packit |
a07778 |
status = xmlUnsetProp(object->priv->node, (xmlChar *)attr_name);
|
|
Packit |
a07778 |
} while (status == 0);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static gboolean
|
|
Packit |
a07778 |
gvir_config_object_set_xmlnode_namespace(xmlNodePtr node, const char *ns,
|
|
Packit |
a07778 |
const char *ns_uri)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNsPtr namespace;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
namespace = xmlNewNs(node, (xmlChar *)ns_uri, (xmlChar *)ns);
|
|
Packit |
a07778 |
if (namespace == NULL)
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
xmlSetNs(node, namespace);
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static gboolean
|
|
Packit |
a07778 |
gvir_config_object_set_namespace_recursively(xmlNodePtr node,
|
|
Packit |
a07778 |
const char *ns,
|
|
Packit |
a07778 |
const char *ns_uri)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNodePtr n;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
for (n = node; n != NULL; n = n->next) {
|
|
Packit |
a07778 |
if (n->type == XML_ELEMENT_NODE) {
|
|
Packit |
a07778 |
if (!gvir_config_object_set_xmlnode_namespace(n, ns, ns_uri))
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_config_object_set_namespace_recursively(n->children, ns, NULL))
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL gboolean
|
|
Packit |
a07778 |
gvir_config_object_set_namespace(GVirConfigObject *object, const char *ns,
|
|
Packit |
a07778 |
const char *ns_uri, gboolean ns_children)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_CONFIG_IS_OBJECT(object), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(ns != NULL, FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(ns_uri != NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!ns_children) {
|
|
Packit |
a07778 |
return gvir_config_object_set_xmlnode_namespace(object->priv->node,
|
|
Packit |
a07778 |
ns, ns_uri);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return gvir_config_object_set_namespace_recursively(object->priv->node,
|
|
Packit |
a07778 |
ns, ns_uri);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL GVirConfigObject *
|
|
Packit |
a07778 |
gvir_config_object_get_child_with_type(GVirConfigObject *object,
|
|
Packit |
a07778 |
const gchar *child_name,
|
|
Packit |
a07778 |
GType child_type)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNodePtr node;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_CONFIG_IS_OBJECT(object), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(child_name != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
node = gvir_config_xml_get_element(object->priv->node, child_name, NULL);
|
|
Packit |
a07778 |
if (node == NULL)
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return gvir_config_object_new_from_tree(child_type,
|
|
Packit |
a07778 |
object->priv->doc,
|
|
Packit |
a07778 |
object->priv->schema,
|
|
Packit |
a07778 |
node);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL GVirConfigObject *
|
|
Packit |
a07778 |
gvir_config_object_get_child(GVirConfigObject *object,
|
|
Packit |
a07778 |
const gchar *child_name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
return gvir_config_object_get_child_with_type(object,
|
|
Packit |
a07778 |
child_name,
|
|
Packit |
a07778 |
GVIR_CONFIG_TYPE_OBJECT);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL gboolean
|
|
Packit |
a07778 |
gvir_config_object_has_child(GVirConfigObject *object, const gchar *child_name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNodePtr node;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_CONFIG_IS_OBJECT(object), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(child_name != NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
node = gvir_config_xml_get_element(object->priv->node, child_name, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return (node != NULL);
|
|
Packit |
a07778 |
}
|