diff options
Diffstat (limited to 'Swiften/Parser/LibXMLParser.cpp')
-rw-r--r-- | Swiften/Parser/LibXMLParser.cpp | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/Swiften/Parser/LibXMLParser.cpp b/Swiften/Parser/LibXMLParser.cpp index 1590262..e4938e1 100644 --- a/Swiften/Parser/LibXMLParser.cpp +++ b/Swiften/Parser/LibXMLParser.cpp @@ -1,4 +1,4 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. @@ -8,12 +8,19 @@ #include <iostream> +#include <boost/numeric/conversion/cast.hpp> #include <cassert> #include <cstring> - +#include <libxml/parser.h> #include <string> + #include <Swiften/Parser/XMLParserClient.h> namespace Swift { +struct LibXMLParser::Private { + xmlSAXHandler handler_; + xmlParserCtxtPtr context_; +}; + static void handleStartElement(void* parser, const xmlChar* name, const xmlChar*, const xmlChar* xmlns, int, const xmlChar**, int nbAttributes, int nbDefaulted, const xmlChar ** attributes) { AttributeMap attributeValues; @@ -27,5 +34,9 @@ static void handleStartElement(void* parser, const xmlChar* name, const xmlChar* attributeNS = std::string(reinterpret_cast<const char*>(attributes[i+2])); } - attributeValues.addAttribute(std::string(reinterpret_cast<const char*>(attributes[i])), attributeNS, std::string(reinterpret_cast<const char*>(attributes[i+3]), attributes[i+4]-attributes[i+3])); + attributeValues.addAttribute( + std::string(reinterpret_cast<const char*>(attributes[i])), + attributeNS, + std::string(reinterpret_cast<const char*>(attributes[i+3]), + boost::numeric_cast<size_t>(attributes[i+4]-attributes[i+3]))); } static_cast<XMLParser*>(parser)->getClient()->handleStartElement(reinterpret_cast<const char*>(name), (xmlns ? reinterpret_cast<const char*>(xmlns) : std::string()), attributeValues); @@ -37,5 +48,5 @@ static void handleEndElement(void *parser, const xmlChar* name, const xmlChar*, static void handleCharacterData(void* parser, const xmlChar* data, int len) { - static_cast<XMLParser*>(parser)->getClient()->handleCharacterData(std::string(reinterpret_cast<const char*>(data), len)); + static_cast<XMLParser*>(parser)->getClient()->handleCharacterData(std::string(reinterpret_cast<const char*>(data), boost::numeric_cast<size_t>(len))); } @@ -54,5 +65,5 @@ static void handleWarning(void*, const char*, ... ) { bool LibXMLParser::initialized = false; -LibXMLParser::LibXMLParser(XMLParserClient* client) : XMLParser(client) { +LibXMLParser::LibXMLParser(XMLParserClient* client) : XMLParser(client), p(new Private()) { // Initialize libXML for multithreaded applications if (!initialized) { @@ -61,30 +72,31 @@ LibXMLParser::LibXMLParser(XMLParserClient* client) : XMLParser(client) { } - memset(&handler_, 0, sizeof(handler_) ); - handler_.initialized = XML_SAX2_MAGIC; - handler_.startElementNs = &handleStartElement; - handler_.endElementNs = &handleEndElement; - handler_.characters = &handleCharacterData; - handler_.warning = &handleWarning; - handler_.error = &handleError; + memset(&p->handler_, 0, sizeof(p->handler_) ); + p->handler_.initialized = XML_SAX2_MAGIC; + p->handler_.startElementNs = &handleStartElement; + p->handler_.endElementNs = &handleEndElement; + p->handler_.characters = &handleCharacterData; + p->handler_.warning = &handleWarning; + p->handler_.error = &handleError; - context_ = xmlCreatePushParserCtxt(&handler_, this, 0, 0, 0); - assert(context_); + p->context_ = xmlCreatePushParserCtxt(&p->handler_, this, 0, 0, 0); + xmlCtxtUseOptions(p->context_, XML_PARSE_NOENT); + assert(p->context_); } LibXMLParser::~LibXMLParser() { - if (context_) { - xmlFreeParserCtxt(context_); + if (p->context_) { + xmlFreeParserCtxt(p->context_); } } bool LibXMLParser::parse(const std::string& data) { - if (xmlParseChunk(context_, data.c_str(), data.size(), false) == XML_ERR_OK) { + if (xmlParseChunk(p->context_, data.c_str(), boost::numeric_cast<int>(data.size()), false) == XML_ERR_OK) { return true; } - xmlError* error = xmlCtxtGetLastError(context_); + xmlError* error = xmlCtxtGetLastError(p->context_); if (error->code == XML_WAR_NS_URI || error->code == XML_WAR_NS_URI_RELATIVE) { - xmlCtxtResetLastError(context_); - context_->errNo = XML_ERR_OK; + xmlCtxtResetLastError(p->context_); + p->context_->errNo = XML_ERR_OK; return true; } |