diff options
author | John Mark Bell <jmb@netsurf-browser.org> | 2007-07-28 20:41:41 +0000 |
---|---|---|
committer | John Mark Bell <jmb@netsurf-browser.org> | 2007-07-28 20:41:41 +0000 |
commit | ddbf47a33aa4fba4ce23e751db78acf59895fcc3 (patch) | |
tree | 08ff52e60d85dd31ef7f22c5792cf7794eeb8736 /src/core/node.c | |
parent | f6b4e5eeaf8e7afda0df4a5d44a309c291788382 (diff) | |
download | libdom-ddbf47a33aa4fba4ce23e751db78acf59895fcc3.tar.gz libdom-ddbf47a33aa4fba4ce23e751db78acf59895fcc3.tar.bz2 |
Finalisation and destruction of nodes
svn path=/trunk/dom/; revision=3467
Diffstat (limited to 'src/core/node.c')
-rw-r--r-- | src/core/node.c | 139 |
1 files changed, 135 insertions, 4 deletions
diff --git a/src/core/node.c b/src/core/node.c index 04a1230..db0fb05 100644 --- a/src/core/node.c +++ b/src/core/node.c @@ -8,11 +8,90 @@ #include <dom/core/document.h> #include <dom/core/string.h> +#include "core/attr.h" +#include "core/cdatasection.h" +#include "core/comment.h" #include "core/document.h" +#include "core/doc_fragment.h" +#include "core/element.h" +#include "core/entity_ref.h" #include "core/node.h" +#include "core/pi.h" +#include "core/text.h" #include "utils/utils.h" /** + * Destroy a DOM node + * + * \param node The node to destroy + * + * ::node's parent link must be NULL and its reference count must be 0. + * + * ::node will be freed. + * + * This function should only be called from dom_node_unref or type-specific + * destructors (for destroying child nodes). Anything else should not + * be attempting to destroy nodes -- they should simply be unreferencing + * them (so destruction will occur at the appropriate time). + */ +void dom_node_destroy(struct dom_node *node) +{ + struct dom_document *owner = node->owner; + + /* This function simply acts as a central despatcher + * for type-specific destructors. It claims a reference upon the + * owning document during destruction to ensure that the document + * doesn't get destroyed before its contents. */ + + dom_node_ref((struct dom_node *) owner); + + switch (node->type) { + case DOM_ELEMENT_NODE: + dom_element_destroy(owner, (struct dom_element *) node); + break; + case DOM_ATTRIBUTE_NODE: + dom_attr_destroy(owner, (struct dom_attr *) node); + break; + case DOM_TEXT_NODE: + dom_text_destroy(owner, (struct dom_text *) node); + break; + case DOM_CDATA_SECTION_NODE: + dom_cdata_section_destroy(owner, + (struct dom_cdata_section *) node); + break; + case DOM_ENTITY_REFERENCE_NODE: + dom_entity_reference_destroy(owner, + (struct dom_entity_reference *) node); + break; + case DOM_ENTITY_NODE: + /** \todo entity node */ + break; + case DOM_PROCESSING_INSTRUCTION_NODE: + dom_processing_instruction_destroy(owner, + (struct dom_processing_instruction *) node); + break; + case DOM_COMMENT_NODE: + dom_comment_destroy(owner, (struct dom_comment *) node); + break; + case DOM_DOCUMENT_NODE: + /** \todo document node */ + break; + case DOM_DOCUMENT_TYPE_NODE: + /** \todo document type node */ + break; + case DOM_DOCUMENT_FRAGMENT_NODE: + dom_document_fragment_destroy(owner, + (struct dom_document_fragment *) node); + break; + case DOM_NOTATION_NODE: + /** \todo notation node */ + break; + } + + dom_node_unref((struct dom_node *) owner); +} + +/** * Initialise a DOM node * * \param node The node to initialise @@ -61,6 +140,55 @@ dom_exception dom_node_initialise(struct dom_node *node, } /** + * Finalise a DOM node + * + * \param doc The owning document + * \param node The node to finalise + * + * The contents of ::node will be cleaned up. ::node will not be freed. + * All children of ::node should have been removed prior to finalisation. + */ +void dom_node_finalise(struct dom_document *doc, struct dom_node *node) +{ + struct dom_user_data *u, *v; + + /* Destroy user data */ + for (u = node->user_data; u != NULL; u = v) { + v = u->next; + + dom_string_unref(u->key); + + dom_document_alloc(doc, u, 0); + } + + if (node->localname != NULL) + dom_string_unref(node->localname); + + if (node->prefix != NULL) + dom_string_unref(node->prefix); + + if (node->namespace != NULL) + dom_string_unref(node->namespace); + + dom_node_unref((struct dom_node *) node->owner); + node->owner = NULL; + + /* Paranoia */ + node->attributes = NULL; + node->next = NULL; + node->previous = NULL; + node->last_child = NULL; + node->first_child = NULL; + node->parent = NULL; + + if (node->value != NULL) + dom_string_unref(node->value); + + if (node->name != NULL) + dom_string_unref(node->name); +} + +/** * Claim a reference on a DOM node * * \param node The node to claim a reference on @@ -75,13 +203,16 @@ void dom_node_ref(struct dom_node *node) * * \param node The node to release the reference from * - * If the reference count reaches zero, any memory claimed by the - * node will be released + * If the reference count reaches zero and the node is not part of any + * document, any memory claimed by the node will be released. */ void dom_node_unref(struct dom_node *node) { - if (--node->refcnt == 0) { - /** \todo implement */ + if (node->refcnt > 0) + node->refcnt--; + + if (node->refcnt == 0 && node->parent == NULL) { + dom_node_destroy(node); } } |