Author: jmb
Date: Sat Jul 28 21:41:41 2007
New Revision: 3467
URL:
http://source.netsurf-browser.org?rev=3467&view=rev
Log:
Finalisation and destruction of nodes
Modified:
trunk/dom/src/core/attr.c
trunk/dom/src/core/attr.h
trunk/dom/src/core/cdatasection.c
trunk/dom/src/core/cdatasection.h
trunk/dom/src/core/characterdata.c
trunk/dom/src/core/characterdata.h
trunk/dom/src/core/comment.c
trunk/dom/src/core/comment.h
trunk/dom/src/core/doc_fragment.c
trunk/dom/src/core/doc_fragment.h
trunk/dom/src/core/document.c
trunk/dom/src/core/element.c
trunk/dom/src/core/element.h
trunk/dom/src/core/entity_ref.c
trunk/dom/src/core/entity_ref.h
trunk/dom/src/core/node.c
trunk/dom/src/core/node.h
trunk/dom/src/core/pi.c
trunk/dom/src/core/pi.h
trunk/dom/src/core/text.c
trunk/dom/src/core/text.h
Modified: trunk/dom/src/core/attr.c
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/attr.c?rev=3467&...
==============================================================================
--- trunk/dom/src/core/attr.c (original)
+++ trunk/dom/src/core/attr.c Sat Jul 28 21:41:41 2007
@@ -80,6 +80,53 @@
}
/**
+ * Destroy an attribute node
+ *
+ * \param doc The owning document
+ * \param attr The attribute to destroy
+ *
+ * The contents of ::attr will be destroyed and ::attr will be freed
+ */
+void dom_attr_destroy(struct dom_document *doc, struct dom_attr *attr)
+{
+ struct dom_node *c, *d;
+
+ /* Destroy children of this node */
+ for (c = attr->base.first_child; c != NULL; c = d) {
+ d = c->next;
+
+ /* Detach child */
+ c->parent = NULL;
+
+ if (c->refcnt > 0) {
+ /* Something is using this child */
+
+ /** \todo add to list of nodes pending deletion */
+
+ continue;
+ }
+
+ /* Detach from sibling list */
+ c->previous = NULL;
+ c->next = NULL;
+
+ dom_node_destroy(c);
+ }
+
+ /* Now, clean up this node and destroy it */
+
+ if (attr->schema_type_info != NULL) {
+ /** \todo destroy schema type info */
+ }
+
+ attr->owner = NULL;
+
+ dom_node_finalise(doc, &attr->base);
+
+ dom_document_alloc(doc, attr, 0);
+}
+
+/**
* Retrieve an attribute's name
*
* \param attr Attribute to retrieve name from
Modified: trunk/dom/src/core/attr.h
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/attr.h?rev=3467&...
==============================================================================
--- trunk/dom/src/core/attr.h (original)
+++ trunk/dom/src/core/attr.h Sat Jul 28 21:41:41 2007
@@ -16,5 +16,6 @@
dom_exception dom_attr_create(struct dom_document *doc,
struct dom_string *name, struct dom_attr **result);
+void dom_attr_destroy(struct dom_document *doc, struct dom_attr *attr);
#endif
Modified: trunk/dom/src/core/cdatasection.c
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/cdatasection.c?rev=3...
==============================================================================
--- trunk/dom/src/core/cdatasection.c (original)
+++ trunk/dom/src/core/cdatasection.c Sat Jul 28 21:41:41 2007
@@ -54,3 +54,21 @@
return DOM_NO_ERR;
}
+
+/**
+ * Destroy a CDATA section
+ *
+ * \param doc The owning document
+ * \param cdata The cdata section to destroy
+ *
+ * The contents of ::cdata will be destroyed and ::cdata will be freed.
+ */
+void dom_cdata_section_destroy(struct dom_document *doc,
+ struct dom_cdata_section *cdata)
+{
+ /* Clean up base node contents */
+ dom_text_finalise(doc, &cdata->base);
+
+ /* Destroy the node */
+ dom_document_alloc(doc, cdata, 0);
+}
Modified: trunk/dom/src/core/cdatasection.h
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/cdatasection.h?rev=3...
==============================================================================
--- trunk/dom/src/core/cdatasection.h (original)
+++ trunk/dom/src/core/cdatasection.h Sat Jul 28 21:41:41 2007
@@ -18,4 +18,7 @@
struct dom_string *name, struct dom_string *value,
struct dom_cdata_section **result);
+void dom_cdata_section_destroy(struct dom_document *doc,
+ struct dom_cdata_section *cdata);
+
#endif
Modified: trunk/dom/src/core/characterdata.c
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/characterdata.c?rev=...
==============================================================================
--- trunk/dom/src/core/characterdata.c (original)
+++ trunk/dom/src/core/characterdata.c Sat Jul 28 21:41:41 2007
@@ -29,6 +29,20 @@
struct dom_string *name, struct dom_string *value)
{
return dom_node_initialise(&cdata->base, doc, type, name, value);
+}
+
+/**
+ * Finalise a character data node
+ *
+ * \param doc The owning document
+ * \param cdata The node to finalise
+ *
+ * The contents of ::cdata will be cleaned up. ::cdata will not be freed.
+ */
+void dom_characterdata_finalise(struct dom_document *doc,
+ struct dom_characterdata *cdata)
+{
+ dom_node_finalise(doc, &cdata->base);
}
/**
Modified: trunk/dom/src/core/characterdata.h
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/characterdata.h?rev=...
==============================================================================
--- trunk/dom/src/core/characterdata.h (original)
+++ trunk/dom/src/core/characterdata.h Sat Jul 28 21:41:41 2007
@@ -21,4 +21,7 @@
struct dom_document *doc, dom_node_type type,
struct dom_string *name, struct dom_string *value);
+void dom_characterdata_finalise(struct dom_document *doc,
+ struct dom_characterdata *cdata);
+
#endif
Modified: trunk/dom/src/core/comment.c
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/comment.c?rev=3467&a...
==============================================================================
--- trunk/dom/src/core/comment.c (original)
+++ trunk/dom/src/core/comment.c Sat Jul 28 21:41:41 2007
@@ -54,3 +54,21 @@
return DOM_NO_ERR;
}
+
+/**
+ * Destroy a comment node
+ *
+ * \param doc The owning document
+ * \param comment The node to destroy
+ *
+ * The contents of ::comment will be destroyed and ::comment will be freed
+ */
+void dom_comment_destroy(struct dom_document *doc,
+ struct dom_comment *comment)
+{
+ /* Finalise base class contents */
+ dom_characterdata_finalise(doc, &comment->base);
+
+ /* Free node */
+ dom_document_alloc(doc, comment, 0);
+}
Modified: trunk/dom/src/core/comment.h
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/comment.h?rev=3467&a...
==============================================================================
--- trunk/dom/src/core/comment.h (original)
+++ trunk/dom/src/core/comment.h Sat Jul 28 21:41:41 2007
@@ -18,4 +18,7 @@
struct dom_string *name, struct dom_string *value,
struct dom_comment **result);
+void dom_comment_destroy(struct dom_document *doc,
+ struct dom_comment *comment);
+
#endif
Modified: trunk/dom/src/core/doc_fragment.c
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/doc_fragment.c?rev=3...
==============================================================================
--- trunk/dom/src/core/doc_fragment.c (original)
+++ trunk/dom/src/core/doc_fragment.c Sat Jul 28 21:41:41 2007
@@ -55,3 +55,45 @@
return DOM_NO_ERR;
}
+
+/**
+ * Destroy a document fragment
+ *
+ * \param doc The owning document
+ * \param frag The document fragment to destroy
+ *
+ * The contents of ::frag will be destroyed and ::frag will be freed.
+ */
+void dom_document_fragment_destroy(struct dom_document *doc,
+ struct dom_document_fragment *frag)
+{
+ struct dom_node *c, *d;
+
+ /* Destroy children of this node */
+ for (c = frag->base.first_child; c != NULL; c = d) {
+ d = c->next;
+
+ /* Detach child */
+ c->parent = NULL;
+
+ if (c->refcnt > 0) {
+ /* Something is using this child */
+
+ /** \todo add to list of nodes pending deletion */
+
+ continue;
+ }
+
+ /* Detach from sibling list */
+ c->previous = NULL;
+ c->next = NULL;
+
+ dom_node_destroy(c);
+ }
+
+ /* Finalise base class */
+ dom_node_finalise(doc, &frag->base);
+
+ /* Destroy fragment */
+ dom_document_alloc(doc, frag, 0);
+}
Modified: trunk/dom/src/core/doc_fragment.h
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/doc_fragment.h?rev=3...
==============================================================================
--- trunk/dom/src/core/doc_fragment.h (original)
+++ trunk/dom/src/core/doc_fragment.h Sat Jul 28 21:41:41 2007
@@ -18,4 +18,7 @@
struct dom_string *name, struct dom_string *value,
struct dom_document_fragment **result);
+void dom_document_fragment_destroy(struct dom_document *doc,
+ struct dom_document_fragment *frag);
+
#endif
Modified: trunk/dom/src/core/document.c
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/document.c?rev=3467&...
==============================================================================
--- trunk/dom/src/core/document.c (original)
+++ trunk/dom/src/core/document.c Sat Jul 28 21:41:41 2007
@@ -15,7 +15,6 @@
#include "core/attr.h"
#include "core/cdatasection.h"
-#include "core/characterdata.h"
#include "core/comment.h"
#include "core/document.h"
#include "core/doc_fragment.h"
Modified: trunk/dom/src/core/element.c
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/element.c?rev=3467&a...
==============================================================================
--- trunk/dom/src/core/element.c (original)
+++ trunk/dom/src/core/element.c Sat Jul 28 21:41:41 2007
@@ -62,6 +62,75 @@
*result = el;
return DOM_NO_ERR;
+}
+
+/**
+ * Destroy an element
+ *
+ * \param doc The owning document
+ * \param element The element to destroy
+ *
+ * The contents of ::element will be destroyed and ::element will be freed.
+ */
+void dom_element_destroy(struct dom_document *doc,
+ struct dom_element *element)
+{
+ struct dom_node *c, *d;
+
+ /* Destroy children of this node */
+ for (c = element->base.first_child; c != NULL; c = d) {
+ d = c->next;
+
+ /* Detach child */
+ c->parent = NULL;
+
+ if (c->refcnt > 0) {
+ /* Something is using this child */
+
+ /** \todo add to list of nodes pending deletion */
+
+ continue;
+ }
+
+ /* Detach from sibling list */
+ c->previous = NULL;
+ c->next = NULL;
+
+ dom_node_destroy(c);
+ }
+
+ /* Destroy attributes attached to this node */
+ for (c = (struct dom_node *) element->base.attributes;
+ c != NULL; c = d) {
+ d = c->next;
+
+ /* Detach child */
+ c->parent = NULL;
+
+ if (c->refcnt > 0) {
+ /* Something is using this attribute */
+
+ /** \todo add to list of nodes pending deletion */
+
+ continue;
+ }
+
+ /* Detach from sibling list */
+ c->previous = NULL;
+ c->next = NULL;
+
+ dom_node_destroy(c);
+ }
+
+ if (element->schema_type_info != NULL) {
+ /** \todo destroy schema type info */
+ }
+
+ /* Finalise base class */
+ dom_node_finalise(doc, &element->base);
+
+ /* Free the element */
+ dom_document_alloc(doc, element, 0);
}
/**
Modified: trunk/dom/src/core/element.h
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/element.h?rev=3467&a...
==============================================================================
--- trunk/dom/src/core/element.h (original)
+++ trunk/dom/src/core/element.h Sat Jul 28 21:41:41 2007
@@ -17,4 +17,7 @@
dom_exception dom_element_create(struct dom_document *doc,
struct dom_string *name, struct dom_element **result);
+void dom_element_destroy(struct dom_document *doc,
+ struct dom_element *element);
+
#endif
Modified: trunk/dom/src/core/entity_ref.c
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/entity_ref.c?rev=346...
==============================================================================
--- trunk/dom/src/core/entity_ref.c (original)
+++ trunk/dom/src/core/entity_ref.c Sat Jul 28 21:41:41 2007
@@ -55,3 +55,45 @@
return DOM_NO_ERR;
}
+
+/**
+ * Destroy an entity reference
+ *
+ * \param doc The owning document
+ * \param entity The entity reference to destroy
+ *
+ * The contents of ::entity will be destroyed and ::entity will be freed.
+ */
+void dom_entity_reference_destroy(struct dom_document *doc,
+ struct dom_entity_reference *entity)
+{
+ struct dom_node *c, *d;
+
+ /* Destroy children of this node */
+ for (c = entity->base.first_child; c != NULL; c = d) {
+ d = c->next;
+
+ /* Detach child */
+ c->parent = NULL;
+
+ if (c->refcnt > 0) {
+ /* Something is using this child */
+
+ /** \todo add to list of nodes pending deletion */
+
+ continue;
+ }
+
+ /* Detach from sibling list */
+ c->previous = NULL;
+ c->next = NULL;
+
+ dom_node_destroy(c);
+ }
+
+ /* Finalise base class */
+ dom_node_finalise(doc, &entity->base);
+
+ /* Destroy fragment */
+ dom_document_alloc(doc, entity, 0);
+}
Modified: trunk/dom/src/core/entity_ref.h
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/entity_ref.h?rev=346...
==============================================================================
--- trunk/dom/src/core/entity_ref.h (original)
+++ trunk/dom/src/core/entity_ref.h Sat Jul 28 21:41:41 2007
@@ -18,4 +18,7 @@
struct dom_string *name, struct dom_string *value,
struct dom_entity_reference **result);
+void dom_entity_reference_destroy(struct dom_document *doc,
+ struct dom_entity_reference *entity);
+
#endif
Modified: trunk/dom/src/core/node.c
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/node.c?rev=3467&...
==============================================================================
--- trunk/dom/src/core/node.c (original)
+++ trunk/dom/src/core/node.c Sat Jul 28 21:41:41 2007
@@ -8,9 +8,88 @@
#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
@@ -61,6 +140,55 @@
}
/**
+ * 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 @@
*
* \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);
}
}
Modified: trunk/dom/src/core/node.h
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/node.h?rev=3467&...
==============================================================================
--- trunk/dom/src/core/node.h (original)
+++ trunk/dom/src/core/node.h Sat Jul 28 21:41:41 2007
@@ -52,8 +52,12 @@
uint32_t refcnt; /**< Reference count */
};
+void dom_node_destroy(struct dom_node *node);
+
dom_exception dom_node_initialise(struct dom_node *node,
struct dom_document *doc, dom_node_type type,
struct dom_string *name, struct dom_string *value);
+void dom_node_finalise(struct dom_document *doc, struct dom_node *node);
+
#endif
Modified: trunk/dom/src/core/pi.c
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/pi.c?rev=3467&r1...
==============================================================================
--- trunk/dom/src/core/pi.c (original)
+++ trunk/dom/src/core/pi.c Sat Jul 28 21:41:41 2007
@@ -56,3 +56,21 @@
return DOM_NO_ERR;
}
+
+/**
+ * Destroy a processing instruction
+ *
+ * \param doc The owning document
+ * \param pi The processing instruction to destroy
+ *
+ * The contents of ::pi will be destroyed and ::pi will be freed.
+ */
+void dom_processing_instruction_destroy(struct dom_document *doc,
+ struct dom_processing_instruction *pi)
+{
+ /* Finalise base class */
+ dom_node_finalise(doc, &pi->base);
+
+ /* Free processing instruction */
+ dom_document_alloc(doc, pi, 0);
+}
Modified: trunk/dom/src/core/pi.h
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/pi.h?rev=3467&r1...
==============================================================================
--- trunk/dom/src/core/pi.h (original)
+++ trunk/dom/src/core/pi.h Sat Jul 28 21:41:41 2007
@@ -18,4 +18,7 @@
struct dom_string *name, struct dom_string *value,
struct dom_processing_instruction **result);
+void dom_processing_instruction_destroy(struct dom_document *doc,
+ struct dom_processing_instruction *pi);
+
#endif
Modified: trunk/dom/src/core/text.c
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/text.c?rev=3467&...
==============================================================================
--- trunk/dom/src/core/text.c (original)
+++ trunk/dom/src/core/text.c Sat Jul 28 21:41:41 2007
@@ -52,6 +52,23 @@
}
/**
+ * Destroy a text node
+ *
+ * \param doc The owning document
+ * \param text The text node to destroy
+ *
+ * The contents of ::text will be destroyed and ::text will be freed.
+ */
+void dom_text_destroy(struct dom_document *doc, struct dom_text *text)
+{
+ /* Finalise node */
+ dom_text_finalise(doc, text);
+
+ /* Free node */
+ dom_document_alloc(doc, text, 0);
+}
+
+/**
* Initialise a text node
*
* \param text The node to initialise
@@ -79,6 +96,19 @@
text->element_content_whitespace = false;
return DOM_NO_ERR;
+}
+
+/**
+ * Finalise a text node
+ *
+ * \param doc The owning document
+ * \param text The text node to finalise
+ *
+ * The contents of ::text will be cleaned up. ::text will not be freed.
+ */
+void dom_text_finalise(struct dom_document *doc, struct dom_text *text)
+{
+ dom_characterdata_finalise(doc, &text->base);
}
/**
Modified: trunk/dom/src/core/text.h
URL:
http://source.netsurf-browser.org/trunk/dom/src/core/text.h?rev=3467&...
==============================================================================
--- trunk/dom/src/core/text.h (original)
+++ trunk/dom/src/core/text.h Sat Jul 28 21:41:41 2007
@@ -31,8 +31,12 @@
struct dom_string *name, struct dom_string *value,
struct dom_text **result);
+void dom_text_destroy(struct dom_document *doc, struct dom_text *text);
+
dom_exception dom_text_initialise(struct dom_text *text,
struct dom_document *doc, dom_node_type type,
struct dom_string *name, struct dom_string *value);
+void dom_text_finalise(struct dom_document *doc, struct dom_text *text);
+
#endif