/*
* ovirt-utils.c
*
* Copyright (C) 2011, 2013 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
* .
*
* Author: Christophe Fergeau
*/
#include
#include
#include
#include
#include
#include "ovirt-utils.h"
#include "ovirt-error.h"
RestXmlNode *
ovirt_rest_xml_node_from_call(RestProxyCall *call)
{
RestXmlParser *parser;
RestXmlNode *node;
parser = rest_xml_parser_new ();
node = rest_xml_parser_parse_from_data (parser,
rest_proxy_call_get_payload (call),
rest_proxy_call_get_payload_length (call));
g_object_unref(G_OBJECT(parser));
return node;
}
static const char *
ovirt_rest_xml_node_get_content_va(RestXmlNode *node,
va_list *args,
GStrv str_array)
{
g_return_val_if_fail((args != NULL) || (str_array != NULL), NULL);
while (TRUE) {
const char *node_name;
if (args != NULL) {
node_name = va_arg(*args, const char *);
} else {
node_name = *str_array;
str_array++;
}
if (node_name == NULL)
break;
node = rest_xml_node_find(node, node_name);
if (node == NULL) {
g_debug("could not find XML node '%s'", node_name);
return NULL;
}
}
return node->content;
}
G_GNUC_INTERNAL const char *
ovirt_rest_xml_node_get_content_from_path(RestXmlNode *node, const char *path)
{
GStrv pathv;
const char *content;
pathv = g_strsplit(path, "/", -1);
content = ovirt_rest_xml_node_get_content_va(node, NULL, pathv);
g_strfreev(pathv);
return content;
}
G_GNUC_INTERNAL const char *
ovirt_rest_xml_node_get_content(RestXmlNode *node, ...)
{
va_list args;
const char *content;
g_return_val_if_fail(node != NULL, NULL);
va_start(args, node);
content = ovirt_rest_xml_node_get_content_va(node, &args, NULL);
va_end(args);
g_warn_if_fail(node != NULL);
return content;
}
/* These 2 functions come from
* libvirt-glib/libvirt-gconfig/libvirt-gconfig-helpers.c
* Copyright (C) 2010, 2011 Red Hat, Inc.
* LGPLv2.1+ licensed */
G_GNUC_INTERNAL const char *
ovirt_utils_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
ovirt_utils_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 gboolean
ovirt_utils_boolean_from_string(const char *value)
{
g_return_val_if_fail(value != NULL, FALSE);
return (g_strcmp0(value, "true") == 0);
}
G_GNUC_INTERNAL gboolean
ovirt_utils_guint64_from_string(const char *value_str, guint64 *value)
{
char *end_ptr;
guint64 result;
g_return_val_if_fail(value_str != NULL, FALSE);
result = g_ascii_strtoull(value_str, &end_ptr, 10);
if ((result == G_MAXUINT64) && (errno == ERANGE)) {
/* overflow */
return FALSE;
}
if ((result == 0) && (errno == EINVAL)) {
/* should not happen, invalid base */
return FALSE;
}
if (*end_ptr != '\0') {
return FALSE;
}
*value = result;
return TRUE;
}
G_GNUC_INTERNAL gboolean
ovirt_utils_guint_from_string(const char *value_str, guint *value)
{
guint64 value64;
gboolean success;
success = ovirt_utils_guint64_from_string(value_str, &value64);
if (!success) {
return FALSE;
}
if (value64 > G_MAXUINT) {
return FALSE;
}
*value = (guint)value64;
return TRUE;
}
G_GNUC_INTERNAL gboolean ovirt_utils_gerror_from_xml_fault(RestXmlNode *root, GError **error)
{
RestXmlNode *reason_node;
RestXmlNode *detail_node;
const char *reason_key = g_intern_string("reason");
const char *detail_key = g_intern_string("detail");
g_return_val_if_fail((error == NULL) || (*error == NULL), FALSE);
if (g_strcmp0(root->name, "fault") != 0)
return FALSE;
reason_node = g_hash_table_lookup(root->children, reason_key);
if (reason_node == NULL) {
g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_PARSING_FAILED,
_("Could not find 'reason' node"));
g_return_val_if_reached(FALSE);
}
g_debug("Reason: %s\n", reason_node->content);
detail_node = g_hash_table_lookup(root->children, detail_key);
if (detail_node != NULL) {
g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_FAILED, "%s: %s",
reason_node->content, detail_node->content);
} else {
g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_FAILED, "%s",
reason_node->content);
}
return TRUE;
}
G_GNUC_INTERNAL gboolean g_object_set_guint_property_from_xml(GObject *g_object,
RestXmlNode *node,
const gchar *node_name,
const gchar *prop_name)
{
RestXmlNode *sub_node;
GParamSpec *spec;
sub_node = rest_xml_node_find(node, node_name);
if (sub_node != NULL && sub_node->content != NULL) {
guint value;
if (!ovirt_utils_guint_from_string(sub_node->content, &value)) {
return FALSE;
}
spec = g_object_class_find_property(G_OBJECT_GET_CLASS(g_object), prop_name);
if (spec != NULL && spec->value_type == G_TYPE_UINT) {
g_object_set(g_object, prop_name, value, NULL);
return TRUE;
}
}
return FALSE;
}