From edabab9987aa7fd74f7db5dcfc77677472406180 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Thu, 9 Dec 2010 22:00:03 +0100
Subject: Added Stream error parserialement.


diff --git a/Swiften/Elements/StreamError.h b/Swiften/Elements/StreamError.h
new file mode 100644
index 0000000..a480d5a
--- /dev/null
+++ b/Swiften/Elements/StreamError.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include <Swiften/Elements/Element.h>
+#include <Swiften/Base/String.h>
+
+namespace Swift {
+	class StreamError : public Element {
+		public:
+			typedef boost::shared_ptr<StreamError> ref;
+
+			enum Type { 
+				BadFormat,
+				BadNamespacePrefix,
+				Conflict,
+				ConnectionTimeout,
+				HostGone,
+				HostUnknown,
+				ImproperAddressing,
+				InternalServerError,
+				InvalidFrom,
+				InvalidID,
+				InvalidNamespace,
+				InvalidXML,
+				NotAuthorized,
+				PolicyViolation,
+				RemoteConnectionFailed,
+				ResourceConstraint,
+				RestrictedXML,
+				SeeOtherHost,
+				SystemShutdown,
+				UndefinedCondition,
+				UnsupportedEncoding,
+				UnsupportedStanzaType,
+				UnsupportedVersion,
+				XMLNotWellFormed,
+			};
+
+			StreamError(Type type = UndefinedCondition, const String& text = String()) : type_(type), text_(text) { }
+
+			Type getType() const {
+				return type_; 
+			}
+
+			void setType(Type type) {
+				type_ = type;
+			}
+
+			void setText(const String& text) {
+				text_ = text;
+			}
+
+			const String& getText() const { 
+				return text_; 
+			}
+
+		private:
+			Type type_;
+			String text_;
+	};
+}
diff --git a/Swiften/Parser/SConscript b/Swiften/Parser/SConscript
index 29398f0..6e77109 100644
--- a/Swiften/Parser/SConscript
+++ b/Swiften/Parser/SConscript
@@ -54,6 +54,7 @@ sources = [
 		"PresenceParser.cpp",
 		"SerializingParser.cpp",
 		"StanzaParser.cpp",
+		"StreamErrorParser.cpp",
 		"StreamFeaturesParser.cpp",
 		"XMLParser.cpp",
 		"XMLParserClient.cpp",
diff --git a/Swiften/Parser/StreamErrorParser.cpp b/Swiften/Parser/StreamErrorParser.cpp
new file mode 100644
index 0000000..b121ef2
--- /dev/null
+++ b/Swiften/Parser/StreamErrorParser.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Parser/StreamErrorParser.h>
+
+namespace Swift {
+
+StreamErrorParser::StreamErrorParser() : level(TopLevel) {
+}
+
+void StreamErrorParser::handleStartElement(const String&, const String&, const AttributeMap&) {
+	++level;
+}
+
+void StreamErrorParser::handleEndElement(const String& element, const String&) {
+	--level;
+	if (level == ElementLevel) {
+		if (element == "text") {
+			getElementGeneric()->setText(currentText);
+		}
+		else if (element == "bad-format") {
+			getElementGeneric()->setType(StreamError::BadFormat);
+		}
+		else if(element == "bad-namespace-prefix") {
+			getElementGeneric()->setType(StreamError::BadNamespacePrefix);
+		}
+		else if(element == "conflict") {
+			getElementGeneric()->setType(StreamError::Conflict);
+		}
+		else if(element == "connection-timeout") {
+			getElementGeneric()->setType(StreamError::ConnectionTimeout);
+		}
+		else if(element == "host-gone") {
+			getElementGeneric()->setType(StreamError::HostGone);
+		}
+		else if(element == "host-unknown") {
+			getElementGeneric()->setType(StreamError::HostUnknown);
+		}
+		else if(element == "improper-addressing") {
+			getElementGeneric()->setType(StreamError::ImproperAddressing);
+		}
+		else if(element == "internal-server-error") {
+			getElementGeneric()->setType(StreamError::InternalServerError);
+		}
+		else if(element == "invalid-from") {
+			getElementGeneric()->setType(StreamError::InvalidFrom);
+		}
+		else if(element == "invalid-id") {
+			getElementGeneric()->setType(StreamError::InvalidID);
+		}
+		else if(element == "invalid-namespace") {
+			getElementGeneric()->setType(StreamError::InvalidNamespace);
+		}
+		else if(element == "invalid-xml") {
+			getElementGeneric()->setType(StreamError::InvalidXML);
+		}
+		else if(element == "not-authorized") {
+			getElementGeneric()->setType(StreamError::NotAuthorized);
+		}
+		else if(element == "policy-violation") {
+			getElementGeneric()->setType(StreamError::PolicyViolation);
+		}
+		else if(element == "remote-connection-failed") {
+			getElementGeneric()->setType(StreamError::RemoteConnectionFailed);
+		}
+		else if(element == "resource-constraint") {
+			getElementGeneric()->setType(StreamError::ResourceConstraint);
+		}
+		else if(element == "restricted-xml") {
+			getElementGeneric()->setType(StreamError::RestrictedXML);
+		}
+		else if(element == "see-other-host") {
+			getElementGeneric()->setType(StreamError::SeeOtherHost);
+		}
+		else if(element == "system-shutdown") {
+			getElementGeneric()->setType(StreamError::SystemShutdown);
+		}
+		else if(element == "undefined-condition") {
+			getElementGeneric()->setType(StreamError::UndefinedCondition);
+		}
+		else if(element == "unsupported-encoding") {
+			getElementGeneric()->setType(StreamError::UnsupportedEncoding);
+		}
+		else if(element == "unsupported-stanza-type") {
+			getElementGeneric()->setType(StreamError::UnsupportedStanzaType);
+		}
+		else if(element == "unsupported-version") {
+			getElementGeneric()->setType(StreamError::UnsupportedVersion);
+		}
+		else if(element == "xml-not-well-formed") {
+			getElementGeneric()->setType(StreamError::XMLNotWellFormed);
+		}
+		else {
+			getElementGeneric()->setType(StreamError::UndefinedCondition);
+		}
+	}
+}
+
+void StreamErrorParser::handleCharacterData(const String& data) {
+	currentText += data;
+}
+
+}
diff --git a/Swiften/Parser/StreamErrorParser.h b/Swiften/Parser/StreamErrorParser.h
new file mode 100644
index 0000000..a2aaa67
--- /dev/null
+++ b/Swiften/Parser/StreamErrorParser.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/StreamError.h>
+#include <Swiften/Parser/GenericElementParser.h>
+
+namespace Swift {
+	class StreamErrorParser : public GenericElementParser<StreamError> {
+		public:
+			StreamErrorParser();
+
+			virtual void handleStartElement(const String& element, const String&, const AttributeMap& attributes);
+			virtual void handleEndElement(const String& element, const String&);
+			virtual void handleCharacterData(const String& data);
+
+		private:
+			enum Level { 
+				TopLevel = 0, 
+				ElementLevel = 1
+			};
+			int level;
+			String currentText;
+	};
+}
diff --git a/Swiften/Parser/XMPPParser.cpp b/Swiften/Parser/XMPPParser.cpp
index 6bd6082..26cebe2 100644
--- a/Swiften/Parser/XMPPParser.cpp
+++ b/Swiften/Parser/XMPPParser.cpp
@@ -20,6 +20,7 @@
 #include "Swiften/Parser/IQParser.h"
 #include "Swiften/Parser/MessageParser.h"
 #include "Swiften/Parser/StreamFeaturesParser.h"
+#include "Swiften/Parser/StreamErrorParser.h"
 #include "Swiften/Parser/AuthRequestParser.h"
 #include "Swiften/Parser/AuthSuccessParser.h"
 #include "Swiften/Parser/AuthFailureParser.h"
@@ -136,6 +137,9 @@ ElementParser* XMPPParser::createElementParser(const String& element, const Stri
 	else if (element == "features"  && ns == "http://etherx.jabber.org/streams") {
 		return new StreamFeaturesParser();
 	}
+	else if (element == "error" && ns == "urn:ietf:params:xml:ns:xmpp-streams") {
+		return new StreamErrorParser();
+	}
 	else if (element == "auth") {
 		return new AuthRequestParser();
 	}
diff --git a/Swiften/SConscript b/Swiften/SConscript
index afab713..c5198a6 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -119,6 +119,7 @@ if env["SCONS_STAGE"] == "build" :
 			"Serializer/PayloadSerializers/NicknameSerializer.cpp",
 			"Serializer/PresenceSerializer.cpp",
 			"Serializer/StanzaSerializer.cpp",
+			"Serializer/StreamErrorSerializer.cpp",
 			"Serializer/StreamFeaturesSerializer.cpp",
 			"Serializer/XML/XMLElement.cpp",
 			"Serializer/XML/XMLNode.cpp",
diff --git a/Swiften/Serializer/GenericElementSerializer.h b/Swiften/Serializer/GenericElementSerializer.h
index 702e374..0329411 100644
--- a/Swiften/Serializer/GenericElementSerializer.h
+++ b/Swiften/Serializer/GenericElementSerializer.h
@@ -6,7 +6,9 @@
 
 #pragma once
 
-#include "Swiften/Serializer/ElementSerializer.h"
+#include <boost/shared_ptr.hpp>
+
+#include <Swiften/Serializer/ElementSerializer.h>
 
 namespace Swift {
 	template<typename T>
@@ -15,7 +17,7 @@ namespace Swift {
 			virtual String serialize(boost::shared_ptr<Element> element) const = 0;
 
 			virtual bool canSerialize(boost::shared_ptr<Element> element) const {
-				return dynamic_cast<T*>(element.get()) != 0;
+				return boost::dynamic_pointer_cast<T>(element);
 			}
 	};
 }
diff --git a/Swiften/Serializer/GenericPayloadSerializer.h b/Swiften/Serializer/GenericPayloadSerializer.h
index b415256..13603e5 100644
--- a/Swiften/Serializer/GenericPayloadSerializer.h
+++ b/Swiften/Serializer/GenericPayloadSerializer.h
@@ -8,8 +8,7 @@
 
 #include <boost/shared_ptr.hpp>
 
-#include "Swiften/Serializer/PayloadSerializer.h"
-#include "Swiften/Elements/Body.h"
+#include <Swiften/Serializer/PayloadSerializer.h>
 
 namespace Swift {
 	template<typename PAYLOAD_TYPE>
@@ -20,7 +19,7 @@ namespace Swift {
 			}
 
 			virtual bool canSerialize(boost::shared_ptr<Payload> element) const {
-				return dynamic_cast<PAYLOAD_TYPE*>(element.get());
+				return boost::dynamic_pointer_cast<PAYLOAD_TYPE>(element);
 			}
 
 			virtual String serializePayload(boost::shared_ptr<PAYLOAD_TYPE>) const = 0;
diff --git a/Swiften/Serializer/XMPPSerializer.cpp b/Swiften/Serializer/XMPPSerializer.cpp
index da4715c..ad84152 100644
--- a/Swiften/Serializer/XMPPSerializer.cpp
+++ b/Swiften/Serializer/XMPPSerializer.cpp
@@ -7,6 +7,7 @@
 #include "Swiften/Serializer/XMPPSerializer.h"
 
 #include <boost/bind.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
 #include <iostream>
 #include <cassert>
 
@@ -14,6 +15,7 @@
 #include "Swiften/Base/foreach.h"
 #include "Swiften/Serializer/CompressRequestSerializer.h"
 #include "Swiften/Serializer/CompressFailureSerializer.h"
+#include "Swiften/Serializer/StreamErrorSerializer.h"
 #include "Swiften/Serializer/StreamFeaturesSerializer.h"
 #include "Swiften/Serializer/AuthRequestSerializer.h"
 #include "Swiften/Serializer/AuthFailureSerializer.h"
@@ -36,26 +38,27 @@
 namespace Swift {
 
 XMPPSerializer::XMPPSerializer(PayloadSerializerCollection* payloadSerializers, StreamType type) : type_(type) {
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new PresenceSerializer(payloadSerializers)));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new IQSerializer(payloadSerializers)));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new MessageSerializer(payloadSerializers)));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new CompressRequestSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new CompressFailureSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new AuthRequestSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new AuthFailureSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new AuthSuccessSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new AuthChallengeSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new AuthResponseSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new StartTLSRequestSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new StartTLSFailureSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new TLSProceedSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new StreamFeaturesSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new EnableStreamManagementSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new StreamManagementEnabledSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new StreamManagementFailedSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new StanzaAckSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new StanzaAckRequestSerializer()));
-	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new ComponentHandshakeSerializer()));
+	serializers_.push_back(boost::make_shared<PresenceSerializer>(payloadSerializers));
+	serializers_.push_back(boost::make_shared<IQSerializer>(payloadSerializers));
+	serializers_.push_back(boost::make_shared<MessageSerializer>(payloadSerializers));
+	serializers_.push_back(boost::make_shared<CompressRequestSerializer>());
+	serializers_.push_back(boost::make_shared<CompressFailureSerializer>());
+	serializers_.push_back(boost::make_shared<AuthRequestSerializer>());
+	serializers_.push_back(boost::make_shared<AuthFailureSerializer>());
+	serializers_.push_back(boost::make_shared<AuthSuccessSerializer>());
+	serializers_.push_back(boost::make_shared<AuthChallengeSerializer>());
+	serializers_.push_back(boost::make_shared<AuthResponseSerializer>());
+	serializers_.push_back(boost::make_shared<StartTLSRequestSerializer>());
+	serializers_.push_back(boost::make_shared<StartTLSFailureSerializer>());
+	serializers_.push_back(boost::make_shared<TLSProceedSerializer>());
+	serializers_.push_back(boost::make_shared<StreamFeaturesSerializer>());
+	serializers_.push_back(boost::make_shared<StreamErrorSerializer>());
+	serializers_.push_back(boost::make_shared<EnableStreamManagementSerializer>());
+	serializers_.push_back(boost::make_shared<StreamManagementEnabledSerializer>());
+	serializers_.push_back(boost::make_shared<StreamManagementFailedSerializer>());
+	serializers_.push_back(boost::make_shared<StanzaAckSerializer>());
+	serializers_.push_back(boost::make_shared<StanzaAckRequestSerializer>());
+	serializers_.push_back(boost::make_shared<ComponentHandshakeSerializer>());
 }
 
 String XMPPSerializer::serializeHeader(const ProtocolHeader& header) const {
-- 
cgit v0.10.2-6-g49f6