From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 22 Jun 2017 13:06:53 -0300
Subject: [PATCH] storage-domain: Move out ovirt_resource_parse_xml() to
 ovirt-utils

There were a couple of tweaks to the function:

1) Renamed to ovirt_rest_xml_node_parse()
    More suited to the task performed.

2) Validates GObject instead of OvirtResource
    This removes the restriction of usage by a OvirtResource, and in the
    future it can also be used by OvirtVmDisplay to parse the elements.
    It also makes it more coherent to its purpose, as the function only
    sets properties of a GObject and does not really require a
    OvirtResource.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
 govirt/ovirt-storage-domain.c | 152 +++++++---------------------------
 govirt/ovirt-utils.c          |  71 +++++++++++++++-
 govirt/ovirt-utils.h          |  13 ++-
 3 files changed, 113 insertions(+), 123 deletions(-)

diff --git a/govirt/ovirt-storage-domain.c b/govirt/ovirt-storage-domain.c
index 07c0ef0..0582203 100644
--- a/govirt/ovirt-storage-domain.c
+++ b/govirt/ovirt-storage-domain.c
@@ -53,10 +53,6 @@ enum {
     PROP_STATE
 };

-static gboolean
-ovirt_storage_domain_refresh_from_xml(OvirtStorageDomain *domain,
-                                      RestXmlNode *node);
-
 static void ovirt_storage_domain_get_property(GObject *object,
                                               guint prop_id,
                                               GValue *value,
@@ -145,10 +141,39 @@ static gboolean ovirt_storage_domain_init_from_xml(OvirtResource *resource,
 {
     gboolean parsed_ok;
     OvirtResourceClass *parent_class;
-    OvirtStorageDomain *domain;
+    OvirtXmlElement storage_domain_elements[] = {
+        { .prop_name = "type",
+          .type = OVIRT_TYPE_STORAGE_DOMAIN_TYPE,
+          .xml_path = "type",
+        },
+        { .prop_name = "master",
+          .type = G_TYPE_BOOLEAN,
+          .xml_path = "master",
+        },
+        { .prop_name = "available",
+          .type = G_TYPE_UINT64,
+          .xml_path = "available",
+        },
+        { .prop_name = "used",
+          .type = G_TYPE_UINT64,
+          .xml_path = "used",
+        },
+        { .prop_name = "committed",
+          .type = G_TYPE_UINT64,
+          .xml_path = "committed",
+        },
+        { .prop_name = "version",
+          .type = OVIRT_TYPE_STORAGE_DOMAIN_FORMAT_VERSION,
+          .xml_path = "storage_format",
+        },
+        { .prop_name = "state",
+          .type = OVIRT_TYPE_STORAGE_DOMAIN_STATE,
+          .xml_path = "status/state",
+        },
+        { NULL , }
+    };

-    domain = OVIRT_STORAGE_DOMAIN(resource);
-    parsed_ok = ovirt_storage_domain_refresh_from_xml(domain, node);
+    parsed_ok = ovirt_rest_xml_node_parse(node, G_OBJECT(resource), storage_domain_elements);
     if (!parsed_ok) {
         return FALSE;
     }
@@ -277,119 +302,6 @@ OvirtStorageDomain *ovirt_storage_domain_new(void)
     return OVIRT_STORAGE_DOMAIN(domain);
 }

-static gboolean
-_set_property_value_from_type(GValue *value,
-                              GType type,
-                              const char *value_str,
-                              RestXmlNode *node)
-{
-    gboolean ret = TRUE;
-
-    if (g_type_is_a(type, OVIRT_TYPE_RESOURCE)) {
-        GObject *resource_value = g_initable_new(type, NULL, NULL, "xml-node", node, NULL);
-        g_value_set_object(value, resource_value);
-        goto end;
-    }
-
-    /* All other types require valid value_str */
-    if (value_str == NULL)
-        return FALSE;
-
-    if (G_TYPE_IS_ENUM(type)) {
-        int enum_value = ovirt_utils_genum_get_value(type, value_str, 0);
-        g_value_set_enum(value, enum_value);
-        goto end;
-    }
-
-    switch(type) {
-    case G_TYPE_BOOLEAN: {
-        gboolean bool_value = ovirt_utils_boolean_from_string(value_str);
-        g_value_set_boolean(value, bool_value);
-        break;
-    }
-    case G_TYPE_UINT64: {
-        guint64 int64_value = g_ascii_strtoull(value_str, NULL, 0);
-        g_value_set_uint64(value, int64_value);
-        break;
-    }
-    default: {
-        g_warning("Unexpected type '%s' with value '%s'", g_type_name(type), value_str);
-        ret = FALSE;
-    }
-    }
-
-end:
-    return ret;
-}
-
-typedef struct {
-    const char *prop_name;
-    GType type;
-    const char *xml_path;
-} OvirtXmlElement;
-
-static gboolean
-ovirt_resource_parse_xml(OvirtResource *resource,
-                         RestXmlNode *node,
-                         OvirtXmlElement *elements)
-{
-    g_return_val_if_fail(OVIRT_IS_RESOURCE(resource), FALSE);
-    g_return_val_if_fail(elements != NULL, FALSE);
-
-    for (;elements->xml_path != NULL; elements++) {
-        const char *value_str;
-        GValue value = { 0, };
-
-        value_str = ovirt_rest_xml_node_get_content_from_path(node, elements->xml_path);
-
-        g_value_init(&value, elements->type);
-        if (_set_property_value_from_type(&value, elements->type, value_str, node))
-            g_object_set_property(G_OBJECT(resource), elements->prop_name, &value);
-        g_value_unset(&value);
-    }
-
-    return TRUE;
-}
-
-static gboolean
-ovirt_storage_domain_refresh_from_xml(OvirtStorageDomain *domain,
-                                      RestXmlNode *node)
-{
-    OvirtXmlElement storage_domain_elements[] = {
-        { .prop_name = "type",
-          .type = OVIRT_TYPE_STORAGE_DOMAIN_TYPE,
-          .xml_path = "type",
-        },
-        { .prop_name = "master",
-          .type = G_TYPE_BOOLEAN,
-          .xml_path = "master",
-        },
-        { .prop_name = "available",
-          .type = G_TYPE_UINT64,
-          .xml_path = "available",
-        },
-        { .prop_name = "used",
-          .type = G_TYPE_UINT64,
-          .xml_path = "used",
-        },
-        { .prop_name = "committed",
-          .type = G_TYPE_UINT64,
-          .xml_path = "committed",
-        },
-        { .prop_name = "version",
-          .type = OVIRT_TYPE_STORAGE_DOMAIN_FORMAT_VERSION,
-          .xml_path = "storage_format",
-        },
-        { .prop_name = "state",
-          .type = OVIRT_TYPE_STORAGE_DOMAIN_STATE,
-          .xml_path = "status/state",
-        },
-        { NULL , }
-    };
-
-    return ovirt_resource_parse_xml(OVIRT_RESOURCE(domain), node, storage_domain_elements);
-}
-

 /**
  * ovirt_storage_domain_get_files:
diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index 0e0134c..44ea7da 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -31,6 +31,7 @@
 #include "ovirt-utils.h"

 #include "ovirt-error.h"
+#include "ovirt-resource.h"

 RestXmlNode *
 ovirt_rest_xml_node_from_call(RestProxyCall *call)
@@ -77,7 +78,7 @@ ovirt_rest_xml_node_get_content_va(RestXmlNode *node,
     return node->content;
 }

-G_GNUC_INTERNAL const char *
+static const char *
 ovirt_rest_xml_node_get_content_from_path(RestXmlNode *node, const char *path)
 {
     GStrv pathv;
@@ -109,6 +110,74 @@ ovirt_rest_xml_node_get_content(RestXmlNode *node, ...)
     return content;
 }

+static gboolean
+_set_property_value_from_type(GValue *value,
+                              GType type,
+                              const char *value_str,
+                              RestXmlNode *node)
+{
+    gboolean ret = TRUE;
+
+    if (g_type_is_a(type, OVIRT_TYPE_RESOURCE)) {
+        GObject *resource_value = g_initable_new(type, NULL, NULL, "xml-node", node, NULL);
+        g_value_set_object(value, resource_value);
+        goto end;
+    }
+
+    /* All other types require valid value_str */
+    if (value_str == NULL)
+        return FALSE;
+
+    if (G_TYPE_IS_ENUM(type)) {
+        int enum_value = ovirt_utils_genum_get_value(type, value_str, 0);
+        g_value_set_enum(value, enum_value);
+        goto end;
+    }
+
+    switch(type) {
+    case G_TYPE_BOOLEAN: {
+        gboolean bool_value = ovirt_utils_boolean_from_string(value_str);
+        g_value_set_boolean(value, bool_value);
+        break;
+    }
+    case G_TYPE_UINT64: {
+        guint64 int64_value = g_ascii_strtoull(value_str, NULL, 0);
+        g_value_set_uint64(value, int64_value);
+        break;
+    }
+    default: {
+        g_warning("Unexpected type '%s' with value '%s'", g_type_name(type), value_str);
+        ret = FALSE;
+    }
+    }
+
+end:
+    return ret;
+}
+
+gboolean
+ovirt_rest_xml_node_parse(RestXmlNode *node,
+                          GObject *object,
+                          OvirtXmlElement *elements)
+{
+    g_return_val_if_fail(G_IS_OBJECT(object), FALSE);
+    g_return_val_if_fail(elements != NULL, FALSE);
+
+    for (;elements->xml_path != NULL; elements++) {
+        const char *value_str;
+        GValue value = { 0, };
+
+        value_str = ovirt_rest_xml_node_get_content_from_path(node, elements->xml_path);
+
+        g_value_init(&value, elements->type);
+        if (_set_property_value_from_type(&value, elements->type, value_str, node))
+            g_object_set_property(object, elements->prop_name, &value);
+        g_value_unset(&value);
+    }
+
+    return TRUE;
+}
+

 /* These 2 functions come from
  * libvirt-glib/libvirt-gconfig/libvirt-gconfig-helpers.c
diff --git a/govirt/ovirt-utils.h b/govirt/ovirt-utils.h
index 3f43fc9..4fd4164 100644
--- a/govirt/ovirt-utils.h
+++ b/govirt/ovirt-utils.h
@@ -27,10 +27,19 @@

 G_BEGIN_DECLS

+typedef struct _OvirtXmlElement OvirtXmlElement;
+struct _OvirtXmlElement
+{
+    const char *prop_name;
+    GType type;
+    const char *xml_path;
+};
+
 RestXmlNode *ovirt_rest_xml_node_from_call(RestProxyCall *call);
 const char *ovirt_rest_xml_node_get_content(RestXmlNode *node, ...);
-const char *ovirt_rest_xml_node_get_content_from_path(RestXmlNode *node,
-                                                      const char *path);
+gboolean ovirt_rest_xml_node_parse(RestXmlNode *node,
+                                   GObject *object,
+                                   OvirtXmlElement *elements);
 gboolean ovirt_utils_gerror_from_xml_fault(RestXmlNode *root, GError **error);
 gboolean g_object_set_guint_property_from_xml(GObject *g_object,
                                                    RestXmlNode *node,
