summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/dom/bootstrap/implpriv.h4
-rw-r--r--src/core/document.c107
2 files changed, 108 insertions, 3 deletions
diff --git a/include/dom/bootstrap/implpriv.h b/include/dom/bootstrap/implpriv.h
index d9cc787..00ba9fc 100644
--- a/include/dom/bootstrap/implpriv.h
+++ b/include/dom/bootstrap/implpriv.h
@@ -244,6 +244,10 @@ struct dom_implementation_source {
dom_exception dom_register_source(struct dom_implementation_source *source,
dom_alloc alloc, void *pw);
+/* Create a DOM document */
+dom_exception dom_document_create(struct dom_implementation *impl,
+ dom_alloc alloc, void *pw, struct dom_document **doc);
+
/* Set a Document's DocumentType */
dom_exception dom_document_set_doctype(struct dom_document *doc,
struct dom_document_type *doctype);
diff --git a/src/core/document.c b/src/core/document.c
index cc38c3e..0495f59 100644
--- a/src/core/document.c
+++ b/src/core/document.c
@@ -5,9 +5,13 @@
* Copyright 2007 John-Mark Bell <jmb@netsurf-browser.org>
*/
+#include <string.h>
+
#include <dom/functypes.h>
#include <dom/bootstrap/implpriv.h>
#include <dom/core/document.h>
+#include <dom/core/implementation.h>
+#include <dom/core/string.h>
#include "core/attr.h"
#include "core/cdatasection.h"
@@ -54,18 +58,117 @@ struct dom_document {
struct dom_document_type *type; /**< Associated doctype */
+ struct dom_implementation *impl; /**< Owning implementation */
+
struct dom_doc_nl *nodelists; /**< List of active nodelists */
struct dom_doc_nnm *maps; /**< List of active namednodemaps */
/** Interned node name strings, indexed by node type */
- struct dom_string *nodenames[DOM_NODE_TYPE_COUNT];
+ /* Index 0 is unused */
+ struct dom_string *nodenames[DOM_NODE_TYPE_COUNT + 1];
dom_alloc alloc; /**< Memory (de)allocation function */
void *pw; /**< Pointer to client data */
};
/**
+ * Create a Document
+ *
+ * \param impl The DOM implementation owning the document
+ * \param alloc Memory (de)allocation function
+ * \param pw Pointer to client-specific private data
+ * \param doc Pointer to location to receive created document
+ * \return DOM_NO_ERR on success, DOM_NO_MEM_ERR on memory exhaustion.
+ *
+ * ::impl will have its reference count increased.
+ *
+ * The returned document will already be referenced.
+ */
+dom_exception dom_document_create(struct dom_implementation *impl,
+ dom_alloc alloc, void *pw, struct dom_document **doc)
+{
+ static const char *names[DOM_NODE_TYPE_COUNT + 1] = {
+ NULL, /* Unused */
+ NULL, /* Element */
+ NULL, /* Attr */
+ "#text", /* Text */
+ "#cdata-section", /* CDATA section */
+ NULL, /* Entity reference */
+ NULL, /* Entity */
+ NULL, /* Processing instruction */
+ "#comment", /* Comment */
+ "#document", /* Document */
+ NULL, /* Document type */
+ "#document-fragment", /* Document fragment */
+ NULL /* Notation */
+ };
+ struct dom_document *d;
+ dom_exception err;
+
+ /* Create document */
+ d = alloc(NULL, sizeof(struct dom_document), pw);
+ if (d == NULL)
+ return DOM_NO_MEM_ERR;
+
+ /* Set up document allocation context - must be first */
+ d->alloc = alloc;
+ d->pw = pw;
+
+ /* Initialise interned node names */
+ for (int i = 0; i <= DOM_NODE_TYPE_COUNT; i++) {
+ if (names[i] == NULL) {
+ /* Nothing to intern; skip this entry */
+ d->nodenames[i] = NULL;
+ continue;
+ }
+
+ /* Make string */
+ err = dom_string_create_from_const_ptr(d,
+ (const uint8_t *) names[i],
+ strlen(names[i]), &d->nodenames[i]);
+ if (err != DOM_NO_ERR) {
+ /* Failed, clean up strings we've created so far */
+ for (int j = 0; j < i; j++) {
+ if (d->nodenames[i] != NULL)
+ dom_string_unref(d->nodenames[i]);
+ }
+ /* And destroy document */
+ alloc(d, 0, pw);
+ return err;
+ }
+ }
+
+ /* Initialise base class */
+ err = dom_node_initialise(&d->base, d, DOM_DOCUMENT_NODE,
+ NULL, NULL);
+ if (err != DOM_NO_ERR) {
+ /* Clean up interned strings */
+ for (int i = 0; i <= DOM_NODE_TYPE_COUNT; i++) {
+ if (d->nodenames[i] != NULL)
+ dom_string_unref(d->nodenames[i]);
+ }
+ /* And document */
+ alloc(d, 0, pw);
+ return err;
+ }
+
+ /* Initialise remaining type-specific data */
+ d->type = NULL;
+
+ if (impl != NULL)
+ dom_implementation_ref(impl);
+ d->impl = impl;
+
+ d->nodelists = NULL;
+ d->maps = NULL;
+
+ *doc = d;
+
+ return DOM_NO_ERR;
+}
+
+/**
* Retrieve the doctype of a document
*
* \param doc The document to retrieve the doctype from
@@ -252,8 +355,6 @@ dom_exception dom_document_create_processing_instruction(
struct dom_string *data,
struct dom_processing_instruction **result)
{
- /** \todo is the use of target as the node name correct? */
-
return dom_processing_instruction_create(doc, target, data, result);
}