From 54353aeaa58e2807a42a8130f72404764ac0357d Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Tue, 18 Sep 2007 23:34:13 +0000 Subject: Implement dom_element_get_tag_name() Implement dom_element_set_attribute_node() [still has some outstanding sanity checking] svn path=/trunk/dom/; revision=3549 --- src/core/element.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 105 insertions(+), 8 deletions(-) (limited to 'src/core/element.c') diff --git a/src/core/element.c b/src/core/element.c index 8c5ed6a..15f0152 100644 --- a/src/core/element.c +++ b/src/core/element.c @@ -5,7 +5,10 @@ * Copyright 2007 John-Mark Bell */ +#include + #include +#include #include "core/document.h" #include "core/element.h" @@ -138,7 +141,8 @@ void dom_element_destroy(struct dom_document *doc, * * \param element The element to retrieve the name from * \param name Pointer to location to receive name - * \return DOM_NO_ERR. + * \return DOM_NO_ERR on success, + * DOM_NO_MEM_ERR on memory exhaustion. * * The returned string will have its reference count increased. It is * the responsibility of the caller to unref the string once it has @@ -147,10 +151,41 @@ void dom_element_destroy(struct dom_document *doc, dom_exception dom_element_get_tag_name(struct dom_element *element, struct dom_string **name) { - UNUSED(element); - UNUSED(name); + struct dom_node *e = (struct dom_node *) element; + struct dom_string *tag_name; - return DOM_NOT_SUPPORTED_ERR; + if (e->localname != NULL) { + /* Has a localname, so build a qname string */ + size_t local_len = 0, prefix_len = 0; + const uint8_t *local = NULL, *prefix = NULL; + dom_exception err; + + if (e->prefix != NULL) + dom_string_get_data(e->prefix, &prefix, &prefix_len); + + dom_string_get_data(e->localname, &local, &local_len); + + uint8_t qname[prefix_len + 1 /* : */ + local_len + 1 /* \0 */]; + + sprintf((char *) qname, "%s:%s", + prefix ? (const char *) prefix : "", + (const char *) local); + + err = dom_string_create_from_ptr(e->owner, qname, + prefix_len + 1 + local_len, &tag_name); + if (err != DOM_NO_ERR) + return err; + + /* tag_name is referenced for us */ + } else { + tag_name = e->name; + + dom_string_ref(tag_name); + } + + *name = tag_name; + + return DOM_NO_ERR; } /** @@ -254,11 +289,73 @@ dom_exception dom_element_get_attribute_node(struct dom_element *element, dom_exception dom_element_set_attribute_node(struct dom_element *element, struct dom_attr *attr, struct dom_attr **result) { - UNUSED(element); - UNUSED(attr); - UNUSED(result); + struct dom_node *e = (struct dom_node *) element; + struct dom_node *a = (struct dom_node *) attr; + struct dom_attr *prev = NULL; - return DOM_NOT_SUPPORTED_ERR; + /* Ensure element and attribute belong to the same document */ + if (e->owner != a->owner) + return DOM_WRONG_DOCUMENT_ERR; + + /** \todo ensure ::element can be written to */ + + /* Ensure attribute isn't attached to another element */ + if (a->parent != NULL && a->parent != e) + return DOM_INUSE_ATTRIBUTE_ERR; + + /* Attach attr to element, if not already attached */ + if (a->parent == NULL) { + + /* Search for existing attribute with same name */ + prev = e->attributes; + while (prev != NULL) { + struct dom_node *p = (struct dom_node *) prev; + + if (dom_string_cmp(a->name, p->name) == 0) + break; + + prev = (struct dom_attr *) p->next; + } + + a->parent = e; + + if (prev != NULL) { + /* Found an existing attribute, so replace it */ + struct dom_node *p = (struct dom_node *) prev; + + a->previous = p->previous; + a->next = p->next; + + if (a->previous != NULL) + a->previous->next = a; + else + e->attributes = attr; + + if (a->next != NULL) + a->next->previous = a; + + /* Invalidate existing attribute's location info */ + p->next = NULL; + p->previous = NULL; + p->parent = NULL; + } else { + /* No existing attribute, so insert at front of list */ + a->previous = NULL; + a->next = (struct dom_node *) e->attributes; + + if (a->next != NULL) + a->next->previous = a; + + e->attributes = attr; + } + } + + if (prev != NULL) + dom_node_ref((struct dom_node *) prev); + + *result = prev; + + return DOM_NO_ERR; } /** -- cgit v1.2.3