summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2007-07-12 21:24:08 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2007-07-12 21:24:08 +0000
commit0448f3de0bc3e9aa71bd095e87fd1cc2584e0a99 (patch)
tree9ad95bcba5e6f988763835f24b40e773551f53f6
parent92311b20c73b13766fb93c123c67e5045356ff49 (diff)
downloadlibdom-0448f3de0bc3e9aa71bd095e87fd1cc2584e0a99.tar.gz
libdom-0448f3de0bc3e9aa71bd095e87fd1cc2584e0a99.tar.bz2
Add DOMImplementation, DOMImplementationList
Add DOMImplementationRegistry Define DOMImplementationSource and provide API to allow their registration This little lot should permit some kind of sensible DOM bootstrapping. svn path=/trunk/dom/; revision=3403
-rw-r--r--include/dom/bootstrap/implpriv.h244
-rw-r--r--include/dom/bootstrap/implregistry.h30
-rw-r--r--include/dom/core/implementation.h48
-rw-r--r--include/dom/core/impllist.h26
-rw-r--r--src/Makefile3
-rw-r--r--src/bootstrap/Makefile53
-rw-r--r--src/bootstrap/implregistry.c184
-rw-r--r--src/core/Makefile4
-rw-r--r--src/core/implementation.c157
-rw-r--r--src/core/impllist.c108
10 files changed, 855 insertions, 2 deletions
diff --git a/include/dom/bootstrap/implpriv.h b/include/dom/bootstrap/implpriv.h
new file mode 100644
index 0000000..aa123e0
--- /dev/null
+++ b/include/dom/bootstrap/implpriv.h
@@ -0,0 +1,244 @@
+/*
+ * This file is part of libdom.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2007 John-Mark Bell <jmb@netsurf-browser.org>
+ */
+
+/** \file
+ * This file defines all the grubby details that implementation backends
+ * need to know in order to permit themselves to be bootstrapped.
+ *
+ * The DOMImplementation and DOMImplementationList implementations also
+ * include this, as those types are defined here.
+ *
+ * No other client should be including this.
+ */
+
+#ifndef dom_bootstrap_implpriv_h_
+#define dom_bootstrap_implpriv_h_
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include <dom/core/exceptions.h>
+#include <dom/functypes.h>
+
+struct dom_document;
+struct dom_document_type;
+struct dom_string;
+
+/**
+ * DOM Implementation
+ */
+struct dom_implementation {
+ /**
+ * Test whether a DOM implementation implements a specific feature
+ * and version
+ *
+ * \param impl The DOM implementation to query
+ * \param feature The feature to test for
+ * \param version The version number of the feature to test for
+ * \param result Pointer to location to receive result
+ * \return DOM_NO_ERR.
+ */
+ dom_exception (*has_feature)(struct dom_implementation *impl,
+ struct dom_string *feature,
+ struct dom_string *version,
+ bool *result);
+
+ /**
+ * Create a document type node
+ *
+ * \param impl The implementation to create the node
+ * \param qname The qualified name of the document type
+ * \param public_id The external subset public identifier
+ * \param system_id The external subset system identifier
+ * \param doctype Pointer to location to receive result
+ * \param alloc Memory (de)allocation function
+ * \param pw Pointer to client-specific private data
+ * \return DOM_NO_ERR on success,
+ * DOM_INVALID_CHARACTER_ERR if ::qname is invalid,
+ * DOM_NAMESPACE_ERR if ::qname is malformed,
+ * DOM_NOT_SUPPORTED_ERR if ::impl does not support the
+ * feature "XML" and the language
+ * exposed through Document does
+ * not support XML namespaces.
+ *
+ * Any memory allocated by this call should be allocated using
+ * the provided memory (de)allocation function.
+ *
+ * The doctype will be referenced, so the client need not do this
+ * explicitly. The client must unref the doctype once it has
+ * finished with it.
+ */
+ dom_exception (*create_document_type)(
+ struct dom_implementation *impl,
+ struct dom_string *qname,
+ struct dom_string *public_id,
+ struct dom_string *system_id,
+ struct dom_document_type **doctype,
+ dom_alloc alloc, void *pw);
+
+ /**
+ * Create a document node
+ *
+ * \param impl The implementation to create the node
+ * \param namespace The namespace URI of the document element
+ * \param qname The qualified name of the document element
+ * \param doctype The type of document to create
+ * \param doc Pointer to location to receive result
+ * \param alloc Memory (de)allocation function
+ * \param pw Pointer to client-specific private data
+ * \return DOM_NO_ERR on success,
+ * DOM_INVALID_CHARACTER_ERR if ::qname is invalid,
+ * DOM_NAMESPACE_ERR if ::qname is malformed, or if
+ * ::qname has a prefix and
+ * ::namespace is NULL, or if
+ * ::qname is NULL and ::namespace
+ * is non-NULL, or if ::qname has
+ * a prefix "xml" and ::namespace
+ * is not
+ * "http://www.w3.org/XML/1998/namespace",
+ * or if ::impl does not support
+ * the "XML" feature and
+ * ::namespace is non-NULL,
+ * DOM_WRONG_DOCUMENT_ERR if ::doctype is already being
+ * used by a document, or if it
+ * was not created by ::impl,
+ * DOM_NOT_SUPPORTED_ERR if ::impl does not support the
+ * feature "XML" and the language
+ * exposed through Document does
+ * not support XML namespaces.
+ *
+ * Any memory allocated by this call should be allocated using
+ * the provided memory (de)allocation function.
+ *
+ * The doctype will be referenced, so the client need not do this
+ * explicitly. The client must unref the doctype once it has
+ * finished with it.
+ */
+ dom_exception (*create_document)(struct dom_implementation *impl,
+ struct dom_string *namespace,
+ struct dom_string *qname,
+ struct dom_document_type *doctype,
+ struct dom_document **doc,
+ dom_alloc alloc, void *pw);
+
+ /**
+ * Retrieve a specialized object which implements the specified
+ * feature and version
+ *
+ * \param impl The implementation to create the object
+ * \param feature The requested feature
+ * \param version The version number of the feature
+ * \param object Pointer to location to receive object
+ * \param alloc Memory (de)allocation function
+ * \param pw Pointer to client-specific private data
+ * \return DOM_NO_ERR.
+ *
+ * Any memory allocated by this call should be allocated using
+ * the provided memory (de)allocation function.
+ */
+ dom_exception (*get_feature)(struct dom_implementation *impl,
+ struct dom_string *feature,
+ struct dom_string *version,
+ void **object,
+ dom_alloc alloc, void *pw);
+
+ /**
+ * Destroy a DOM implementation instance
+ *
+ * \param impl The instance to destroy
+ */
+ void (*destroy)(struct dom_implementation *impl);
+
+ uint32_t refcnt; /**< Reference count */
+};
+
+
+/**
+ * An item in a DOM Implementation List
+ */
+struct dom_implementation_list_item {
+ struct dom_implementation *impl; /**< Implementation */
+
+ struct dom_implementation_list_item *next; /**< Next in list */
+ struct dom_implementation_list_item *prev; /**< Prev in list */
+};
+
+/**
+ * DOM Implementation List
+ */
+struct dom_implementation_list {
+ struct dom_implementation_list_item *head; /**< Head of list */
+
+ dom_alloc alloc; /**< Memory (de)allocation function */
+ void *pw; /**< Pointer to client data */
+
+ uint32_t refcnt; /**< Reference count */
+};
+
+
+/**
+ * DOM Implementation Source
+ *
+ * This is simply a pair of function pointers in a struct.
+ *
+ * This is assumed to be statically allocated within the backend.
+ */
+struct dom_implementation_source {
+ /**
+ * Get a DOM implementation that supports the requested features
+ *
+ * \param features String containing required features
+ * \param impl Pointer to location to receive implementation
+ * \param alloc Function to (de)allocate memory
+ * \param pw Pointer to client-specific private data
+ * \return DOM_NO_ERR on success, DOM_NO_MEM_ERR on memory exhaustion
+ *
+ * Any memory allocated by this call should be allocated using
+ * the provided memory (de)allocation function. The implementation's
+ * destroy() method will be called once it is no longer used.
+ *
+ * The implementation will be referenced, so the client need not
+ * do this explicitly. The client must unref the implementation
+ * once it has finished with it.
+ */
+ dom_exception (*get_dom_implementation)(
+ struct dom_string *features,
+ struct dom_implementation **impl,
+ dom_alloc alloc, void *pw);
+
+ /**
+ * Get a list of DOM implementations that support the requested
+ * features
+ *
+ * \param features String containing required features
+ * \param list Pointer to location to receive list
+ * \param alloc Function to (de)allocate memory
+ * \param pw Pointer to client-specific private data
+ * \return DOM_NO_ERR on success, DOM_NO_MEM_ERR on memory exhaustion
+ *
+ * Any memory allocated by this call should be allocated using
+ * the provided memory (de)allocation function. The ::alloc/::pw
+ * pair must be stored on the list object, such that the list
+ * and its contents may be freed once they are no longer needed.
+ *
+ * List nodes reference the implementation objects they point to.
+ *
+ * The list will be referenced, so the client need not do this
+ * explicitly. The client must unref the list once it has finished
+ * with it.
+ */
+ dom_exception (*get_dom_implementation_list)(
+ struct dom_string *features,
+ struct dom_implementation_list **list,
+ dom_alloc alloc, void *pw);
+};
+
+/* Register a source with the DOM library */
+dom_exception dom_register_source(struct dom_implementation_source *source,
+ dom_alloc alloc, void *pw);
+
+#endif
diff --git a/include/dom/bootstrap/implregistry.h b/include/dom/bootstrap/implregistry.h
new file mode 100644
index 0000000..1e93ea6
--- /dev/null
+++ b/include/dom/bootstrap/implregistry.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of libdom.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2007 John-Mark Bell <jmb@netsurf-browser.org>
+ */
+
+#ifndef dom_bootstrap_implregistry_h_
+#define dom_bootstrap_implregistry_h_
+
+#include <dom/core/exceptions.h>
+#include <dom/functypes.h>
+
+struct dom_implementation;
+struct dom_implementation_list;
+struct dom_string;
+
+/* Retrieve a DOM implementation from the registry */
+dom_exception dom_implregistry_get_dom_implementation(
+ struct dom_string *features,
+ struct dom_implementation **impl,
+ dom_alloc alloc, void *pw);
+
+/* Get a list of DOM implementations that support the requested features */
+dom_exception dom_implregistry_get_dom_implementation_list(
+ struct dom_string *features,
+ struct dom_implementation_list **list,
+ dom_alloc alloc, void *pw);
+
+#endif
diff --git a/include/dom/core/implementation.h b/include/dom/core/implementation.h
new file mode 100644
index 0000000..3f42ab7
--- /dev/null
+++ b/include/dom/core/implementation.h
@@ -0,0 +1,48 @@
+/*
+ * This file is part of libdom.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2007 John-Mark Bell <jmb@netsurf-browser.org>
+ */
+
+#ifndef dom_core_implementation_h_
+#define dom_core_implementation_h_
+
+#include <stdbool.h>
+
+#include <dom/core/exceptions.h>
+#include <dom/functypes.h>
+
+struct dom_document;
+struct dom_document_type;
+struct dom_implementation;
+struct dom_string;
+
+void dom_implementation_ref(struct dom_implementation *impl);
+void dom_implementation_unref(struct dom_implementation *impl);
+
+dom_exception dom_implementation_has_feature(
+ struct dom_implementation *impl,
+ struct dom_string *feature, struct dom_string *version,
+ bool *result);
+
+dom_exception dom_implementation_create_document_type(
+ struct dom_implementation *impl, struct dom_string *qname,
+ struct dom_string *public_id, struct dom_string *system_id,
+ struct dom_document_type **doctype,
+ dom_alloc alloc, void *pw);
+
+dom_exception dom_implementation_create_document(
+ struct dom_implementation *impl,
+ struct dom_string *namespace, struct dom_string *qname,
+ struct dom_document_type *doctype,
+ struct dom_document **doc,
+ dom_alloc alloc, void *pw);
+
+dom_exception dom_implementation_get_feature(
+ struct dom_implementation *impl,
+ struct dom_string *feature, struct dom_string *version,
+ void **object,
+ dom_alloc alloc, void *pw);
+
+#endif
diff --git a/include/dom/core/impllist.h b/include/dom/core/impllist.h
new file mode 100644
index 0000000..af303ae
--- /dev/null
+++ b/include/dom/core/impllist.h
@@ -0,0 +1,26 @@
+/*
+ * This file is part of libdom.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2007 John-Mark Bell <jmb@netsurf-browser.org>
+ */
+
+#ifndef dom_core_impllist_h_
+#define dom_core_impllist_h_
+
+#include <dom/core/exceptions.h>
+
+struct dom_implementation;
+struct dom_implementation_list;
+
+void dom_implementation_list_ref(struct dom_implementation_list *list);
+void dom_implementation_list_unref(struct dom_implementation_list *list);
+
+dom_exception dom_implementation_list_get_length(
+ struct dom_implementation_list *list, unsigned long *length);
+
+dom_exception dom_implementation_list_item(
+ struct dom_implementation_list *list, unsigned long index,
+ struct dom_implementation **impl);
+
+#endif
diff --git a/src/Makefile b/src/Makefile
index ae0c9eb..b0f78b2 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -34,14 +34,17 @@ OBJS =
# Targets
release: $(addprefix Release/, $(addsuffix .o, $(OBJS)))
+ @${MAKE} -C bootstrap release
@${MAKE} -C core release
@${AR} ${ARFLAGS} $(RELEASE) Release/*
debug: $(addprefix Debug/, $(addsuffix .o, $(OBJS)))
+ @${MAKE} -C bootstrap debug
@${MAKE} -C core debug
@${AR} ${ARFLAGS} $(DEBUG) Debug/*
clean:
+ @${MAKE} -C bootstrap clean
@${MAKE} -C core clean
ifneq (${OBJS}, )
-@${RM} ${RMFLAGS} $(addprefix Release/, $(addsuffix .o, ${OBJS}))
diff --git a/src/bootstrap/Makefile b/src/bootstrap/Makefile
new file mode 100644
index 0000000..6c904cc
--- /dev/null
+++ b/src/bootstrap/Makefile
@@ -0,0 +1,53 @@
+# Makefile for libdom
+#
+# Toolchain is exported by top-level makefile
+#
+# Top-level makefile also exports the following variables:
+#
+# COMPONENT Name of component
+# EXPORT Absolute path of export directory
+# TOP Absolute path of source tree root
+#
+# The top-level makefile requires the following targets to exist:
+#
+# clean Clean source tree
+# debug Create a debug binary
+# distclean Fully clean source tree, back to pristine condition
+# export Export distributable components to ${EXPORT}
+# release Create a release binary
+# setup Perform any setup required prior to compilation
+# test Execute any test cases
+
+# Manipulate include paths
+CFLAGS += -I$(CURDIR)
+
+# Objects
+OBJS = implregistry
+
+.PHONY: clean debug distclean export release setup test
+
+# Targets
+release: $(addprefix ../Release/, $(addsuffix .o, $(OBJS)))
+
+debug: $(addprefix ../Debug/, $(addsuffix .o, $(OBJS)))
+
+clean:
+ -@${RM} ${RMFLAGS} $(addprefix ../Release/, $(addsuffix .o, ${OBJS}))
+ -@${RM} ${RMFLAGS} $(addprefix ../Debug/, $(addsuffix .o, ${OBJS}))
+
+distclean:
+
+setup:
+
+export:
+
+test:
+
+# Pattern rules
+../Release/%.o: %.c
+ @${ECHO} ${ECHOFLAGS} "==> $<"
+ @${CC} -c ${CFLAGS} -DNDEBUG -o $@ $<
+
+../Debug/%.o: %.c
+ @${ECHO} ${ECHOFLAGS} "==> $<"
+ @${CC} -c -g ${CFLAGS} -o $@ $<
diff --git a/src/bootstrap/implregistry.c b/src/bootstrap/implregistry.c
new file mode 100644
index 0000000..9407ee1
--- /dev/null
+++ b/src/bootstrap/implregistry.c
@@ -0,0 +1,184 @@
+/*
+ * This file is part of libdom.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2007 John-Mark Bell <jmb@netsurf-browser.org>
+ */
+
+#include <stddef.h>
+
+#include <dom/bootstrap/implpriv.h>
+#include <dom/bootstrap/implregistry.h>
+
+#include <dom/core/impllist.h>
+
+/**
+ * Item in list of registered DOM implementation sources
+ */
+struct dom_impl_src_item {
+ struct dom_implementation_source *source; /**< Source */
+
+ struct dom_impl_src_item *next; /**< Next in list */
+ struct dom_impl_src_item *prev; /**< Previous in list */
+};
+
+static struct dom_impl_src_item *sources; /**< List of registered sources */
+
+/**
+ * Retrieve a DOM implementation from the registry
+ *
+ * \param features String containing required features
+ * \param impl Pointer to location to receive implementation
+ * \param alloc Function to (de)allocate memory
+ * \param pw Pointer to client-specific private data
+ * \return DOM_NO_ERR on success, DOM_NO_MEM_ERR on memory exhaustion
+ *
+ * Any memory allocated by this call should be allocated using
+ * the provided memory (de)allocation function. The implementation's
+ * destroy() method will be called once it is no longer used.
+ *
+ * The implementation will be referenced, so the client need not
+ * do this explicitly. The client must unref the implementation
+ * once it has finished with it.
+ */
+dom_exception dom_implregistry_get_dom_implementation(
+ struct dom_string *features,
+ struct dom_implementation **impl,
+ dom_alloc alloc, void *pw)
+{
+ struct dom_impl_src_item *item;
+ struct dom_implementation *found = NULL;
+ dom_exception err;
+
+ for (item = sources; item; item = item->next) {
+ err = item->source->get_dom_implementation(features, &found,
+ alloc, pw);
+ if (err != DOM_NO_ERR)
+ return err;
+
+ if (found != NULL)
+ break;
+ }
+
+ *impl = found;
+
+ return DOM_NO_ERR;
+}
+
+/**
+ * Get a list of DOM implementations that support the requested
+ * features
+ *
+ * \param features String containing required features
+ * \param list Pointer to location to receive list
+ * \param alloc Function to (de)allocate memory
+ * \param pw Pointer to client-specific private data
+ * \return DOM_NO_ERR on success, DOM_NO_MEM_ERR on memory exhaustion
+ *
+ * Any memory allocated by this call should be allocated using
+ * the provided memory (de)allocation function. The ::alloc/::pw
+ * pair must be stored on the list object, such that the list
+ * and its contents may be freed once they are no longer needed.
+ *
+ * List nodes reference the implementation objects they point to.
+ *
+ * The list will be referenced, so the client need not do this
+ * explicitly. The client must unref the list once it has finished
+ * with it.
+ */
+dom_exception dom_implregistry_get_dom_implementation_list(
+ struct dom_string *features,
+ struct dom_implementation_list **list,
+ dom_alloc alloc, void *pw)
+{
+ struct dom_implementation_list *l;
+ struct dom_impl_src_item *item;
+ dom_exception err;
+
+ l = alloc(NULL, sizeof(struct dom_implementation_list), pw);
+ if (l == NULL)
+ return DOM_NO_MEM_ERR;
+
+ l->head = NULL;
+ l->alloc = alloc;
+ l->pw = pw;
+ l->refcnt = 1;
+
+ for (item = sources; item; item = item->next) {
+ struct dom_implementation_list *plist = NULL;
+ struct dom_implementation_list_item *plast = NULL;
+
+ err = item->source->get_dom_implementation_list(features,
+ &plist, alloc, pw);
+ if (err != DOM_NO_ERR) {
+ dom_implementation_list_unref(l);
+ return err;
+ }
+
+ if (plist == NULL)
+ continue;
+
+ if (plist->head == NULL) {
+ dom_implementation_list_unref(plist);
+ continue;
+ }
+
+ /* Get last item in list for this source */
+ for (plast = plist->head; plast; plast = plast->next) {
+ if (plast->next == NULL)
+ break;
+ }
+
+ /* Prepend list for this source onto result list */
+ plast->next = l->head;
+ if (l->head != NULL)
+ l->head->prev = plast;
+ l->head = plist->head;
+
+ /* Invalidate entire content of list for this source */
+ plist->head = NULL;
+
+ /* And unref it */
+ dom_implementation_list_unref(plist);
+ }
+
+ if (l->head == NULL) {
+ *list = NULL;
+ dom_implementation_list_unref(l);
+ } else {
+ *list = l;
+ }
+
+ return DOM_NO_ERR;
+}
+
+/**
+ * Register a DOM implementation source with the DOM library
+ *
+ * \param source The implementation source to register
+ * \param alloc Memory (de)allocation function
+ * \param pw Pointer to client-specific private data
+ * \return DOM_NO_ERR on success, DOM_NO_MEM_ERR on memory exhaustion.
+ */
+dom_exception dom_register_source(struct dom_implementation_source *source,
+ dom_alloc alloc, void *pw)
+{
+ struct dom_impl_src_item *item;
+
+ item = alloc(NULL, sizeof(struct dom_impl_src_item), pw);
+ if (item == NULL)
+ return DOM_NO_MEM_ERR;
+
+ item->source = source;
+
+ item->next = sources;
+ item->prev = NULL;
+
+ if (sources != NULL)
+ sources->prev = item;
+
+ sources = item;
+
+ return DOM_NO_ERR;
+}
+
diff --git a/src/core/Makefile b/src/core/Makefile
index 9d21bf7..bc25ed7 100644
--- a/src/core/Makefile
+++ b/src/core/Makefile
@@ -22,8 +22,8 @@
CFLAGS += -I$(CURDIR)
# Objects
-OBJS = attr characterdata document element namednodemap node nodelist \
- string text
+OBJS = attr characterdata document element implementation impllist \
+ namednodemap node nodelist string text
.PHONY: clean debug distclean export release setup test
diff --git a/src/core/implementation.c b/src/core/implementation.c
new file mode 100644
index 0000000..d9bb0fa
--- /dev/null
+++ b/src/core/implementation.c
@@ -0,0 +1,157 @@
+/*
+ * This file is part of libdom.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2007 John-Mark Bell <jmb@netsurf-browser.org>
+ */
+
+#include <dom/bootstrap/implpriv.h>
+#include <dom/core/implementation.h>
+
+/**
+ * Claim a reference on a DOM implementation
+ *
+ * \param impl The implementation to claim a reference on
+ */
+void dom_implementation_ref(struct dom_implementation *impl)
+{
+ impl->refcnt++;
+}
+
+/**
+ * Release a reference from a DOM implementation
+ *
+ * \param impl The implementation to release the reference from
+ *
+ * If the reference count reaches zero, any memory claimed by the
+ * implementation will be released
+ */
+void dom_implementation_unref(struct dom_implementation *impl)
+{
+ if (--impl->refcnt == 0) {
+ impl->destroy(impl);
+ }
+}
+
+/**
+ * Test whether a DOM implementation implements a specific feature
+ * and version
+ *
+ * \param impl The DOM implementation to query
+ * \param feature The feature to test for
+ * \param version The version number of the feature to test for
+ * \param result Pointer to location to receive result
+ * \return DOM_NO_ERR.
+ */
+dom_exception dom_implementation_has_feature(
+ struct dom_implementation *impl,
+ struct dom_string *feature, struct dom_string *version,
+ bool *result)
+{
+ return impl->has_feature(impl, feature, version, result);
+}
+
+/**
+ * Create a document type node
+ *
+ * \param impl The implementation to create the node
+ * \param qname The qualified name of the document type
+ * \param public_id The external subset public identifier
+ * \param system_id The external subset system identifier
+ * \param doctype Pointer to location to receive result
+ * \param alloc Memory (de)allocation function
+ * \param pw Pointer to client-specific private data
+ * \return DOM_NO_ERR on success,
+ * DOM_INVALID_CHARACTER_ERR if ::qname is invalid,
+ * DOM_NAMESPACE_ERR if ::qname is malformed,
+ * DOM_NOT_SUPPORTED_ERR if ::impl does not support the feature
+ * "XML" and the language exposed through
+ * Document does not support XML
+ * namespaces.
+ *
+ * Any memory allocated by this call should be allocated using
+ * the provided memory (de)allocation function.
+ *
+ * The doctype will be referenced, so the client need not do this
+ * explicitly. The client must unref the doctype once it has
+ * finished with it.
+ */
+dom_exception dom_implementation_create_document_type(
+ struct dom_implementation *impl, struct dom_string *qname,
+ struct dom_string *public_id, struct dom_string *system_id,
+ struct dom_document_type **doctype,
+ dom_alloc alloc, void *pw)
+{
+ return impl->create_document_type(impl, qname, public_id, system_id,
+ doctype, alloc, pw);
+}
+
+/**
+ * Create a document node
+ *
+ * \param impl The implementation to create the node
+ * \param namespace The namespace URI of the document element
+ * \param qname The qualified name of the document element
+ * \param doctype The type of document to create
+ * \param doc Pointer to location to receive result
+ * \param alloc Memory (de)allocation function
+ * \param pw Pointer to client-specific private data
+ * \return DOM_NO_ERR on success,
+ * DOM_INVALID_CHARACTER_ERR if ::qname is invalid,
+ * DOM_NAMESPACE_ERR if ::qname is malformed, or if ::qname
+ * has a prefix and ::namespace is NULL,
+ * or if ::qname is NULL and ::namespace
+ * is non-NULL, or if ::qname has a prefix
+ * "xml" and ::namespace is not
+ * "http://www.w3.org/XML/1998/namespace",
+ * or if ::impl does not support the "XML"
+ * feature and ::namespace is non-NULL,
+ * DOM_WRONG_DOCUMENT_ERR if ::doctype is already being used by a
+ * document, or if it was not created by
+ * ::impl,
+ * DOM_NOT_SUPPORTED_ERR if ::impl does not support the feature
+ * "XML" and the language exposed through
+ * Document does not support XML
+ * namespaces.
+ *
+ * Any memory allocated by this call should be allocated using
+ * the provided memory (de)allocation function.
+ *
+ * The doctype will be referenced, so the client need not do this
+ * explicitly. The client must unref the doctype once it has
+ * finished with it.
+ */
+dom_exception dom_implementation_create_document(
+ struct dom_implementation *impl,
+ struct dom_string *namespace, struct dom_string *qname,
+ struct dom_document_type *doctype,
+ struct dom_document **doc,
+ dom_alloc alloc, void *pw)
+{
+ return impl->create_document(impl, namespace, qname, doctype, doc,
+ alloc, pw);
+}
+
+/**
+ * Retrieve a specialized object which implements the specified
+ * feature and version
+ *
+ * \param impl The implementation to create the object
+ * \param feature The requested feature
+ * \param version The version number of the feature
+ * \param object Pointer to location to receive object
+ * \param alloc Memory (de)allocation function
+ * \param pw Pointer to client-specific private data
+ * \return DOM_NO_ERR.
+ *
+ * Any memory allocated by this call should be allocated using
+ * the provided memory (de)allocation function.
+ */
+dom_exception dom_implementation_get_feature(
+ struct dom_implementation *impl,
+ struct dom_string *feature, struct dom_string *version,
+ void **object,
+ dom_alloc alloc, void *pw)
+{
+ return impl->get_feature(impl, feature, version, object, alloc, pw);
+}
diff --git a/src/core/impllist.c b/src/core/impllist.c
new file mode 100644
index 0000000..522c3f7
--- /dev/null
+++ b/src/core/impllist.c
@@ -0,0 +1,108 @@
+/*
+ * This file is part of libdom.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2007 John-Mark Bell <jmb@netsurf-browser.org>
+ */
+
+#include <dom/bootstrap/implpriv.h>
+#include <dom/core/implementation.h>
+#include <dom/core/impllist.h>
+
+/**
+ * Claim a reference on a DOM implementation list
+ *
+ * \param list The list to claim a reference on
+ */
+void dom_implementation_list_ref(struct dom_implementation_list *list)
+{
+ list->refcnt++;
+}
+
+/**
+ * Release a reference from a DOM implementation list
+ *
+ * \param list The list to release the reference from
+ *
+ * If the reference count reaches zero, any memory claimed by the
+ * list will be released
+ */
+void dom_implementation_list_unref(struct dom_implementation_list *list)
+{
+ struct dom_implementation_list_item *i, *j;
+
+ if (--list->refcnt == 0) {
+ /* Destroy all list entries */
+ for (i = list->head; i; i = j) {
+ j = i->next;
+
+ /* Unreference the implementation */
+ dom_implementation_unref(i->impl);
+
+ /* And free the entry */
+ list->alloc(i, 0, list->pw);
+ }
+
+ /* Free the list object */
+ list->alloc(list, 0, list->pw);
+ }
+}
+
+/**
+ * Retrieve the length of a DOM implementation list
+ *
+ * \param list The list to retrieve the length of
+ * \param length Pointer to location to receive result
+ * \return DOM_NO_ERR.
+ */
+dom_exception dom_implementation_list_get_length(
+ struct dom_implementation_list *list, unsigned long *length)
+{
+ unsigned long count = 0;
+ struct dom_implementation_list_item *i;
+
+ for (i = list->head; i; i = i->next)
+ count++;
+
+ *length = count;
+
+ return DOM_NO_ERR;
+}
+
+/**
+ * Retrieve an item by index from a DOM implementation list
+ *
+ * \param list The list to retrieve the item from
+ * \param index The list index to retrieve
+ * \param impl Pointer to location to receive result
+ * \return DOM_NO_ERR.
+ *
+ * ::index is a zero-based index into ::list.
+ * ::index lies in the range [0, length-1]
+ *
+ * The returned implementation will have had its reference count increased.
+ * The client should unref the implementation once it has finished with it.
+ */
+dom_exception dom_implementation_list_item(
+ struct dom_implementation_list *list, unsigned long index,
+ struct dom_implementation **impl)
+{
+ unsigned long idx = 0;
+ struct dom_implementation_list_item *i;
+
+ for (i = list->head; i; i = i->next) {
+ if (idx == index)
+ break;
+
+ idx++;
+ }
+
+ if (i == NULL) {
+ *impl = NULL;
+ } else {
+ dom_implementation_ref(i->impl);
+ *impl = i->impl;
+ }
+
+ return DOM_NO_ERR;
+}