diff options
Diffstat (limited to 'Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp')
-rw-r--r-- | Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp | 117 |
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; + } +} + + +} |