summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp')
-rw-r--r--Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp117
1 files changed, 117 insertions, 0 deletions
diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp b/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp
new file mode 100644
index 0000000..76925af
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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/PayloadParsers/StreamInitiationParser.h"
+
+#include <boost/lexical_cast.hpp>
+
+#include "Swiften/Parser/PayloadParsers/FormParserFactory.h"
+#include "Swiften/Parser/PayloadParsers/FormParser.h"
+#include "Swiften/Base/foreach.h"
+
+
+#define FILE_TRANSFER_NS "http://jabber.org/protocol/si/profile/file-transfer"
+#define FEATURE_NEG_NS "http://jabber.org/protocol/feature-neg"
+
+namespace Swift {
+
+StreamInitiationParser::StreamInitiationParser() : level(TopLevel), formParser(0), inFile(false), inFeature(false) {
+ formParserFactory = new FormParserFactory();
+}
+
+StreamInitiationParser::~StreamInitiationParser() {
+ delete formParserFactory;
+}
+
+void StreamInitiationParser::handleStartElement(const String& element, const String& ns, const AttributeMap& attributes) {
+ if (level == TopLevel) {
+ getPayloadInternal()->setID(attributes.getAttribute("id"));
+ if (!attributes.getAttribute("profile").isEmpty()) {
+ getPayloadInternal()->setIsFileTransfer(attributes.getAttribute("profile") == FILE_TRANSFER_NS);
+ }
+ }
+ else if (level == PayloadLevel) {
+ if (element == "file") {
+ inFile = true;
+ currentFile = StreamInitiation::FileInfo();
+ currentFile.name = attributes.getAttribute("name");
+ try {
+ currentFile.size = boost::lexical_cast<int>(attributes.getAttribute("size"));
+ }
+ catch (boost::bad_lexical_cast& e) {
+ }
+ }
+ else if (element == "feature" && ns == FEATURE_NEG_NS) {
+ inFeature = true;
+ }
+ }
+ else if (level == FileOrFeatureLevel) {
+ if (inFile && element == "desc") {
+ currentText.clear();
+ }
+ else if (inFeature && formParserFactory->canParse(element, ns, attributes)) {
+ formParser = dynamic_cast<FormParser*>(formParserFactory->createPayloadParser());
+ }
+ }
+
+ if (formParser) {
+ formParser->handleStartElement(element, ns, attributes);
+ }
+ ++level;
+}
+
+void StreamInitiationParser::handleEndElement(const String& element, const String& ns) {
+ --level;
+ if (formParser) {
+ formParser->handleEndElement(element, ns);
+ }
+ if (level == TopLevel) {
+ }
+ else if (level == PayloadLevel) {
+ if (element == "file") {
+ getPayloadInternal()->setFileInfo(currentFile);
+ inFile = false;
+ }
+ else if (element == "feature" && ns == FEATURE_NEG_NS) {
+ inFeature = false;
+ }
+ }
+ else if (level == FileOrFeatureLevel) {
+ if (inFile && element == "desc") {
+ currentFile.description = currentText;
+ }
+ else if (formParser) {
+ Form::ref form = formParser->getPayloadInternal();
+ if (form) {
+ FormField::ref field = boost::dynamic_pointer_cast<FormField>(form->getField("stream-method"));
+ if (field) {
+ if (form->getType() == Form::FormType) {
+ foreach (const FormField::Option& option, field->getOptions()) {
+ getPayloadInternal()->addProvidedMethod(option.value);
+ }
+ }
+ else if (form->getType() == Form::SubmitType) {
+ if (field->getRawValues().size() > 0) {
+ getPayloadInternal()->setRequestedMethod(field->getRawValues()[0]);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void StreamInitiationParser::handleCharacterData(const String& data) {
+ if (formParser) {
+ formParser->handleCharacterData(data);
+ }
+ else {
+ currentText += data;
+ }
+}
+
+
+}