summaryrefslogtreecommitdiff
path: root/src/utils/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/namespace.c')
-rw-r--r--src/utils/namespace.c138
1 files changed, 68 insertions, 70 deletions
diff --git a/src/utils/namespace.c b/src/utils/namespace.c
index 8a53e45..9c0d214 100644
--- a/src/utils/namespace.c
+++ b/src/utils/namespace.c
@@ -12,10 +12,14 @@
#include "utils/namespace.h"
#include "utils/utils.h"
-/** XML namespace URI */
+/** XML prefix */
static struct dom_string *xml;
-/** XMLNS namespace URI */
+/** XML namespace URI */
+static struct dom_string *xml_ns;
+/** XMLNS prefix */
static struct dom_string *xmlns;
+/** XMLNS namespace URI */
+static struct dom_string *xmlns_ns;
/**
* Initialise the namespace component
@@ -29,11 +33,27 @@ dom_exception _dom_namespace_initialise(dom_alloc alloc, void *pw)
dom_exception err;
err = dom_string_create_from_ptr_no_doc(alloc, pw,
+ DOM_STRING_UTF8, (const uint8_t *) "xml", SLEN("xml"), &xml);
+ if (err != DOM_NO_ERR) {
+ return err;
+ }
+
+ err = dom_string_create_from_ptr_no_doc(alloc, pw,
DOM_STRING_UTF8,
(const uint8_t *) "http://www.w3.org/XML/1998/namespace",
SLEN("http://www.w3.org/XML/1998/namespace"),
- &xml);
+ &xml_ns);
if (err != DOM_NO_ERR) {
+ dom_string_unref(xml);
+ return err;
+ }
+
+ err = dom_string_create_from_ptr_no_doc(alloc, pw,
+ DOM_STRING_UTF8,
+ (const uint8_t *) "xmlns", SLEN("xmlns"), &xmlns);
+ if (err != DOM_NO_ERR) {
+ dom_string_unref(xml_ns);
+ dom_string_unref(xml);
return err;
}
@@ -41,8 +61,10 @@ dom_exception _dom_namespace_initialise(dom_alloc alloc, void *pw)
DOM_STRING_UTF8,
(const uint8_t *) "http://www.w3.org/2000/xmlns",
SLEN("http://www.w3.org/2000/xmlns"),
- &xmlns);
+ &xmlns_ns);
if (err != DOM_NO_ERR) {
+ dom_string_unref(xmlns);
+ dom_string_unref(xml_ns);
dom_string_unref(xml);
return err;
}
@@ -57,7 +79,9 @@ dom_exception _dom_namespace_initialise(dom_alloc alloc, void *pw)
*/
dom_exception _dom_namespace_finalise(void)
{
+ dom_string_unref(xmlns_ns);
dom_string_unref(xmlns);
+ dom_string_unref(xml_ns);
dom_string_unref(xml);
return DOM_NO_ERR;
@@ -86,62 +110,59 @@ dom_exception _dom_namespace_finalise(void)
dom_exception _dom_namespace_validate_qname(struct dom_string *qname,
struct dom_string *namespace)
{
- const uint8_t *qname_data, *c;
- size_t qname_len;
-
- dom_string_get_data(qname, &qname_data, &qname_len);
+ uint32_t colon;
/** \todo search qname for invalid characters */
/** \todo ensure qname is not malformed */
/* Find colon */
- /** \todo assumes ASCII-compatible encoding */
- for (c = qname_data; c != qname_data + qname_len; c++) {
- if (*c == (const uint8_t) ':') {
- break;
- }
- }
+ colon = dom_string_index(qname, ':');
- if (c == qname_data + qname_len) {
+ if (colon == (uint32_t) -1) {
/* No prefix */
/* If namespace URI is for xmlns, ensure qname == "xmlns" */
if (namespace != NULL &&
- dom_string_cmp(namespace, xmlns) == 0 &&
- (qname_len != SLEN("xmlns") ||
- strncmp((const char *) qname_data, "xmlns",
- SLEN("xmlns")) != 0)) {
+ dom_string_cmp(namespace, xmlns_ns) == 0 &&
+ dom_string_cmp(qname, xmlns) != 0) {
return DOM_NAMESPACE_ERR;
}
} else {
/* Prefix */
+ struct dom_string *prefix;
+ dom_exception err;
+
/* Ensure there is a namespace URI */
if (namespace == NULL) {
return DOM_NAMESPACE_ERR;
}
+ err = dom_string_substr(qname, 0, colon - 1, &prefix);
+ if (err != DOM_NO_ERR) {
+ return err;
+ }
+
/* Test for invalid XML namespace */
- if (c - qname_data == SLEN("xml") &&
- strncmp((const char *) qname_data, "xml",
- SLEN("xml")) == 0 &&
- dom_string_cmp(namespace, xml) != 0) {
+ if (dom_string_cmp(prefix, xml) == 0 &&
+ dom_string_cmp(namespace, xml_ns) != 0) {
+ dom_string_unref(prefix);
return DOM_NAMESPACE_ERR;
}
/* Test for invalid xmlns namespace */
- if (c - qname_data == SLEN("xmlns") &&
- strncmp((const char *) qname_data, "xmlns",
- SLEN("xmlns")) == 0 &&
- dom_string_cmp(namespace, xmlns) != 0) {
+ if (dom_string_cmp(prefix, xmlns) == 0 &&
+ dom_string_cmp(namespace, xmlns_ns) != 0) {
+ dom_string_unref(prefix);
return DOM_NAMESPACE_ERR;
}
/* Test for presence of xmlns namespace with non xmlns prefix */
- if (dom_string_cmp(namespace, xmlns) == 0 &&
- (c - qname_data != SLEN("xmlns") ||
- strncmp((const char *) qname_data, "xmlns",
- SLEN("xmlns")) != 0)) {
+ if (dom_string_cmp(namespace, xmlns_ns) == 0 &&
+ dom_string_cmp(prefix, xmlns) != 0) {
+ dom_string_unref(prefix);
return DOM_NAMESPACE_ERR;
}
+
+ dom_string_unref(prefix);
}
return DOM_NO_ERR;
@@ -151,7 +172,6 @@ dom_exception _dom_namespace_validate_qname(struct dom_string *qname,
* Split a QName into a namespace prefix and localname string
*
* \param qname The qname to split
- * \param doc The document context to create the prefix/localname in
* \param prefix Pointer to location to receive prefix
* \param localname Pointer to location to receive localname
* \return DOM_NO_ERR on success.
@@ -162,59 +182,37 @@ dom_exception _dom_namespace_validate_qname(struct dom_string *qname,
* them once finished.
*/
dom_exception _dom_namespace_split_qname(struct dom_string *qname,
- struct dom_document *doc, struct dom_string **prefix,
- struct dom_string **localname)
+ struct dom_string **prefix, struct dom_string **localname)
{
- const uint8_t *qname_data, *c, *local_data;
- size_t qname_len;
- size_t local_len;
- size_t prefix_len;
- struct dom_string *p = NULL;
- struct dom_string *l;
+ uint32_t colon;
dom_exception err;
- dom_string_get_data(qname, &qname_data, &qname_len);
-
/* Find colon, if any */
- /** \todo assumes ASCII-compatible encoding */
- for (c = qname_data; c != qname_data + qname_len; c++) {
- if (*c == (const uint8_t) ':')
- break;
- }
+ colon = dom_string_index(qname, ':');
- if (c == qname_data + qname_len) {
+ if (colon == (uint32_t) -1) {
/* None found => no prefix */
- local_data = qname_data;
- local_len = qname_len;
- prefix_len = 0;
+ *prefix = NULL;
+ err = dom_string_dup(qname, localname);
+ if (err != DOM_NO_ERR) {
+ return err;
+ }
} else {
/* Found one => prefix */
- local_data = ++c;
- local_len = qname_len - (c - qname_data);
- prefix_len = (c - qname_data - 1 /* ':' */);
- }
-
- /* Create prefix, if one exists */
- if (prefix_len > 0) {
- err = dom_string_create_from_ptr(doc, qname_data,
- prefix_len, &p);
+ err = dom_string_substr(qname, 0, colon - 1, prefix);
if (err != DOM_NO_ERR) {
return err;
}
- }
- /* Create localname */
- err = dom_string_create_from_ptr(doc, local_data, local_len, &l);
- if (err != DOM_NO_ERR) {
- if (p != NULL) {
- dom_string_unref(p);
+ err = dom_string_substr(qname, colon + 1,
+ dom_string_length(qname), localname);
+ if (err != DOM_NO_ERR) {
+ dom_string_unref(*prefix);
+ *prefix = NULL;
+ return err;
}
- return err;
}
- *prefix = p;
- *localname = l;
-
return DOM_NO_ERR;
}