From fbe2f40509da8c6c25d07de18ded3c0e3194ef6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sun, 15 Jul 2012 08:11:34 +0200
Subject: Hide XML parser implementations.


diff --git a/Swiften/Parser/ExpatParser.cpp b/Swiften/Parser/ExpatParser.cpp
index f3b5250..236202b 100644
--- a/Swiften/Parser/ExpatParser.cpp
+++ b/Swiften/Parser/ExpatParser.cpp
@@ -8,6 +8,7 @@
 
 #include <iostream>
 #include <string>
+#include <expat.h>
 
 #include <Swiften/Base/String.h>
 #include <Swiften/Parser/XMLParserClient.h>
@@ -16,6 +17,10 @@ namespace Swift {
 
 static const char NAMESPACE_SEPARATOR = '\x01';
 
+struct ExpatParser::Private {
+	XML_Parser parser_;
+};
+
 static void handleStartElement(void* parser, const XML_Char* name, const XML_Char** attributes) {
 	std::pair<std::string,std::string> nsTagPair = String::getSplittedAtFirst(name, NAMESPACE_SEPARATOR);
 	if (nsTagPair.second == "") {
@@ -54,29 +59,33 @@ static void handleXMLDeclaration(void*, const XML_Char*, const XML_Char*, int) {
 }
 
 static void handleEntityDeclaration(void* parser, const XML_Char*, int, const XML_Char*, int, const XML_Char*, const XML_Char*, const XML_Char*, const XML_Char*) {
-	XML_StopParser(static_cast<ExpatParser*>(parser)->getParser(), static_cast<XML_Bool>(0));
+	static_cast<ExpatParser*>(parser)->stopParser();
 }
 
 
 ExpatParser::ExpatParser(XMLParserClient* client) : XMLParser(client) {
-	parser_ = XML_ParserCreateNS("UTF-8", NAMESPACE_SEPARATOR);
-	XML_SetUserData(parser_, this);
-	XML_SetElementHandler(parser_, handleStartElement, handleEndElement);
-	XML_SetCharacterDataHandler(parser_, handleCharacterData);
-	XML_SetXmlDeclHandler(parser_, handleXMLDeclaration);
-	XML_SetEntityDeclHandler(parser_, handleEntityDeclaration);
+	p->parser_ = XML_ParserCreateNS("UTF-8", NAMESPACE_SEPARATOR);
+	XML_SetUserData(p->parser_, this);
+	XML_SetElementHandler(p->parser_, handleStartElement, handleEndElement);
+	XML_SetCharacterDataHandler(p->parser_, handleCharacterData);
+	XML_SetXmlDeclHandler(p->parser_, handleXMLDeclaration);
+	XML_SetEntityDeclHandler(p->parser_, handleEntityDeclaration);
 }
 
 ExpatParser::~ExpatParser() {
-	XML_ParserFree(parser_);
+	XML_ParserFree(p->parser_);
 }
 
 bool ExpatParser::parse(const std::string& data) {
-	bool success = XML_Parse(parser_, data.c_str(), data.size(), false) == XML_STATUS_OK;
+	bool success = XML_Parse(p->parser_, data.c_str(), data.size(), false) == XML_STATUS_OK;
 	/*if (!success) {
-		std::cout << "ERROR: " << XML_ErrorString(XML_GetErrorCode(parser_)) << " while parsing " << data << std::endl;
+		std::cout << "ERROR: " << XML_ErrorString(XML_GetErrorCode(p->parser_)) << " while parsing " << data << std::endl;
 	}*/
 	return success;
 }
 
+void ExpatParser::stopParser() {
+	XML_StopParser(p->parser_, static_cast<XML_Bool>(0));
+}
+
 }
diff --git a/Swiften/Parser/ExpatParser.h b/Swiften/Parser/ExpatParser.h
index 359f786..415f40b 100644
--- a/Swiften/Parser/ExpatParser.h
+++ b/Swiften/Parser/ExpatParser.h
@@ -6,8 +6,8 @@
 
 #pragma once
 
-#include <expat.h>
 #include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
 
 #include <Swiften/Parser/XMLParser.h>
 
@@ -19,11 +19,10 @@ namespace Swift {
 
 			bool parse(const std::string& data);
 
-			XML_Parser getParser() {
-				return parser_;
-			}
+			void stopParser();
 
 		private:
-			XML_Parser parser_;
+			class Private;
+			boost::shared_ptr<Private> p;
 	};
 }
diff --git a/Swiften/Parser/LibXMLParser.cpp b/Swiften/Parser/LibXMLParser.cpp
index 7e8a093..caba716 100644
--- a/Swiften/Parser/LibXMLParser.cpp
+++ b/Swiften/Parser/LibXMLParser.cpp
@@ -9,12 +9,18 @@
 #include <iostream>
 #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;
 	if (nbDefaulted != 0) {
@@ -53,40 +59,40 @@ 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) {
 		xmlInitParser();
 		initialized = true;
 	}
 
-	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;
-
-	context_ = xmlCreatePushParserCtxt(&handler_, this, 0, 0, 0);
-	xmlCtxtUseOptions(context_, XML_PARSE_NOENT);
-	assert(context_);
+	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;
+
+	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(), 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;
 	}
 	return false;
diff --git a/Swiften/Parser/LibXMLParser.h b/Swiften/Parser/LibXMLParser.h
index cd73637..25c0604 100644
--- a/Swiften/Parser/LibXMLParser.h
+++ b/Swiften/Parser/LibXMLParser.h
@@ -6,8 +6,8 @@
 
 #pragma once
 
-#include <libxml/parser.h>
 #include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
 
 #include <Swiften/Parser/XMLParser.h>
 
@@ -25,7 +25,8 @@ namespace Swift {
 
 		private:
 			static bool initialized;
-			xmlSAXHandler handler_;
-			xmlParserCtxtPtr context_;
+
+			class Private;
+			boost::shared_ptr<Private> p;
 	};
 }
-- 
cgit v0.10.2-6-g49f6