summaryrefslogtreecommitdiff
path: root/bindings/xml/xmlparser.c
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@netsurf-browser.org>2012-03-24 14:59:13 +0000
committerDaniel Silverstone <dsilvers@netsurf-browser.org>2012-03-24 14:59:13 +0000
commit2eea8e30c3e5b2bdfc4abc19e2e94c0f795ceb6d (patch)
tree75e03edda4783902370da9d26146a9e6d8c81f05 /bindings/xml/xmlparser.c
parent03ae3655cd0dd14156f54ac008cf1aa8eb8a39a8 (diff)
downloadlibdom-2eea8e30c3e5b2bdfc4abc19e2e94c0f795ceb6d.tar.gz
libdom-2eea8e30c3e5b2bdfc4abc19e2e94c0f795ceb6d.tar.bz2
Beginnings of an expat binding -- NOT FUNCTIONAL YET
svn path=/trunk/libdom/; revision=13594
Diffstat (limited to 'bindings/xml/xmlparser.c')
-rw-r--r--bindings/xml/xmlparser.c1367
1 files changed, 0 insertions, 1367 deletions
diff --git a/bindings/xml/xmlparser.c b/bindings/xml/xmlparser.c
deleted file mode 100644
index 3ae1a3c..0000000
--- a/bindings/xml/xmlparser.c
+++ /dev/null
@@ -1,1367 +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 <jmb@netsurf-browser.org>
- */
-
-#include <stdbool.h>
-#include <string.h>
-#include <assert.h>
-
-#include <libxml/parser.h>
-#include <libxml/SAX2.h>
-#include <libxml/xmlerror.h>
-
-#include <dom/dom.h>
-
-#include <libwapcaplet/libwapcaplet.h>
-
-#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,
- const xmlChar *prefix, const xmlChar *URI,
- int nb_namespaces, const xmlChar **namespaces,
- int nb_attributes, int nb_defaulted,
- const xmlChar **attributes);
-static void xml_parser_end_element_ns(void *ctx, const xmlChar *localname,
- const xmlChar *prefix, const xmlChar *URI);
-
-static dom_exception xml_parser_link_nodes(dom_xml_parser *parser,
- struct dom_node *dom, xmlNodePtr xml);
-
-static void xml_parser_add_node(dom_xml_parser *parser, struct dom_node *parent,
- xmlNodePtr child);
-static void xml_parser_add_element_node(dom_xml_parser *parser,
- struct dom_node *parent, xmlNodePtr child);
-static void xml_parser_add_text_node(dom_xml_parser *parser,
- struct dom_node *parent, xmlNodePtr child);
-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,
- struct dom_node *parent, xmlNodePtr child);
-
-static void xml_parser_internal_subset(void *ctx, const xmlChar *name,
- const xmlChar *ExternalID, const xmlChar *SystemID);
-static int xml_parser_is_standalone(void *ctx);
-static int xml_parser_has_internal_subset(void *ctx);
-static int xml_parser_has_external_subset(void *ctx);
-static xmlParserInputPtr xml_parser_resolve_entity(void *ctx,
- const xmlChar *publicId, const xmlChar *systemId);
-static xmlEntityPtr xml_parser_get_entity(void *ctx, const xmlChar *name);
-static void xml_parser_entity_decl(void *ctx, const xmlChar *name,
- int type, const xmlChar *publicId, const xmlChar *systemId,
- xmlChar *content);
-static void xml_parser_notation_decl(void *ctx, const xmlChar *name,
- const xmlChar *publicId, const xmlChar *systemId);
-static void xml_parser_attribute_decl(void *ctx, const xmlChar *elem,
- const xmlChar *fullname, int type, int def,
- const xmlChar *defaultValue, xmlEnumerationPtr tree);
-static void xml_parser_element_decl(void *ctx, const xmlChar *name,
- int type, xmlElementContentPtr content);
-static void xml_parser_unparsed_entity_decl(void *ctx, const xmlChar *name,
- const xmlChar *publicId, const xmlChar *systemId,
- const xmlChar *notationName);
-static void xml_parser_set_document_locator(void *ctx, xmlSAXLocatorPtr loc);
-static void xml_parser_reference(void *ctx, const xmlChar *name);
-static void xml_parser_characters(void *ctx, const xmlChar *ch, int len);
-static void xml_parser_comment(void *ctx, const xmlChar *value);
-static xmlEntityPtr xml_parser_get_parameter_entity(void *ctx,
- const xmlChar *name);
-static void xml_parser_cdata_block(void *ctx, const xmlChar *value, int len);
-static void xml_parser_external_subset(void *ctx, const xmlChar *name,
- const xmlChar *ExternalID, const xmlChar *SystemID);
-
-/**
- * libdom XML parser object
- */
-struct dom_xml_parser {
- xmlParserCtxtPtr xml_ctx; /**< libxml parser context */
-
- struct dom_document *doc; /**< DOM Document we're building */
-
- bool complete; /**< Indicate stream completion */
-
- dom_string *udkey; /**< Key for DOM node user data */
-
- dom_msg msg; /**< Informational message function */
- void *mctx; /**< Pointer to client data */
-};
-
-/**
- * SAX callback dispatch table
- */
-static xmlSAXHandler sax_handler = {
- .internalSubset = xml_parser_internal_subset,
- .isStandalone = xml_parser_is_standalone,
- .hasInternalSubset = xml_parser_has_internal_subset,
- .hasExternalSubset = xml_parser_has_external_subset,
- .resolveEntity = xml_parser_resolve_entity,
- .getEntity = xml_parser_get_entity,
- .entityDecl = xml_parser_entity_decl,
- .notationDecl = xml_parser_notation_decl,
- .attributeDecl = xml_parser_attribute_decl,
- .elementDecl = xml_parser_element_decl,
- .unparsedEntityDecl = xml_parser_unparsed_entity_decl,
- .setDocumentLocator = xml_parser_set_document_locator,
- .startDocument = xml_parser_start_document,
- .endDocument = xml_parser_end_document,
- .startElement = NULL,
- .endElement = NULL,
- .reference = xml_parser_reference,
- .characters = xml_parser_characters,
- .ignorableWhitespace = xml_parser_characters,
- .processingInstruction = NULL,
- .comment = xml_parser_comment,
- .warning = NULL,
- .error = NULL,
- .fatalError = NULL,
- .getParameterEntity = xml_parser_get_parameter_entity,
- .cdataBlock = xml_parser_cdata_block,
- .externalSubset = xml_parser_external_subset,
- .initialized = XML_SAX2_MAGIC,
- ._private = NULL,
- .startElementNs = xml_parser_start_element_ns,
- .endElementNs = xml_parser_end_element_ns,
- .serror = NULL
-};
-
-static void *dom_xml_alloc(void *ptr, size_t len, void *pw)
-{
- UNUSED(pw);
-
- if (ptr == NULL)
- return len > 0 ? malloc(len) : NULL;
-
- if (len == 0) {
- free(ptr);
- return NULL;
- }
-
- return realloc(ptr, len);
-}
-
-/**
- * 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 msg Informational message function
- * \param mctx 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
- */
-dom_xml_parser *dom_xml_parser_create(const char *enc, const char *int_enc,
- dom_msg msg, void *mctx)
-{
- dom_xml_parser *parser;
- dom_exception err;
- int ret;
-
- UNUSED(enc);
- UNUSED(int_enc);
-
- parser = dom_xml_alloc(NULL, sizeof(dom_xml_parser), NULL);
- if (parser == NULL) {
- msg(DOM_MSG_CRITICAL, mctx, "No memory for parser");
- return NULL;
- }
-
- parser->xml_ctx =
- xmlCreatePushParserCtxt(&sax_handler, parser, "", 0, NULL);
- if (parser->xml_ctx == NULL) {
- dom_xml_alloc(parser, 0, NULL);
- msg(DOM_MSG_CRITICAL, mctx, "Failed to create XML parser");
- return NULL;
- }
-
- /* Set options of parsing context */
- ret = xmlCtxtUseOptions(parser->xml_ctx, XML_PARSE_DTDATTR |
- XML_PARSE_DTDLOAD);
- if (ret != 0) {
- xmlFreeParserCtxt(parser->xml_ctx);
- dom_xml_alloc(parser, 0, NULL);
- msg(DOM_MSG_CRITICAL, mctx, "Failed setting parser options");
- return NULL;
- }
-
- parser->doc = NULL;
-
- parser->complete = false;
-
- /* Create key for user data registration */
- err = dom_string_create((const uint8_t *) "__xmlnode",
- SLEN("__xmlnode"), &parser->udkey);
- if (err != DOM_NO_ERR) {
- xmlFreeParserCtxt(parser->xml_ctx);
- dom_xml_alloc(parser, 0, NULL);
- msg(DOM_MSG_CRITICAL, mctx, "No memory for userdata key");
- return NULL;
- }
-
- parser->msg = msg;
- parser->mctx = mctx;
-
- return parser;
-}
-
-/**
- * Destroy an XML parser instance
- *
- * \param parser The parser instance to destroy
- */
-void dom_xml_parser_destroy(dom_xml_parser *parser)
-{
- dom_string_unref(parser->udkey);
-
- xmlFreeDoc(parser->xml_ctx->myDoc);
-
- xmlFreeParserCtxt(parser->xml_ctx);
-
- dom_xml_alloc(parser, 0, NULL);
-}
-
-/**
- * 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 DOM_XML_OK on success, DOM_XML_LIBXML_ERR | <libxml error> on failure
- */
-dom_xml_error dom_xml_parser_parse_chunk(dom_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) {
- parser->msg(DOM_MSG_ERROR, parser->mctx,
- "xmlParseChunk failed: %d", err);
- return DOM_XML_LIBXML_ERR | err;
- }
-
- return DOM_XML_OK;
-}
-
-/**
- * Notify parser that datastream is empty
- *
- * \param parser The XML parser instance to notify
- * \return DOM_XML_OK on success, DOM_XML_LIBXML_ERR | <libxml error> on failure
- *
- * This will force any remaining data through the parser
- */
-dom_xml_error dom_xml_parser_completed(dom_xml_parser *parser)
-{
- xmlParserErrors err;
- dom_string *name = NULL;
- dom_exception derr;
-
- err = xmlParseChunk(parser->xml_ctx, "", 0, 1);
- if (err != XML_ERR_OK) {
- parser->msg(DOM_MSG_ERROR, parser->mctx,
- "xmlParseChunk failed: %d", err);
- return DOM_XML_LIBXML_ERR | err;
- }
-
- parser->complete = true;
-
- /* TODO: In future, this string "id" should be extracted from the
- * document schema file instead of just setting it as "id".
- */
- derr = dom_string_create((const uint8_t *) "id", SLEN("id"), &name);
- if (derr != DOM_NO_ERR)
- return derr;
-
- _dom_document_set_id_name(parser->doc, name);
- dom_string_unref(name);
-
- return DOM_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 *dom_xml_parser_get_document(dom_xml_parser *parser)
-{
- return (parser->complete ? parser->doc : NULL);
-}
-
-/**
- * Handle a document start SAX event
- *
- * \param ctx The callback context
- */
-void xml_parser_start_document(void *ctx)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
- struct dom_document *doc;
- dom_exception err;
-
- /* Invoke libxml2's default behaviour */
- xmlSAX2StartDocument(parser->xml_ctx);
-
- /* TODO: Just pass the dom_events_default_action_fetcher a NULL,
- * we should pass the real function when we integrate libDOM with
- * Netsurf */
- err = dom_implementation_create_document(
- DOM_IMPLEMENTATION_XML,
- /* namespace */ NULL,
- /* qname */ NULL,
- /* doctype */ NULL,
- NULL,
- &doc);
- if (err != DOM_NO_ERR) {
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "Failed creating document");
- return;
- }
-
- /* Link nodes together */
- err = xml_parser_link_nodes(parser, (struct dom_node *) doc,
- (xmlNodePtr) parser->xml_ctx->myDoc);
- if (err != DOM_NO_ERR) {
- dom_node_unref((struct dom_node *) doc);
- return;
- }
-
- /* And squirrel the document away for later use */
- parser->doc = doc;
-}
-
-/**
- * Handle a document end SAX event
- *
- * \param ctx The callback context
- */
-void xml_parser_end_document(void *ctx)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
- xmlNodePtr node;
- xmlNodePtr n;
- dom_exception err;
-
- /* Invoke libxml2's default behaviour */
- xmlSAX2EndDocument(parser->xml_ctx);
-
- /* If there is no document, we can't do anything */
- if (parser->doc == NULL) {
- parser->msg(DOM_MSG_WARNING, parser->mctx,
- "No document in end_document");
- return;
- }
-
- /* We need to mirror any child nodes at the end of the list of
- * children which occur after the last Element node in the list */
-
- /* Get XML node */
- err = dom_node_get_user_data((struct dom_node *) parser->doc,
- parser->udkey, (void **) (void *) &node);
- if (err != DOM_NO_ERR) {
- parser->msg(DOM_MSG_WARNING, parser->mctx,
- "Failed finding XML node");
- return;
- }
-
- /* Find last Element node, if any */
- for (n = node->last; n != NULL; n = n->prev) {
- if (n->type == XML_ELEMENT_NODE)
- break;
- }
-
- if (n == NULL) {
- /* No Element node found; entire list needs mirroring */
- n = node->children;
- } else {
- /* Found last Element; skip over it */
- n = n->next;
- }
-
- /* Now, mirror nodes in the DOM */
- for (; n != NULL; n = n->next) {
- xml_parser_add_node(parser,
- (struct dom_node *) node->_private, n);
- }
-}
-
-/**
- * Handle an element open SAX event
- *
- * \param ctx The callback context
- * \param localname The local name of the element
- * \param prefix The element namespace prefix
- * \param URI The element namespace URI
- * \param nb_namespaces The number of namespace definitions
- * \param namespaces Array of nb_namespaces prefix/URI pairs
- * \param nb_attributes The total number of attributes
- * \param nb_defaulted The number of defaulted attributes
- * \param attributes Array of nb_attributes attribute values
- *
- * The number of non-defaulted attributes is ::nb_attributes - ::nb_defaulted
- * The defaulted attributes are at the end of the array ::attributes.
- */
-void xml_parser_start_element_ns(void *ctx, const xmlChar *localname,
- const xmlChar *prefix, const xmlChar *URI,
- int nb_namespaces, const xmlChar **namespaces,
- int nb_attributes, int nb_defaulted,
- const xmlChar **attributes)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
- xmlNodePtr parent = parser->xml_ctx->node;
-
- /* Invoke libxml2's default behaviour */
- xmlSAX2StartElementNs(parser->xml_ctx, localname, prefix, URI,
- nb_namespaces, namespaces, nb_attributes,
- nb_defaulted, attributes);
-
- /* If there is no document, we can't do anything */
- if (parser->doc == NULL) {
- parser->msg(DOM_MSG_WARNING, parser->mctx,
- "No document in start_element_ns");
- return;
- }
-
- if (parent == NULL) {
- /* No parent; use document */
- parent = (xmlNodePtr) parser->xml_ctx->myDoc;
- }
-
- if (parent->type == XML_DOCUMENT_NODE ||
- parent->type == XML_ELEMENT_NODE) {
- /* Mirror in the DOM all children of the parent node
- * between the previous Element child (or the start,
- * whichever is encountered first) and the Element
- * just created */
- xmlNodePtr n;
-
- /* Find previous element node, if any */
- for (n = parser->xml_ctx->node->prev; n != NULL;
- n = n->prev) {
- if (n->type == XML_ELEMENT_NODE)
- break;
- }
-
- if (n == NULL) {
- /* No previous Element; use parent's children */
- n = parent->children;
- } else {
- /* Previous Element; skip over it */
- n = n->next;
- }
-
- /* Now, mirror nodes in the DOM */
- for (; n != parser->xml_ctx->node; n = n->next) {
- xml_parser_add_node(parser,
- (struct dom_node *) parent->_private,
- n);
- }
- }
-
- /* Mirror the created node and its attributes in the DOM */
- xml_parser_add_node(parser, (struct dom_node *) parent->_private,
- parser->xml_ctx->node);
-
-}
-
-/**
- * Handle an element close SAX event
- *
- * \param ctx The callback context
- * \param localname The local name of the element
- * \param prefix The element namespace prefix
- * \param URI The element namespace URI
- */
-void xml_parser_end_element_ns(void *ctx, const xmlChar *localname,
- const xmlChar *prefix, const xmlChar *URI)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
- xmlNodePtr node = parser->xml_ctx->node;
- xmlNodePtr n;
-
- /* Invoke libxml2's default behaviour */
- xmlSAX2EndElementNs(parser->xml_ctx, localname, prefix, URI);
-
- /* If there is no document, we can't do anything */
- if (parser->doc == NULL) {
- parser->msg(DOM_MSG_WARNING, parser->mctx,
- "No document in end_element_ns");
- return;
- }
-
- /* If node wasn't linked, we can't do anything */
- if (node->_private == NULL) {
- parser->msg(DOM_MSG_WARNING, parser->mctx,
- "Node '%s' not linked", node->name);
- return;
- }
-
- /* We need to mirror any child nodes at the end of the list of
- * children which occur after the last Element node in the list */
-
- /* Find last Element node, if any */
- for (n = node->last; n != NULL; n = n->prev) {
- if (n->type == XML_ELEMENT_NODE)
- break;
- }
-
- if (n == NULL) {
- /* No Element node found; entire list needs mirroring */
- n = node->children;
- } else {
- /* Found last Element; skip over it */
- n = n->next;
- }
-
- /* Now, mirror nodes in the DOM */
- for (; n != NULL; n = n->next) {
- xml_parser_add_node(parser,
- (struct dom_node *) node->_private, n);
- }
-}
-
-/**
- * Link a DOM and XML node together
- *
- * \param parser The parser context
- * \param dom The DOM node
- * \param xml The XML node
- * \return DOM_NO_ERR on success, appropriate error otherwise
- */
-dom_exception xml_parser_link_nodes(dom_xml_parser *parser,
- struct dom_node *dom, xmlNodePtr xml)
-{
- void *prev_data;
- dom_exception err;
-
- /* Register XML node as user data for DOM node */
- err = dom_node_set_user_data(dom, parser->udkey, xml, NULL,
- &prev_data);
- if (err != DOM_NO_ERR) {
- parser->msg(DOM_MSG_ERROR, parser->mctx,
- "Failed setting user data: %d", err);
- return err;
- }
-
- /* Register DOM node with the XML node */
- xml->_private = dom;
-
- return DOM_NO_ERR;
-}
-
-/**
- * Add a node to the DOM
- *
- * \param parser The parser context
- * \param parent The parent DOM node
- * \param child The xmlNode to mirror in the DOM as a child of parent
- */
-void xml_parser_add_node(dom_xml_parser *parser, struct dom_node *parent,
- xmlNodePtr child)
-{
- static const char *node_types[] = {
- "THIS_IS_NOT_A_NODE",
- "XML_ELEMENT_NODE",
- "XML_ATTRIBUTE_NODE",
- "XML_TEXT_NODE",
- "XML_CDATA_SECTION_NODE",
- "XML_ENTITY_REF_NODE",
- "XML_ENTITY_NODE",
- "XML_PI_NODE",
- "XML_COMMENT_NODE",
- "XML_DOCUMENT_NODE",
- "XML_DOCUMENT_TYPE_NODE",
- "XML_DOCUMENT_FRAG_NODE",
- "XML_NOTATION_NODE",
- "XML_HTML_DOCUMENT_NODE",
- "XML_DTD_NODE",
- "XML_ELEMENT_DECL",
- "XML_ATTRIBUTE_DECL",
- "XML_ENTITY_DECL",
- "XML_NAMESPACE_DECL",
- "XML_XINCLUDE_START",
- "XML_XINCLUDE_END",
- "XML_DOCB_DOCUMENT_NODE"
- };
-
- switch (child->type) {
- case XML_ELEMENT_NODE:
- xml_parser_add_element_node(parser, parent, child);
- break;
- case XML_TEXT_NODE:
- xml_parser_add_text_node(parser, parent, child);
- break;
- case XML_CDATA_SECTION_NODE:
- xml_parser_add_cdata_section(parser, parent, child);
- break;
- case XML_ENTITY_REF_NODE:
- xml_parser_add_entity_reference(parser, parent, child);
- break;
- case XML_COMMENT_NODE:
- xml_parser_add_comment(parser, parent, child);
- break;
- 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",
- node_types[child->type]);
- }
-}
-
-/**
- * Add an element node to the DOM
- *
- * \param parser The parser context
- * \param parent The parent DOM node
- * \param child The xmlNode to mirror in the DOM as a child of parent
- */
-void xml_parser_add_element_node(dom_xml_parser *parser,
- struct dom_node *parent, xmlNodePtr child)
-{
- struct dom_element *el, *ins_el = NULL;
- xmlAttrPtr a;
- dom_exception err;
-
- /* Create the element node */
- if (child->ns == NULL) {
- /* No namespace */
- dom_string *tag_name;
-
- /* Create tag name DOM string */
- err = dom_string_create(child->name,
- strlen((const char *) child->name), &tag_name);
- if (err != DOM_NO_ERR) {
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for tag name");
- return;
- }
-
- /* Create element node */
- err = dom_document_create_element(parser->doc,
- tag_name, &el);
- if (err != DOM_NO_ERR) {
- dom_string_unref(tag_name);
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "Failed creating element '%s'",
- child->name);
- return;
- }
-
- /* No longer need tag name */
- dom_string_unref(tag_name);
- } else {
- /* Namespace */
- dom_string *namespace;
- dom_string *qname;
- size_t qnamelen = (child->ns->prefix != NULL ?
- strlen((const char *) child->ns->prefix) : 0) +
- (child->ns->prefix != NULL ? 1 : 0) /* ':' */ +
- strlen((const char *) child->name);
- uint8_t qnamebuf[qnamelen + 1 /* '\0' */];
-
- /* Create namespace DOM string */
- err = dom_string_create(
- child->ns->href,
- strlen((const char *) child->ns->href),
- &namespace);
- if (err != DOM_NO_ERR) {
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for namespace");
- return;
- }
-
- /* QName is "prefix:localname",
- * or "localname" if there is no prefix */
- sprintf((char *) qnamebuf, "%s%s%s",
- child->ns->prefix != NULL ?
- (const char *) child->ns->prefix : "",
- child->ns->prefix != NULL ? ":" : "",
- (const char *) child->name);
-
- /* Create qname DOM string */
- err = dom_string_create(
- qnamebuf,
- qnamelen,
- &qname);
- if (err != DOM_NO_ERR) {
- dom_string_unref(namespace);
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for qname");
- return;
- }
-
- /* Create element node */
- err = dom_document_create_element_ns(parser->doc,
- namespace, qname, &el);
- if (err != DOM_NO_ERR) {
- dom_string_unref(namespace);
- dom_string_unref(qname);
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "Failed creating element '%s'",
- qnamebuf);
- return;
- }
-
- /* No longer need namespace / qname */
- dom_string_unref(namespace);
- dom_string_unref(qname);
- }
-
- /* Add attributes to created element */
- for (a = child->properties; a != NULL; a = a->next) {
- struct dom_attr *attr, *prev_attr;
- xmlNodePtr c;
-
- /* Create attribute node */
- if (a->ns == NULL) {
- /* Attribute has no namespace */
- dom_string *name;
-
- /* Create attribute name DOM string */
- err = dom_string_create(
- a->name,
- strlen((const char *) a->name),
- &name);
- if (err != DOM_NO_ERR) {
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for attribute name");
- goto cleanup;
- }
-
- /* Create attribute */
- err = dom_document_create_attribute(parser->doc,
- name, &attr);
- if (err != DOM_NO_ERR) {
- dom_string_unref(name);
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "Failed creating attribute \
- '%s'", a->name);
- goto cleanup;
- }
-
- /* No longer need attribute name */
- dom_string_unref(name);
- } else {
- /* Attribute has namespace */
- dom_string *namespace;
- dom_string *qname;
- size_t qnamelen = (a->ns->prefix != NULL ?
- strlen((const char *) a->ns->prefix) : 0) +
- (a->ns->prefix != NULL ? 1 : 0) /* ':' */ +
- strlen((const char *) a->name);
- uint8_t qnamebuf[qnamelen + 1 /* '\0' */];
-
- /* Create namespace DOM string */
- err = dom_string_create(
- a->ns->href,
- strlen((const char *) a->ns->href),
- &namespace);
- if (err != DOM_NO_ERR) {
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for namespace");
- return;
- }
-
- /* QName is "prefix:localname",
- * or "localname" if there is no prefix */
- sprintf((char *) qnamebuf, "%s%s%s",
- a->ns->prefix != NULL ?
- (const char *) a->ns->prefix : "",
- a->ns->prefix != NULL ? ":" : "",
- (const char *) a->name);
-
- /* Create qname DOM string */
- err = dom_string_create(
- qnamebuf,
- qnamelen,
- &qname);
- if (err != DOM_NO_ERR) {
- dom_string_unref(namespace);
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for qname");
- return;
- }
-
- /* Create attribute */
- err = dom_document_create_attribute_ns(parser->doc,
- namespace, qname, &attr);
- if (err != DOM_NO_ERR) {
- dom_string_unref(namespace);
- dom_string_unref(qname);
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "Failed creating attribute \
- '%s'", qnamebuf);
- return;
- }
-
- /* No longer need namespace / qname */
- dom_string_unref(namespace);
- dom_string_unref(qname);
- }
-
- /* Clone subtree (attribute value) */
- for (c = a->children; c != NULL; c = c->next) {
- xml_parser_add_node(parser,
- (struct dom_node *) attr, c);
- }
-
- /* Link nodes together */
- err = xml_parser_link_nodes(parser,
- (struct dom_node *) attr, (xmlNodePtr) a);
- if (err != DOM_NO_ERR) {
- dom_node_unref((struct dom_node *) attr);
- 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 && prev_attr != attr)
- dom_node_unref((struct dom_node *) prev_attr);
-
- /* We're no longer interested in the attribute node */
- dom_node_unref((struct dom_node *) attr);
- }
-
- /* Append element to parent */
- err = dom_node_append_child(parent, (struct dom_node *) el,
- (struct dom_node **) (void *) &ins_el);
- if (err != DOM_NO_ERR) {
- parser->msg(DOM_MSG_ERROR, parser->mctx,
- "Failed attaching element '%s'",
- child->name);
- goto cleanup;
- }
-
- /* We're not interested in the inserted element */
- if (ins_el != NULL)
- dom_node_unref((struct dom_node *) ins_el);
-
- /* Link nodes together */
- err = xml_parser_link_nodes(parser, (struct dom_node *) el,
- child);
- if (err != DOM_NO_ERR) {
- goto cleanup;
- }
-
- /* No longer interested in element node */
- dom_node_unref((struct dom_node *) el);
-
- return;
-
-cleanup:
- /* No longer want node (any attributes attached to it
- * will be cleaned up with it) */
- dom_node_unref((struct dom_node *) el);
-
- return;
-}
-
-/**
- * Add a text node to the DOM
- *
- * \param parser The parser context
- * \param parent The parent DOM node
- * \param child The xmlNode to mirror in the DOM as a child of parent
- */
-void xml_parser_add_text_node(dom_xml_parser *parser, struct dom_node *parent,
- xmlNodePtr child)
-{
- struct dom_text *text, *ins_text = NULL;
- dom_string *data;
- dom_exception err;
-
- /* Create DOM string data for text node */
- err = dom_string_create(child->content,
- strlen((const char *) child->content), &data);
- if (err != DOM_NO_ERR) {
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for text node contents ");
- return;
- }
-
- /* Create text node */
- err = dom_document_create_text_node(parser->doc, data, &text);
- if (err != DOM_NO_ERR) {
- dom_string_unref(data);
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for text node");
- return;
- }
-
- /* No longer need data */
- dom_string_unref(data);
-
- /* Append text node to parent */
- err = dom_node_append_child(parent, (struct dom_node *) text,
- (struct dom_node **) (void *) &ins_text);
- if (err != DOM_NO_ERR) {
- dom_node_unref((struct dom_node *) text);
- parser->msg(DOM_MSG_ERROR, parser->mctx,
- "Failed attaching text node");
- return;
- }
-
- /* We're not interested in the inserted text node */
- if (ins_text != NULL)
- dom_node_unref((struct dom_node *) ins_text);
-
- /* Link nodes together */
- err = xml_parser_link_nodes(parser, (struct dom_node *) text,
- child);
- if (err != DOM_NO_ERR) {
- dom_node_unref((struct dom_node *) text);
- return;
- }
-
- /* No longer interested in text node */
- dom_node_unref((struct dom_node *) text);
-}
-
-/**
- * Add a cdata section to the DOM
- *
- * \param parser The parser context
- * \param parent The parent DOM node
- * \param child The xmlNode to mirror in the DOM as a child of parent
- */
-void xml_parser_add_cdata_section(dom_xml_parser *parser,
- struct dom_node *parent, xmlNodePtr child)
-{
- struct dom_cdata_section *cdata, *ins_cdata = NULL;
- dom_string *data;
- dom_exception err;
-
- /* Create DOM string data for cdata section */
- err = dom_string_create(child->content,
- strlen((const char *) child->content), &data);
- if (err != DOM_NO_ERR) {
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for cdata section contents");
- return;
- }
-
- /* Create cdata section */
- err = dom_document_create_cdata_section(parser->doc, data, &cdata);
- if (err != DOM_NO_ERR) {
- dom_string_unref(data);
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for cdata section");
- return;
- }
-
- /* No longer need data */
- dom_string_unref(data);
-
- /* Append cdata section to parent */
- err = dom_node_append_child(parent, (struct dom_node *) cdata,
- (struct dom_node **) (void *) &ins_cdata);
- if (err != DOM_NO_ERR) {
- dom_node_unref((struct dom_node *) cdata);
- parser->msg(DOM_MSG_ERROR, parser->mctx,
- "Failed attaching cdata section");
- return;
- }
-
- /* We're not interested in the inserted cdata section */
- if (ins_cdata != NULL)
- dom_node_unref((struct dom_node *) ins_cdata);
-
- /* Link nodes together */
- err = xml_parser_link_nodes(parser, (struct dom_node *) cdata,
- child);
- if (err != DOM_NO_ERR) {
- dom_node_unref((struct dom_node *) cdata);
- return;
- }
-
- /* No longer interested in cdata section */
- dom_node_unref((struct dom_node *) cdata);
-}
-
-/**
- * Add an entity reference to the DOM
- *
- * \param parser The parser context
- * \param parent The parent DOM node
- * \param child The xmlNode to mirror in the DOM as a child of parent
- */
-void xml_parser_add_entity_reference(dom_xml_parser *parser,
- struct dom_node *parent, xmlNodePtr child)
-{
- struct dom_entity_reference *entity, *ins_entity = NULL;
- dom_string *name;
- xmlNodePtr c;
- dom_exception err;
-
- /* Create name of entity reference */
- err = dom_string_create(child->name,
- strlen((const char *) child->name), &name);
- if (err != DOM_NO_ERR) {
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for entity reference name");
- return;
- }
-
- /* Create text node */
- err = dom_document_create_entity_reference(parser->doc, name,
- &entity);
- if (err != DOM_NO_ERR) {
- dom_string_unref(name);
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for entity reference");
- return;
- }
-
- /* No longer need name */
- dom_string_unref(name);
-
- /* Mirror subtree (reference value) */
- for (c = child->children; c != NULL; c = c->next) {
- xml_parser_add_node(parser, (struct dom_node *) entity, c);
- }
-
- /* Append entity reference to parent */
- err = dom_node_append_child(parent, (struct dom_node *) entity,
- (struct dom_node **) (void *) &ins_entity);
- if (err != DOM_NO_ERR) {
- dom_node_unref((struct dom_node *) entity);
- parser->msg(DOM_MSG_ERROR, parser->mctx,
- "Failed attaching entity reference");
- return;
- }
-
- /* We're not interested in the inserted entity reference */
- if (ins_entity != NULL)
- dom_node_unref((struct dom_node *) ins_entity);
-
- /* Link nodes together */
- err = xml_parser_link_nodes(parser, (struct dom_node *) entity,
- child);
- if (err != DOM_NO_ERR) {
- dom_node_unref((struct dom_node *) entity);
- return;
- }
-
- /* No longer interested in entity reference */
- 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
- *
- * \param parser The parser context
- * \param parent The parent DOM node
- * \param child The xmlNode to mirror in the DOM as a child of parent
- */
-void xml_parser_add_comment(dom_xml_parser *parser, struct dom_node *parent,
- xmlNodePtr child)
-{
- struct dom_comment *comment, *ins_comment = NULL;
- dom_string *data;
- dom_exception err;
-
- /* Create DOM string data for comment */
- err = dom_string_create(child->content,
- strlen((const char *) child->content), &data);
- if (err != DOM_NO_ERR) {
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for comment data");
- return;
- }
-
- /* Create comment */
- err = dom_document_create_comment(parser->doc, data, &comment);
- if (err != DOM_NO_ERR) {
- dom_string_unref(data);
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "No memory for comment node");
- return;
- }
-
- /* No longer need data */
- dom_string_unref(data);
-
- /* Append comment to parent */
- err = dom_node_append_child(parent, (struct dom_node *) comment,
- (struct dom_node **) (void *) &ins_comment);
- if (err != DOM_NO_ERR) {
- dom_node_unref((struct dom_node *) comment);
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "Failed attaching comment node");
- return;
- }
-
- /* We're not interested in the inserted comment */
- if (ins_comment != NULL)
- dom_node_unref((struct dom_node *) ins_comment);
-
- /* Link nodes together */
- err = xml_parser_link_nodes(parser, (struct dom_node *) comment,
- child);
- if (err != DOM_NO_ERR) {
- dom_node_unref((struct dom_node *) comment);
- return;
- }
-
- /* No longer interested in comment */
- dom_node_unref((struct dom_node *) comment);
-}
-
-/**
- * Add a document type to the DOM
- *
- * \param parser The parser context
- * \param parent The parent DOM node
- * \param child The xmlNode to mirror in the DOM as a child of parent
- */
-void xml_parser_add_document_type(dom_xml_parser *parser,
- struct dom_node *parent, xmlNodePtr child)
-{
- xmlDtdPtr dtd = (xmlDtdPtr) child;
- struct dom_document_type *doctype, *ins_doctype = NULL;
- const char *qname, *public_id, *system_id;
- dom_exception err;
-
- /* Create qname for doctype */
- qname = (const char *) dtd->name;
-
- /* Create public ID for doctype */
- public_id = dtd->ExternalID != NULL ?
- (const char *) dtd->ExternalID : "";
-
- /* Create system ID for doctype */
- system_id = dtd->SystemID != NULL ?
- (const char *) dtd->SystemID : "";
-
- /* Create doctype */
- err = dom_implementation_create_document_type(
- qname, public_id, system_id,
- &doctype);
- if (err != DOM_NO_ERR) {
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "Failed to create document type");
- return;
- }
-
- /* Add doctype to document */
- err = dom_node_append_child(parent, (struct dom_node *) doctype,
- (struct dom_node **) (void *) &ins_doctype);
- if (err != DOM_NO_ERR) {
- dom_node_unref((struct dom_node *) doctype);
- parser->msg(DOM_MSG_CRITICAL, parser->mctx,
- "Failed attaching doctype");
- return;
- }
-
- /* Not interested in inserted node */
- if (ins_doctype != NULL)
- dom_node_unref((struct dom_node *) ins_doctype);
-
- /* Link nodes together */
- err = xml_parser_link_nodes(parser, (struct dom_node *) doctype,
- child);
- if (err != DOM_NO_ERR) {
- dom_node_unref((struct dom_node *) doctype);
- return;
- }
-
- /* No longer interested in doctype */
- dom_node_unref((struct dom_node *) doctype);
-}
-
-/* ------------------------------------------------------------------------*/
-
-void xml_parser_internal_subset(void *ctx, const xmlChar *name,
- const xmlChar *ExternalID, const xmlChar *SystemID)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- xmlSAX2InternalSubset(parser->xml_ctx, name, ExternalID, SystemID);
-}
-
-int xml_parser_is_standalone(void *ctx)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- return xmlSAX2IsStandalone(parser->xml_ctx);
-}
-
-int xml_parser_has_internal_subset(void *ctx)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- return xmlSAX2HasInternalSubset(parser->xml_ctx);
-}
-
-int xml_parser_has_external_subset(void *ctx)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- return xmlSAX2HasExternalSubset(parser->xml_ctx);
-}
-
-xmlParserInputPtr xml_parser_resolve_entity(void *ctx,
- const xmlChar *publicId, const xmlChar *systemId)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- return xmlSAX2ResolveEntity(parser->xml_ctx, publicId, systemId);
-}
-
-xmlEntityPtr xml_parser_get_entity(void *ctx, const xmlChar *name)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- return xmlSAX2GetEntity(parser->xml_ctx, name);
-}
-
-void xml_parser_entity_decl(void *ctx, const xmlChar *name,
- int type, const xmlChar *publicId, const xmlChar *systemId,
- xmlChar *content)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- xmlSAX2EntityDecl(parser->xml_ctx, name, type, publicId, systemId,
- content);
-}
-
-void xml_parser_notation_decl(void *ctx, const xmlChar *name,
- const xmlChar *publicId, const xmlChar *systemId)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- xmlSAX2NotationDecl(parser->xml_ctx, name, publicId, systemId);
-}
-
-void xml_parser_attribute_decl(void *ctx, const xmlChar *elem,
- const xmlChar *fullname, int type, int def,
- const xmlChar *defaultValue, xmlEnumerationPtr tree)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- xmlSAX2AttributeDecl(parser->xml_ctx, elem, fullname, type, def,
- defaultValue, tree);
-}
-
-void xml_parser_element_decl(void *ctx, const xmlChar *name,
- int type, xmlElementContentPtr content)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- xmlSAX2ElementDecl(parser->xml_ctx, name, type, content);
-}
-
-void xml_parser_unparsed_entity_decl(void *ctx, const xmlChar *name,
- const xmlChar *publicId, const xmlChar *systemId,
- const xmlChar *notationName)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- xmlSAX2UnparsedEntityDecl(parser->xml_ctx, name, publicId,
- systemId, notationName);
-}
-
-void xml_parser_set_document_locator(void *ctx, xmlSAXLocatorPtr loc)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- xmlSAX2SetDocumentLocator(parser->xml_ctx, loc);
-}
-
-void xml_parser_reference(void *ctx, const xmlChar *name)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- xmlSAX2Reference(parser->xml_ctx, name);
-}
-
-void xml_parser_characters(void *ctx, const xmlChar *ch, int len)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- xmlSAX2Characters(parser->xml_ctx, ch, len);
-}
-
-void xml_parser_comment(void *ctx, const xmlChar *value)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- xmlSAX2Comment(parser->xml_ctx, value);
-}
-
-xmlEntityPtr xml_parser_get_parameter_entity(void *ctx, const xmlChar *name)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- return xmlSAX2GetParameterEntity(parser->xml_ctx, name);
-}
-
-void xml_parser_cdata_block(void *ctx, const xmlChar *value, int len)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- xmlSAX2CDataBlock(parser->xml_ctx, value, len);
-}
-
-void xml_parser_external_subset(void *ctx, const xmlChar *name,
- const xmlChar *ExternalID, const xmlChar *SystemID)
-{
- dom_xml_parser *parser = (dom_xml_parser *) ctx;
-
- xmlSAX2ExternalSubset(parser->xml_ctx, name, ExternalID, SystemID);
-}