[Libvirt-cim] [PATCH V2 21/48] Add basic functions about converting others link list to xml

Xu Wang cngesaint at gmail.com
Mon Oct 28 02:45:50 UTC 2013


Signed-off-by: Xu Wang <gesaint at linux.vnet.ibm.com>
---
 libxkutil/xmlgen.c |  231 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 231 insertions(+), 0 deletions(-)

diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c
index 7e8801d..d1e1c94 100644
--- a/libxkutil/xmlgen.c
+++ b/libxkutil/xmlgen.c
@@ -42,6 +42,237 @@ typedef const char *(*devfn_t)(xmlNodePtr node, struct domain *dominfo);
 typedef const char *(*poolfn_t)(xmlNodePtr node, struct virt_pool *pool);
 typedef const char *(*resfn_t)(xmlNodePtr node, struct virt_pool_res *res);
 
+/*
+ * Parse all attributes of node into xml.
+ *
+ * @node: The root node.
+ * @head: The link list saved all data to be parsed.
+ * @parent_id: Node id of attributes.
+ * @parent_name: Node name of attributes.
+ *
+ * If @parent_id or @parent_name is not as a condition, plese set them into
+ * -1 or NULL.
+ */
+static struct others *props_to_xml(xmlNodePtr node,
+                                   struct others *head,
+                                   int parent_id,
+                                   const char *parent_name)
+{
+        struct others *tmp = head;
+
+        if (head == NULL) {
+                CU_DEBUG("others is null.");
+                goto out;
+        }
+
+        while (tmp) {
+                if (compare_param_int(tmp->parent_id, parent_id) &&
+                    compare_param_str(tmp->parent_name, parent_name) &&
+                    tmp->type == TYPE_PROP &&
+                    tmp->status == ACTIVE) {
+                        xmlNewProp(node, BAD_CAST tmp->name, BAD_CAST tmp->value);
+                        tmp->status = INACTIVE;
+                }
+                tmp = tmp->next;
+        }
+
+out:
+        return head;
+}
+
+/*
+ * Parse all data in others link list to a xml data structure.
+ * The link list returned after operation.
+ *
+ * @root: The root node of xml to be built.
+ * @head: The link list saved all data needed.
+ * @parent_id: Parent node id of root node.
+ * @parent_name: Parent node name of root node.
+ *
+ * @parent_id/@parent_name is not mandatory (please set them
+ * as -1/NULL) but others not.
+ */
+static struct others *others_to_xml(xmlNodePtr root,
+                                    struct others *head,
+                                    int parent_id,
+                                    const char *parent_name)
+{
+        struct others *tmp = head;
+        xmlNodePtr new_node = NULL;
+
+        if (head == NULL) {
+                CU_DEBUG("others is null.");
+                goto out;
+        }
+
+        /* fetch all node items from others to build structure of xml */
+        while (tmp) {
+                if (compare_param_int(tmp->parent_id, parent_id) &&
+                    compare_param_str(tmp->parent_name, parent_name) &&
+                    tmp->type == TYPE_NODE &&
+                    tmp->status == ACTIVE) {
+                        new_node = xmlNewChild(root, NULL,
+                                               BAD_CAST tmp->name,
+                                               BAD_CAST tmp->value);
+
+                        if (new_node == NULL) {
+                                 CU_DEBUG("xmlNewChild failed.");
+                                 goto out;
+                        }
+
+                        tmp->status = INACTIVE;
+
+                        /* find all properties of this node and build new tag in xml */
+                        head = props_to_xml(new_node,
+                                            head,
+                                            tmp->id,
+                                            (char *)new_node->name);
+
+                        /* recursive build sub node of tmp */
+                        head = others_to_xml(new_node,
+                                             head,
+                                             tmp->id,
+                                             (char *)new_node->name);
+
+                }
+                tmp = tmp->next;
+        }
+
+out:
+        return head;
+}
+
+/*
+ * Restore data in the member of virtual device structure back to others link
+ * list. The new link list would be returned after operation finished.
+ *
+ * @head: The link list data to be added into.
+ * @id: Id of new node to be added.
+ * @name: Name of new node to be added.
+ * @value: Value of new node to be added.
+ * @type: Type of new node to be added.
+ *        TYPE_NODE: The value is from a node of xml.
+ *        TYPE_PROP: The value is from a attribute of a node.
+ * @parent_id: Parent node id of new node to be added.
+ * @parent_name: Parent node name of new node to be added.
+ * 
+ * Among parameters above @id/@parent_id/@parent_name is not
+ * mandatory. They should be set as -1/-1/NULL if caller needn't
+ * set them.
+ */
+static struct others *add_node_to_others(struct others *head,
+                                         int id,
+                                         const char *name,
+                                         const char *value,
+                                         enum others_type type,
+                                         int parent_id,
+                                         const char *parent_name)
+{
+        struct others *tmp = head;
+        struct others *new_node = NULL;
+
+        /* Check if there is such a node with INACTIVE status in others */
+        while (tmp) {
+                if (compare_param_int(tmp->id, id) &&
+                    STREQ(tmp->name, name) &&
+                    tmp->type == type &&
+                    compare_param_int(tmp->parent_id, parent_id) &&
+                    compare_param_str(tmp->parent_name, parent_name) &&
+                    tmp->status == INACTIVE) {
+                        if (tmp->value) {
+                                free(tmp->value);
+                        }
+                        if (value) {
+                                tmp->value = strdup(value);
+                        } else {
+                                tmp->value = NULL;
+                        }
+                        tmp->status = ACTIVE;
+
+                        return head;
+                }
+                tmp = tmp->next;
+        }
+
+        /* Create a new node */
+        new_node = calloc(1, sizeof(*new_node));
+        if (new_node == NULL) {
+                CU_DEBUG("calloc failed.");
+                return NULL;
+        }
+
+        new_node->id = id;
+
+        if (name == NULL) {
+                CU_DEBUG("name is null");
+                return NULL;
+        }
+        new_node->name = strdup(name);
+
+        if (value) {
+                new_node->value = strdup(value);
+        } else {
+                new_node->value = NULL;
+        }
+
+        new_node->type = type;
+
+        new_node->parent_id = parent_id;
+
+        if (parent_name) {
+                new_node->parent_name = strdup(parent_name);
+        } else {
+                new_node->parent_name = NULL;
+        }
+
+        if (head == NULL) {
+                new_node->next = NULL;
+        } else {
+                new_node->next = head;
+        }
+
+        return new_node;
+}
+
+static int get_id_of_others(struct others *others,
+                            const char *name,
+                            const char *value,
+                            enum others_type type,
+                            int parent_id,
+                            const char *parent_name)
+{
+        struct others *tmp = others;
+
+        while (tmp) {
+                if (STREQ(tmp->name, name) &&
+                    compare_param_str(tmp->value, value) &&
+                    tmp->type == type &&
+                    compare_param_int(tmp->parent_id, parent_id) &&
+                    compare_param_str(tmp->parent_name, parent_name)) {
+                        return tmp->id;
+                }
+                tmp = tmp->next;
+        }
+
+        return -1;
+}
+
+/*
+ * Check if there is node(s) with ACTIVE status. If such node(s) exists
+ * means operation failed. Some node of xml missed. 
+ */
+static const char *check_others_active(struct others *others)
+{
+        while (others) {
+                if (others->status == ACTIVE) {
+                        return "There are active nodes in others.";
+                }
+                others = others->next;
+        }
+
+        return NULL;
+}                 
+
 static const char *console_xml(xmlNodePtr root, struct domain *dominfo)
 {
         int i;
-- 
1.7.1




More information about the Libvirt-cim mailing list