summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/element.c38
-rw-r--r--src/core/node.c106
-rw-r--r--src/core/node.h5
-rw-r--r--src/core/nodelist.c20
4 files changed, 113 insertions, 56 deletions
diff --git a/src/core/element.c b/src/core/element.c
index 1b351ce..027d597 100644
--- a/src/core/element.c
+++ b/src/core/element.c
@@ -9,6 +9,7 @@
#include <dom/core/attr.h>
#include <dom/core/element.h>
+#include <dom/core/node.h>
#include <dom/core/string.h>
#include "core/attr.h"
@@ -156,41 +157,8 @@ void dom_element_destroy(struct dom_document *doc,
dom_exception dom_element_get_tag_name(struct dom_element *element,
struct dom_string **name)
{
- struct dom_node *e = (struct dom_node *) element;
- struct dom_string *tag_name;
-
- 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;
+ /* This is the same as nodeName */
+ return dom_node_get_node_name((struct dom_node *) element, name);
}
/**
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;
}
diff --git a/src/core/node.h b/src/core/node.h
index 2297ca5..fd23625 100644
--- a/src/core/node.h
+++ b/src/core/node.h
@@ -32,7 +32,9 @@ struct dom_user_data {
* DOM nodes are reference counted
*/
struct dom_node {
- struct dom_string *name; /**< Node name */
+ struct dom_string *name; /**< Node name (this is the local part
+ * of a QName in the cases where a
+ * namespace exists) */
struct dom_string *value; /**< Node value */
dom_node_type type; /**< Node type */
struct dom_node *parent; /**< Parent node */
@@ -45,7 +47,6 @@ struct dom_node {
struct dom_string *namespace; /**< Namespace URI */
struct dom_string *prefix; /**< Namespace prefix */
- struct dom_string *localname; /**< Local part of qualified name */
struct dom_user_data *user_data; /**< User data list */
diff --git a/src/core/nodelist.c b/src/core/nodelist.c
index 6cdd099..4377426 100644
--- a/src/core/nodelist.c
+++ b/src/core/nodelist.c
@@ -174,13 +174,17 @@ dom_exception dom_nodelist_get_length(struct dom_nodelist *list,
if (list->type == DOM_NODELIST_CHILDREN) {
len++;
} else if (list->type == DOM_NODELIST_BY_NAME) {
- if (dom_string_cmp(cur->name, list->data.name) == 0) {
+ if (cur->name != NULL &&
+ dom_string_cmp(cur->name,
+ list->data.name) == 0) {
len++;
}
} else {
- if (dom_string_cmp(cur->namespace,
+ if (cur->namespace != NULL &&
+ dom_string_cmp(cur->namespace,
list->data.ns.namespace) == 0 &&
- dom_string_cmp(cur->localname,
+ cur->name != NULL &&
+ dom_string_cmp(cur->name,
list->data.ns.localname) == 0) {
len++;
}
@@ -245,13 +249,17 @@ dom_exception dom_nodelist_item(struct dom_nodelist *list,
if (list->type == DOM_NODELIST_CHILDREN) {
count++;
} else if (list->type == DOM_NODELIST_BY_NAME) {
- if (dom_string_cmp(cur->name, list->data.name) == 0) {
+ if (cur->name != NULL &&
+ dom_string_cmp(cur->name,
+ list->data.name) == 0) {
count++;
}
} else {
- if (dom_string_cmp(cur->namespace,
+ if (cur->namespace != NULL &&
+ dom_string_cmp(cur->namespace,
list->data.ns.namespace) == 0 &&
- dom_string_cmp(cur->localname,
+ cur->name != NULL &&
+ dom_string_cmp(cur->name,
list->data.ns.localname) == 0) {
count++;
}