summaryrefslogtreecommitdiff
path: root/src/core/node.c
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2007-09-26 23:55:36 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2007-09-26 23:55:36 +0000
commit2aac5e44f227f0fd36d801fb05508e2de41ce44a (patch)
tree4fbbf2458c260e4e097f23484d12f10fcadf6a0b /src/core/node.c
parent41b84a1c6517d8c06f54c0e21babfeff76e4f871 (diff)
downloadlibdom-2aac5e44f227f0fd36d801fb05508e2de41ce44a.tar.gz
libdom-2aac5e44f227f0fd36d801fb05508e2de41ce44a.tar.bz2
Begin to cater for XML namespaces.
The localname member of Node has been removed. The name member already caters for this. Fix NodeList to cope with this and add some pointer vs NULL comparisons for sanity. Replace implementation of dom_element_get_tag_name() with a simple call to dom_node_get_node_name(), which is where the gory details lie. Add the QName building stuff to dom_node_get_node_name() (as per previous implementation of dom_element_get_tag_name()). Implement dom_node_set_prefix(). Ensure dom_node_get_local_name() returns NULL for nodes created by non-namespace-aware methods (nodes must also be Elements or Attributes) svn path=/trunk/dom/; revision=3596
Diffstat (limited to 'src/core/node.c')
-rw-r--r--src/core/node.c106
1 files changed, 93 insertions, 13 deletions
diff --git a/src/core/node.c b/src/core/node.c
index ea957e4..2a90df8 100644
--- a/src/core/node.c
+++ b/src/core/node.c
@@ -7,6 +7,7 @@
#include <assert.h>
#include <stdbool.h>
+#include <stdio.h>
#include <dom/core/attr.h>
#include <dom/core/document.h>
@@ -181,7 +182,6 @@ dom_exception dom_node_initialise(struct dom_node *node,
/** \todo Namespace handling */
node->namespace = NULL;
node->prefix = NULL;
- node->localname = NULL;
node->user_data = NULL;
@@ -216,9 +216,6 @@ void dom_node_finalise(struct dom_document *doc, struct dom_node *node)
dom_document_alloc(doc, u, 0);
}
- if (node->localname != NULL)
- dom_string_unref(node->localname);
-
if (node->prefix != NULL)
dom_string_unref(node->prefix);
@@ -286,10 +283,45 @@ void dom_node_unref(struct dom_node *node)
dom_exception dom_node_get_node_name(struct dom_node *node,
struct dom_string **result)
{
- if (node->name != NULL)
+ struct dom_string *node_name;
+
+ assert(node->name != NULL);
+
+ /* If this node was created using a namespace-aware method and
+ * has a defined prefix, then nodeName is a QName comprised
+ * of prefix:name. */
+ if ((node->type == DOM_ELEMENT_NODE ||
+ node->type == DOM_ATTRIBUTE_NODE) &&
+ node->prefix != NULL) {
+ const uint8_t *prefix, *localname;
+ size_t prefix_len, local_len;
+ dom_exception err;
+
+ dom_string_get_data(node->prefix, &prefix, &prefix_len);
+
+ dom_string_get_data(node->name, &localname, &local_len);
+
+ uint8_t qname[prefix_len + 1 /* : */ + local_len + 1 /* \0 */];
+
+ sprintf((char *) qname, "%.*s:%.*s",
+ prefix_len, (const char *) prefix,
+ local_len, (const char *) localname);
+
+ /* Create the string */
+ err = dom_string_create_from_ptr(node->owner, qname,
+ prefix_len + 1 + local_len, &node_name);
+ if (err != DOM_NO_ERR) {
+ return err;
+ }
+
+ /* QName is referenced on exit from constructor */
+ } else {
dom_string_ref(node->name);
- *result = node->name;
+ node_name = node->name;
+ }
+
+ *result = node_name;
return DOM_NO_ERR;
}
@@ -1064,10 +1096,45 @@ dom_exception dom_node_get_prefix(struct dom_node *node,
dom_exception dom_node_set_prefix(struct dom_node *node,
struct dom_string *prefix)
{
- UNUSED(node);
- UNUSED(prefix);
+ /* Only Element and Attribute nodes created using
+ * namespace-aware methods may have a prefix */
+ if ((node->type != DOM_ELEMENT_NODE &&
+ node->type != DOM_ATTRIBUTE_NODE) ||
+ node->namespace == NULL) {
+ return DOM_NO_ERR;
+ }
- return DOM_NOT_SUPPORTED_ERR;
+ /** \todo validate prefix */
+
+ /* Ensure node is writable */
+ if (_dom_node_readonly(node)) {
+ return DOM_NO_MODIFICATION_ALLOWED_ERR;
+ }
+
+ /* No longer want existing prefix */
+ if (node->prefix != NULL) {
+ dom_string_unref(node->prefix);
+ }
+
+ /* Set the prefix */
+ if (prefix != NULL) {
+ const uint8_t *data;
+ size_t len;
+
+ dom_string_get_data(prefix, &data, &len);
+
+ /* Empty string is treated as NULL */
+ if (len == 0) {
+ node->prefix = NULL;
+ } else {
+ dom_string_ref(prefix);
+ node->prefix = prefix;
+ }
+ } else {
+ node->prefix = NULL;
+ }
+
+ return DOM_NO_ERR;
}
/**
@@ -1084,11 +1151,24 @@ dom_exception dom_node_set_prefix(struct dom_node *node,
dom_exception dom_node_get_local_name(struct dom_node *node,
struct dom_string **result)
{
- /* If there is a local name, increase its reference count */
- if (node->localname != NULL)
- dom_string_ref(node->localname);
+ /* Only Element and Attribute nodes may have a local name */
+ if (node->type != DOM_ELEMENT_NODE &&
+ node->type != DOM_ATTRIBUTE_NODE) {
+ *result = NULL;
+ return DOM_NO_ERR;
+ }
- *result = node->localname;
+ /* Node must have been created using a namespace-aware method */
+ if (node->namespace == NULL) {
+ *result = NULL;
+ return DOM_NO_ERR;
+ }
+
+ /* The node may have a local name, reference it if so */
+ if (node->name != NULL) {
+ dom_string_ref(node->name);
+ }
+ *result = node->name;
return DOM_NO_ERR;
}