From ccfb6a1c6d7e941e871181d4bbaba3a5089810f0 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 3 Nov 2012 11:16:49 +0000 Subject: Change XML Parser API to be more sane --- bindings/xml/expat_xmlparser.c | 28 +++++------------ bindings/xml/libxml_xmlparser.c | 69 ++++++++++++++--------------------------- bindings/xml/xmlparser.h | 7 +---- 3 files changed, 32 insertions(+), 72 deletions(-) (limited to 'bindings') diff --git a/bindings/xml/expat_xmlparser.c b/bindings/xml/expat_xmlparser.c index 6b708de..a5cc143 100644 --- a/bindings/xml/expat_xmlparser.c +++ b/bindings/xml/expat_xmlparser.c @@ -26,7 +26,6 @@ struct dom_xml_parser { dom_msg msg; /**< Informational message function */ void *mctx; /**< Pointer to client data */ XML_Parser parser; /**< expat parser context */ - bool complete; /**< Indicate stream completion */ struct dom_document *doc; /**< DOM Document we're building */ struct dom_node *current; /**< DOM node we're currently building */ bool is_cdata; /**< If the character data is cdata or text */ @@ -445,7 +444,7 @@ expat_xmlparser_unknown_data_handler(void *_parser, */ dom_xml_parser * dom_xml_parser_create(const char *enc, const char *int_enc, - dom_msg msg, void *mctx) + dom_msg msg, void *mctx, dom_document **document) { dom_xml_parser *parser; dom_exception err; @@ -469,7 +468,6 @@ dom_xml_parser_create(const char *enc, const char *int_enc, return NULL; } - parser->complete = false; parser->doc = NULL; err = dom_implementation_create_document( @@ -478,7 +476,7 @@ dom_xml_parser_create(const char *enc, const char *int_enc, /* qname */ NULL, /* doctype */ NULL, NULL, - &parser->doc); + document); if (err != DOM_NO_ERR) { parser->msg(DOM_MSG_CRITICAL, parser->mctx, @@ -488,6 +486,8 @@ dom_xml_parser_create(const char *enc, const char *int_enc, return NULL; } + parser->doc = (dom_document *) dom_node_ref(*document); + XML_SetUserData(parser->parser, parser); XML_SetElementHandler(parser->parser, @@ -532,7 +532,9 @@ void dom_xml_parser_destroy(dom_xml_parser *parser) { XML_ParserFree(parser->parser); - + if (parser->current != NULL) + dom_node_unref(parser->current); + dom_node_unref(parser->doc); free(parser); } @@ -579,22 +581,6 @@ dom_xml_parser_completed(dom_xml_parser *parser) return DOM_XML_EXTERNAL_ERR | status; } - parser->complete = true; - 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); -} diff --git a/bindings/xml/libxml_xmlparser.c b/bindings/xml/libxml_xmlparser.c index ca3317e..dde598c 100644 --- a/bindings/xml/libxml_xmlparser.c +++ b/bindings/xml/libxml_xmlparser.c @@ -92,8 +92,6 @@ struct dom_xml_parser { 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 */ @@ -167,7 +165,7 @@ static void *dom_xml_alloc(void *ptr, size_t len, void *pw) * 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_msg msg, void *mctx, dom_document **document) { dom_xml_parser *parser; dom_exception err; @@ -200,10 +198,6 @@ dom_xml_parser *dom_xml_parser_create(const char *enc, const char *int_enc, 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); @@ -214,6 +208,25 @@ dom_xml_parser *dom_xml_parser_create(const char *enc, const char *int_enc, return NULL; } + err = dom_implementation_create_document( + DOM_IMPLEMENTATION_XML, + /* namespace */ NULL, + /* qname */ NULL, + /* doctype */ NULL, + NULL, + document); + + if (err != DOM_NO_ERR) { + xmlFreeParserCtxt(parser->xml_ctx); + dom_string_unref(parser->udkey); + dom_xml_alloc(parser, 0, NULL); + parser->msg(DOM_MSG_CRITICAL, parser->mctx, + "Failed creating document"); + return NULL; + } + + parser->doc = (dom_document *) dom_node_ref(*document); + parser->msg = msg; parser->mctx = mctx; @@ -228,6 +241,7 @@ dom_xml_parser *dom_xml_parser_create(const char *enc, const char *int_enc, void dom_xml_parser_destroy(dom_xml_parser *parser) { dom_string_unref(parser->udkey); + dom_node_unref(parser->doc); xmlFreeDoc(parser->xml_ctx->myDoc); @@ -278,24 +292,9 @@ dom_xml_error dom_xml_parser_completed(dom_xml_parser *parser) return DOM_XML_EXTERNAL_ERR | err; } - parser->complete = true; - 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 * @@ -304,38 +303,18 @@ struct dom_document *dom_xml_parser_get_document(dom_xml_parser *parser) 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, + err = xml_parser_link_nodes(parser, (struct dom_node *) parser->doc, (xmlNodePtr) parser->xml_ctx->myDoc); if (err != DOM_NO_ERR) { - dom_node_unref((struct dom_node *) doc); - return; + parser->msg(DOM_MSG_WARNING, parser->mctx, + "Not able to link document nodes"); } - - /* And squirrel the document away for later use */ - parser->doc = doc; } /** diff --git a/bindings/xml/xmlparser.h b/bindings/xml/xmlparser.h index 31771b5..d9bd07b 100644 --- a/bindings/xml/xmlparser.h +++ b/bindings/xml/xmlparser.h @@ -15,13 +15,11 @@ #include "xmlerror.h" -struct dom_document; - 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_msg msg, void *mctx); + dom_msg msg, void *mctx, dom_document **document); /* Destroy an XML parser instance */ void dom_xml_parser_destroy(dom_xml_parser *parser); @@ -33,7 +31,4 @@ dom_xml_error dom_xml_parser_parse_chunk(dom_xml_parser *parser, /* Notify parser that datastream is empty */ dom_xml_error dom_xml_parser_completed(dom_xml_parser *parser); -/* Retrieve the created DOM Document */ -struct dom_document *dom_xml_parser_get_document(dom_xml_parser *parser); - #endif -- cgit v1.2.3