summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bindings/Makefile72
-rw-r--r--bindings/xml/Makefile53
-rw-r--r--bindings/xml/README35
-rw-r--r--bindings/xml/functypes.h16
-rw-r--r--bindings/xml/utils.h28
-rw-r--r--bindings/xml/xmlbinding.c344
-rw-r--r--bindings/xml/xmlbinding.h17
-rw-r--r--bindings/xml/xmlerror.h19
-rw-r--r--bindings/xml/xmlparser.c187
-rw-r--r--bindings/xml/xmlparser.h38
-rw-r--r--build/Makefile.common6
-rw-r--r--include/dom/dom.h17
12 files changed, 832 insertions, 0 deletions
diff --git a/bindings/Makefile b/bindings/Makefile
new file mode 100644
index 0000000..7a0a9b6
--- /dev/null
+++ b/bindings/Makefile
@@ -0,0 +1,72 @@
+# 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)
+
+# Release output
+RELEASE = ${TOP}/${COMPONENT}.a
+
+# Debug output
+DEBUG = ${TOP}/${COMPONENT}-debug.a
+
+# Objects
+OBJS =
+
+.PHONY: clean debug distclean export release setup test
+
+# Targets
+release: $(addprefix Release/, $(addsuffix .o, $(OBJS)))
+ @${MAKE} -C xml release
+ @${AR} ${ARFLAGS} $(RELEASE) Release/*
+
+debug: $(addprefix Debug/, $(addsuffix .o, $(OBJS)))
+ @${MAKE} -C xml debug
+ @${AR} ${ARFLAGS} $(DEBUG) Debug/*
+
+clean:
+ @${MAKE} -C xml clean
+ifneq (${OBJS}, )
+ -@${RM} ${RMFLAGS} $(addprefix Release/, $(addsuffix .o, ${OBJS}))
+ -@${RM} ${RMFLAGS} $(addprefix Debug/, $(addsuffix .o, ${OBJS}))
+endif
+ -@${RM} ${RMFLAGS} $(RELEASE) $(DEBUG)
+
+distclean:
+ -@${RM} ${RMFLAGS} -r Release
+ -@${RM} ${RMFLAGS} -r Debug
+
+setup:
+ @${MKDIR} ${MKDIRFLAGS} Release
+ @${MKDIR} ${MKDIRFLAGS} Debug
+
+export:
+ @${CP} ${CPFLAGS} $(RELEASE) ${EXPORT}/lib/
+
+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/bindings/xml/Makefile b/bindings/xml/Makefile
new file mode 100644
index 0000000..e1239ec
--- /dev/null
+++ b/bindings/xml/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) `pkg-config --cflags libxml-2.0` -D_POSIX_C_SOURCE
+
+# Objects
+OBJS = xmlbinding xmlparser
+
+.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/bindings/xml/README b/bindings/xml/README
new file mode 100644
index 0000000..0e427c7
--- /dev/null
+++ b/bindings/xml/README
@@ -0,0 +1,35 @@
+LibXML binding for libdom
+=========================
+
+Overview
+--------
+
+ This is an example binding of libxml2 to libdom. It consists of two,
+ orthogonal, parts:
+
+ 1) libxml push parser wrapper
+ 2) libxml-specific DOMImplementationSource for libdom
+
+Push parser wrapper
+-------------------
+
+ This is a wrapper around libxml's push parser API, to facilitate
+ construction of a libdom DOM tree. The basic premise is that the wrapper
+ intercepts the SAX events emitted by libxml's tokeniser then invokes
+ libxml's own SAX handlers, wrapping the results up in libdom-specific
+ data structures.
+
+ The tree created is thus a tree of libdom nodes, each of which is linked
+ to the libxml node that backs it. This allows the binding to process the
+ DOM tree using libxml api, should it need to (e.g. for normalization
+ purposes).
+
+DOMImplementationSource
+-----------------------
+
+ The DOMImplementationSource exposes the APIs needed to create a new
+ document based upon the libxml binding. It also provides the utility
+ functions that libdom uses when performing some operations (such as
+ document normalization). This is needed as libdom is document language
+ agnostic; therefore, it requires support from the binding to perform
+ some operations.
diff --git a/bindings/xml/functypes.h b/bindings/xml/functypes.h
new file mode 100644
index 0000000..d0706b8
--- /dev/null
+++ b/bindings/xml/functypes.h
@@ -0,0 +1,16 @@
+/*
+ * 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 xml_functypes_h_
+#define xml_functypes_h_
+
+/**
+ * Type of XML parser allocation function
+ */
+typedef void *(*xml_alloc)(void *ptr, size_t len, void *pw);
+
+#endif
diff --git a/bindings/xml/utils.h b/bindings/xml/utils.h
new file mode 100644
index 0000000..75ca536
--- /dev/null
+++ b/bindings/xml/utils.h
@@ -0,0 +1,28 @@
+/*
+ * 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 xml_utils_h_
+#define xml_utils_h_
+
+#ifndef max
+#define max(a,b) ((a)>(b)?(a):(b))
+#endif
+
+#ifndef min
+#define min(a,b) ((a)<(b)?(a):(b))
+#endif
+
+#ifndef SLEN
+/* Calculate length of a string constant */
+#define SLEN(s) (sizeof((s)) - 1) /* -1 for '\0' */
+#endif
+
+#ifndef UNUSED
+#define UNUSED(x) ((x)=(x))
+#endif
+
+#endif
diff --git a/bindings/xml/xmlbinding.c b/bindings/xml/xmlbinding.c
new file mode 100644
index 0000000..3e1460f
--- /dev/null
+++ b/bindings/xml/xmlbinding.c
@@ -0,0 +1,344 @@
+/*
+ * 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/bootstrap/implregistry.h>
+
+#include "functypes.h"
+#include "xmlbinding.h"
+#include "utils.h"
+
+static dom_exception xml_dom_get_dom_implementation(
+ struct dom_string *features,
+ struct dom_implementation **impl, dom_alloc alloc, void *pw);
+static dom_exception xml_dom_get_dom_implementation_list(
+ struct dom_string *features,
+ struct dom_implementation_list **list,
+ dom_alloc alloc, void *pw);
+
+static dom_exception xml_dom_implementation_has_feature(
+ struct dom_implementation *impl,
+ struct dom_string *feature,
+ struct dom_string *version,
+ bool *result);
+static dom_exception xml_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);
+static dom_exception xml_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);
+static dom_exception xml_dom_implementation_get_feature(
+ struct dom_implementation *impl,
+ struct dom_string *feature,
+ struct dom_string *version,
+ void **object,
+ dom_alloc alloc, void *pw);
+static void xml_dom_implementation_destroy(struct dom_implementation *impl);
+
+
+/**
+ * DOM implementation source for XML documents
+ */
+static struct dom_implementation_source xml_dom_impl_src = {
+ xml_dom_get_dom_implementation,
+ xml_dom_get_dom_implementation_list
+};
+
+/**
+ * DOM implementation for XML documents
+ */
+static struct dom_implementation xml_dom_impl = {
+ xml_dom_implementation_has_feature,
+ xml_dom_implementation_create_document_type,
+ xml_dom_implementation_create_document,
+ xml_dom_implementation_get_feature,
+ xml_dom_implementation_destroy,
+ 0
+};
+
+/**
+ * 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 xml_dom_get_dom_implementation(
+ struct dom_string *features,
+ struct dom_implementation **impl, dom_alloc alloc, void *pw)
+{
+ UNUSED(features);
+ UNUSED(alloc);
+ UNUSED(pw);
+
+ xml_dom_impl.refcnt++;
+
+ *impl = &xml_dom_impl;
+
+ 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 xml_dom_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_implementation_list_item *i;
+
+ UNUSED(features);
+
+ l = alloc(NULL, sizeof(struct dom_implementation_list), pw);
+ if (l == NULL)
+ return DOM_NO_MEM_ERR;
+
+ i = alloc(NULL, sizeof(struct dom_implementation_list_item), pw);
+ if (i == NULL) {
+ alloc(l, 0, pw);
+ return DOM_NO_MEM_ERR;
+ }
+
+ i->impl = &xml_dom_impl;
+ i->next = NULL;
+ i->prev = NULL;
+
+ l->head = i;
+ l->alloc = alloc;
+ l->pw = pw;
+
+ l->refcnt = 1;
+
+ *list = l;
+
+ return DOM_NO_ERR;
+}
+
+/**
+ * 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 xml_dom_implementation_has_feature(
+ struct dom_implementation *impl,
+ struct dom_string *feature,
+ struct dom_string *version,
+ bool *result)
+{
+ UNUSED(impl);
+ UNUSED(feature);
+ UNUSED(version);
+ UNUSED(result);
+
+ return DOM_NOT_SUPPORTED_ERR;
+}
+
+/**
+ * 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 xml_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)
+{
+ UNUSED(impl);
+ UNUSED(qname);
+ UNUSED(public_id);
+ UNUSED(system_id);
+ UNUSED(doctype);
+ UNUSED(alloc);
+ UNUSED(pw);
+
+ return DOM_NOT_SUPPORTED_ERR;
+}
+
+/**
+ * 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 xml_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)
+{
+ UNUSED(impl);
+ UNUSED(namespace);
+ UNUSED(qname);
+ UNUSED(doctype);
+ UNUSED(doc);
+ UNUSED(alloc);
+ UNUSED(pw);
+
+ return DOM_NOT_SUPPORTED_ERR;
+}
+
+/**
+ * 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 xml_dom_implementation_get_feature(
+ struct dom_implementation *impl,
+ struct dom_string *feature,
+ struct dom_string *version,
+ void **object,
+ dom_alloc alloc, void *pw)
+{
+ UNUSED(impl);
+ UNUSED(feature);
+ UNUSED(version);
+ UNUSED(object);
+ UNUSED(alloc);
+ UNUSED(pw);
+
+ return DOM_NOT_SUPPORTED_ERR;
+}
+
+/**
+ * Destroy a DOM implementation instance
+ *
+ * \param impl The instance to destroy
+ */
+void xml_dom_implementation_destroy(struct dom_implementation *impl)
+{
+ UNUSED(impl);
+
+ /* Nothing to do -- we're statically allocated */
+}
+
+/**
+ * Initialise the XML DOM binding
+ *
+ * \param alloc Pointer to memory (de)allocation function
+ * \param pw Pointer to client-specific private data
+ * \return XML_OK on success, XML_NOMEM on memory exhaustion
+ */
+xml_error xml_dom_binding_initialise(xml_alloc alloc, void *pw)
+{
+ dom_exception err;
+
+ err = dom_register_source(&xml_dom_impl_src, (dom_alloc) alloc, pw);
+ if (err != DOM_NO_ERR)
+ return XML_NOMEM;
+
+ return XML_OK;
+}
diff --git a/bindings/xml/xmlbinding.h b/bindings/xml/xmlbinding.h
new file mode 100644
index 0000000..b7f9002
--- /dev/null
+++ b/bindings/xml/xmlbinding.h
@@ -0,0 +1,17 @@
+/*
+ * 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 xml_xmlbinding_h_
+#define xml_xmlbinding_h_
+
+#include "xmlerror.h"
+#include "functypes.h"
+
+/* Initialise the XML DOM binding */
+xml_error xml_dom_binding_initialise(xml_alloc alloc, void *pw);
+
+#endif
diff --git a/bindings/xml/xmlerror.h b/bindings/xml/xmlerror.h
new file mode 100644
index 0000000..f407e45
--- /dev/null
+++ b/bindings/xml/xmlerror.h
@@ -0,0 +1,19 @@
+/*
+ * 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 xml_xmlerror_h_
+#define xml_xmlerror_h_
+
+typedef enum {
+ XML_OK = 0,
+
+ XML_NOMEM = 1,
+
+ XML_LIBXML_ERR = (1<<16),
+} xml_error;
+
+#endif
diff --git a/bindings/xml/xmlparser.c b/bindings/xml/xmlparser.c
new file mode 100644
index 0000000..7b93fd1
--- /dev/null
+++ b/bindings/xml/xmlparser.c
@@ -0,0 +1,187 @@
+/*
+ * 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 <stdbool.h>
+
+#include <libxml/parser.h>
+#include <libxml/SAX2.h>
+#include <libxml/xmlerror.h>
+
+#include <dom/dom.h>
+
+#include "xmlerror.h"
+#include "xmlparser.h"
+#include "utils.h"
+
+/**
+ * XML parser object
+ */
+struct xml_parser {
+ xmlParserCtxtPtr xml_ctx; /**< libxml parser context */
+
+ struct dom_document *doc; /**< DOM Document we're building */
+
+ bool complete; /**< Indicate stream completion */
+
+ xml_alloc alloc; /**< Memory (de)allocation function */
+ void *pw; /**< Pointer to client data */
+};
+
+/**
+ * SAX callback dispatch table
+ */
+static xmlSAXHandler sax_handler;
+#if 0
+ = {
+ internalSubsetSAXFunc internalSubset;
+ isStandaloneSAXFunc isStandalone;
+ hasInternalSubsetSAXFunc hasInternalSubset;
+ hasExternalSubsetSAXFunc hasExternalSubset;
+ resolveEntitySAXFunc resolveEntity;
+ getEntitySAXFunc getEntity;
+ entityDeclSAXFunc entityDecl;
+ notationDeclSAXFunc notationDecl;
+ attributeDeclSAXFunc attributeDecl;
+ elementDeclSAXFunc elementDecl;
+ unparsedEntityDeclSAXFunc unparsedEntityDecl;
+ setDocumentLocatorSAXFunc setDocumentLocator;
+ startDocumentSAXFunc startDocument;
+ endDocumentSAXFunc endDocument;
+ startElementSAXFunc startElement;
+ endElementSAXFunc endElement;
+ referenceSAXFunc reference;
+ charactersSAXFunc characters;
+ ignorableWhitespaceSAXFunc ignorableWhitespace;
+ processingInstructionSAXFunc processingInstruction;
+ commentSAXFunc comment;
+ warningSAXFunc warning;
+ errorSAXFunc error;
+ fatalErrorSAXFunc fatalError; /* unused error() get all the errors */
+ getParameterEntitySAXFunc getParameterEntity;
+ cdataBlockSAXFunc cdataBlock;
+ externalSubsetSAXFunc externalSubset;
+ unsigned int initialized;
+ /* The following fields are extensions available only on version 2 */
+ void *_private;
+ startElementNsSAX2Func startElementNs;
+ endElementNsSAX2Func endElementNs;
+ xmlStructuredErrorFunc serror;
+};
+#endif
+
+/**
+ * Create an XML parser instance
+ *
+ * \param enc Source charset, or NULL
+ * \param int_enc Desired charset of document buffer (UTF-8 or UTF-16)
+ * \param alloc Memory (de)allocation function
+ * \param pw Pointer to client-specific private data
+ * \return Pointer to instance, or NULL on memory exhaustion
+ *
+ * Neither ::enc nor ::int_enc are used here.
+ * libxml only supports a UTF-8 document buffer and forcibly setting the
+ * parser encoding is not yet implemented
+ */
+xml_parser *xml_parser_create(const char *enc, const char *int_enc,
+ xml_alloc alloc, void *pw)
+{
+ xml_parser *parser;
+
+ UNUSED(enc);
+ UNUSED(int_enc);
+
+ parser = alloc(NULL, sizeof(xml_parser), pw);
+ if (parser == NULL)
+ return NULL;
+
+ parser->xml_ctx =
+ xmlCreatePushParserCtxt(&sax_handler, parser, "", 0,
+ NULL);
+ if (parser->xml_ctx == NULL) {
+ alloc(parser, 0, pw);
+ return NULL;
+ }
+
+ parser->doc = NULL;
+
+ parser->complete = false;
+
+ parser->alloc = alloc;
+ parser->pw = pw;
+
+ return parser;
+}
+
+/**
+ * Destroy an XML parser instance
+ *
+ * \param parser The parser instance to destroy
+ */
+void xml_parser_destroy(xml_parser *parser)
+{
+ xmlFreeParserCtxt(parser->xml_ctx);
+
+ /** \todo Do we want to clean up the document here, too? */
+ /* Obviously, document cleanup wouldn't happen if the client has
+ * claimed the document from us via xml_parser_get_document() */
+
+ parser->alloc(parser, 0, parser->pw);
+}
+
+/**
+ * Parse a chunk of data
+ *
+ * \param parser The XML parser instance to use for parsing
+ * \param data Pointer to data chunk
+ * \param len Byte length of data chunk
+ * \return XML_OK on success, XML_LIBXML_ERR | <libxml error> on failure
+ */
+xml_error xml_parser_parse_chunk(xml_parser *parser,
+ uint8_t *data, size_t len)
+{
+ xmlParserErrors err;
+
+ err = xmlParseChunk(parser->xml_ctx, (char *) data, len, 0);
+ if (err != XML_ERR_OK)
+ return XML_LIBXML_ERR | err;
+
+ return XML_OK;
+}
+
+/**
+ * Notify parser that datastream is empty
+ *
+ * \param parser The XML parser instance to notify
+ * \return XML_OK on success, XML_LIBXML_ERR | <libxml error> on failure
+ *
+ * This will force any remaining data through the parser
+ */
+xml_error xml_parser_completed(xml_parser *parser)
+{
+ xmlParserErrors err;
+
+ err = xmlParseChunk(parser->xml_ctx, "", 0, 1);
+ if (err != XML_ERR_OK)
+ return XML_LIBXML_ERR | err;
+
+ parser->complete = true;
+
+ return XML_OK;
+}
+
+/**
+ * Retrieve the created DOM Document from a parser
+ *
+ * \param parser The parser instance to retrieve the document from
+ * \return Pointer to document, or NULL if parsing is not complete
+ *
+ * This may only be called after xml_parser_completed().
+ */
+struct dom_document *xml_parser_get_document(xml_parser *parser)
+{
+ return (parser->complete ? parser->doc : NULL);
+}
diff --git a/bindings/xml/xmlparser.h b/bindings/xml/xmlparser.h
new file mode 100644
index 0000000..e8cff7e
--- /dev/null
+++ b/bindings/xml/xmlparser.h
@@ -0,0 +1,38 @@
+/*
+ * 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 xml_xmlparser_h_
+#define xml_xmlparser_h_
+
+#include <stddef.h>
+#include <inttypes.h>
+
+#include "xmlerror.h"
+#include "functypes.h"
+
+struct dom_document;
+
+typedef struct xml_parser xml_parser;
+
+/* Create an XML parser instance */
+xml_parser *xml_parser_create(const char *enc, const char *int_enc,
+ xml_alloc alloc, void *pw);
+
+/* Destroy an XML parser instance */
+void xml_parser_destroy(xml_parser *parser);
+
+/* Parse a chunk of data */
+xml_error xml_parser_parse_chunk(xml_parser *parser,
+ uint8_t *data, size_t len);
+
+/* Notify parser that datastream is empty */
+xml_error xml_parser_completed(xml_parser *parser);
+
+/* Retrieve the created DOM Document */
+struct dom_document *xml_parser_get_document(xml_parser *parser);
+
+#endif
diff --git a/build/Makefile.common b/build/Makefile.common
index 3b3f92c..c445a4c 100644
--- a/build/Makefile.common
+++ b/build/Makefile.common
@@ -11,29 +11,35 @@ export TOP = $(CURDIR)
# Rules
release: setup
+ @$(MAKE) $(MAKEFLAGS) -C bindings release
@$(MAKE) $(MAKEFLAGS) -C src release
debug: setup
+ @$(MAKE) $(MAKEFLAGS) -C bindings debug
@$(MAKE) $(MAKEFLAGS) -C src debug
test: debug
@$(MAKE) $(MAKEFLAGS) -C test test
clean:
+ @$(MAKE) $(MAKEFLAGS) -C bindings clean
@$(MAKE) $(MAKEFLAGS) -C src clean
@$(MAKE) $(MAKEFLAGS) -C test clean
setup:
+ @$(MAKE) $(MAKEFLAGS) -C bindings setup
@$(MAKE) $(MAKEFLAGS) -C src setup
@$(MAKE) $(MAKEFLAGS) -C test setup
export: release
@$(MKDIR) $(MKDIRFLAGS) $(TOP)/dist/lib
@$(CP) $(CPFLAGS) -r include $(EXPORT)/
+ @$(MAKE) $(MAKEFLAGS) -C bindings export
@$(MAKE) $(MAKEFLAGS) -C src export
@$(MAKE) $(MAKEFLAGS) -C test export
distclean: clean
-@$(RM) $(RMFLAGS) -r $(TOP)/dist
+ @$(MAKE) $(MAKEFLAGS) -C bindings distclean
@$(MAKE) $(MAKEFLAGS) -C src distclean
@$(MAKE) $(MAKEFLAGS) -C test distclean
diff --git a/include/dom/dom.h b/include/dom/dom.h
new file mode 100644
index 0000000..b28aa21
--- /dev/null
+++ b/include/dom/dom.h
@@ -0,0 +1,17 @@
+/*
+ * 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_dom_h_
+#define dom_dom_h_
+
+/** \todo populate this file */
+
+/* This is the top-level header file for libdom. The intention of this is
+ * to allow client applications to simply include this file and get access
+ * to all the libdom API. */
+
+#endif