From aba54ed61e31df318abdfa165f971a11ce084608 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Tue, 11 Aug 2009 11:17:23 +0000 Subject: Merge the branches/struggleyb/libdom-remain back to trunk. svn path=/trunk/dom/; revision=9191 --- bindings/hubbub/README | 21 --- bindings/hubbub/parser.c | 163 +++++++++++++------ bindings/hubbub/parser.h | 5 +- bindings/xml/Makefile | 2 +- bindings/xml/README | 21 --- bindings/xml/xmlbinding.c | 404 ---------------------------------------------- bindings/xml/xmlbinding.h | 19 --- bindings/xml/xmlparser.c | 133 ++++++++++----- bindings/xml/xmlparser.h | 4 +- 9 files changed, 216 insertions(+), 556 deletions(-) delete mode 100644 bindings/xml/xmlbinding.c delete mode 100644 bindings/xml/xmlbinding.h (limited to 'bindings') diff --git a/bindings/hubbub/README b/bindings/hubbub/README index 43b7be7..ab498a0 100644 --- a/bindings/hubbub/README +++ b/bindings/hubbub/README @@ -1,29 +1,8 @@ Hubbub binding for libdom ========================= -Overview --------- - - This is an example binding of hubbub to libdom. It consists of two, - orthogonal, parts: - - 1) hubbub parser wrapper - 2) hubbub-specific DOMImplementationSource for libdom - -Push parser wrapper -------------------- - This is a wrapper around hubbub's parser API, to facilitate construction of a libdom DOM tree. The basic premise is that the wrapper intercepts the SAX-like events emitted by hubbub's tokeniser then builds a libdom DOM tree from them. -DOMImplementationSource ------------------------ - - The DOMImplementationSource exposes the APIs needed to create a new - document based upon the hubbub 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/hubbub/parser.c b/bindings/hubbub/parser.c index 1c8859c..4551f13 100644 --- a/bindings/hubbub/parser.c +++ b/bindings/hubbub/parser.c @@ -7,6 +7,7 @@ */ #include +#include #include #include @@ -17,6 +18,10 @@ #include "parser.h" #include "utils.h" +#include "core/document.h" + +#include + /** * libdom Hubbub parser context */ @@ -38,12 +43,15 @@ struct dom_hubbub_parser { dom_alloc alloc; /**< Memory (de)allocation function */ void *pw; /**< Pointer to client data */ - dom_msg msg; /**< Informational messaging function */ - void *mctx; /**< Pointer to client data */ + dom_msg msg; /**< Informational messaging function */ + void *mctx; /**< Pointer to client data */ + + struct lwc_context_s *ctx; /**< The string intern context */ }; -static hubbub_error create_comment(void *parser, const hubbub_string *data, +/* The callbacks declarations */ +static hubbub_error create_comment(void *parser, const hubbub_string *data, void **result); static hubbub_error create_doctype(void *parser, const hubbub_doctype *doctype, void **result); @@ -109,7 +117,8 @@ static bool __initialised = false; */ dom_hubbub_parser *dom_hubbub_parser_create(const char *aliases, const char *enc, bool fix_enc, - dom_alloc alloc, void *pw, dom_msg msg, void *mctx) + dom_alloc alloc, void *pw, dom_msg msg, void *mctx, + lwc_context *ctx) { dom_hubbub_parser *parser; hubbub_parser_optparams params; @@ -118,7 +127,8 @@ dom_hubbub_parser *dom_hubbub_parser_create(const char *aliases, struct dom_string *features; if (__initialised == false) { - error = hubbub_initialise(aliases, alloc, pw); + error = hubbub_initialise(aliases, + (hubbub_allocator_fn) alloc, pw); if (error != HUBBUB_OK) { msg(DOM_MSG_ERROR, mctx, "Failed initialising hubbub"); @@ -147,6 +157,7 @@ dom_hubbub_parser *dom_hubbub_parser_create(const char *aliases, parser->pw = pw; parser->msg = msg; parser->mctx = mctx; + parser->ctx = ctx; error = hubbub_parser_create(enc, fix_enc, alloc, pw, &parser->parser); if (error != HUBBUB_OK) { @@ -155,7 +166,6 @@ dom_hubbub_parser *dom_hubbub_parser_create(const char *aliases, return NULL; } - /* Get DOM implementation */ /* Create string representation of the features we want */ err = dom_string_create(alloc, pw, (const uint8_t *) "HTML", SLEN("HTML"), &features); @@ -168,7 +178,7 @@ dom_hubbub_parser *dom_hubbub_parser_create(const char *aliases, /* Now, try to get an appropriate implementation from the registry */ err = dom_implregistry_get_dom_implementation(features, - &parser->impl, alloc, pw); + &parser->impl); if (err != DOM_NO_ERR) { dom_string_unref(features); hubbub_parser_destroy(parser->parser); @@ -177,11 +187,11 @@ dom_hubbub_parser *dom_hubbub_parser_create(const char *aliases, return NULL; } - /* no longer need the features string */ + /* No longer need the feature string */ dom_string_unref(features); err = dom_implementation_create_document(parser->impl, NULL, NULL, NULL, - &parser->doc, alloc, pw); + alloc, pw, ctx, &parser->doc); if (err != DOM_NO_ERR) { hubbub_parser_destroy(parser->parser); alloc(parser, 0, pw); @@ -204,7 +214,11 @@ dom_hubbub_parser *dom_hubbub_parser_create(const char *aliases, return parser; } -/* Destroy a Hubbub parser instance */ +/** + * Destroy a Hubbub parser instance + * + * \param parser The Hubbub parser object + */ void dom_hubbub_parser_destroy(dom_hubbub_parser *parser) { dom_implementation_unref(parser->impl); @@ -219,6 +233,15 @@ void dom_hubbub_parser_destroy(dom_hubbub_parser *parser) parser->alloc(parser, 0, parser->pw); } +/** + * Parse data with Hubbub parser + * + * \param parser The parser object + * \param data The data to be parsed + * \param len The length of the data to be parsed + * \return DOM_HUBBUB_OK on success, + * DOM_HUBBUB_HUBBUB_ERR | on failure + */ dom_hubbub_error dom_hubbub_parser_parse_chunk(dom_hubbub_parser *parser, uint8_t *data, size_t len) { @@ -231,9 +254,19 @@ dom_hubbub_error dom_hubbub_parser_parse_chunk(dom_hubbub_parser *parser, return DOM_HUBBUB_OK; } +/** + * Notify the parser to complete parsing + * + * \param parser The parser object + * \return DOM_HUBBUB_OK on success, + * DOM_HUBBUB_HUBBUB_ERR | on underlaying parser failure + * DOMHUBBUB_UNKNOWN | on libwapcaplet failure + */ dom_hubbub_error dom_hubbub_parser_completed(dom_hubbub_parser *parser) { hubbub_error err; + lwc_string *name = NULL; + lwc_error lerr; err = hubbub_parser_completed(parser->parser); if (err != DOM_HUBBUB_OK) { @@ -244,9 +277,22 @@ dom_hubbub_error dom_hubbub_parser_completed(dom_hubbub_parser *parser) parser->complete = true; + lerr = lwc_context_intern(parser->ctx, "id", strlen("id"), &name); + if (lerr != lwc_error_ok) + return HUBBUB_UNKNOWN; + + _dom_document_set_id_name(parser->doc, name); + lwc_context_string_unref(parser->ctx, name); + return DOM_HUBBUB_OK; } +/** + * Fetch the Document object from the parser + * + * \param parser The parser object + * \return the created document on success, NULL on failure + */ struct dom_document *dom_hubbub_parser_get_document(dom_hubbub_parser *parser) { struct dom_document *doc = NULL; @@ -259,6 +305,13 @@ struct dom_document *dom_hubbub_parser_get_document(dom_hubbub_parser *parser) return doc; } +/** + * Retrieve the encoding + * + * \param parser The parser object + * \param source The encoding_source + * \return the encoding name + */ const char *dom_hubbub_parser_get_encoding(dom_hubbub_parser *parser, dom_hubbub_encoding_source *source) { @@ -268,8 +321,9 @@ const char *dom_hubbub_parser_get_encoding(dom_hubbub_parser *parser, : "Windows-1252"; } -/* The callbacks definitions */ -hubbub_error create_comment(void *parser, const hubbub_string *data, + +/*--------------------- The callbacks definitions --------------------*/ +static hubbub_error create_comment(void *parser, const hubbub_string *data, void **result) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; @@ -284,7 +338,7 @@ hubbub_error create_comment(void *parser, const hubbub_string *data, if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Can't create comment node text"); - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; } err = dom_document_create_comment(dom_parser->doc, str, &comment); @@ -293,7 +347,7 @@ hubbub_error create_comment(void *parser, const hubbub_string *data, dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Can't create comment node with text '%.*s'", data->len, data->ptr); - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; } *result = comment; @@ -303,7 +357,7 @@ hubbub_error create_comment(void *parser, const hubbub_string *data, return HUBBUB_OK; } -hubbub_error create_doctype(void *parser, const hubbub_doctype *doctype, +static hubbub_error create_doctype(void *parser, const hubbub_doctype *doctype, void **result) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; @@ -350,8 +404,8 @@ hubbub_error create_doctype(void *parser, const hubbub_doctype *doctype, } err = dom_implementation_create_document_type(dom_parser->impl, qname, - public_id, system_id, &dtype, dom_parser->alloc, - dom_parser->pw); + public_id, system_id, dom_parser->alloc, + dom_parser->pw, dom_parser->ctx, &dtype); if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Can't create the document type"); @@ -371,17 +425,19 @@ clean1: fail: if (*result == NULL) - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; else return HUBBUB_OK; } -hubbub_error create_element(void *parser, const hubbub_tag *tag, void **result) +static hubbub_error create_element(void *parser, const hubbub_tag *tag, + void **result) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; dom_exception err; struct dom_string *name; struct dom_element *element = NULL; + hubbub_error herr; *result = NULL; @@ -412,17 +468,27 @@ hubbub_error create_element(void *parser, const hubbub_tag *tag, void **result) } *result = element; + if (element != NULL) { + if (tag->n_attributes != 0) { + herr = add_attributes(parser, element, tag->attributes, + tag->n_attributes); + if (herr != HUBBUB_OK) + return herr; + } + } + clean1: dom_string_unref(name); fail: if (*result == NULL) - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; else return HUBBUB_OK; } -hubbub_error create_text(void *parser, const hubbub_string *data, void **result) +static hubbub_error create_text(void *parser, const hubbub_string *data, + void **result) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; dom_exception err; @@ -453,13 +519,13 @@ clean1: fail: if (*result == NULL) - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; else return HUBBUB_OK; } -hubbub_error ref_node(void *parser, void *node) +static hubbub_error ref_node(void *parser, void *node) { struct dom_node *dnode = (struct dom_node *) node; @@ -470,7 +536,7 @@ hubbub_error ref_node(void *parser, void *node) return HUBBUB_OK; } -hubbub_error unref_node(void *parser, void *node) +static hubbub_error unref_node(void *parser, void *node) { struct dom_node *dnode = (struct dom_node *) node; @@ -481,7 +547,8 @@ hubbub_error unref_node(void *parser, void *node) return HUBBUB_OK; } -hubbub_error append_child(void *parser, void *parent, void *child, void **result) +static hubbub_error append_child(void *parser, void *parent, void *child, + void **result) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; dom_exception err; @@ -493,13 +560,13 @@ hubbub_error append_child(void *parser, void *parent, void *child, void **result dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Can't append child '%p' for parent '%p'", child, parent); - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; } return HUBBUB_OK; } -hubbub_error insert_before(void *parser, void *parent, void *child, +static hubbub_error insert_before(void *parser, void *parent, void *child, void *ref_child, void **result) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; @@ -513,13 +580,14 @@ hubbub_error insert_before(void *parser, void *parent, void *child, dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Can't insert node '%p' before node '%p'", child, ref_child); - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; } return HUBBUB_OK; } -hubbub_error remove_child(void *parser, void *parent, void *child, void **result) +static hubbub_error remove_child(void *parser, void *parent, void *child, + void **result) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; dom_exception err; @@ -530,13 +598,14 @@ hubbub_error remove_child(void *parser, void *parent, void *child, void **result if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Can't remove child '%p'", child); - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; } return HUBBUB_OK; } -hubbub_error clone_node(void *parser, void *node, bool deep, void **result) +static hubbub_error clone_node(void *parser, void *node, bool deep, + void **result) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; dom_exception err; @@ -546,13 +615,14 @@ hubbub_error clone_node(void *parser, void *node, bool deep, void **result) if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Can't clone node '%p'", node); - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; } return HUBBUB_OK; } -hubbub_error reparent_children(void *parser, void *node, void *new_parent) +static hubbub_error reparent_children(void *parser, void *node, + void *new_parent) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; dom_exception err; @@ -564,7 +634,7 @@ hubbub_error reparent_children(void *parser, void *node, void *new_parent) if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Error in dom_note_get_first_child"); - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; } if (child == NULL) break; @@ -592,10 +662,10 @@ hubbub_error reparent_children(void *parser, void *node, void *new_parent) fail: dom_node_unref(child); - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; } -hubbub_error get_parent(void *parser, void *node, bool element_only, +static hubbub_error get_parent(void *parser, void *node, bool element_only, void **result) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; @@ -608,7 +678,7 @@ hubbub_error get_parent(void *parser, void *node, bool element_only, if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Error in dom_node_get_parent"); - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; } if (element_only == false) { *result = parent; @@ -623,18 +693,20 @@ hubbub_error get_parent(void *parser, void *node, bool element_only, } if (type == DOM_ELEMENT_NODE) { *result = parent; + return HUBBUB_OK; } else { *result = NULL; dom_node_unref(parent); + return HUBBUB_OK; } return HUBBUB_OK; fail: dom_node_unref(parent); - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; } -hubbub_error has_children(void *parser, void *node, bool *result) +static hubbub_error has_children(void *parser, void *node, bool *result) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; dom_exception err; @@ -645,13 +717,12 @@ hubbub_error has_children(void *parser, void *node, bool *result) if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Error in dom_node_has_child_nodes"); - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; } - return HUBBUB_OK; } -hubbub_error form_associate(void *parser, void *form, void *node) +static hubbub_error form_associate(void *parser, void *form, void *node) { UNUSED(parser); UNUSED(form); @@ -660,7 +731,7 @@ hubbub_error form_associate(void *parser, void *form, void *node) return HUBBUB_OK; } -hubbub_error add_attributes(void *parser, void *node, +static hubbub_error add_attributes(void *parser, void *node, const hubbub_attribute *attributes, uint32_t n_attributes) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; @@ -719,10 +790,10 @@ hubbub_error add_attributes(void *parser, void *node, return HUBBUB_OK; fail: - return HUBBUB_NOMEM; + return HUBBUB_UNKNOWN; } -hubbub_error set_quirks_mode(void *parser, hubbub_quirks_mode mode) +static hubbub_error set_quirks_mode(void *parser, hubbub_quirks_mode mode) { UNUSED(parser); UNUSED(mode); @@ -730,7 +801,7 @@ hubbub_error set_quirks_mode(void *parser, hubbub_quirks_mode mode) return HUBBUB_OK; } -hubbub_error change_encoding(void *parser, const char *charset) +static hubbub_error change_encoding(void *parser, const char *charset) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; uint32_t source; diff --git a/bindings/hubbub/parser.h b/bindings/hubbub/parser.h index 7e28916..8b2218d 100644 --- a/bindings/hubbub/parser.h +++ b/bindings/hubbub/parser.h @@ -16,6 +16,7 @@ #include "errors.h" struct dom_document; +struct lwc_context_s; typedef struct dom_hubbub_parser dom_hubbub_parser; @@ -50,7 +51,8 @@ typedef enum dom_hubub_encoding_source { /* Create a Hubbub parser instance */ dom_hubbub_parser *dom_hubbub_parser_create(const char *aliases, const char *enc, bool fix_enc, - dom_alloc alloc, void *pw, dom_msg msg, void *mctx); + dom_alloc alloc, void *pw, dom_msg msg, void *mctx, + struct lwc_context_s *ctx); /* Destroy a Hubbub parser instance */ void dom_hubbub_parser_destroy(dom_hubbub_parser *parser); @@ -68,4 +70,5 @@ struct dom_document *dom_hubbub_parser_get_document(dom_hubbub_parser *parser); /* Retrieve the document's encoding */ const char *dom_hubbub_parser_get_encoding(dom_hubbub_parser *parser, dom_hubbub_encoding_source *source); + #endif diff --git a/bindings/xml/Makefile b/bindings/xml/Makefile index 6fc3c83..c5f0198 100644 --- a/bindings/xml/Makefile +++ b/bindings/xml/Makefile @@ -1,5 +1,5 @@ ifeq ($(WITH_LIBXML_BINDING),yes) - DIR_SOURCES := xmlbinding.c xmlparser.c + DIR_SOURCES := xmlparser.c DIR_INSTALL_ITEMS := /include/dom/bindings/libxml:xmlbinding.h;xmlerror.h;xmlparser.h diff --git a/bindings/xml/README b/bindings/xml/README index 0e427c7..2e70fde 100644 --- a/bindings/xml/README +++ b/bindings/xml/README @@ -1,18 +1,6 @@ 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 @@ -24,12 +12,3 @@ Push parser wrapper 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/xmlbinding.c b/bindings/xml/xmlbinding.c deleted file mode 100644 index b03b7af..0000000 --- a/bindings/xml/xmlbinding.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * This file is part of libdom. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2007 John-Mark Bell - */ - -#include -#include -#include - -#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. - * - * 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) -{ - struct dom_document_type *d; - dom_exception err; - - /* We have no use for the impl -- we only have one */ - UNUSED(impl); - - /** \todo validate qname */ - - /* Create the doctype */ - err = dom_document_type_create(qname, public_id, system_id, - alloc, pw, &d); - if (err != DOM_NO_ERR) - return err; - - *doctype = d; - - return DOM_NO_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 document will be referenced, so the client need not do this - * explicitly. The client must unref the document 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) -{ - struct dom_document *d; - dom_exception err; - - /* Create document object */ - err = dom_document_create(impl, alloc, pw, &d); - if (err != DOM_NO_ERR) - return err; - - /* Set its doctype, if necessary */ - if (doctype != NULL) { - struct dom_node *ins_doctype = NULL; - - err = dom_node_append_child((struct dom_node *) d, - (struct dom_node *) doctype, &ins_doctype); - if (err != DOM_NO_ERR) { - dom_node_unref((struct dom_node *) d); - return err; - } - - /* Not interested in inserted doctype */ - if (ins_doctype != NULL) - dom_node_unref(ins_doctype); - } - - /* Create root element and attach it to document */ - if (qname != NULL) { - struct dom_element *e; - struct dom_node *inserted; - - err = dom_document_create_element_ns(d, namespace, qname, &e); - if (err != DOM_NO_ERR) { - dom_node_unref((struct dom_node *) d); - return err; - } - - err = dom_node_append_child((struct dom_node *) d, - (struct dom_node *) e, &inserted); - if (err != DOM_NO_ERR) { - dom_node_unref((struct dom_node *) e); - dom_node_unref((struct dom_node *) d); - return err; - } - - /* No longer interested in inserted node */ - dom_node_unref(inserted); - - /* Done with element */ - dom_node_unref((struct dom_node *) e); - } - - *doc = d; - - return DOM_NO_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 DOM_XML_OK on success, DOM_XML_NOMEM on memory exhaustion - */ -dom_xml_error dom_xml_binding_initialise(dom_alloc alloc, void *pw) -{ - dom_exception err; - - err = dom_register_source(&xml_dom_impl_src, alloc, pw); - if (err != DOM_NO_ERR) - return DOM_XML_NOMEM; - - return DOM_XML_OK; -} - -/** - * Finalise the XML DOM binding - * - * \return DOM_XML_OK on success. - */ -dom_xml_error dom_xml_binding_finalise(void) -{ - return DOM_XML_OK; -} - - diff --git a/bindings/xml/xmlbinding.h b/bindings/xml/xmlbinding.h deleted file mode 100644 index 1a8c207..0000000 --- a/bindings/xml/xmlbinding.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * This file is part of libdom. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2007 John-Mark Bell - */ - -#ifndef xml_xmlbinding_h_ -#define xml_xmlbinding_h_ - -#include "xmlerror.h" - -/* Initialise the XML DOM binding */ -dom_xml_error dom_xml_binding_initialise(dom_alloc alloc, void *pw); - -/* Finalise the XML DOM binding */ -dom_xml_error dom_xml_binding_finalise(void); - -#endif diff --git a/bindings/xml/xmlparser.c b/bindings/xml/xmlparser.c index 73fbcd1..e451699 100644 --- a/bindings/xml/xmlparser.c +++ b/bindings/xml/xmlparser.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -15,10 +16,14 @@ #include #include +#include + #include "xmlerror.h" #include "xmlparser.h" #include "utils.h" +#include "core/document.h" + static void xml_parser_start_document(void *ctx); static void xml_parser_end_document(void *ctx); static void xml_parser_start_element_ns(void *ctx, const xmlChar *localname, @@ -42,6 +47,8 @@ static void xml_parser_add_cdata_section(dom_xml_parser *parser, struct dom_node *parent, xmlNodePtr child); static void xml_parser_add_entity_reference(dom_xml_parser *parser, struct dom_node *parent, xmlNodePtr child); +static void xml_parser_add_entity(dom_xml_parser *parser, + struct dom_node *parent, xmlNodePtr child); static void xml_parser_add_comment(dom_xml_parser *parser, struct dom_node *parent, xmlNodePtr child); static void xml_parser_add_document_type(dom_xml_parser *parser, @@ -95,8 +102,10 @@ struct dom_xml_parser { dom_alloc alloc; /**< Memory (de)allocation function */ void *pw; /**< Pointer to client data */ - dom_msg msg; /**< Informational message function */ - void *mctx; /**< Pointer to client data */ + dom_msg msg; /**< Informational message function */ + void *mctx; /**< Pointer to client data */ + + struct lwc_context_s *ctx; /**< The lwc_context of the parser */ }; /** @@ -153,11 +162,13 @@ static xmlSAXHandler sax_handler = { * parser encoding is not yet implemented */ dom_xml_parser *dom_xml_parser_create(const char *enc, const char *int_enc, - dom_alloc alloc, void *pw, dom_msg msg, void *mctx) + dom_alloc alloc, void *pw, dom_msg msg, void *mctx, + lwc_context *ctx) { dom_xml_parser *parser; struct dom_string *features; dom_exception err; + int ret; UNUSED(enc); UNUSED(int_enc); @@ -176,6 +187,11 @@ dom_xml_parser *dom_xml_parser_create(const char *enc, const char *int_enc, return NULL; } + /* Set options of parsing context */ + ret = xmlCtxtUseOptions(parser->xml_ctx, XML_PARSE_DTDATTR | + XML_PARSE_DTDLOAD); + assert(ret == 0); + parser->doc = NULL; parser->complete = false; @@ -191,7 +207,6 @@ dom_xml_parser *dom_xml_parser_create(const char *enc, const char *int_enc, return NULL; } - /* Get DOM implementation */ /* Create a string representation of the features we want */ err = dom_string_create((dom_alloc) alloc, pw, (const uint8_t *) "XML", SLEN("XML"), &features); @@ -205,7 +220,7 @@ dom_xml_parser *dom_xml_parser_create(const char *enc, const char *int_enc, /* Now, try to get an appropriate implementation from the registry */ err = dom_implregistry_get_dom_implementation(features, - &parser->impl, (dom_alloc) alloc, pw); + &parser->impl); if (err != DOM_NO_ERR) { dom_string_unref(features); dom_string_unref(parser->udkey); @@ -215,7 +230,7 @@ dom_xml_parser *dom_xml_parser_create(const char *enc, const char *int_enc, return NULL; } - /* No longer need the features string */ + /* No longer need the feature string */ dom_string_unref(features); parser->alloc = alloc; @@ -224,6 +239,8 @@ dom_xml_parser *dom_xml_parser_create(const char *enc, const char *int_enc, parser->msg = msg; parser->mctx = mctx; + parser->ctx = ctx; + return parser; } @@ -240,9 +257,7 @@ void dom_xml_parser_destroy(dom_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() */ + xmlFreeDoc(parser->xml_ctx->myDoc); parser->alloc(parser, 0, parser->pw); } @@ -281,6 +296,8 @@ dom_xml_error dom_xml_parser_parse_chunk(dom_xml_parser *parser, dom_xml_error dom_xml_parser_completed(dom_xml_parser *parser) { xmlParserErrors err; + lwc_string *name = NULL; + lwc_error lerr; err = xmlParseChunk(parser->xml_ctx, "", 0, 1); if (err != XML_ERR_OK) { @@ -291,6 +308,16 @@ dom_xml_error dom_xml_parser_completed(dom_xml_parser *parser) parser->complete = true; + /* TODO: In future, this string "id" should be extracted from the + * document schema file instead of just setting it as "id". + */ + lerr = lwc_context_intern(parser->ctx, "id", SLEN("id"), &name); + if (lerr != lwc_error_ok) + return _dom_exception_from_lwc_error(lerr); + + _dom_document_set_id_name(parser->doc, name); + lwc_context_string_unref(parser->ctx, name); + return DOM_XML_OK; } @@ -326,9 +353,8 @@ void xml_parser_start_document(void *ctx) /* namespace */ NULL, /* qname */ NULL, /* doctype */ NULL, - &doc, - (dom_alloc) parser->alloc, - parser->pw); + parser->alloc, parser->pw, parser->ctx, + &doc); if (err != DOM_NO_ERR) { parser->msg(DOM_MSG_CRITICAL, parser->mctx, "Failed creating document"); @@ -620,6 +646,9 @@ void xml_parser_add_node(dom_xml_parser *parser, struct dom_node *parent, case XML_DTD_NODE: xml_parser_add_document_type(parser, parent, child); break; + case XML_ENTITY_DECL: + xml_parser_add_entity(parser, parent, child); + break; default: parser->msg(DOM_MSG_NOTICE, parser->mctx, "Unsupported node type: %s", @@ -647,7 +676,7 @@ void xml_parser_add_element_node(dom_xml_parser *parser, struct dom_string *tag_name; /* Create tag name DOM string */ - err = dom_document_create_string(parser->doc, + err = _dom_document_create_string(parser->doc, child->name, strlen((const char *) child->name), &tag_name); if (err != DOM_NO_ERR) { @@ -680,7 +709,7 @@ void xml_parser_add_element_node(dom_xml_parser *parser, uint8_t qnamebuf[qnamelen + 1 /* '\0' */]; /* Create namespace DOM string */ - err = dom_document_create_string(parser->doc, + err = _dom_document_create_string(parser->doc, child->ns->href, strlen((const char *) child->ns->href), &namespace); @@ -699,7 +728,7 @@ void xml_parser_add_element_node(dom_xml_parser *parser, (const char *) child->name); /* Create qname DOM string */ - err = dom_document_create_string(parser->doc, + err = _dom_document_create_string(parser->doc, qnamebuf, qnamelen, &qname); @@ -738,7 +767,7 @@ void xml_parser_add_element_node(dom_xml_parser *parser, struct dom_string *name; /* Create attribute name DOM string */ - err = dom_document_create_string(parser->doc, + err = _dom_document_create_string(parser->doc, a->name, strlen((const char *) a->name), &name); @@ -754,8 +783,8 @@ void xml_parser_add_element_node(dom_xml_parser *parser, if (err != DOM_NO_ERR) { dom_string_unref(name); parser->msg(DOM_MSG_CRITICAL, parser->mctx, - "Failed creating attribute '%s'", - a->name); + "Failed creating attribute \ + '%s'", a->name); goto cleanup; } @@ -772,7 +801,7 @@ void xml_parser_add_element_node(dom_xml_parser *parser, uint8_t qnamebuf[qnamelen + 1 /* '\0' */]; /* Create namespace DOM string */ - err = dom_document_create_string(parser->doc, + err = _dom_document_create_string(parser->doc, a->ns->href, strlen((const char *) a->ns->href), &namespace); @@ -791,7 +820,7 @@ void xml_parser_add_element_node(dom_xml_parser *parser, (const char *) a->name); /* Create qname DOM string */ - err = dom_document_create_string(parser->doc, + err = _dom_document_create_string(parser->doc, qnamebuf, qnamelen, &qname); @@ -809,8 +838,8 @@ void xml_parser_add_element_node(dom_xml_parser *parser, dom_string_unref(namespace); dom_string_unref(qname); parser->msg(DOM_MSG_CRITICAL, parser->mctx, - "Failed creating attribute '%s'", - qnamebuf); + "Failed creating attribute \ + '%s'", qnamebuf); return; } @@ -833,18 +862,31 @@ void xml_parser_add_element_node(dom_xml_parser *parser, goto cleanup; } - /* And add attribute to the element */ - err = dom_element_set_attribute_node(el, attr, &prev_attr); - if (err != DOM_NO_ERR) { - dom_node_unref((struct dom_node *) attr); - parser->msg(DOM_MSG_ERROR, parser->mctx, - "Failed attaching attribute '%s'", - a->name); - goto cleanup; + if (a->ns == NULL) { + /* And add attribute to the element */ + err = dom_element_set_attribute_node(el, attr, + &prev_attr); + if (err != DOM_NO_ERR) { + dom_node_unref((struct dom_node *) attr); + parser->msg(DOM_MSG_ERROR, parser->mctx, + "Failed attaching attribute \ + '%s'", a->name); + goto cleanup; + } + } else { + err = dom_element_set_attribute_node_ns(el, attr, + &prev_attr); + if (err != DOM_NO_ERR) { + dom_node_unref((struct dom_node *) attr); + parser->msg(DOM_MSG_ERROR, parser->mctx, + "Failed attaching attribute \ + '%s'", a->name); + goto cleanup; + } } /* We're not interested in the previous attribute (if any) */ - if (prev_attr != NULL) + if (prev_attr != NULL && prev_attr != attr) dom_node_unref((struct dom_node *) prev_attr); /* We're no longer interested in the attribute node */ @@ -900,7 +942,7 @@ void xml_parser_add_text_node(dom_xml_parser *parser, struct dom_node *parent, dom_exception err; /* Create DOM string data for text node */ - err = dom_document_create_string(parser->doc, child->content, + err = _dom_document_create_string(parser->doc, child->content, strlen((const char *) child->content), &data); if (err != DOM_NO_ERR) { parser->msg(DOM_MSG_CRITICAL, parser->mctx, @@ -961,7 +1003,7 @@ void xml_parser_add_cdata_section(dom_xml_parser *parser, dom_exception err; /* Create DOM string data for cdata section */ - err = dom_document_create_string(parser->doc, child->content, + err = _dom_document_create_string(parser->doc, child->content, strlen((const char *) child->content), &data); if (err != DOM_NO_ERR) { parser->msg(DOM_MSG_CRITICAL, parser->mctx, @@ -1023,7 +1065,7 @@ void xml_parser_add_entity_reference(dom_xml_parser *parser, dom_exception err; /* Create name of entity reference */ - err = dom_document_create_string(parser->doc, child->name, + err = _dom_document_create_string(parser->doc, child->name, strlen((const char *) child->name), &name); if (err != DOM_NO_ERR) { parser->msg(DOM_MSG_CRITICAL, parser->mctx, @@ -1075,6 +1117,14 @@ void xml_parser_add_entity_reference(dom_xml_parser *parser, dom_node_unref((struct dom_node *) entity); } +static void xml_parser_add_entity(dom_xml_parser *parser, + struct dom_node *parent, xmlNodePtr child) +{ + UNUSED(parser); + UNUSED(parent); + UNUSED(child); +} + /** * Add a comment to the DOM * @@ -1090,7 +1140,7 @@ void xml_parser_add_comment(dom_xml_parser *parser, struct dom_node *parent, dom_exception err; /* Create DOM string data for comment */ - err = dom_document_create_string(parser->doc, child->content, + err = _dom_document_create_string(parser->doc, child->content, strlen((const char *) child->content), &data); if (err != DOM_NO_ERR) { parser->msg(DOM_MSG_CRITICAL, parser->mctx, @@ -1152,7 +1202,7 @@ void xml_parser_add_document_type(dom_xml_parser *parser, dom_exception err; /* Create qname for doctype */ - err = dom_document_create_string(parser->doc, dtd->name, + err = _dom_document_create_string(parser->doc, dtd->name, strlen((const char *) dtd->name), &qname); if (err != DOM_NO_ERR) { parser->msg(DOM_MSG_CRITICAL, parser->mctx, @@ -1161,7 +1211,7 @@ void xml_parser_add_document_type(dom_xml_parser *parser, } /* Create public ID for doctype */ - err = dom_document_create_string(parser->doc, + err = _dom_document_create_string(parser->doc, dtd->ExternalID, (dtd->ExternalID == NULL) ? 0 : strlen((const char *) dtd->ExternalID), @@ -1174,7 +1224,7 @@ void xml_parser_add_document_type(dom_xml_parser *parser, } /* Create system ID for doctype */ - err = dom_document_create_string(parser->doc, + err = _dom_document_create_string(parser->doc, dtd->SystemID, (dtd->SystemID == NULL) ? 0 : strlen((const char *) dtd->SystemID), @@ -1189,8 +1239,8 @@ void xml_parser_add_document_type(dom_xml_parser *parser, /* Create doctype */ err = dom_implementation_create_document_type(parser->impl, - qname, public_id, system_id, &doctype, - (dom_alloc) parser->alloc, parser->pw); + qname, public_id, system_id, + parser->alloc, parser->pw, parser->ctx, &doctype); if (err != DOM_NO_ERR) { dom_string_unref(system_id); dom_string_unref(public_id); @@ -1231,9 +1281,8 @@ void xml_parser_add_document_type(dom_xml_parser *parser, dom_node_unref((struct dom_node *) doctype); } -/* */ /* ------------------------------------------------------------------------*/ -/* */ + void xml_parser_internal_subset(void *ctx, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID) { diff --git a/bindings/xml/xmlparser.h b/bindings/xml/xmlparser.h index 7bf3807..366ceec 100644 --- a/bindings/xml/xmlparser.h +++ b/bindings/xml/xmlparser.h @@ -16,12 +16,14 @@ #include "xmlerror.h" struct dom_document; +struct lwc_context_s; typedef struct dom_xml_parser dom_xml_parser; /* Create an XML parser instance */ dom_xml_parser *dom_xml_parser_create(const char *enc, const char *int_enc, - dom_alloc alloc, void *pw, dom_msg msg, void *mctx); + dom_alloc alloc, void *pw, dom_msg msg, void *mctx, + struct lwc_context_s *ctx); /* Destroy an XML parser instance */ void dom_xml_parser_destroy(dom_xml_parser *parser); -- cgit v1.2.3