diff options
author | John Mark Bell <jmb@netsurf-browser.org> | 2007-09-17 00:10:56 +0000 |
---|---|---|
committer | John Mark Bell <jmb@netsurf-browser.org> | 2007-09-17 00:10:56 +0000 |
commit | fbb008b9200a0e0326380366f5d0ffdbc10e4082 (patch) | |
tree | 484fc73165facbafbdb2df0a26a5aefeab21556a /src/core | |
parent | 9131bec4aac229e9f45416b83ba40dbca94d5dac (diff) | |
download | libdom-fbb008b9200a0e0326380366f5d0ffdbc10e4082.tar.gz libdom-fbb008b9200a0e0326380366f5d0ffdbc10e4082.tar.bz2 |
Make Document nodes own themselves (removes need for special case for Documents)
Fixup dom_node_destroy appropriately.
Implement dom_node_{set,get}_user_data.
svn path=/trunk/dom/; revision=3542
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/document.c | 6 | ||||
-rw-r--r-- | src/core/node.c | 89 |
2 files changed, 78 insertions, 17 deletions
diff --git a/src/core/document.c b/src/core/document.c index d238558..de57f72 100644 --- a/src/core/document.c +++ b/src/core/document.c @@ -140,8 +140,10 @@ dom_exception dom_document_create(struct dom_implementation *impl, /* Initialise base class -- the Document has no parent, so * destruction will be attempted as soon as its reference count - * reaches zero. */ - err = dom_node_initialise(&d->base, NULL, DOM_DOCUMENT_NODE, + * reaches zero. Documents own themselves (this simplifies the + * rest of the code, as it doesn't need to special case Documents) + */ + err = dom_node_initialise(&d->base, d, DOM_DOCUMENT_NODE, NULL, NULL); if (err != DOM_NO_ERR) { /* Clean up interned strings */ diff --git a/src/core/node.c b/src/core/node.c index 26748c4..db4838b 100644 --- a/src/core/node.c +++ b/src/core/node.c @@ -39,14 +39,14 @@ void dom_node_destroy(struct dom_node *node) { struct dom_document *owner = node->owner; + bool document_node = (node->type == DOM_DOCUMENT_NODE); /* This function simply acts as a central despatcher * for type-specific destructors. */ - assert(owner != NULL || - (owner == NULL && node->type == DOM_DOCUMENT_NODE)); + assert(owner != NULL); - if (owner != NULL) { + if (!document_node) { /* Claim a reference upon the owning document during * destruction to ensure that the document doesn't get * destroyed before its contents. */ @@ -96,7 +96,7 @@ void dom_node_destroy(struct dom_node *node) break; } - if (owner != NULL) { + if (!document_node) { /* Release the reference we claimed on the document. If this * is the last reference held on the document and the list * of nodes pending deletion is empty, then the document will @@ -115,7 +115,7 @@ void dom_node_destroy(struct dom_node *node) * \param value The node value, or NULL * \return DOM_NO_ERR on success. * - * ::doc, ::name and ::value will have their reference counts increased. + * ::name and ::value will have their reference counts increased. */ dom_exception dom_node_initialise(struct dom_node *node, struct dom_document *doc, dom_node_type type, @@ -1105,13 +1105,62 @@ dom_exception dom_node_set_user_data(struct dom_node *node, struct dom_string *key, void *data, dom_user_data_handler handler, void **result) { - UNUSED(node); - UNUSED(key); - UNUSED(data); - UNUSED(handler); - UNUSED(result); + struct dom_user_data *ud = NULL; + void *prevdata = NULL; - return DOM_NOT_SUPPORTED_ERR; + /* Search for user data */ + for (ud = node->user_data; ud != NULL; ud = ud->next) { + if (dom_string_cmp(ud->key, key) == 0) + break; + }; + + /* Remove it, if found and no new data */ + if (data == NULL && ud != NULL) { + dom_string_unref(ud->key); + + if (ud->next != NULL) + ud->next->prev = ud->prev; + if (ud->prev != NULL) + ud->prev->next = ud->next; + else + node->user_data = ud->next; + + *result = ud->data; + + dom_document_alloc(node->owner, ud, 0); + + return DOM_NO_ERR; + } + + /* Otherwise, create a new user data object if one wasn't found */ + if (ud == NULL) { + ud = dom_document_alloc(node->owner, NULL, + sizeof(struct dom_user_data)); + if (ud == NULL) + return DOM_NO_MEM_ERR; + + dom_string_ref(key); + ud->key = key; + ud->data = NULL; + ud->handler = NULL; + + /* Insert into list */ + ud->prev = NULL; + ud->next = node->user_data; + if (node->user_data) + node->user_data->prev = ud; + node->user_data = ud; + } + + prevdata = ud->data; + + /* And associate data with it */ + ud->data = data; + ud->handler = handler; + + *result = prevdata; + + return DOM_NO_ERR; } /** @@ -1125,9 +1174,19 @@ dom_exception dom_node_set_user_data(struct dom_node *node, dom_exception dom_node_get_user_data(struct dom_node *node, struct dom_string *key, void **result) { - UNUSED(node); - UNUSED(key); - UNUSED(result); + struct dom_user_data *ud = NULL; - return DOM_NOT_SUPPORTED_ERR; + /* Search for user data */ + for (ud = node->user_data; ud != NULL; ud = ud->next) { + if (dom_string_cmp(ud->key, key) == 0) + break; + }; + + if (ud != NULL) + *result = ud->data; + else + *result = NULL; + + return DOM_NO_ERR; } + |