/*
* libvirt-gconfig-helpers.c: libvirt configuration helpers
*
* Copyright (C) 2010, 2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* .
*
* Authors: Daniel P. Berrange
* Christophe Fergeau
*/
#include
#include
#include
#include
#include "libvirt-gconfig/libvirt-gconfig.h"
#include "libvirt-gconfig/libvirt-gconfig-helpers-private.h"
GQuark
gvir_config_object_error_quark(void)
{
return g_quark_from_static_string("gvir-config-object");
}
static GError *gvir_config_error_new_literal(GQuark domain,
gint code,
const gchar *message)
{
xmlErrorPtr xerr = xmlGetLastError();
if (!xerr)
return NULL;
if (message)
return g_error_new(domain,
code,
"%s: %s",
message,
xerr->message);
else
return g_error_new(domain,
code,
"%s",
xerr->message);
}
GError *gvir_config_error_new(GQuark domain,
gint code,
const gchar *format,
...)
{
GError *err;
va_list args;
gchar *message;
va_start(args, format);
message = g_strdup_vprintf(format, args);
va_end(args);
err = gvir_config_error_new_literal(domain, code, message);
g_free(message);
return err;
}
void gvir_config_set_error(GError **err,
GQuark domain, gint code,
const gchar *format, ...)
{
va_list args;
gchar *message;
if (!err)
return;
va_start(args, format);
message = g_strdup_vprintf(format, args);
va_end(args);
*err = gvir_config_error_new_literal(domain, code, message);
g_free(message);
}
void gvir_config_set_error_literal(GError **err,
GQuark domain, gint code,
const gchar *message)
{
if (!err)
return;
*err = gvir_config_error_new_literal(domain, code, message);
}
void gvir_config_set_error_valist(GError **err,
GQuark domain, gint code,
const gchar *format,
va_list args)
{
gchar *message;
if (!err)
return;
message = g_strdup_vprintf(format, args);
*err = gvir_config_error_new_literal(domain, code, message);
g_free(message);
}
xmlNodePtr
gvir_config_xml_parse(const char *xml, const char *root_node, GError **err)
{
xmlDocPtr doc;
if (!xml) {
*err = g_error_new(GVIR_CONFIG_OBJECT_ERROR,
0,
"%s",
_("No XML document to parse"));
return NULL;
}
doc = xmlParseMemory(xml, strlen(xml));
if (!doc) {
gvir_config_set_error_literal(err, GVIR_CONFIG_OBJECT_ERROR,
0,
_("Unable to parse configuration"));
return NULL;
}
if ((!doc->children) ||
((root_node != NULL) && g_strcmp0((char *)doc->children->name, root_node) != 0)) {
g_set_error(err,
GVIR_CONFIG_OBJECT_ERROR,
0,
_("XML data has no '%s' node"),
root_node);
xmlFreeDoc(doc);
return NULL;
}
return doc->children;
}
void gvir_config_xml_foreach_child(xmlNodePtr node,
GVirConfigXmlNodeIterator iter_func,
gpointer opaque)
{
xmlNodePtr it;
g_return_if_fail(iter_func != NULL);
it = node->children;
while (it != NULL) {
gboolean cont;
xmlNodePtr next = it->next;
if (!xmlIsBlankNode(it)) {
cont = iter_func(it, opaque);
if (!cont)
break;
}
it = next;
}
}
/*
* gvir_config_xml_get_element is
*
* Copyright (C) 2006, 2007 OpenedHand Ltd.
*
* Author: Jorn Baayen
*/
xmlNode *
gvir_config_xml_get_element (xmlNode *node, ...)
{
va_list var_args;
va_start (var_args, node);
while (TRUE) {
const char *arg;
arg = va_arg (var_args, const char *);
if (!arg)
break;
for (node = node->children; node; node = node->next)
if (!g_strcmp0 (arg, (char *) node->name))
break;
if (!node)
break;
}
va_end (var_args);
return node;
}
G_GNUC_INTERNAL const char *
gvir_config_xml_get_child_element_content (xmlNode *node,
const char *child_name)
{
xmlNode *child_node;
child_node = gvir_config_xml_get_element(node, child_name, NULL);
if (!child_node || !(child_node->children))
return NULL;
return (const char *)child_node->children->content;
}
G_GNUC_INTERNAL const char *
gvir_config_xml_get_attribute_content(xmlNodePtr node, const char *attr_name)
{
xmlAttr *attr;
for (attr = node->properties; attr; attr = attr->next)
if (g_strcmp0 (attr_name, (char *)attr->name) == 0)
return (const char *)attr->children->content;
return NULL;
}
const char *gvir_config_genum_get_nick (GType enum_type, gint value)
{
GEnumClass *enum_class;
GEnumValue *enum_value;
g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
enum_class = g_type_class_ref(enum_type);
enum_value = g_enum_get_value(enum_class, value);
g_type_class_unref(enum_class);
if (enum_value != NULL)
return enum_value->value_nick;
g_return_val_if_reached(NULL);
}
G_GNUC_INTERNAL int
gvir_config_genum_get_value (GType enum_type, const char *nick,
gint default_value)
{
GEnumClass *enum_class;
GEnumValue *enum_value;
g_return_val_if_fail(G_TYPE_IS_ENUM(enum_type), default_value);
g_return_val_if_fail(nick != NULL, default_value);
enum_class = g_type_class_ref(enum_type);
enum_value = g_enum_get_value_by_nick(enum_class, nick);
g_type_class_unref(enum_class);
if (enum_value != NULL)
return enum_value->value;
g_return_val_if_reached(default_value);
}
G_GNUC_INTERNAL char *
gvir_config_xml_node_to_string(xmlNodePtr node)
{
xmlBufferPtr xmlbuf;
char *xml;
if (node == NULL)
return NULL;
xmlbuf = xmlBufferCreate();
if (xmlNodeDump(xmlbuf, node->doc, node, 0, 1) < 0)
xml = NULL;
else
xml = g_strndup((gchar *)xmlBufferContent(xmlbuf), xmlBufferLength(xmlbuf));
xmlBufferFree(xmlbuf);
return xml;
}