From a7d63a9edf93e820e081c3488f3d21bdfbf25938 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Mon, 24 Sep 2007 22:53:16 +0000 Subject: Implement dom_nodelist_get_length() Implement dom_nodelist_item() svn path=/trunk/dom/; revision=3589 --- src/core/nodelist.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 111 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/core/nodelist.c b/src/core/nodelist.c index a66ec55..6cdd099 100644 --- a/src/core/nodelist.c +++ b/src/core/nodelist.c @@ -10,12 +10,11 @@ #include #include "core/document.h" +#include "core/node.h" #include "core/nodelist.h" #include "utils/utils.h" -struct dom_node; - /** * DOM node list */ @@ -166,10 +165,58 @@ void dom_nodelist_unref(struct dom_nodelist *list) dom_exception dom_nodelist_get_length(struct dom_nodelist *list, unsigned long *length) { - UNUSED(list); - UNUSED(length); + struct dom_node *cur = list->root->first_child; + unsigned long len = 0; + + /* Traverse data structure */ + while (cur != NULL) { + /* Process current node */ + if (list->type == DOM_NODELIST_CHILDREN) { + len++; + } else if (list->type == DOM_NODELIST_BY_NAME) { + if (dom_string_cmp(cur->name, list->data.name) == 0) { + len++; + } + } else { + if (dom_string_cmp(cur->namespace, + list->data.ns.namespace) == 0 && + dom_string_cmp(cur->localname, + list->data.ns.localname) == 0) { + len++; + } + } + + /* Now, find next node */ + if (list->type == DOM_NODELIST_CHILDREN) { + /* Just interested in sibling list */ + cur = cur->next; + } else { + /* Want a full in-order tree traversal */ + if (cur->first_child != NULL) { + /* Has children */ + cur = cur->first_child; + } else if (cur->next != NULL) { + /* No children, but has siblings */ + cur = cur->next; + } else { + /* No children or siblings. + * Find first unvisited relation. */ + struct dom_node *parent = cur->parent; + + while (parent != list->root && + cur == parent->last_child) { + cur = parent; + parent = parent->parent; + } + + cur = cur->next; + } + } + } - return DOM_NOT_SUPPORTED_ERR; + *length = len; + + return DOM_NO_ERR; } /** @@ -189,11 +236,66 @@ dom_exception dom_nodelist_get_length(struct dom_nodelist *list, dom_exception dom_nodelist_item(struct dom_nodelist *list, unsigned long index, struct dom_node **node) { - UNUSED(list); - UNUSED(index); - UNUSED(node); + struct dom_node *cur = list->root->first_child; + unsigned long count = 0; + + /* Traverse data structure */ + while (cur != NULL) { + /* Process current node */ + if (list->type == DOM_NODELIST_CHILDREN) { + count++; + } else if (list->type == DOM_NODELIST_BY_NAME) { + if (dom_string_cmp(cur->name, list->data.name) == 0) { + count++; + } + } else { + if (dom_string_cmp(cur->namespace, + list->data.ns.namespace) == 0 && + dom_string_cmp(cur->localname, + list->data.ns.localname) == 0) { + count++; + } + } - return DOM_NOT_SUPPORTED_ERR; + /* Stop if this is the requested index */ + if ((index + 1) == count) { + break; + } + + /* Now, find next node */ + if (list->type == DOM_NODELIST_CHILDREN) { + /* Just interested in sibling list */ + cur = cur->next; + } else { + /* Want a full in-order tree traversal */ + if (cur->first_child != NULL) { + /* Has children */ + cur = cur->first_child; + } else if (cur->next != NULL) { + /* No children, but has siblings */ + cur = cur->next; + } else { + /* No children or siblings. + * Find first unvisited relation. */ + struct dom_node *parent = cur->parent; + + while (parent != list->root && + cur == parent->last_child) { + cur = parent; + parent = parent->parent; + } + + cur = cur->next; + } + } + } + + if (cur != NULL) { + dom_node_ref(cur); + } + *node = cur; + + return DOM_NO_ERR; } /** -- cgit v1.2.3