From 4f82098cae7c00568c1ca436f0b2f8d1103d6760 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Tue, 25 Sep 2007 00:02:07 +0000 Subject: Add library-internal accessor to the head of an Element's attribute list (dom_element_get_first_attribute()) Implement dom_namednodemap_get_length() Implement dom_namednodemap_get_named_item() Implement dom_namednodemap_set_named_item() Implement dom_namednodemap_remove_named_item() Implement dom_namednodemap_item() All dom_namednodemap_*() still require support for maps of Entity and Notation nodes to be added (this requires DocumentType to gain support for these nodes). svn path=/trunk/dom/; revision=3591 --- src/core/element.c | 11 +++ src/core/element.h | 4 ++ src/core/namednodemap.c | 175 ++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 171 insertions(+), 19 deletions(-) diff --git a/src/core/element.c b/src/core/element.c index a0f0b51..1b351ce 100644 --- a/src/core/element.c +++ b/src/core/element.c @@ -883,3 +883,14 @@ dom_exception dom_element_has_attributes(struct dom_element *element, return DOM_NO_ERR; } +/** + * Retrieve a pointer to the first attribute attached to an element + * + * \param element The element to retrieve the first attribute from + * \return Pointer to first attribute, or NULL if none. + */ +struct dom_node *dom_element_get_first_attribute(struct dom_element *element) +{ + return (struct dom_node *) element->attributes; +} + diff --git a/src/core/element.h b/src/core/element.h index f51b9ae..95e7cfe 100644 --- a/src/core/element.h +++ b/src/core/element.h @@ -15,6 +15,7 @@ struct dom_document; struct dom_element; struct dom_namednodemap; +struct dom_node; struct dom_string; dom_exception dom_element_create(struct dom_document *doc, @@ -28,4 +29,7 @@ dom_exception dom_element_get_attributes(struct dom_element *element, dom_exception dom_element_has_attributes(struct dom_element *element, bool *result); + +struct dom_node *dom_element_get_first_attribute(struct dom_element *element); + #endif diff --git a/src/core/namednodemap.c b/src/core/namednodemap.c index c049a6c..2d1fbc8 100644 --- a/src/core/namednodemap.c +++ b/src/core/namednodemap.c @@ -5,10 +5,14 @@ * Copyright 2007 John-Mark Bell */ +#include #include +#include #include "core/document.h" +#include "core/element.h" #include "core/namednodemap.h" +#include "core/node.h" #include "utils/utils.h" @@ -118,10 +122,29 @@ void dom_namednodemap_unref(struct dom_namednodemap *map) dom_exception dom_namednodemap_get_length(struct dom_namednodemap *map, unsigned long *length) { - UNUSED(map); - UNUSED(length); + struct dom_node *cur; + unsigned long len = 0; + + switch (map->type) { + case DOM_ATTRIBUTE_NODE: + cur = dom_element_get_first_attribute( + (struct dom_element *) map->head); + break; + case DOM_NOTATION_NODE: + case DOM_ENTITY_NODE: + /** \todo handle notation and entity nodes */ + default: + return DOM_NOT_SUPPORTED_ERR; + break; + } - return DOM_NOT_SUPPORTED_ERR; + for (; cur != NULL; cur = cur->next) { + len++; + } + + *length = len; + + return DOM_NO_ERR; } /** @@ -138,11 +161,33 @@ dom_exception dom_namednodemap_get_length(struct dom_namednodemap *map, dom_exception dom_namednodemap_get_named_item(struct dom_namednodemap *map, struct dom_string *name, struct dom_node **node) { - UNUSED(map); - UNUSED(name); - UNUSED(node); + struct dom_node *cur; + + switch (map->type) { + case DOM_ATTRIBUTE_NODE: + cur = dom_element_get_first_attribute( + (struct dom_element *) map->head); + break; + case DOM_NOTATION_NODE: + case DOM_ENTITY_NODE: + /** \todo handle notation and entity nodes */ + default: + return DOM_NOT_SUPPORTED_ERR; + break; + } - return DOM_NOT_SUPPORTED_ERR; + for (; cur != NULL; cur = cur->next) { + if (dom_string_cmp(cur->name, name) == 0) { + break; + } + } + + if (cur != NULL) { + dom_node_ref(cur); + } + *node = cur; + + return DOM_NO_ERR; } /** @@ -172,11 +217,45 @@ dom_exception dom_namednodemap_get_named_item(struct dom_namednodemap *map, dom_exception dom_namednodemap_set_named_item(struct dom_namednodemap *map, struct dom_node *arg, struct dom_node **node) { - UNUSED(map); - UNUSED(arg); - UNUSED(node); + dom_exception err; + + /* Ensure arg and map belong to the same document */ + if (arg->owner != map->owner) + return DOM_WRONG_DOCUMENT_ERR; + + /* Ensure map is writable */ + if (_dom_node_readonly(map->head)) + return DOM_NO_MODIFICATION_ALLOWED_ERR; + + /* Ensure arg isn't attached to another element */ + if (arg->type == DOM_ATTRIBUTE_NODE && arg->parent != NULL && + arg->parent != map->head) + return DOM_INUSE_ATTRIBUTE_ERR; + + /* Ensure arg is permitted in the map */ + if (arg->type != map->type) + return DOM_HIERARCHY_REQUEST_ERR; + + /* Now delegate to the container-specific function. + * NamedNodeMaps are live, so this is fine. */ + switch (map->type) { + case DOM_ATTRIBUTE_NODE: + err = dom_element_set_attribute_node( + (struct dom_element *) map->head, + (struct dom_attr *) arg, + (struct dom_attr **) node); + break; + case DOM_NOTATION_NODE: + case DOM_ENTITY_NODE: + /** \todo handle notation and entity nodes */ + default: + err = DOM_NOT_SUPPORTED_ERR; + break; + } - return DOM_NOT_SUPPORTED_ERR; + /* Reference counting is handled by the container-specific call */ + + return err; } /** @@ -197,11 +276,44 @@ dom_exception dom_namednodemap_remove_named_item( struct dom_namednodemap *map, struct dom_string *name, struct dom_node **node) { - UNUSED(map); - UNUSED(name); - UNUSED(node); + dom_exception err; + + /* Ensure map is writable */ + if (_dom_node_readonly(map->head)) + return DOM_NO_MODIFICATION_ALLOWED_ERR; + + /* Now delegate to the container-specific function. + * NamedNodeMaps are live, so this is fine. */ + switch (map->type) { + case DOM_ATTRIBUTE_NODE: + { + struct dom_attr *attr; + + err = dom_element_get_attribute_node( + (struct dom_element *) map->head, + name, &attr); + if (err == DOM_NO_ERR) { + err = dom_element_remove_attribute_node( + (struct dom_element *) map->head, + attr, (struct dom_attr **) node); + if (err == DOM_NO_ERR) { + /* No longer want attr */ + dom_node_unref((struct dom_node *) attr); + } + } + } + break; + case DOM_NOTATION_NODE: + case DOM_ENTITY_NODE: + /** \todo handle notation and entity nodes */ + default: + err = DOM_NOT_SUPPORTED_ERR; + break; + } - return DOM_NOT_SUPPORTED_ERR; + /* Reference counting is handled by the container-specific call */ + + return err; } /** @@ -221,11 +333,36 @@ dom_exception dom_namednodemap_remove_named_item( dom_exception dom_namednodemap_item(struct dom_namednodemap *map, unsigned long index, struct dom_node **node) { - UNUSED(map); - UNUSED(index); - UNUSED(node); + struct dom_node *cur; + unsigned long count = 0; + + switch (map->type) { + case DOM_ATTRIBUTE_NODE: + cur = dom_element_get_first_attribute( + (struct dom_element *) map->head); + break; + case DOM_NOTATION_NODE: + case DOM_ENTITY_NODE: + /** \todo handle notation and entity nodes */ + default: + return DOM_NOT_SUPPORTED_ERR; + break; + } - return DOM_NOT_SUPPORTED_ERR; + for (; cur != NULL; cur = cur->next) { + count++; + + if ((index + 1) == count) { + break; + } + } + + if (cur != NULL) { + dom_node_ref(cur); + } + *node = cur; + + return DOM_NO_ERR; } /** -- cgit v1.2.3