diff options
Diffstat (limited to 'Swiften')
1165 files changed, 23037 insertions, 5887 deletions
diff --git a/Swiften/AdHoc/OutgoingAdHocCommandSession.cpp b/Swiften/AdHoc/OutgoingAdHocCommandSession.cpp new file mode 100644 index 0000000..ecc6cd0 --- /dev/null +++ b/Swiften/AdHoc/OutgoingAdHocCommandSession.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2010-2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/AdHoc/OutgoingAdHocCommandSession.h> + +#include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Base/Algorithm.h> + +namespace Swift { +OutgoingAdHocCommandSession::OutgoingAdHocCommandSession(const JID& to, const std::string& commandNode, IQRouter* iqRouter) : to_(to), commandNode_(commandNode), iqRouter_(iqRouter), isMultiStage_(false) { + +} + +void OutgoingAdHocCommandSession::handleResponse(boost::shared_ptr<Command> payload, ErrorPayload::ref error) { + if (error) { + onError(error); + } else { + const std::vector<Command::Action>& actions = payload->getAvailableActions(); + actionStates_.clear(); + if (payload->getStatus() == Command::Executing ) { + actionStates_[Command::Cancel] = EnabledAndPresent; + actionStates_[Command::Complete] = Present; + if (std::find(actions.begin(), actions.end(), Command::Complete) != actions.end()) { + actionStates_[Command::Complete] = EnabledAndPresent; + } + + if (getIsMultiStage()) { + actionStates_[Command::Next] = Present; + actionStates_[Command::Prev] = Present; + } + + if (std::find(actions.begin(), actions.end(), Command::Next) != actions.end()) { + actionStates_[Command::Next] = EnabledAndPresent; + } + if (std::find(actions.begin(), actions.end(), Command::Prev) != actions.end()) { + actionStates_[Command::Prev] = EnabledAndPresent; + } + } + + sessionID_ = payload->getSessionID(); + if (std::find(actions.begin(), actions.end(), Command::Next) != actions.end() + || std::find(actions.begin(), actions.end(), Command::Prev) != actions.end()) { + isMultiStage_ = true; + } + onNextStageReceived(payload); + } +} + +bool OutgoingAdHocCommandSession::getIsMultiStage() const { + return isMultiStage_; +} + +void OutgoingAdHocCommandSession::start() { + boost::shared_ptr<GenericRequest<Command> > commandRequest = boost::make_shared< GenericRequest<Command> >(IQ::Set, to_, boost::make_shared<Command>(commandNode_), iqRouter_); + commandRequest->onResponse.connect(boost::bind(&OutgoingAdHocCommandSession::handleResponse, this, _1, _2)); + commandRequest->send(); +} + +void OutgoingAdHocCommandSession::cancel() { + if (!sessionID_.empty()) { + submitForm(Form::ref(), Command::Cancel); + } +} + +void OutgoingAdHocCommandSession::goBack() { + submitForm(Form::ref(), Command::Prev); +} + +void OutgoingAdHocCommandSession::complete(Form::ref form) { + submitForm(form, Command::Complete); +} + +void OutgoingAdHocCommandSession::goNext(Form::ref form) { + submitForm(form, Command::Next); +} + +void OutgoingAdHocCommandSession::submitForm(Form::ref form, Command::Action action) { + boost::shared_ptr<Command> command(boost::make_shared<Command>(commandNode_, sessionID_, action)); + command->setForm(form); + boost::shared_ptr<GenericRequest<Command> > commandRequest = boost::make_shared< GenericRequest<Command> >(IQ::Set, to_, command, iqRouter_); + commandRequest->onResponse.connect(boost::bind(&OutgoingAdHocCommandSession::handleResponse, this, _1, _2)); + commandRequest->send(); +} + +OutgoingAdHocCommandSession::ActionState OutgoingAdHocCommandSession::getActionState(Command::Action action) const { + return get(actionStates_, action, Absent); +} + +} diff --git a/Swiften/AdHoc/OutgoingAdHocCommandSession.h b/Swiften/AdHoc/OutgoingAdHocCommandSession.h new file mode 100644 index 0000000..a64eb4e --- /dev/null +++ b/Swiften/AdHoc/OutgoingAdHocCommandSession.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2010-2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> +#include <string> +#include <map> + +#include <Swiften/JID/JID.h> +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Elements/Command.h> +#include <Swiften/Elements/ErrorPayload.h> + +namespace Swift { + class IQRouter; + class MainWindow; + class UIEventStream; + + class OutgoingAdHocCommandSession { + public: + + /** + * Availability of action. + */ + enum ActionState { + Absent /** Action isn't applicable to this command. */ = 0, + Present /** Action is applicable to this command */= 1, + Enabled /** Action is applicable and currently available */ = 2, + EnabledAndPresent = 3}; + + OutgoingAdHocCommandSession(const JID& to, const std::string& commandNode, IQRouter* iqRouter); + /** + * Send initial request to the target. + */ + void start(); + /** + * Cancel command session with the target. + */ + void cancel(); + /** + * Return to the previous stage. + */ + void goBack(); + /** + * Send the form to complete the command. + * \param form Form for submission - if missing the command will be submitted with no form. + */ + void complete(Form::ref form); + /** + * Send the form to advance to the next stage of the command. + * \param form Form for submission - if missing the command will be submitted with no form. + */ + void goNext(Form::ref form); + + /** + * Is the form multi-stage? + */ + bool getIsMultiStage() const; + + /** + * Emitted when the form for the next stage is available. + */ + boost::signal<void (Command::ref)> onNextStageReceived; + + /** + * Emitted on error. + */ + boost::signal<void (ErrorPayload::ref)> onError; + + /** + * Get the state of a given action. + * This is useful for a UI to determine which buttons should be visible, + * and which enabled. + * Use for Next, Prev, Cancel and Complete only. + * If no actions are available, the command has completed. + */ + ActionState getActionState(Command::Action action) const; + + private: + void handleResponse(boost::shared_ptr<Command> payload, ErrorPayload::ref error); + void submitForm(Form::ref, Command::Action action); + + private: + JID to_; + std::string commandNode_; + IQRouter* iqRouter_; + bool isMultiStage_; + std::string sessionID_; + std::map<Command::Action, ActionState> actionStates_; + }; +} diff --git a/Swiften/AdHoc/SConscript b/Swiften/AdHoc/SConscript new file mode 100644 index 0000000..69c9083 --- /dev/null +++ b/Swiften/AdHoc/SConscript @@ -0,0 +1,6 @@ +Import("swiften_env") + +objects = swiften_env.SwiftenObject([ + "OutgoingAdHocCommandSession.cpp", + ]) +swiften_env.Append(SWIFTEN_OBJECTS = [objects]) diff --git a/Swiften/Avatars/AvatarFileStorage.cpp b/Swiften/Avatars/AvatarFileStorage.cpp deleted file mode 100644 index 4f76c80..0000000 --- a/Swiften/Avatars/AvatarFileStorage.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include <Swiften/Avatars/AvatarFileStorage.h> - -#include <iostream> -#include <boost/filesystem/fstream.hpp> - -#include <Swiften/Base/foreach.h> -#include <Swiften/Base/String.h> -#include <Swiften/StringCodecs/SHA1.h> -#include <Swiften/StringCodecs/Hexify.h> - -namespace Swift { - -AvatarFileStorage::AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile) : avatarsDir(avatarsDir), avatarsFile(avatarsFile) { - if (boost::filesystem::exists(avatarsFile)) { - try { - boost::filesystem::ifstream file(avatarsFile); - std::string line; - if (file.is_open()) { - while (!file.eof()) { - getline(file, line); - std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' '); - JID jid(r.second); - if (jid.isValid()) { - jidAvatars.insert(std::make_pair(jid, r.first)); - } - else if (!r.first.empty() || !r.second.empty()) { - std::cerr << "Invalid entry in avatars file: " << r.second << std::endl; - } - } - } - } - catch (...) { - std::cerr << "Error reading avatars file" << std::endl; - } - } -} - -bool AvatarFileStorage::hasAvatar(const std::string& hash) const { - return boost::filesystem::exists(getAvatarPath(hash)); -} - -void AvatarFileStorage::addAvatar(const std::string& hash, const ByteArray& avatar) { - assert(Hexify::hexify(SHA1::getHash(avatar)) == hash); - - boost::filesystem::path avatarPath = getAvatarPath(hash); - if (!boost::filesystem::exists(avatarPath.parent_path())) { - try { - boost::filesystem::create_directories(avatarPath.parent_path()); - } - catch (const boost::filesystem::filesystem_error& e) { - std::cerr << "ERROR: " << e.what() << std::endl; - } - } - boost::filesystem::ofstream file(avatarPath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out); - file.write(reinterpret_cast<const char*>(avatar.getData()), avatar.getSize()); - file.close(); -} - -boost::filesystem::path AvatarFileStorage::getAvatarPath(const std::string& hash) const { - return avatarsDir / hash; -} - -ByteArray AvatarFileStorage::getAvatar(const std::string& hash) const { - ByteArray data; - data.readFromFile(getAvatarPath(hash).string()); - return data; -} - -void AvatarFileStorage::setAvatarForJID(const JID& jid, const std::string& hash) { - std::pair<JIDAvatarMap::iterator, bool> r = jidAvatars.insert(std::make_pair(jid, hash)); - if (r.second) { - saveJIDAvatars(); - } - else if (r.first->second != hash) { - r.first->second = hash; - saveJIDAvatars(); - } -} - -std::string AvatarFileStorage::getAvatarForJID(const JID& jid) const { - JIDAvatarMap::const_iterator i = jidAvatars.find(jid); - return i == jidAvatars.end() ? "" : i->second; -} - -void AvatarFileStorage::saveJIDAvatars() { - try { - boost::filesystem::ofstream file(avatarsFile); - for (JIDAvatarMap::const_iterator i = jidAvatars.begin(); i != jidAvatars.end(); ++i) { - file << i->second << " " << i->first.toString() << std::endl; - } - file.close(); - } - catch (...) { - std::cerr << "Error writing avatars file" << std::endl; - } -} - -} diff --git a/Swiften/Avatars/AvatarFileStorage.h b/Swiften/Avatars/AvatarFileStorage.h deleted file mode 100644 index e736230..0000000 --- a/Swiften/Avatars/AvatarFileStorage.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 <map> -#include <string> -#include <boost/filesystem.hpp> - -#include <Swiften/JID/JID.h> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Avatars/AvatarStorage.h" - -namespace Swift { - class AvatarFileStorage : public AvatarStorage { - public: - AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile); - - virtual bool hasAvatar(const std::string& hash) const; - virtual void addAvatar(const std::string& hash, const ByteArray& avatar); - virtual ByteArray getAvatar(const std::string& hash) const; - - virtual boost::filesystem::path getAvatarPath(const std::string& hash) const; - - virtual void setAvatarForJID(const JID& jid, const std::string& hash); - virtual std::string getAvatarForJID(const JID& jid) const; - - private: - void saveJIDAvatars(); - - private: - boost::filesystem::path avatarsDir; - boost::filesystem::path avatarsFile; - typedef std::map<JID, std::string> JIDAvatarMap; - JIDAvatarMap jidAvatars; - }; - -} diff --git a/Swiften/Avatars/AvatarManager.h b/Swiften/Avatars/AvatarManager.h index e1af451..3461973 100644 --- a/Swiften/Avatars/AvatarManager.h +++ b/Swiften/Avatars/AvatarManager.h @@ -6,7 +6,7 @@ #pragma once -#include <boost/filesystem.hpp> +#include <boost/filesystem/path.hpp> #include <Swiften/Base/boost_bsignals.h> #include <Swiften/Base/ByteArray.h> diff --git a/Swiften/Avatars/AvatarManagerImpl.cpp b/Swiften/Avatars/AvatarManagerImpl.cpp index 509ff47..78d94dc 100644 --- a/Swiften/Avatars/AvatarManagerImpl.cpp +++ b/Swiften/Avatars/AvatarManagerImpl.cpp @@ -4,15 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Avatars/AvatarManagerImpl.h" +#include <Swiften/Avatars/AvatarManagerImpl.h> #include <boost/bind.hpp> -#include "Swiften/Avatars/VCardUpdateAvatarManager.h" -#include "Swiften/Avatars/VCardAvatarManager.h" -#include "Swiften/Avatars/AvatarStorage.h" +#include <Swiften/Avatars/VCardUpdateAvatarManager.h> +#include <Swiften/Avatars/VCardAvatarManager.h> +#include <Swiften/Avatars/AvatarStorage.h> #include <Swiften/Avatars/OfflineAvatarManager.h> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> namespace Swift { diff --git a/Swiften/Avatars/AvatarProvider.cpp b/Swiften/Avatars/AvatarProvider.cpp index 680b58d..44c89d5 100644 --- a/Swiften/Avatars/AvatarProvider.cpp +++ b/Swiften/Avatars/AvatarProvider.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Avatars/AvatarProvider.h" +#include <Swiften/Avatars/AvatarProvider.h> namespace Swift { diff --git a/Swiften/Avatars/AvatarProvider.h b/Swiften/Avatars/AvatarProvider.h index 0f66904..d2d408e 100644 --- a/Swiften/Avatars/AvatarProvider.h +++ b/Swiften/Avatars/AvatarProvider.h @@ -6,9 +6,10 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" #include <string> +#include <Swiften/Base/boost_bsignals.h> + namespace Swift { class JID; diff --git a/Swiften/Avatars/AvatarStorage.cpp b/Swiften/Avatars/AvatarStorage.cpp index 1bf71e1..8bb1126 100644 --- a/Swiften/Avatars/AvatarStorage.cpp +++ b/Swiften/Avatars/AvatarStorage.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Avatars/AvatarStorage.h" +#include <Swiften/Avatars/AvatarStorage.h> namespace Swift { diff --git a/Swiften/Avatars/AvatarStorage.h b/Swiften/Avatars/AvatarStorage.h index 48fc885..c33d38b 100644 --- a/Swiften/Avatars/AvatarStorage.h +++ b/Swiften/Avatars/AvatarStorage.h @@ -6,12 +6,12 @@ #pragma once -#include <boost/filesystem.hpp> +#include <boost/filesystem/path.hpp> #include <string> +#include <Swiften/Base/ByteArray.h> namespace Swift { class JID; - class ByteArray; class AvatarStorage { public: diff --git a/Swiften/Avatars/CombinedAvatarProvider.cpp b/Swiften/Avatars/CombinedAvatarProvider.cpp index eea0b89..d283664 100644 --- a/Swiften/Avatars/CombinedAvatarProvider.cpp +++ b/Swiften/Avatars/CombinedAvatarProvider.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Avatars/CombinedAvatarProvider.h" +#include <Swiften/Avatars/CombinedAvatarProvider.h> #include <algorithm> #include <boost/bind.hpp> diff --git a/Swiften/Avatars/CombinedAvatarProvider.h b/Swiften/Avatars/CombinedAvatarProvider.h index 72e67cf..7b29efc 100644 --- a/Swiften/Avatars/CombinedAvatarProvider.h +++ b/Swiften/Avatars/CombinedAvatarProvider.h @@ -9,8 +9,8 @@ #include <vector> #include <map> -#include "Swiften/Avatars/AvatarProvider.h" -#include "Swiften/JID/JID.h" +#include <Swiften/Avatars/AvatarProvider.h> +#include <Swiften/JID/JID.h> namespace Swift { class CombinedAvatarProvider : public AvatarProvider { diff --git a/Swiften/Avatars/NullAvatarManager.h b/Swiften/Avatars/NullAvatarManager.h index e96ed7a..3f5b9f5 100644 --- a/Swiften/Avatars/NullAvatarManager.h +++ b/Swiften/Avatars/NullAvatarManager.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Avatars/AvatarManager.h" +#include <Swiften/Avatars/AvatarManager.h> namespace Swift { class NullAvatarManager : public AvatarManager { diff --git a/Swiften/Avatars/SConscript b/Swiften/Avatars/SConscript index 46ae897..9c219a4 100644 --- a/Swiften/Avatars/SConscript +++ b/Swiften/Avatars/SConscript @@ -1,7 +1,6 @@ Import("swiften_env") objects = swiften_env.SwiftenObject([ - "AvatarFileStorage.cpp", "VCardUpdateAvatarManager.cpp", "VCardAvatarManager.cpp", "OfflineAvatarManager.cpp", diff --git a/Swiften/Avatars/UnitTest/CombinedAvatarProviderTest.cpp b/Swiften/Avatars/UnitTest/CombinedAvatarProviderTest.cpp index 4894e14..50b0adb 100644 --- a/Swiften/Avatars/UnitTest/CombinedAvatarProviderTest.cpp +++ b/Swiften/Avatars/UnitTest/CombinedAvatarProviderTest.cpp @@ -8,9 +8,9 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/bind.hpp> -#include "Swiften/JID/JID.h" +#include <Swiften/JID/JID.h> #include <string> -#include "Swiften/Avatars/CombinedAvatarProvider.h" +#include <Swiften/Avatars/CombinedAvatarProvider.h> using namespace Swift; @@ -47,13 +47,13 @@ class CombinedAvatarProviderTest : public CppUnit::TestFixture { } void testGetAvatarWithNoAvatarProviderReturnsEmpty() { - std::auto_ptr<CombinedAvatarProvider> testling(createProvider()); + boost::shared_ptr<CombinedAvatarProvider> testling(createProvider()); CPPUNIT_ASSERT(testling->getAvatarHash(user1).empty()); } void testGetAvatarWithSingleAvatarProvider() { - std::auto_ptr<CombinedAvatarProvider> testling(createProvider()); + boost::shared_ptr<CombinedAvatarProvider> testling(createProvider()); avatarProvider1->avatars[user1] = avatarHash1; testling->addProvider(avatarProvider1); @@ -61,7 +61,7 @@ class CombinedAvatarProviderTest : public CppUnit::TestFixture { } void testGetAvatarWithMultipleAvatarProviderReturnsFirstAvatar() { - std::auto_ptr<CombinedAvatarProvider> testling(createProvider()); + boost::shared_ptr<CombinedAvatarProvider> testling(createProvider()); avatarProvider1->avatars[user1] = avatarHash1; avatarProvider2->avatars[user1] = avatarHash2; testling->addProvider(avatarProvider1); @@ -71,7 +71,7 @@ class CombinedAvatarProviderTest : public CppUnit::TestFixture { } void testGetAvatarWithMultipleAvatarProviderAndFailingFirstProviderReturnsSecondAvatar() { - std::auto_ptr<CombinedAvatarProvider> testling(createProvider()); + boost::shared_ptr<CombinedAvatarProvider> testling(createProvider()); avatarProvider2->avatars[user1] = avatarHash2; testling->addProvider(avatarProvider1); testling->addProvider(avatarProvider2); @@ -80,7 +80,7 @@ class CombinedAvatarProviderTest : public CppUnit::TestFixture { } void testProviderUpdateTriggersChange() { - std::auto_ptr<CombinedAvatarProvider> testling(createProvider()); + boost::shared_ptr<CombinedAvatarProvider> testling(createProvider()); testling->addProvider(avatarProvider1); avatarProvider1->avatars[user1] = avatarHash1; avatarProvider1->onAvatarChanged(user1); @@ -90,7 +90,7 @@ class CombinedAvatarProviderTest : public CppUnit::TestFixture { } void testProviderUpdateWithoutChangeDoesNotTriggerChange() { - std::auto_ptr<CombinedAvatarProvider> testling(createProvider()); + boost::shared_ptr<CombinedAvatarProvider> testling(createProvider()); testling->addProvider(avatarProvider1); testling->addProvider(avatarProvider2); avatarProvider1->avatars[user1] = avatarHash1; @@ -104,7 +104,7 @@ class CombinedAvatarProviderTest : public CppUnit::TestFixture { } void testProviderSecondUpdateTriggersChange() { - std::auto_ptr<CombinedAvatarProvider> testling(createProvider()); + boost::shared_ptr<CombinedAvatarProvider> testling(createProvider()); testling->addProvider(avatarProvider1); avatarProvider1->avatars[user1] = avatarHash1; avatarProvider1->onAvatarChanged(user1); @@ -118,7 +118,7 @@ class CombinedAvatarProviderTest : public CppUnit::TestFixture { void testProviderUpdateWithAvatarDisappearingTriggersChange() { - std::auto_ptr<CombinedAvatarProvider> testling(createProvider()); + boost::shared_ptr<CombinedAvatarProvider> testling(createProvider()); testling->addProvider(avatarProvider1); avatarProvider1->avatars[user1] = avatarHash1; avatarProvider1->onAvatarChanged(user1); @@ -131,7 +131,7 @@ class CombinedAvatarProviderTest : public CppUnit::TestFixture { } void testProviderUpdateAfterAvatarDisappearedTriggersChange() { - std::auto_ptr<CombinedAvatarProvider> testling(createProvider()); + boost::shared_ptr<CombinedAvatarProvider> testling(createProvider()); testling->addProvider(avatarProvider1); avatarProvider1->avatars[user1] = avatarHash1; avatarProvider1->onAvatarChanged(user1); @@ -147,7 +147,7 @@ class CombinedAvatarProviderTest : public CppUnit::TestFixture { void testProviderUpdateAfterGetDoesNotTriggerChange() { - std::auto_ptr<CombinedAvatarProvider> testling(createProvider()); + boost::shared_ptr<CombinedAvatarProvider> testling(createProvider()); testling->addProvider(avatarProvider1); avatarProvider1->avatars[user1] = avatarHash1; @@ -158,7 +158,7 @@ class CombinedAvatarProviderTest : public CppUnit::TestFixture { } void testRemoveProviderDisconnectsUpdates() { - std::auto_ptr<CombinedAvatarProvider> testling(createProvider()); + boost::shared_ptr<CombinedAvatarProvider> testling(createProvider()); testling->addProvider(avatarProvider1); testling->addProvider(avatarProvider2); testling->removeProvider(avatarProvider1); @@ -170,7 +170,7 @@ class CombinedAvatarProviderTest : public CppUnit::TestFixture { } void testProviderUpdateBareJIDAfterGetFullJID() { - std::auto_ptr<CombinedAvatarProvider> testling(createProvider()); + boost::shared_ptr<CombinedAvatarProvider> testling(createProvider()); avatarProvider1->useBare = true; testling->addProvider(avatarProvider1); @@ -183,8 +183,8 @@ class CombinedAvatarProviderTest : public CppUnit::TestFixture { } private: - std::auto_ptr<CombinedAvatarProvider> createProvider() { - std::auto_ptr<CombinedAvatarProvider> result(new CombinedAvatarProvider()); + boost::shared_ptr<CombinedAvatarProvider> createProvider() { + boost::shared_ptr<CombinedAvatarProvider> result(new CombinedAvatarProvider()); result->onAvatarChanged.connect(boost::bind(&CombinedAvatarProviderTest::handleAvatarChanged, this, _1)); return result; } diff --git a/Swiften/Avatars/UnitTest/VCardAvatarManagerTest.cpp b/Swiften/Avatars/UnitTest/VCardAvatarManagerTest.cpp index 7db9c95..81dc12c 100644 --- a/Swiften/Avatars/UnitTest/VCardAvatarManagerTest.cpp +++ b/Swiften/Avatars/UnitTest/VCardAvatarManagerTest.cpp @@ -4,22 +4,23 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/bind.hpp> -#include "Swiften/Elements/VCard.h" -#include "Swiften/Avatars/VCardAvatarManager.h" -#include "Swiften/Avatars/AvatarMemoryStorage.h" -#include "Swiften/VCards/VCardManager.h" -#include "Swiften/VCards/VCardStorage.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Client/DummyStanzaChannel.h" -#include "Swiften/StringCodecs/SHA1.h" -#include "Swiften/StringCodecs/Hexify.h" +#include <Swiften/Elements/VCard.h> +#include <Swiften/Avatars/VCardAvatarManager.h> +#include <Swiften/Avatars/AvatarMemoryStorage.h> +#include <Swiften/VCards/VCardManager.h> +#include <Swiften/VCards/VCardStorage.h> +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/StringCodecs/Hexify.h> using namespace Swift; @@ -55,7 +56,7 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture { return photoHashes.find(jid)->second; } VCard::ref vCard = getVCard(jid); - if (vCard && !vCard->getPhoto().isEmpty()) { + if (vCard && !vCard->getPhoto().empty()) { return Hexify::hexify(SHA1::getHash(vCard->getPhoto())); } else { @@ -79,7 +80,7 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture { avatarStorage = new AvatarMemoryStorage(); vcardStorage = new TestVCardStorage(); vcardManager = new VCardManager(ownJID, iqRouter, vcardStorage); - avatar1 = ByteArray("abcdefg"); + avatar1 = createByteArray("abcdefg"); avatar1Hash = Hexify::hexify(SHA1::getHash(avatar1)); user1 = JID("user1@bar.com/bla"); user2 = JID("user2@foo.com/baz"); @@ -95,7 +96,7 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture { } void testGetAvatarHashKnownAvatar() { - std::auto_ptr<VCardAvatarManager> testling = createManager(); + boost::shared_ptr<VCardAvatarManager> testling = createManager(); storeVCardWithPhoto(user1.toBare(), avatar1); avatarStorage->addAvatar(avatar1Hash, avatar1); @@ -105,7 +106,7 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture { } void testGetAvatarHashEmptyAvatar() { - std::auto_ptr<VCardAvatarManager> testling = createManager(); + boost::shared_ptr<VCardAvatarManager> testling = createManager(); storeEmptyVCard(user1.toBare()); std::string result = testling->getAvatarHash(user1); @@ -114,7 +115,7 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture { } void testGetAvatarHashUnknownAvatarKnownVCardStoresAvatar() { - std::auto_ptr<VCardAvatarManager> testling = createManager(); + boost::shared_ptr<VCardAvatarManager> testling = createManager(); storeVCardWithPhoto(user1.toBare(), avatar1); std::string result = testling->getAvatarHash(user1); @@ -125,7 +126,7 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture { } void testGetAvatarHashUnknownAvatarUnknownVCard() { - std::auto_ptr<VCardAvatarManager> testling = createManager(); + boost::shared_ptr<VCardAvatarManager> testling = createManager(); std::string result = testling->getAvatarHash(user1); @@ -133,7 +134,7 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture { } void testGetAvatarHashKnownAvatarUnknownVCard() { - std::auto_ptr<VCardAvatarManager> testling = createManager(); + boost::shared_ptr<VCardAvatarManager> testling = createManager(); vcardStorage->photoHashes[user1.toBare()] = avatar1Hash; std::string result = testling->getAvatarHash(user1); @@ -143,7 +144,7 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture { void testVCardUpdateTriggersUpdate() { - std::auto_ptr<VCardAvatarManager> testling = createManager(); + boost::shared_ptr<VCardAvatarManager> testling = createManager(); vcardManager->requestVCard(user1); sendVCardResult(); @@ -151,8 +152,8 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture { } private: - std::auto_ptr<VCardAvatarManager> createManager() { - std::auto_ptr<VCardAvatarManager> result(new VCardAvatarManager(vcardManager, avatarStorage, mucRegistry)); + boost::shared_ptr<VCardAvatarManager> createManager() { + boost::shared_ptr<VCardAvatarManager> result(new VCardAvatarManager(vcardManager, avatarStorage, mucRegistry)); result->onAvatarChanged.connect(boost::bind(&VCardAvatarManagerTest::handleAvatarChanged, this, _1)); return result; } diff --git a/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp b/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp index 1fb30f3..821412b 100644 --- a/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp +++ b/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp @@ -4,22 +4,23 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/bind.hpp> -#include "Swiften/Elements/VCardUpdate.h" -#include "Swiften/Avatars/VCardUpdateAvatarManager.h" -#include "Swiften/Avatars/AvatarMemoryStorage.h" -#include "Swiften/VCards/VCardMemoryStorage.h" -#include "Swiften/VCards/VCardManager.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Client/DummyStanzaChannel.h" -#include "Swiften/StringCodecs/SHA1.h" -#include "Swiften/StringCodecs/Hexify.h" +#include <Swiften/Elements/VCardUpdate.h> +#include <Swiften/Avatars/VCardUpdateAvatarManager.h> +#include <Swiften/Avatars/AvatarMemoryStorage.h> +#include <Swiften/VCards/VCardMemoryStorage.h> +#include <Swiften/VCards/VCardManager.h> +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/StringCodecs/Hexify.h> using namespace Swift; @@ -44,7 +45,7 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture { avatarStorage = new AvatarMemoryStorage(); vcardStorage = new VCardMemoryStorage(); vcardManager = new VCardManager(ownJID, iqRouter, vcardStorage); - avatar1 = ByteArray("abcdefg"); + avatar1 = createByteArray("abcdefg"); avatar1Hash = Hexify::hexify(SHA1::getHash(avatar1)); user1 = JID("user1@bar.com/bla"); user2 = JID("user2@foo.com/baz"); @@ -60,7 +61,7 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture { } void testUpdate_NewHashNewVCardRequestsVCard() { - std::auto_ptr<VCardUpdateAvatarManager> testling = createManager(); + boost::shared_ptr<VCardUpdateAvatarManager> testling = createManager(); stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(stanzaChannel->sentStanzas.size())); @@ -68,7 +69,7 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture { } void testUpdate_NewHashStoresAvatarAndEmitsNotificationOnVCardReceive() { - std::auto_ptr<VCardUpdateAvatarManager> testling = createManager(); + boost::shared_ptr<VCardUpdateAvatarManager> testling = createManager(); stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); stanzaChannel->onIQReceived(createVCardResult(avatar1)); @@ -80,7 +81,7 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture { } void testUpdate_KnownHash() { - std::auto_ptr<VCardUpdateAvatarManager> testling = createManager(); + boost::shared_ptr<VCardUpdateAvatarManager> testling = createManager(); stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); stanzaChannel->onIQReceived(createVCardResult(avatar1)); changes.clear(); @@ -93,7 +94,7 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture { } void testUpdate_KnownHashFromDifferentUserDoesNotRequestVCardButTriggersNotification() { - std::auto_ptr<VCardUpdateAvatarManager> testling = createManager(); + boost::shared_ptr<VCardUpdateAvatarManager> testling = createManager(); stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); stanzaChannel->onIQReceived(createVCardResult(avatar1)); changes.clear(); @@ -108,7 +109,7 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture { } void testVCardWithEmptyPhoto() { - std::auto_ptr<VCardUpdateAvatarManager> testling = createManager(); + boost::shared_ptr<VCardUpdateAvatarManager> testling = createManager(); vcardManager->requestVCard(JID("foo@bar.com")); stanzaChannel->onIQReceived(createVCardResult(ByteArray())); @@ -117,7 +118,7 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture { } void testStanzaChannelReset_ClearsHash() { - std::auto_ptr<VCardUpdateAvatarManager> testling = createManager(); + boost::shared_ptr<VCardUpdateAvatarManager> testling = createManager(); stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); stanzaChannel->onIQReceived(createVCardResult(avatar1)); changes.clear(); @@ -132,7 +133,7 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture { } void testStanzaChannelReset_ReceiveHashAfterResetUpdatesHash() { - std::auto_ptr<VCardUpdateAvatarManager> testling = createManager(); + boost::shared_ptr<VCardUpdateAvatarManager> testling = createManager(); stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); stanzaChannel->onIQReceived(createVCardResult(avatar1)); changes.clear(); @@ -148,8 +149,8 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture { } private: - std::auto_ptr<VCardUpdateAvatarManager> createManager() { - std::auto_ptr<VCardUpdateAvatarManager> result(new VCardUpdateAvatarManager(vcardManager, stanzaChannel, avatarStorage, mucRegistry)); + boost::shared_ptr<VCardUpdateAvatarManager> createManager() { + boost::shared_ptr<VCardUpdateAvatarManager> result(new VCardUpdateAvatarManager(vcardManager, stanzaChannel, avatarStorage, mucRegistry)); result->onAvatarChanged.connect(boost::bind(&VCardUpdateAvatarManagerTest::handleAvatarChanged, this, _1)); return result; } @@ -163,7 +164,7 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture { IQ::ref createVCardResult(const ByteArray& avatar) { VCard::ref vcard(new VCard()); - if (!avatar.isEmpty()) { + if (!avatar.empty()) { vcard->setPhoto(avatar); } return IQ::createResult(JID("baz@fum.com"), stanzaChannel->sentStanzas[0]->getTo(), stanzaChannel->sentStanzas[0]->getID(), vcard); diff --git a/Swiften/Avatars/VCardAvatarManager.cpp b/Swiften/Avatars/VCardAvatarManager.cpp index a7e6fea..c9571c3 100644 --- a/Swiften/Avatars/VCardAvatarManager.cpp +++ b/Swiften/Avatars/VCardAvatarManager.cpp @@ -4,16 +4,16 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Avatars/VCardAvatarManager.h" +#include <Swiften/Avatars/VCardAvatarManager.h> #include <boost/bind.hpp> -#include "Swiften/Elements/VCard.h" -#include "Swiften/StringCodecs/SHA1.h" -#include "Swiften/StringCodecs/Hexify.h" -#include "Swiften/Avatars/AvatarStorage.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/VCards/VCardManager.h" +#include <Swiften/Elements/VCard.h> +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/Avatars/AvatarStorage.h> +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/VCards/VCardManager.h> namespace Swift { diff --git a/Swiften/Avatars/VCardAvatarManager.h b/Swiften/Avatars/VCardAvatarManager.h index 3f99dad..cb3945d 100644 --- a/Swiften/Avatars/VCardAvatarManager.h +++ b/Swiften/Avatars/VCardAvatarManager.h @@ -6,11 +6,8 @@ #pragma once -#include <map> - -#include "Swiften/Avatars/AvatarProvider.h" -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/VCard.h" +#include <Swiften/Avatars/AvatarProvider.h> +#include <Swiften/JID/JID.h> namespace Swift { class MUCRegistry; diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.cpp b/Swiften/Avatars/VCardUpdateAvatarManager.cpp index ea074cc..0c3ad23 100644 --- a/Swiften/Avatars/VCardUpdateAvatarManager.cpp +++ b/Swiften/Avatars/VCardUpdateAvatarManager.cpp @@ -4,18 +4,18 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Avatars/VCardUpdateAvatarManager.h" +#include <Swiften/Avatars/VCardUpdateAvatarManager.h> #include <boost/bind.hpp> -#include "Swiften/Client/StanzaChannel.h" -#include "Swiften/Elements/VCardUpdate.h" -#include "Swiften/VCards/GetVCardRequest.h" -#include "Swiften/StringCodecs/SHA1.h" -#include "Swiften/StringCodecs/Hexify.h" -#include "Swiften/Avatars/AvatarStorage.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/VCards/VCardManager.h" +#include <Swiften/Client/StanzaChannel.h> +#include <Swiften/Elements/VCardUpdate.h> +#include <Swiften/VCards/GetVCardRequest.h> +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/Avatars/AvatarStorage.h> +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/VCards/VCardManager.h> #include <Swiften/Base/Log.h> namespace Swift { @@ -50,7 +50,7 @@ void VCardUpdateAvatarManager::handleVCardChanged(const JID& from, VCard::ref vC return; } - if (vCard->getPhoto().isEmpty()) { + if (vCard->getPhoto().empty()) { setAvatarHash(from, ""); } else { diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.h b/Swiften/Avatars/VCardUpdateAvatarManager.h index 1f03898..de68672 100644 --- a/Swiften/Avatars/VCardUpdateAvatarManager.h +++ b/Swiften/Avatars/VCardUpdateAvatarManager.h @@ -9,11 +9,11 @@ #include <boost/shared_ptr.hpp> #include <map> -#include "Swiften/Avatars/AvatarProvider.h" -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/VCard.h" -#include "Swiften/Elements/ErrorPayload.h" +#include <Swiften/Avatars/AvatarProvider.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Elements/VCard.h> +#include <Swiften/Elements/ErrorPayload.h> namespace Swift { class MUCRegistry; diff --git a/Swiften/Base/Algorithm.h b/Swiften/Base/Algorithm.h new file mode 100644 index 0000000..4e68e70 --- /dev/null +++ b/Swiften/Base/Algorithm.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> +#include <list> +#include <map> +#include <algorithm> + +namespace Swift { + + /* + * Generic erase() + */ + namespace Detail { + struct VectorCategory {}; + struct ListCategory {}; + struct MapCategory {}; + + template<typename T> + struct ContainerTraits; + + template<typename A, typename B> + struct ContainerTraits< std::vector<A, B> > { + typedef VectorCategory Category; + }; + + template<> + struct ContainerTraits< std::string > { + typedef VectorCategory Category; + }; + + template<typename A, typename B> + struct ContainerTraits< std::list<A, B> > { + typedef ListCategory Category; + }; + + template<typename A, typename B, typename C, typename D> + struct ContainerTraits< std::map<A, B, C, D> > { + typedef MapCategory Category; + }; + + template<typename C, typename V> + void eraseImpl(C& c, const V& v, VectorCategory) { + c.erase(std::remove(c.begin(), c.end(), v), c.end()); + } + + template<typename C, typename V> + void eraseImpl(C& c, const V& v, ListCategory) { + c.remove(v); + } + + template<typename C, typename V> + void eraseImpl(C& c, const V& v, MapCategory) { + for (typename C::iterator it = c.begin(); it != c.end(); ) { + if (it->second == v) { + c.erase(it++); + } + else { + ++it; + } + } + } + + template<typename C, typename P> + void eraseIfImpl(C& c, const P& p, MapCategory) { + for (typename C::iterator it = c.begin(); it != c.end(); ) { + if (p(*it)) { + c.erase(it++); + } + else { + ++it; + } + } + } + + template<typename C, typename P> + void eraseIfImpl(C& c, const P& p, VectorCategory) { + c.erase(std::remove_if(c.begin(), c.end(), p), c.end()); + } + } + + template<typename C, typename V> + void erase(C& container, const V& value) { + Detail::eraseImpl(container, value, typename Detail::ContainerTraits<C>::Category()); + } + + template<typename C, typename P> + void eraseIf(C& container, const P& predicate) { + Detail::eraseIfImpl(container, predicate, typename Detail::ContainerTraits<C>::Category()); + } + + template<typename Source, typename Target> + void append(Target& target, const Source& source) { + target.insert(target.end(), source.begin(), source.end()); + } + + template<typename A, typename B, typename C, typename D> + B get(const std::map<A, B, C, D>& map, const A& key, const B& defaultValue) { + typename std::map<A, B, C, D>::const_iterator i = map.find(key); + if (i != map.end()) { + return i->second; + } + else { + return defaultValue; + } + } + + template<typename Container> + void safeClear(Container& c) { + std::fill(c.begin(), c.end(), 0); + c.clear(); + } + + /* + * Functors + */ + template<typename K, typename V> + class PairFirstEquals { + public: + PairFirstEquals(const K& value) : value(value) { + } + + bool operator()(const std::pair<K,V>& pair) const { + return pair.first == value; + } + + private: + K value; + }; + + template<typename K, typename V> + class PairSecondEquals { + public: + PairSecondEquals(const V& value) : value(value) { + } + + bool operator()(const std::pair<K,V>& pair) const { + return pair.second == value; + } + + private: + V value; + }; +} diff --git a/Swiften/Base/ByteArray.cpp b/Swiften/Base/ByteArray.cpp index 928e145..6be96aa 100644 --- a/Swiften/Base/ByteArray.cpp +++ b/Swiften/Base/ByteArray.cpp @@ -4,37 +4,46 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> #include <fstream> -std::ostream& operator<<(std::ostream& os, const Swift::ByteArray& s) { - std::ios::fmtflags oldFlags = os.flags(); - os << std::hex; - for (Swift::ByteArray::const_iterator i = s.begin(); i != s.end(); ++i) { - os << "0x" << static_cast<unsigned int>(static_cast<unsigned char>(*i)); - if (i + 1 < s.end()) { - os << " "; - } - } - os << std::endl; - os.flags(oldFlags); - return os; -} - namespace Swift { static const int BUFFER_SIZE = 4096; -void ByteArray::readFromFile(const std::string& file) { +void readByteArrayFromFile(ByteArray& data, const std::string& file) { std::ifstream input(file.c_str(), std::ios_base::in|std::ios_base::binary); while (input.good()) { - size_t oldSize = data_.size(); - data_.resize(oldSize + BUFFER_SIZE); - input.read(reinterpret_cast<char*>(&data_[oldSize]), BUFFER_SIZE); - data_.resize(oldSize + input.gcount()); + size_t oldSize = data.size(); + data.resize(oldSize + BUFFER_SIZE); + input.read(reinterpret_cast<char*>(&data[oldSize]), BUFFER_SIZE); + data.resize(oldSize + input.gcount()); } input.close(); } +std::vector<unsigned char> createByteArray(const std::string& s) { + return std::vector<unsigned char>(s.begin(), s.end()); +} + +std::vector<unsigned char> createByteArray(const char* c) { + std::vector<unsigned char> data; + while (*c) { + data.push_back(static_cast<unsigned char>(*c)); + ++c; + } + return data; +} + +std::string byteArrayToString(const ByteArray& b) { + size_t i; + for (i = b.size(); i > 0; --i) { + if (b[i - 1] != 0) { + break; + } + } + return i > 0 ? std::string(reinterpret_cast<const char*>(vecptr(b)), i) : ""; +} + } diff --git a/Swiften/Base/ByteArray.h b/Swiften/Base/ByteArray.h index ad2c1e5..b368ef8 100644 --- a/Swiften/Base/ByteArray.h +++ b/Swiften/Base/ByteArray.h @@ -6,135 +6,39 @@ #pragma once -#include <cstring> #include <vector> -#include <iostream> - #include <string> namespace Swift { - class ByteArray - { - public: - typedef std::vector<unsigned char>::const_iterator const_iterator; - - ByteArray() : data_() {} - - ByteArray(const std::string& s) : data_(s.begin(), s.end()) {} - - ByteArray(const char* c) { - while (*c) { - data_.push_back(*c); - ++c; - } - } - - ByteArray(const char* c, size_t n) { - if (n > 0) { - data_.resize(n); - memcpy(&data_[0], c, n); - } - } - - ByteArray(const unsigned char* c, size_t n) { - if (n > 0) { - data_.resize(n); - memcpy(&data_[0], c, n); - } - } - - ByteArray(const std::vector<unsigned char>& data) : data_(data) { - } - - const unsigned char* getData() const { - return data_.empty() ? NULL : &data_[0]; - } - - unsigned char* getData() { - return data_.empty() ? NULL : &data_[0]; - } - - const std::vector<unsigned char>& getVector() const { - return data_; - } - - std::vector<unsigned char>& getVector() { - return data_; - } - - size_t getSize() const { - return data_.size(); - } - - bool isEmpty() const { - return data_.empty(); - } - - void resize(size_t size) { - return data_.resize(size); - } - - void resize(size_t size, char c) { - return data_.resize(size, c); - } - - friend ByteArray operator+(const ByteArray& a, const ByteArray&b) { - ByteArray result(a); - result.data_.insert(result.data_.end(), b.data_.begin(), b.data_.end()); - return result; - } - - friend ByteArray operator+(const ByteArray& a, char b) { - ByteArray x; - x.resize(1); - x[0] = b; - return a + x; - } - - ByteArray& operator+=(const ByteArray& b) { - data_.insert(data_.end(), b.data_.begin(), b.data_.end()); - return *this; - } - - ByteArray& operator+=(char c) { - data_.push_back(c); - return *this; - } - - friend bool operator==(const ByteArray& a, const ByteArray& b) { - return a.data_ == b.data_; - } + typedef std::vector<unsigned char> ByteArray; + ByteArray createByteArray(const std::string& s); + ByteArray createByteArray(const char* c); - const unsigned char& operator[](size_t i) const { - return data_[i]; - } + inline ByteArray createByteArray(const unsigned char* c, size_t n) { + return ByteArray(c, c + n); + } - unsigned char& operator[](size_t i) { - return data_[i]; - } + inline ByteArray createByteArray(const char* c, size_t n) { + return ByteArray(c, c + n); + } - const_iterator begin() const { - return data_.begin(); - } - - const_iterator end() const { - return data_.end(); - } + inline ByteArray createByteArray(char c) { + return std::vector<unsigned char>(1, c); + } - std::string toString() const { - return std::string(reinterpret_cast<const char*>(getData()), getSize()); - } + template<typename T, typename A> + static const T* vecptr(const std::vector<T, A>& v) { + return v.empty() ? NULL : &v[0]; + } - void readFromFile(const std::string& file); + template<typename T, typename A> + static T* vecptr(std::vector<T, A>& v) { + return v.empty() ? NULL : &v[0]; + } - void clear() { - data_.clear(); - } + std::string byteArrayToString(const ByteArray& b); - private: - std::vector<unsigned char> data_; - }; + void readByteArrayFromFile(ByteArray&, const std::string& file); } -std::ostream& operator<<(std::ostream& os, const Swift::ByteArray& s); diff --git a/Swiften/Base/Concat.h b/Swiften/Base/Concat.h new file mode 100644 index 0000000..83a43b6 --- /dev/null +++ b/Swiften/Base/Concat.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +namespace Swift { + template<typename C> + C concat(const C& c1, const C& c2) { + C result; + result.resize(c1.size() + c2.size()); + std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin())); + return result; + } + + template<typename C> + C concat(const C& c1, const C& c2, const C& c3) { + C result; + result.resize(c1.size() + c2.size() + c3.size()); + std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin()))); + return result; + } + + template<typename C> + C concat(const C& c1, const C& c2, const C& c3, const C& c4) { + C result; + result.resize(c1.size() + c2.size() + c3.size() + c4.size()); + std::copy(c4.begin(), c4.end(), std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin())))); + return result; + } + + template<typename C> + C concat(const C& c1, const C& c2, const C& c3, const C& c4, const C& c5) { + C result; + result.resize(c1.size() + c2.size() + c3.size() + c4.size() + c5.size()); + std::copy(c5.begin(), c5.end(), std::copy(c4.begin(), c4.end(), std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin()))))); + return result; + } + + template<typename C> + C concat(const C& c1, const C& c2, const C& c3, const C& c4, const C& c5, const C& c6) { + C result; + result.resize(c1.size() + c2.size() + c3.size() + c4.size() + c5.size() + c6.size()); + std::copy(c6.begin(), c6.end(), std::copy(c5.begin(), c5.end(), std::copy(c4.begin(), c4.end(), std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin())))))); + return result; + } + + template<typename C> + C concat(const C& c1, const C& c2, const C& c3, const C& c4, const C& c5, const C& c6, const C& c7) { + C result; + result.resize(c1.size() + c2.size() + c3.size() + c4.size() + c5.size() + c6.size() + c7.size()); + std::copy(c7.begin(), c7.end(), std::copy(c6.begin(), c6.end(), std::copy(c5.begin(), c5.end(), std::copy(c4.begin(), c4.end(), std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin()))))))); + return result; + } + + template<typename C> + C concat(const C& c1, const C& c2, const C& c3, const C& c4, const C& c5, const C& c6, const C& c7, const C& c8) { + C result; + result.resize(c1.size() + c2.size() + c3.size() + c4.size() + c5.size() + c6.size() + c7.size() + c8.size()); + std::copy(c8.begin(), c8.end(), std::copy(c7.begin(), c7.end(), std::copy(c6.begin(), c6.end(), std::copy(c5.begin(), c5.end(), std::copy(c4.begin(), c4.end(), std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin())))))))); + return result; + } + + template<typename C> + C concat(const C& c1, const C& c2, const C& c3, const C& c4, const C& c5, const C& c6, const C& c7, const C& c8, const C& c9) { + C result; + result.resize(c1.size() + c2.size() + c3.size() + c4.size() + c5.size() + c6.size() + c7.size() + c8.size() + c9.size()); + std::copy(c9.begin(), c9.end(), std::copy(c8.begin(), c8.end(), std::copy(c7.begin(), c7.end(), std::copy(c6.begin(), c6.end(), std::copy(c5.begin(), c5.end(), std::copy(c4.begin(), c4.end(), std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin()))))))))); + return result; + } +} diff --git a/Swiften/Base/DateTime.cpp b/Swiften/Base/DateTime.cpp new file mode 100644 index 0000000..fae26d4 --- /dev/null +++ b/Swiften/Base/DateTime.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Base/DateTime.h> + +#include <locale> +#include <boost/date_time/time_facet.hpp> +#include <boost/date_time/local_time/local_time.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> + +#include <Swiften/Base/String.h> + +namespace Swift { + +boost::posix_time::ptime stringToDateTime(const std::string& string) { + static std::locale locale(std::locale::classic(), new boost::local_time::local_time_input_facet("%Y-%m-%d %H:%M:%S%F%ZP")); + std::istringstream stream(string); + stream.imbue(locale); + boost::local_time::local_date_time result(boost::date_time::not_a_date_time); + stream >> result; + return result.utc_time(); +} + +std::string dateTimeToString(const boost::posix_time::ptime& time) { + std::string stampString = std::string(boost::posix_time::to_iso_extended_string(time)); + String::replaceAll(stampString, ',', "."); + stampString += "Z"; + return stampString; +} + +} diff --git a/Swiften/Base/DateTime.h b/Swiften/Base/DateTime.h new file mode 100644 index 0000000..2407ddc --- /dev/null +++ b/Swiften/Base/DateTime.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/date_time/posix_time/ptime.hpp> + +namespace Swift { + /** + * Converts a date formatted according to XEP-0082 into a ptime + * object (in UTC). + */ + boost::posix_time::ptime stringToDateTime(const std::string& string); + + /** + * Converts a UTC ptime object to a XEP-0082 formatted string. + */ + std::string dateTimeToString(const boost::posix_time::ptime& time); +} diff --git a/Swiften/Base/Error.cpp b/Swiften/Base/Error.cpp index dd127a6..60ad7ac 100644 --- a/Swiften/Base/Error.cpp +++ b/Swiften/Base/Error.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/Error.h" +#include <Swiften/Base/Error.h> namespace Swift { diff --git a/Swiften/Base/IDGenerator.cpp b/Swiften/Base/IDGenerator.cpp index 74a0f65..5556f7b 100644 --- a/Swiften/Base/IDGenerator.cpp +++ b/Swiften/Base/IDGenerator.cpp @@ -1,10 +1,15 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2011 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/IDGenerator.h" +#include <Swiften/Base/IDGenerator.h> + +#include <boost/uuid/uuid.hpp> +#include <boost/uuid/uuid_io.hpp> +#include <boost/uuid/uuid_generators.hpp> +#include <boost/lexical_cast.hpp> namespace Swift { @@ -12,23 +17,8 @@ IDGenerator::IDGenerator() { } std::string IDGenerator::generateID() { - bool carry = true; - size_t i = 0; - while (carry && i < currentID_.size()) { - char c = currentID_[i]; - if (c >= 'z') { - currentID_[i] = 'a'; - } - else { - currentID_[i] = c+1; - carry = false; - } - ++i; - } - if (carry) { - currentID_ += 'a'; - } - return currentID_; + static boost::uuids::random_generator generator; + return boost::lexical_cast<std::string>(generator()); } } diff --git a/Swiften/Base/IDGenerator.h b/Swiften/Base/IDGenerator.h index 4b6289b..44eeb76 100644 --- a/Swiften/Base/IDGenerator.h +++ b/Swiften/Base/IDGenerator.h @@ -4,8 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_IDGenerator_H -#define SWIFTEN_IDGenerator_H +#pragma once #include <string> @@ -15,10 +14,5 @@ namespace Swift { IDGenerator(); std::string generateID(); - - private: - std::string currentID_; }; } - -#endif diff --git a/Swiften/Base/Log.cpp b/Swiften/Base/Log.cpp index 2041013..4132353 100644 --- a/Swiften/Base/Log.cpp +++ b/Swiften/Base/Log.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/Log.h" +#include <Swiften/Base/Log.h> namespace Swift { diff --git a/Swiften/Base/Paths.cpp b/Swiften/Base/Paths.cpp index 43eee57..b40f9b8 100644 --- a/Swiften/Base/Paths.cpp +++ b/Swiften/Base/Paths.cpp @@ -24,22 +24,22 @@ boost::filesystem::path Paths::getExecutablePath() { ByteArray path; uint32_t size = 4096; path.resize(size); - if (_NSGetExecutablePath(reinterpret_cast<char*>(path.getData()), &size) == 0) { - return boost::filesystem::path(path.toString().c_str()).parent_path(); + if (_NSGetExecutablePath(const_cast<char*>(reinterpret_cast<const char*>(vecptr(path))), &size) == 0) { + return boost::filesystem::path(std::string(reinterpret_cast<const char*>(vecptr(path)), path.size()).c_str()).parent_path(); } #elif defined(SWIFTEN_PLATFORM_LINUX) ByteArray path; path.resize(4096); - size_t size = readlink("/proc/self/exe", reinterpret_cast<char*>(path.getData()), path.getSize()); + size_t size = readlink("/proc/self/exe", reinterpret_cast<char*>(vecptr(path)), path.size()); if (size > 0) { path.resize(size); - return boost::filesystem::path(path.toString().c_str()).parent_path(); + return boost::filesystem::path(std::string(reinterpret_cast<const char*>(vecptr(path)), path.size()).c_str()).parent_path(); } #elif defined(SWIFTEN_PLATFORM_WINDOWS) ByteArray data; data.resize(2048); - GetModuleFileName(NULL, reinterpret_cast<char*>(data.getData()), data.getSize()); - return boost::filesystem::path(data.toString().c_str()).parent_path(); + GetModuleFileName(NULL, reinterpret_cast<char*>(vecptr(data)), data.size()); + return boost::filesystem::path(std::string(reinterpret_cast<const char*>(vecptr(data)), data.size()).c_str()).parent_path(); #endif return boost::filesystem::path(); } diff --git a/Swiften/Base/Paths.h b/Swiften/Base/Paths.h index 06c6aeb..8ac4640 100644 --- a/Swiften/Base/Paths.h +++ b/Swiften/Base/Paths.h @@ -6,7 +6,7 @@ #pragma once -#include <boost/filesystem.hpp> +#include <boost/filesystem/path.hpp> namespace Swift { class Paths { diff --git a/Swiften/Base/Platform.h b/Swiften/Base/Platform.h index 32e2671..395747c 100644 --- a/Swiften/Base/Platform.h +++ b/Swiften/Base/Platform.h @@ -4,8 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_Platform_H -#define SWIFTEN_Platform_H +#pragma once // Base platforms #if defined(linux) || defined(__linux) || defined(__linux__) @@ -26,6 +25,10 @@ #define SWIFTEN_PLATFORM_BEOS #elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) #define SWIFTEN_PLATFORM_MACOSX +#include <TargetConditionals.h> +# if defined(TARGET_OS_IPHONE) +# define SWIFTEN_PLATFORM_IPHONE +# endif #elif defined(__IBMCPP__) || defined(_AIX) #define SWIFTEN_PLATFORM_AIX #elif defined(__amigaos__) @@ -46,5 +49,3 @@ #elif defined(BOOST_BIG_ENDIAN) #define SWIFTEN_BIG_ENDIAN #endif - -#endif diff --git a/Swiften/Base/SConscript b/Swiften/Base/SConscript index 01252e5..8752ea8 100644 --- a/Swiften/Base/SConscript +++ b/Swiften/Base/SConscript @@ -2,6 +2,8 @@ Import("swiften_env") objects = swiften_env.SwiftenObject([ "ByteArray.cpp", + "DateTime.cpp", + "SafeByteArray.cpp", "Error.cpp", "Log.cpp", "Paths.cpp", diff --git a/Swiften/Base/SafeAllocator.h b/Swiften/Base/SafeAllocator.h new file mode 100644 index 0000000..9f9dd42 --- /dev/null +++ b/Swiften/Base/SafeAllocator.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> +#include <algorithm> + +namespace Swift { + template<typename T> + class SafeAllocator : public std::allocator<T> { + public: + template <class U> struct rebind { + typedef SafeAllocator<U> other; + }; + + SafeAllocator() throw() {} + SafeAllocator(const SafeAllocator&) throw() : std::allocator<T>() {} + template <class U> SafeAllocator(const SafeAllocator<U>&) throw() {} + ~SafeAllocator() throw() {} + + void deallocate (T* p, size_t num) { + std::fill(reinterpret_cast<char*>(p), reinterpret_cast<char*>(p + num), 0); + std::allocator<T>::deallocate(p, num); + } + }; +}; diff --git a/Swiften/Base/SafeByteArray.cpp b/Swiften/Base/SafeByteArray.cpp new file mode 100644 index 0000000..848b6d8 --- /dev/null +++ b/Swiften/Base/SafeByteArray.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Base/SafeByteArray.h> + +using namespace Swift; + +namespace Swift { + +SafeByteArray createSafeByteArray(const char* c) { + SafeByteArray data; + while (*c) { + data.push_back(static_cast<unsigned char>(*c)); + ++c; + } + return data; +} + +} diff --git a/Swiften/Base/SafeByteArray.h b/Swiften/Base/SafeByteArray.h new file mode 100644 index 0000000..1ef1d84 --- /dev/null +++ b/Swiften/Base/SafeByteArray.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> + +#include <Swiften/Base/SafeAllocator.h> +#include <Swiften/Base/ByteArray.h> +#include <boost/smart_ptr/make_shared.hpp> + +namespace Swift { + typedef std::vector<unsigned char, SafeAllocator<unsigned char> > SafeByteArray; + + inline SafeByteArray createSafeByteArray(const ByteArray& a) { + return SafeByteArray(a.begin(), a.end()); + } + + SafeByteArray createSafeByteArray(const char* c); + + inline SafeByteArray createSafeByteArray(const std::string& s) { + return SafeByteArray(s.begin(), s.end()); + } + + inline boost::shared_ptr<SafeByteArray> createSafeByteArrayRef(const std::string& s) { + return boost::make_shared<SafeByteArray>(s.begin(), s.end()); + } + + inline SafeByteArray createSafeByteArray(char c) { + return SafeByteArray(1, c); + } + + inline SafeByteArray createSafeByteArray(const char* c, size_t n) { + return SafeByteArray(c, c + n); + } + + inline boost::shared_ptr<SafeByteArray> createSafeByteArrayRef(const char* c, size_t n) { + return boost::make_shared<SafeByteArray>(c, c + n); + } + + inline SafeByteArray createSafeByteArray(const unsigned char* c, size_t n) { + return SafeByteArray(c, c + n); + } + + inline boost::shared_ptr<SafeByteArray> createSafeByteArrayRef(const unsigned char* c, size_t n) { + return boost::make_shared<SafeByteArray>(c, c + n); + } + + /* WARNING! This breaks the safety of the data in the safe byte array. + * Do not use in modes that require data safety. */ + inline std::string safeByteArrayToString(const SafeByteArray& b) { + return byteArrayToString(ByteArray(b.begin(), b.end())); + } +} + diff --git a/Swiften/Base/SafeString.h b/Swiften/Base/SafeString.h new file mode 100644 index 0000000..ef9c7cc --- /dev/null +++ b/Swiften/Base/SafeString.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Base/SafeByteArray.h> + +namespace Swift { + class SafeString { + public: + SafeString(const SafeByteArray& data) : data(data) { + } + + SafeString(const std::string& s) { + data = createSafeByteArray(s); + } + + SafeString(const char* s) { + data = createSafeByteArray(s); + } + + operator SafeByteArray () const { + return data; + } + + private: + SafeByteArray data; + }; +} diff --git a/Swiften/Base/String.h b/Swiften/Base/String.h index 192d53b..db6c28b 100644 --- a/Swiften/Base/String.h +++ b/Swiften/Base/String.h @@ -6,9 +6,9 @@ #pragma once -#include <map> #include <string> #include <vector> +#include <sstream> #define SWIFTEN_STRING_TO_CFSTRING(a) \ CFStringCreateWithBytes(NULL, reinterpret_cast<const UInt8*>(a.c_str()), a.size(), kCFStringEncodingUTF8, false) @@ -19,11 +19,28 @@ namespace Swift { std::pair<std::string, std::string> getSplittedAtFirst(const std::string&, char c); std::vector<std::string> split(const std::string&, char c); void replaceAll(std::string&, char c, const std::string& s); + inline bool beginsWith(const std::string& s, char c) { return s.size() > 0 && s[0] == c; } + inline bool endsWith(const std::string& s, char c) { return s.size() > 0 && s[s.size()-1] == c; } }; + + class makeString { + public: + template <typename T> makeString& operator<<(T const& v) { + stream << v; + return *this; + } + + operator std::string() const { + return stream.str(); + } + + private: + std::ostringstream stream; + }; } diff --git a/Swiften/Base/UnitTest/ByteArrayTest.cpp b/Swiften/Base/UnitTest/ByteArrayTest.cpp index cb10dd4..ecd0439 100644 --- a/Swiften/Base/UnitTest/ByteArrayTest.cpp +++ b/Swiften/Base/UnitTest/ByteArrayTest.cpp @@ -7,20 +7,49 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <boost/lexical_cast.hpp> using namespace Swift; class ByteArrayTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(ByteArrayTest); CPPUNIT_TEST(testGetData_NoData); + CPPUNIT_TEST(testToString); + CPPUNIT_TEST(testToString_NullTerminated); + CPPUNIT_TEST(testToString_TwoNullTerminated); + CPPUNIT_TEST(testToString_AllNull); CPPUNIT_TEST_SUITE_END(); public: void testGetData_NoData() { ByteArray testling; - CPPUNIT_ASSERT_EQUAL(reinterpret_cast<const char*>(NULL), reinterpret_cast<const char*>(testling.getData())); + CPPUNIT_ASSERT_EQUAL(reinterpret_cast<const char*>(NULL), reinterpret_cast<const char*>(vecptr(testling))); + } + + void testToString() { + ByteArray testling(createByteArray("abcde")); + + CPPUNIT_ASSERT_EQUAL(std::string("abcde"), byteArrayToString(testling)); + } + + void testToString_NullTerminated() { + ByteArray testling(createByteArray("abcde\0", 6)); + + CPPUNIT_ASSERT_EQUAL(std::string("abcde"), byteArrayToString(testling)); + } + + void testToString_TwoNullTerminated() { + ByteArray testling(createByteArray("abcde\0\0", 7)); + + CPPUNIT_ASSERT_EQUAL(std::string("abcde"), byteArrayToString(testling)); + } + + void testToString_AllNull() { + ByteArray testling(createByteArray("\0\0", 2)); + + CPPUNIT_ASSERT_EQUAL(std::string(""), byteArrayToString(testling)); } }; diff --git a/Swiften/Base/UnitTest/DateTimeTest.cpp b/Swiften/Base/UnitTest/DateTimeTest.cpp new file mode 100644 index 0000000..8c3903a --- /dev/null +++ b/Swiften/Base/UnitTest/DateTimeTest.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <string> +#include <boost/date_time/posix_time/posix_time.hpp> + +#include <Swiften/Base/DateTime.h> + +using namespace Swift; + +class DateTimeTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(DateTimeTest); + CPPUNIT_TEST(testStringToDateTime_UTC); + CPPUNIT_TEST(testStringToDateTime_WithTimezone); + CPPUNIT_TEST(testDateTimeToString); + CPPUNIT_TEST_SUITE_END(); + + public: + void testStringToDateTime_UTC() { + boost::posix_time::ptime time = stringToDateTime("1969-07-21T02:56:15Z"); + + CPPUNIT_ASSERT_EQUAL(std::string("1969-07-21T02:56:15"), boost::posix_time::to_iso_extended_string(time)); + } + + void testStringToDateTime_WithTimezone() { + boost::posix_time::ptime time = stringToDateTime("1969-07-20T21:56:15-05:00"); + + CPPUNIT_ASSERT_EQUAL(std::string("1969-07-21T02:56:15"), boost::posix_time::to_iso_extended_string(time)); + } + + void testDateTimeToString() { + boost::posix_time::ptime time = stringToDateTime("1969-07-20T21:56:15-05:00"); + + CPPUNIT_ASSERT_EQUAL(std::string("1969-07-21T02:56:15Z"), dateTimeToString(time)); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(DateTimeTest); diff --git a/Swiften/Base/UnitTest/IDGeneratorTest.cpp b/Swiften/Base/UnitTest/IDGeneratorTest.cpp index 4874684..610138f 100644 --- a/Swiften/Base/UnitTest/IDGeneratorTest.cpp +++ b/Swiften/Base/UnitTest/IDGeneratorTest.cpp @@ -8,7 +8,7 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <set> -#include "Swiften/Base/IDGenerator.h" +#include <Swiften/Base/IDGenerator.h> using namespace Swift; diff --git a/Swiften/Base/foreach.h b/Swiften/Base/foreach.h index 05366d6..87f6147 100644 --- a/Swiften/Base/foreach.h +++ b/Swiften/Base/foreach.h @@ -4,12 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_FOREACH_H -#define SWIFTEN_FOREACH_H +#pragma once #include <boost/foreach.hpp> #undef foreach #define foreach BOOST_FOREACH - -#endif diff --git a/Swiften/Base/format.h b/Swiften/Base/format.h index 4591827..0e49eaa 100644 --- a/Swiften/Base/format.h +++ b/Swiften/Base/format.h @@ -7,6 +7,7 @@ #pragma once #include <boost/format.hpp> +#include <iostream> namespace Swift { inline boost::format format(const std::string& s) { diff --git a/Swiften/Base/sleep.cpp b/Swiften/Base/sleep.cpp index 892a3ba..7161217 100644 --- a/Swiften/Base/sleep.cpp +++ b/Swiften/Base/sleep.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/sleep.h" +#include <Swiften/Base/sleep.h> #include <boost/thread.hpp> diff --git a/Swiften/Base/sleep.h b/Swiften/Base/sleep.h index c2bc601..a95e907 100644 --- a/Swiften/Base/sleep.h +++ b/Swiften/Base/sleep.h @@ -4,11 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_sleep_H -#define SWIFTEN_sleep_H +#pragma once namespace Swift { void sleep(unsigned int msecs); } - -#endif diff --git a/Swiften/Chat/ChatStateNotifier.cpp b/Swiften/Chat/ChatStateNotifier.cpp index 6e0f458..d507c4d 100644 --- a/Swiften/Chat/ChatStateNotifier.cpp +++ b/Swiften/Chat/ChatStateNotifier.cpp @@ -4,14 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Chat/ChatStateNotifier.h" +#include <Swiften/Chat/ChatStateNotifier.h> #include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/Elements/Message.h" -#include "Swiften/Elements/ChatState.h" -#include "Swiften/Client/StanzaChannel.h" -#include "Swiften/Disco/EntityCapsProvider.h" +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/ChatState.h> +#include <Swiften/Client/StanzaChannel.h> +#include <Swiften/Disco/EntityCapsProvider.h> namespace Swift { @@ -68,15 +69,15 @@ bool ChatStateNotifier::contactShouldReceiveStates() { } void ChatStateNotifier::changeState(ChatState::ChatStateType state) { - boost::shared_ptr<Message> message(new Message()); + boost::shared_ptr<Message> message(boost::make_shared<Message>()); message->setTo(contact_); - message->addPayload(boost::shared_ptr<Payload>(new ChatState(state))); + message->addPayload(boost::make_shared<ChatState>(state)); stanzaChannel_->sendMessage(message); } void ChatStateNotifier::addChatStateRequest(Message::ref message) { if (contactShouldReceiveStates()) { - message->addPayload(boost::shared_ptr<Payload>(new ChatState(ChatState::Active))); + message->addPayload(boost::make_shared<ChatState>(ChatState::Active)); } } diff --git a/Swiften/Chat/ChatStateNotifier.h b/Swiften/Chat/ChatStateNotifier.h index 1185ed0..c691092 100644 --- a/Swiften/Chat/ChatStateNotifier.h +++ b/Swiften/Chat/ChatStateNotifier.h @@ -6,12 +6,12 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/Message.h" -#include "Swiften/Elements/ChatState.h" -#include "Swiften/JID/JID.h" +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/ChatState.h> +#include <Swiften/JID/JID.h> namespace Swift { class StanzaChannel; diff --git a/Swiften/Chat/ChatStateTracker.cpp b/Swiften/Chat/ChatStateTracker.cpp index 2afcf67..27be86c 100644 --- a/Swiften/Chat/ChatStateTracker.cpp +++ b/Swiften/Chat/ChatStateTracker.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Chat/ChatStateTracker.h" +#include <Swiften/Chat/ChatStateTracker.h> namespace Swift { ChatStateTracker::ChatStateTracker() { diff --git a/Swiften/Chat/ChatStateTracker.h b/Swiften/Chat/ChatStateTracker.h index 343d828..b356644 100644 --- a/Swiften/Chat/ChatStateTracker.h +++ b/Swiften/Chat/ChatStateTracker.h @@ -6,12 +6,12 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/Message.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/ChatState.h" +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Elements/ChatState.h> namespace Swift { class ChatStateTracker { diff --git a/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp b/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp index 5d7961b..1b91076 100644 --- a/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp +++ b/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp @@ -8,9 +8,10 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/bind.hpp> -#include "Swiften/Chat/ChatStateNotifier.h" -#include "Swiften/Client/DummyStanzaChannel.h" -#include "Swiften/Disco/DummyEntityCapsProvider.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Chat/ChatStateNotifier.h> +#include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/Disco/DummyEntityCapsProvider.h> using namespace Swift; diff --git a/Swiften/Client/BlockList.cpp b/Swiften/Client/BlockList.cpp new file mode 100644 index 0000000..0b2fc12 --- /dev/null +++ b/Swiften/Client/BlockList.cpp @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Client/BlockList.h> + +using namespace Swift; + +BlockList::~BlockList() { + +} diff --git a/Swiften/Client/BlockList.h b/Swiften/Client/BlockList.h new file mode 100644 index 0000000..39a211d --- /dev/null +++ b/Swiften/Client/BlockList.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <set> + +#include <Swiften/JID/JID.h> +#include <Swiften/Base/boost_bsignals.h> + +namespace Swift { + class BlockList { + public: + enum State { + Requesting, + Available, + Error, + }; + virtual ~BlockList(); + + virtual State getState() const = 0; + + virtual const std::set<JID>& getItems() const = 0; + + public: + boost::signal<void ()> onStateChanged; + boost::signal<void (const JID&)> onItemAdded; + boost::signal<void (const JID&)> onItemRemoved; + }; +} diff --git a/Swiften/Client/BlockListImpl.cpp b/Swiften/Client/BlockListImpl.cpp new file mode 100644 index 0000000..dfaaaf1 --- /dev/null +++ b/Swiften/Client/BlockListImpl.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Client/BlockListImpl.h> + +#include <Swiften/Base/foreach.h> + +using namespace Swift; + +BlockListImpl::BlockListImpl() { + +} + +void BlockListImpl::setItems(const std::vector<JID>& items) { + this->items = std::set<JID>(items.begin(), items.end()); +} + +void BlockListImpl::addItem(const JID& item) { + if (items.insert(item).second) { + onItemAdded(item); + } +} + +void BlockListImpl::removeItem(const JID& item) { + if (items.erase(item)) { + onItemRemoved(item); + } +} + +void BlockListImpl::setState(State state) { + if (this->state != state) { + onStateChanged(); + } +} + +void BlockListImpl::addItems(const std::vector<JID>& items) { + foreach (const JID& item, items) { + addItem(item); + } +} + +void BlockListImpl::removeItems(const std::vector<JID>& items) { + foreach (const JID& item, items) { + removeItem(item); + } +} + +void BlockListImpl::removeAllItems() { + foreach (const JID& item, items) { + removeItem(item); + } +} + diff --git a/Swiften/Client/BlockListImpl.h b/Swiften/Client/BlockListImpl.h new file mode 100644 index 0000000..ef08340 --- /dev/null +++ b/Swiften/Client/BlockListImpl.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Client/BlockList.h> + +namespace Swift { + class BlockListImpl : public BlockList { + public: + BlockListImpl(); + + virtual State getState() const { + return state; + } + + void setState(State state); + + virtual const std::set<JID>& getItems() const { + return items; + } + + void setItems(const std::vector<JID>& items); + void addItem(const JID& item); + void removeItem(const JID& item); + void addItems(const std::vector<JID>& items); + void removeItems(const std::vector<JID>& items); + void removeAllItems(); + + private: + State state; + std::set<JID> items; + }; +} diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp index 7918c46..48eddc2 100644 --- a/Swiften/Client/Client.cpp +++ b/Swiften/Client/Client.cpp @@ -4,38 +4,45 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Client/Client.h" - -#include "Swiften/Queries/Responders/SoftwareVersionResponder.h" -#include "Swiften/Roster/XMPPRosterImpl.h" -#include "Swiften/Roster/XMPPRosterController.h" -#include "Swiften/Presence/PresenceOracle.h" -#include "Swiften/Presence/StanzaChannelPresenceSender.h" -#include "Swiften/Presence/DirectedPresenceSender.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/MUC/MUCManager.h" -#include "Swiften/Client/MemoryStorages.h" -#include "Swiften/VCards/VCardManager.h" -#include "Swiften/VCards/VCardManager.h" -#include "Swiften/Avatars/AvatarManagerImpl.h" -#include "Swiften/Disco/CapsManager.h" -#include "Swiften/Disco/EntityCapsManager.h" -#include "Swiften/Disco/ClientDiscoManager.h" -#include "Swiften/Client/NickResolver.h" -#include "Swiften/Presence/SubscriptionManager.h" -#include "Swiften/TLS/BlindCertificateTrustChecker.h" +#include <Swiften/Client/Client.h> + +#include <Swiften/Queries/Responders/SoftwareVersionResponder.h> +#include <Swiften/Roster/XMPPRosterImpl.h> +#include <Swiften/Roster/XMPPRosterController.h> +#include <Swiften/Presence/PresenceOracle.h> +#include <Swiften/Presence/StanzaChannelPresenceSender.h> +#include <Swiften/Presence/DirectedPresenceSender.h> +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/MUC/MUCManager.h> +#include <Swiften/Client/MemoryStorages.h> +#include <Swiften/VCards/VCardManager.h> +#include <Swiften/VCards/VCardManager.h> +#include <Swiften/Avatars/AvatarManagerImpl.h> +#include <Swiften/Disco/CapsManager.h> +#include <Swiften/Disco/EntityCapsManager.h> +#include <Swiften/Disco/ClientDiscoManager.h> +#include <Swiften/Client/NickResolver.h> +#include <Swiften/Presence/SubscriptionManager.h> +#include <Swiften/TLS/BlindCertificateTrustChecker.h> #include <Swiften/Client/NickManagerImpl.h> +#include <Swiften/Client/ClientSession.h> +#include <Swiften/Jingle/JingleSessionManager.h> +#include <Swiften/Network/NetworkFactories.h> +#include <Swiften/FileTransfer/FileTransferManagerImpl.h> +#ifndef SWIFT_EXPERIMENTAL_FT +#include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h> +#endif namespace Swift { -Client::Client(const JID& jid, const std::string& password, NetworkFactories* networkFactories, Storages* storages) : CoreClient(jid, password, networkFactories), storages(storages) { +Client::Client(const JID& jid, const SafeString& password, NetworkFactories* networkFactories, Storages* storages) : CoreClient(jid, password, networkFactories), storages(storages) { memoryStorages = new MemoryStorages(); softwareVersionResponder = new SoftwareVersionResponder(getIQRouter()); softwareVersionResponder->start(); roster = new XMPPRosterImpl(); - rosterController = new XMPPRosterController(getIQRouter(), roster); + rosterController = new XMPPRosterController(getIQRouter(), roster, getStorages()->getRosterStorage()); subscriptionManager = new SubscriptionManager(getStanzaChannel()); @@ -58,9 +65,15 @@ Client::Client(const JID& jid, const std::string& password, NetworkFactories* ne nickResolver = new NickResolver(jid.toBare(), roster, vcardManager, mucRegistry); blindCertificateTrustChecker = new BlindCertificateTrustChecker(); + + jingleSessionManager = new JingleSessionManager(getIQRouter()); + fileTransferManager = NULL; } Client::~Client() { + delete fileTransferManager; + delete jingleSessionManager; + delete blindCertificateTrustChecker; delete nickResolver; @@ -97,7 +110,20 @@ void Client::setSoftwareVersion(const std::string& name, const std::string& vers softwareVersionResponder->setVersion(name, version, os); } +void Client::handleConnected() { +#ifdef SWIFT_EXPERIMENTAL_FT + fileTransferManager = new FileTransferManagerImpl(getJID(), jingleSessionManager, getIQRouter(), getEntityCapsProvider(), presenceOracle, getNetworkFactories()->getConnectionFactory(), getNetworkFactories()->getConnectionServerFactory(), getNetworkFactories()->getTimerFactory(), getNetworkFactories()->getNATTraverser()); +#else + fileTransferManager = new DummyFileTransferManager(); +#endif +} + void Client::requestRoster() { + // FIXME: We should set this once when the session is finished, but there + // is currently no callback for this + if (getSession()) { + rosterController->setUseVersioning(getSession()->getRosterVersioningSupported()); + } rosterController->requestRoster(); } @@ -133,4 +159,8 @@ NickManager* Client::getNickManager() const { return nickManager; } +FileTransferManager* Client::getFileTransferManager() const { + return fileTransferManager; +} + } diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h index 083b8a0..940a526 100644 --- a/Swiften/Client/Client.h +++ b/Swiften/Client/Client.h @@ -6,7 +6,9 @@ #pragma once -#include "Swiften/Client/CoreClient.h" +#include <Swiften/Client/CoreClient.h> + +#include <Swiften/Base/SafeString.h> namespace Swift { class SoftwareVersionResponder; @@ -31,6 +33,9 @@ namespace Swift { class SubscriptionManager; class ClientDiscoManager; class NickManager; + class FileTransferManager; + class JingleSessionManager; + class FileTransferManager; /** * Provides the core functionality for writing XMPP client software. @@ -47,7 +52,7 @@ namespace Swift { * this is NULL, * all data will be stored in memory (and be lost on shutdown) */ - Client(const JID& jid, const std::string& password, NetworkFactories* networkFactories, Storages* storages = NULL); + Client(const JID& jid, const SafeString& password, NetworkFactories* networkFactories, Storages* storages = NULL); ~Client(); @@ -85,12 +90,12 @@ namespace Swift { /** * Returns the last received presence for the given (full) JID. */ - Presence::ref getLastPresence(const JID& jid) const; + boost::shared_ptr<Presence> getLastPresence(const JID& jid) const; /** * Returns the presence with the highest priority received for the given JID. */ - Presence::ref getHighestPriorityPresence(const JID& bareJID) const; + boost::shared_ptr<Presence> getHighestPriorityPresence(const JID& bareJID) const; PresenceOracle* getPresenceOracle() const { return presenceOracle; @@ -129,6 +134,14 @@ namespace Swift { ClientDiscoManager* getDiscoManager() const { return discoManager; } + + /** + * Returns a FileTransferManager for the client. This is only available after the onConnected + * signal has been fired. + * + * WARNING: File transfer will only work if Swiften is built in 'experimental' mode. + */ + FileTransferManager* getFileTransferManager() const; /** * Configures the client to always trust a non-validating @@ -142,11 +155,14 @@ namespace Swift { /** * This signal is emitted when a JID changes presence. */ - boost::signal<void (Presence::ref)> onPresenceChange; + boost::signal<void (boost::shared_ptr<Presence>)> onPresenceChange; private: Storages* getStorages() const; + protected: + void handleConnected(); + private: Storages* storages; MemoryStorages* memoryStorages; @@ -166,6 +182,8 @@ namespace Swift { SubscriptionManager* subscriptionManager; MUCManager* mucManager; ClientDiscoManager* discoManager; + JingleSessionManager* jingleSessionManager; + FileTransferManager* fileTransferManager; BlindCertificateTrustChecker* blindCertificateTrustChecker; }; } diff --git a/Swiften/Client/ClientBlockListManager.cpp b/Swiften/Client/ClientBlockListManager.cpp new file mode 100644 index 0000000..7222cea --- /dev/null +++ b/Swiften/Client/ClientBlockListManager.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Client/ClientBlockListManager.h> + +#include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> +#include <cassert> + +#include <Swiften/Client/BlockListImpl.h> + +using namespace Swift; + +namespace { + class BlockResponder : public SetResponder<BlockPayload> { + public: + BlockResponder(boost::shared_ptr<BlockListImpl> blockList, IQRouter* iqRouter) : SetResponder<BlockPayload>(iqRouter), blockList(blockList) { + } + + virtual bool handleSetRequest(const JID& from, const JID&, const std::string& id, boost::shared_ptr<BlockPayload> payload) { + if (getIQRouter()->isAccountJID(from)) { + if (payload) { + blockList->addItems(payload->getItems()); + } + sendResponse(from, id, boost::shared_ptr<BlockPayload>()); + } + else { + sendError(from, id, ErrorPayload::NotAuthorized, ErrorPayload::Cancel); + } + return true; + } + + private: + boost::shared_ptr<BlockListImpl> blockList; + }; + + class UnblockResponder : public SetResponder<UnblockPayload> { + public: + UnblockResponder(boost::shared_ptr<BlockListImpl> blockList, IQRouter* iqRouter) : SetResponder<UnblockPayload>(iqRouter), blockList(blockList) { + } + + virtual bool handleSetRequest(const JID& from, const JID&, const std::string& id, boost::shared_ptr<UnblockPayload> payload) { + if (getIQRouter()->isAccountJID(from)) { + if (payload) { + if (payload->getItems().empty()) { + blockList->removeAllItems(); + } + else { + blockList->removeItems(payload->getItems()); + } + } + sendResponse(from, id, boost::shared_ptr<UnblockPayload>()); + } + else { + sendError(from, id, ErrorPayload::NotAuthorized, ErrorPayload::Cancel); + } + return true; + } + + private: + boost::shared_ptr<BlockListImpl> blockList; + }; +} + +ClientBlockListManager::ClientBlockListManager(IQRouter* iqRouter) : iqRouter(iqRouter) { +} + +ClientBlockListManager::~ClientBlockListManager() { + unblockResponder->stop(); + blockResponder->stop(); + if (getRequest) { + getRequest->onResponse.disconnect(boost::bind(&ClientBlockListManager::handleBlockListReceived, this, _1, _2)); + } +} + +boost::shared_ptr<BlockList> ClientBlockListManager::getBlockList() { + if (!blockList) { + blockList = boost::make_shared<BlockListImpl>(); + blockList->setState(BlockList::Requesting); + assert(!getRequest); + getRequest = boost::make_shared< GenericRequest<BlockListPayload> >(IQ::Get, JID(), boost::make_shared<BlockListPayload>(), iqRouter); + getRequest->onResponse.connect(boost::bind(&ClientBlockListManager::handleBlockListReceived, this, _1, _2)); + getRequest->send(); + } + return blockList; +} + +void ClientBlockListManager::handleBlockListReceived(boost::shared_ptr<BlockListPayload> payload, ErrorPayload::ref error) { + if (error || !payload) { + blockList->setState(BlockList::Error); + } + else { + blockList->setState(BlockList::Available); + blockList->setItems(payload->getItems()); + blockResponder = boost::make_shared<BlockResponder>(blockList, iqRouter); + blockResponder->start(); + unblockResponder = boost::make_shared<UnblockResponder>(blockList, iqRouter); + unblockResponder->start(); + } +} + diff --git a/Swiften/Client/ClientBlockListManager.h b/Swiften/Client/ClientBlockListManager.h new file mode 100644 index 0000000..21d35e3 --- /dev/null +++ b/Swiften/Client/ClientBlockListManager.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 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/Base/boost_bsignals.h> +#include <Swiften/Elements/BlockPayload.h> +#include <Swiften/Elements/BlockListPayload.h> +#include <Swiften/Elements/UnblockPayload.h> +#include <Swiften/Queries/SetResponder.h> +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Client/BlockList.h> +#include <Swiften/Client/BlockListImpl.h> + +namespace Swift { + class IQRouter; + + class ClientBlockListManager { + public: + ClientBlockListManager(IQRouter *iqRouter); + ~ClientBlockListManager(); + + bool isSupported() const; + + /** + * Returns the blocklist. + */ + boost::shared_ptr<BlockList> getBlockList(); + + private: + void handleBlockListReceived(boost::shared_ptr<BlockListPayload> payload, ErrorPayload::ref); + + private: + IQRouter* iqRouter; + boost::shared_ptr<GenericRequest<BlockListPayload> > getRequest; + boost::shared_ptr<SetResponder<BlockPayload> > blockResponder; + boost::shared_ptr<SetResponder<UnblockPayload> > unblockResponder; + boost::shared_ptr<BlockListImpl> blockList; + }; +} + diff --git a/Swiften/Client/ClientOptions.h b/Swiften/Client/ClientOptions.h new file mode 100644 index 0000000..3b51a87 --- /dev/null +++ b/Swiften/Client/ClientOptions.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +namespace Swift { + struct ClientOptions { + enum UseTLS { + NeverUseTLS, + UseTLSWhenAvailable, + RequireTLS + }; + + ClientOptions() : useStreamCompression(true), useTLS(UseTLSWhenAvailable), allowPLAINWithoutTLS(false), useStreamResumption(false), forgetPassword(false), useAcks(true) { + } + + /** + * Whether ZLib stream compression should be used when available. + * + * Default: true + */ + bool useStreamCompression; + + /** + * Sets whether TLS encryption should be used. + * + * Default: UseTLSWhenAvailable + */ + UseTLS useTLS; + + /** + * Sets whether plaintext authentication is + * allowed over non-TLS-encrypted connections. + * + * Default: false + */ + bool allowPLAINWithoutTLS; + + /** + * Use XEP-196 stream resumption when available. + * + * Default: false + */ + bool useStreamResumption; + + /** + * Forget the password once it's used. + * This makes the Client useless after the first login attempt. + * + * FIXME: This is a temporary workaround. + * + * Default: false + */ + bool forgetPassword; + + /** + * Use XEP-0198 acks in the stream when available. + * Default: true + */ + bool useAcks; + }; +} diff --git a/Swiften/Client/ClientSession.cpp b/Swiften/Client/ClientSession.cpp index e1c1d8e..791ee75 100644 --- a/Swiften/Client/ClientSession.cpp +++ b/Swiften/Client/ClientSession.cpp @@ -4,41 +4,42 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Client/ClientSession.h" +#include <Swiften/Client/ClientSession.h> #include <boost/bind.hpp> #include <boost/uuid/uuid.hpp> #include <boost/uuid/uuid_io.hpp> #include <boost/uuid/uuid_generators.hpp> +#include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/Elements/ProtocolHeader.h" -#include "Swiften/Elements/StreamFeatures.h" -#include "Swiften/Elements/StreamError.h" -#include "Swiften/Elements/StartTLSRequest.h" -#include "Swiften/Elements/StartTLSFailure.h" -#include "Swiften/Elements/TLSProceed.h" -#include "Swiften/Elements/AuthRequest.h" -#include "Swiften/Elements/AuthSuccess.h" -#include "Swiften/Elements/AuthFailure.h" -#include "Swiften/Elements/AuthChallenge.h" -#include "Swiften/Elements/AuthResponse.h" -#include "Swiften/Elements/Compressed.h" -#include "Swiften/Elements/CompressFailure.h" -#include "Swiften/Elements/CompressRequest.h" -#include "Swiften/Elements/EnableStreamManagement.h" -#include "Swiften/Elements/StreamManagementEnabled.h" -#include "Swiften/Elements/StreamManagementFailed.h" -#include "Swiften/Elements/StartSession.h" -#include "Swiften/Elements/StanzaAck.h" -#include "Swiften/Elements/StanzaAckRequest.h" -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/ResourceBind.h" -#include "Swiften/SASL/PLAINClientAuthenticator.h" -#include "Swiften/SASL/SCRAMSHA1ClientAuthenticator.h" -#include "Swiften/SASL/DIGESTMD5ClientAuthenticator.h" -#include "Swiften/Session/SessionStream.h" -#include "Swiften/TLS/CertificateTrustChecker.h" -#include "Swiften/TLS/ServerIdentityVerifier.h" +#include <Swiften/Elements/ProtocolHeader.h> +#include <Swiften/Elements/StreamFeatures.h> +#include <Swiften/Elements/StreamError.h> +#include <Swiften/Elements/StartTLSRequest.h> +#include <Swiften/Elements/StartTLSFailure.h> +#include <Swiften/Elements/TLSProceed.h> +#include <Swiften/Elements/AuthRequest.h> +#include <Swiften/Elements/AuthSuccess.h> +#include <Swiften/Elements/AuthFailure.h> +#include <Swiften/Elements/AuthChallenge.h> +#include <Swiften/Elements/AuthResponse.h> +#include <Swiften/Elements/Compressed.h> +#include <Swiften/Elements/CompressFailure.h> +#include <Swiften/Elements/CompressRequest.h> +#include <Swiften/Elements/EnableStreamManagement.h> +#include <Swiften/Elements/StreamManagementEnabled.h> +#include <Swiften/Elements/StreamManagementFailed.h> +#include <Swiften/Elements/StartSession.h> +#include <Swiften/Elements/StanzaAck.h> +#include <Swiften/Elements/StanzaAckRequest.h> +#include <Swiften/Elements/IQ.h> +#include <Swiften/Elements/ResourceBind.h> +#include <Swiften/SASL/PLAINClientAuthenticator.h> +#include <Swiften/SASL/SCRAMSHA1ClientAuthenticator.h> +#include <Swiften/SASL/DIGESTMD5ClientAuthenticator.h> +#include <Swiften/Session/SessionStream.h> +#include <Swiften/TLS/CertificateTrustChecker.h> +#include <Swiften/TLS/ServerIdentityVerifier.h> namespace Swift { @@ -51,9 +52,11 @@ ClientSession::ClientSession( allowPLAINOverNonTLS(false), useStreamCompression(true), useTLS(UseTLSWhenAvailable), + useAcks(true), needSessionStart(false), needResourceBind(false), needAcking(false), + rosterVersioningSupported(false), authenticator(NULL), certificateTrustChecker(NULL) { } @@ -173,17 +176,20 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) { if (streamFeatures->hasStartTLS() && stream->supportsTLSEncryption() && useTLS != NeverUseTLS) { state = WaitingForEncrypt; - stream->writeElement(boost::shared_ptr<StartTLSRequest>(new StartTLSRequest())); + stream->writeElement(boost::make_shared<StartTLSRequest>()); + } + else if (useTLS == RequireTLS && !stream->isTLSEncrypted()) { + finishSession(Error::NoSupportedAuthMechanismsError); } else if (useStreamCompression && streamFeatures->hasCompressionMethod("zlib")) { state = Compressing; - stream->writeElement(boost::shared_ptr<CompressRequest>(new CompressRequest("zlib"))); + stream->writeElement(boost::make_shared<CompressRequest>("zlib")); } else if (streamFeatures->hasAuthenticationMechanisms()) { if (stream->hasTLSCertificate()) { if (streamFeatures->hasAuthenticationMechanism("EXTERNAL")) { state = Authenticating; - stream->writeElement(boost::shared_ptr<Element>(new AuthRequest("EXTERNAL", ""))); + stream->writeElement(boost::make_shared<AuthRequest>("EXTERNAL", createSafeByteArray(""))); } else { finishSession(Error::TLSClientCertificateError); @@ -191,7 +197,7 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) { } else if (streamFeatures->hasAuthenticationMechanism("EXTERNAL")) { state = Authenticating; - stream->writeElement(boost::shared_ptr<Element>(new AuthRequest("EXTERNAL", ""))); + stream->writeElement(boost::make_shared<AuthRequest>("EXTERNAL", createSafeByteArray(""))); } else if (streamFeatures->hasAuthenticationMechanism("SCRAM-SHA-1") || streamFeatures->hasAuthenticationMechanism("SCRAM-SHA-1-PLUS")) { std::ostringstream s; @@ -223,10 +229,11 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) { } else { // Start the session + rosterVersioningSupported = streamFeatures->hasRosterVersioning(); stream->setWhitespacePingEnabled(true); needSessionStart = streamFeatures->hasSession(); needResourceBind = streamFeatures->hasResourceBind(); - needAcking = streamFeatures->hasStreamManagement(); + needAcking = streamFeatures->hasStreamManagement() && useAcks; if (!needResourceBind) { // Resource binding is a MUST finishSession(Error::ResourceBindError); @@ -247,10 +254,10 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) { finishSession(Error::CompressionFailedError); } else if (boost::dynamic_pointer_cast<StreamManagementEnabled>(element)) { - stanzaAckRequester_ = boost::shared_ptr<StanzaAckRequester>(new StanzaAckRequester()); + stanzaAckRequester_ = boost::make_shared<StanzaAckRequester>(); stanzaAckRequester_->onRequestAck.connect(boost::bind(&ClientSession::requestAck, shared_from_this())); stanzaAckRequester_->onStanzaAcked.connect(boost::bind(&ClientSession::handleStanzaAcked, shared_from_this(), _1)); - stanzaAckResponder_ = boost::shared_ptr<StanzaAckResponder>(new StanzaAckResponder()); + stanzaAckResponder_ = boost::make_shared<StanzaAckResponder>(); stanzaAckResponder_->onAck.connect(boost::bind(&ClientSession::ack, shared_from_this(), _1)); needAcking = false; continueSessionInitialization(); @@ -263,7 +270,7 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) { checkState(Authenticating); assert(authenticator); if (authenticator->setChallenge(challenge->getValue())) { - stream->writeElement(boost::shared_ptr<AuthResponse>(new AuthResponse(authenticator->getResponse()))); + stream->writeElement(boost::make_shared<AuthResponse>(authenticator->getResponse())); } else { finishSession(Error::AuthenticationFailedError); @@ -272,6 +279,8 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) { else if (AuthSuccess* authSuccess = dynamic_cast<AuthSuccess*>(element.get())) { checkState(Authenticating); if (authenticator && !authenticator->setChallenge(authSuccess->getValue())) { + delete authenticator; + authenticator = NULL; finishSession(Error::ServerVerificationFailedError); } else { @@ -305,7 +314,7 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) { void ClientSession::continueSessionInitialization() { if (needResourceBind) { state = BindingResource; - boost::shared_ptr<ResourceBind> resourceBind(new ResourceBind()); + boost::shared_ptr<ResourceBind> resourceBind(boost::make_shared<ResourceBind>()); if (!localJID.getResource().empty()) { resourceBind->setResource(localJID.getResource()); } @@ -313,11 +322,11 @@ void ClientSession::continueSessionInitialization() { } else if (needAcking) { state = EnablingSessionManagement; - stream->writeElement(boost::shared_ptr<EnableStreamManagement>(new EnableStreamManagement())); + stream->writeElement(boost::make_shared<EnableStreamManagement>()); } else if (needSessionStart) { state = StartingSession; - sendStanza(IQ::createRequest(IQ::Set, JID(), "session-start", boost::shared_ptr<StartSession>(new StartSession()))); + sendStanza(IQ::createRequest(IQ::Set, JID(), "session-start", boost::make_shared<StartSession>())); } else { state = Initialized; @@ -333,11 +342,11 @@ bool ClientSession::checkState(State state) { return true; } -void ClientSession::sendCredentials(const std::string& password) { +void ClientSession::sendCredentials(const SafeByteArray& password) { assert(WaitingForCredentials); state = Authenticating; authenticator->setCredentials(localJID.getNode(), password); - stream->writeElement(boost::shared_ptr<AuthRequest>(new AuthRequest(authenticator->getName(), authenticator->getResponse()))); + stream->writeElement(boost::make_shared<AuthRequest>(authenticator->getName(), authenticator->getResponse())); } void ClientSession::handleTLSEncrypted() { @@ -354,8 +363,7 @@ void ClientSession::handleTLSEncrypted() { continueAfterTLSEncrypted(); } else { - boost::shared_ptr<CertificateVerificationError> identityError(new CertificateVerificationError(CertificateVerificationError::InvalidServerIdentity)); - checkTrustOrFinish(certificate, identityError); + checkTrustOrFinish(certificate, boost::make_shared<CertificateVerificationError>(CertificateVerificationError::InvalidServerIdentity)); } } } @@ -407,19 +415,22 @@ void ClientSession::finish() { } void ClientSession::finishSession(Error::Type error) { - finishSession(boost::shared_ptr<Swift::ClientSession::Error>(new Swift::ClientSession::Error(error))); + finishSession(boost::make_shared<Swift::ClientSession::Error>(error)); } void ClientSession::finishSession(boost::shared_ptr<Swift::Error> error) { state = Finishing; error_ = error; assert(stream->isOpen()); + if (stanzaAckResponder_) { + stanzaAckResponder_->handleAckRequestReceived(); + } stream->writeFooter(); stream->close(); } void ClientSession::requestAck() { - stream->writeElement(boost::shared_ptr<StanzaAckRequest>(new StanzaAckRequest())); + stream->writeElement(boost::make_shared<StanzaAckRequest>()); } void ClientSession::handleStanzaAcked(boost::shared_ptr<Stanza> stanza) { @@ -427,7 +438,7 @@ void ClientSession::handleStanzaAcked(boost::shared_ptr<Stanza> stanza) { } void ClientSession::ack(unsigned int handledStanzasCount) { - stream->writeElement(boost::shared_ptr<StanzaAck>(new StanzaAck(handledStanzasCount))); + stream->writeElement(boost::make_shared<StanzaAck>(handledStanzasCount)); } } diff --git a/Swiften/Client/ClientSession.h b/Swiften/Client/ClientSession.h index 25ee694..2205c8d 100644 --- a/Swiften/Client/ClientSession.h +++ b/Swiften/Client/ClientSession.h @@ -6,17 +6,17 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> -#include "Swiften/Base/Error.h" -#include "Swiften/Session/SessionStream.h" +#include <Swiften/Base/Error.h> +#include <Swiften/Session/SessionStream.h> #include <string> -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/Element.h" -#include "Swiften/StreamManagement/StanzaAckRequester.h" -#include "Swiften/StreamManagement/StanzaAckResponder.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/Element.h> +#include <Swiften/StreamManagement/StanzaAckRequester.h> +#include <Swiften/StreamManagement/StanzaAckResponder.h> namespace Swift { class ClientAuthenticator; @@ -59,7 +59,8 @@ namespace Swift { enum UseTLS { NeverUseTLS, - UseTLSWhenAvailable + UseTLSWhenAvailable, + RequireTLS }; ~ClientSession(); @@ -84,11 +85,19 @@ namespace Swift { useTLS = b; } + void setUseAcks(bool b) { + useAcks = b; + } + bool getStreamManagementEnabled() const { return stanzaAckRequester_; } + bool getRosterVersioningSupported() const { + return rosterVersioningSupported; + } + const JID& getLocalJID() const { return localJID; } @@ -100,7 +109,7 @@ namespace Swift { return getState() == Finished; } - void sendCredentials(const std::string& password); + void sendCredentials(const SafeByteArray& password); void sendStanza(boost::shared_ptr<Stanza>); void setCertificateTrustChecker(CertificateTrustChecker* checker) { @@ -150,9 +159,11 @@ namespace Swift { bool allowPLAINOverNonTLS; bool useStreamCompression; UseTLS useTLS; + bool useAcks; bool needSessionStart; bool needResourceBind; bool needAcking; + bool rosterVersioningSupported; ClientAuthenticator* authenticator; boost::shared_ptr<StanzaAckRequester> stanzaAckRequester_; boost::shared_ptr<StanzaAckResponder> stanzaAckResponder_; diff --git a/Swiften/Client/ClientSessionStanzaChannel.cpp b/Swiften/Client/ClientSessionStanzaChannel.cpp index 6b32b3d..5dc0a42 100644 --- a/Swiften/Client/ClientSessionStanzaChannel.cpp +++ b/Swiften/Client/ClientSessionStanzaChannel.cpp @@ -4,9 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Client/ClientSessionStanzaChannel.h" +#include <Swiften/Client/ClientSessionStanzaChannel.h> #include <boost/bind.hpp> +#include <iostream> namespace Swift { diff --git a/Swiften/Client/ClientSessionStanzaChannel.h b/Swiften/Client/ClientSessionStanzaChannel.h index 8a56301..47fb50e 100644 --- a/Swiften/Client/ClientSessionStanzaChannel.h +++ b/Swiften/Client/ClientSessionStanzaChannel.h @@ -8,12 +8,12 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Base/IDGenerator.h" -#include "Swiften/Client/ClientSession.h" -#include "Swiften/Client/StanzaChannel.h" -#include "Swiften/Elements/Message.h" -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/Presence.h" +#include <Swiften/Base/IDGenerator.h> +#include <Swiften/Client/ClientSession.h> +#include <Swiften/Client/StanzaChannel.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/IQ.h> +#include <Swiften/Elements/Presence.h> namespace Swift { /** diff --git a/Swiften/Client/ClientXMLTracer.cpp b/Swiften/Client/ClientXMLTracer.cpp new file mode 100644 index 0000000..c1093eb --- /dev/null +++ b/Swiften/Client/ClientXMLTracer.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Client/ClientXMLTracer.h> + +#include <iostream> +#include <boost/bind.hpp> + +namespace Swift { + +ClientXMLTracer::ClientXMLTracer(CoreClient* client) { + beautifier = new XMLBeautifier(true, true); + client->onDataRead.connect(boost::bind(&ClientXMLTracer::printData, this, '<', _1)); + client->onDataWritten.connect(boost::bind(&ClientXMLTracer::printData, this, '>', _1)); +} + +ClientXMLTracer::~ClientXMLTracer() { + delete beautifier; +} + +void ClientXMLTracer::printData(char direction, const SafeByteArray& data) { + printLine(direction); + std::cerr << beautifier->beautify(byteArrayToString(ByteArray(data.begin(), data.end()))) << std::endl; +} + +void ClientXMLTracer::printLine(char c) { + for (unsigned int i = 0; i < 80; ++i) { + std::cerr << c; + } + std::cerr << std::endl; +} + +} diff --git a/Swiften/Client/ClientXMLTracer.h b/Swiften/Client/ClientXMLTracer.h index bca2a54..0752faa 100644 --- a/Swiften/Client/ClientXMLTracer.h +++ b/Swiften/Client/ClientXMLTracer.h @@ -6,29 +6,20 @@ #pragma once -#include <boost/bind.hpp> - #include <Swiften/Client/CoreClient.h> +#include <Swiften/Client/XMLBeautifier.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class ClientXMLTracer { public: - ClientXMLTracer(CoreClient* client) { - client->onDataRead.connect(boost::bind(&ClientXMLTracer::printData, '<', _1)); - client->onDataWritten.connect(boost::bind(&ClientXMLTracer::printData, '>', _1)); - } - + ClientXMLTracer(CoreClient* client); + ~ClientXMLTracer(); private: - static void printData(char direction, const std::string& data) { - printLine(direction); - std::cerr << data << std::endl; - } + void printData(char direction, const SafeByteArray& data); + void printLine(char c); - static void printLine(char c) { - for (unsigned int i = 0; i < 80; ++i) { - std::cerr << c; - } - std::cerr << std::endl; - } + private: + XMLBeautifier *beautifier; }; } diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp index 8799d4e..a223e3d 100644 --- a/Swiften/Client/CoreClient.cpp +++ b/Swiften/Client/CoreClient.cpp @@ -4,25 +4,31 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Client/CoreClient.h" +#include <Swiften/Client/CoreClient.h> #include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/Client/ClientSession.h" -#include "Swiften/TLS/PlatformTLSFactories.h" -#include "Swiften/TLS/CertificateVerificationError.h" -#include "Swiften/Network/Connector.h" -#include "Swiften/Network/NetworkFactories.h" -#include "Swiften/TLS/PKCS12Certificate.h" -#include "Swiften/Session/BasicSessionStream.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Base/IDGenerator.h" -#include "Swiften/Client/ClientSessionStanzaChannel.h" +#include <Swiften/Base/IDGenerator.h> #include <Swiften/Base/Log.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/Algorithm.h> +#include <Swiften/Client/ClientSession.h> +#include <Swiften/TLS/PlatformTLSFactories.h> +#include <Swiften/TLS/CertificateVerificationError.h> +#include <Swiften/Network/ChainedConnector.h> +#include <Swiften/Network/NetworkFactories.h> +#include <Swiften/TLS/PKCS12Certificate.h> +#include <Swiften/Session/BasicSessionStream.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Client/ClientSessionStanzaChannel.h> +#include <Swiften/Network/PlatformProxyProvider.h> +#include <Swiften/Network/SOCKS5ProxiedConnectionFactory.h> +#include <Swiften/Network/HTTPConnectProxiedConnectionFactory.h> namespace Swift { -CoreClient::CoreClient(const JID& jid, const std::string& password, NetworkFactories* networkFactories) : jid_(jid), password_(password), networkFactories(networkFactories), useStreamCompression(true), useTLS(UseTLSWhenAvailable), disconnectRequested_(false), certificateTrustChecker(NULL) { +CoreClient::CoreClient(const JID& jid, const SafeByteArray& password, NetworkFactories* networkFactories) : jid_(jid), password_(password), networkFactories(networkFactories), disconnectRequested_(false), certificateTrustChecker(NULL) { stanzaChannel_ = new ClientSessionStanzaChannel(); stanzaChannel_->onMessageReceived.connect(boost::bind(&CoreClient::handleMessageReceived, this, _1)); stanzaChannel_->onPresenceReceived.connect(boost::bind(&CoreClient::handlePresenceReceived, this, _1)); @@ -48,8 +54,9 @@ CoreClient::~CoreClient() { delete stanzaChannel_; } -void CoreClient::connect() { +void CoreClient::connect(const ClientOptions& o) { SWIFT_LOG(debug) << "Connecting" << std::endl; + options = o; connect(jid_.getDomain()); } @@ -57,7 +64,19 @@ void CoreClient::connect(const std::string& host) { SWIFT_LOG(debug) << "Connecting to host " << host << std::endl; disconnectRequested_ = false; assert(!connector_); - connector_ = Connector::create(host, networkFactories->getDomainNameResolver(), networkFactories->getConnectionFactory(), networkFactories->getTimerFactory()); + + assert(proxyConnectionFactories.empty()); + PlatformProxyProvider proxyProvider; + if(proxyProvider.getSOCKS5Proxy().isValid()) { + proxyConnectionFactories.push_back(new SOCKS5ProxiedConnectionFactory(networkFactories->getConnectionFactory(), proxyProvider.getSOCKS5Proxy())); + } + if(proxyProvider.getHTTPConnectProxy().isValid()) { + proxyConnectionFactories.push_back(new HTTPConnectProxiedConnectionFactory(networkFactories->getConnectionFactory(), proxyProvider.getHTTPConnectProxy())); + } + std::vector<ConnectionFactory*> connectionFactories(proxyConnectionFactories); + connectionFactories.push_back(networkFactories->getConnectionFactory()); + + connector_ = boost::make_shared<ChainedConnector>(host, networkFactories->getDomainNameResolver(), connectionFactories, networkFactories->getTimerFactory()); connector_->onConnectFinished.connect(boost::bind(&CoreClient::handleConnectorFinished, this, _1)); connector_->setTimeoutMilliseconds(60*1000); connector_->start(); @@ -66,7 +85,15 @@ void CoreClient::connect(const std::string& host) { void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connection) { connector_->onConnectFinished.disconnect(boost::bind(&CoreClient::handleConnectorFinished, this, _1)); connector_.reset(); + foreach(ConnectionFactory* f, proxyConnectionFactories) { + delete f; + } + proxyConnectionFactories.clear(); + if (!connection) { + if (options.forgetPassword) { + purgePassword(); + } onDisconnected(disconnectRequested_ ? boost::optional<ClientError>() : boost::optional<ClientError>(ClientError::ConnectionError)); } else { @@ -74,7 +101,7 @@ void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connectio connection_ = connection; assert(!sessionStream_); - sessionStream_ = boost::shared_ptr<BasicSessionStream>(new BasicSessionStream(ClientStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), tlsFactories->getTLSContextFactory(), networkFactories->getTimerFactory())); + sessionStream_ = boost::make_shared<BasicSessionStream>(ClientStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), tlsFactories->getTLSContextFactory(), networkFactories->getTimerFactory()); if (!certificate_.empty()) { sessionStream_->setTLSCertificate(PKCS12Certificate(certificate_, password_)); } @@ -83,15 +110,20 @@ void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connectio session_ = ClientSession::create(jid_, sessionStream_); session_->setCertificateTrustChecker(certificateTrustChecker); - session_->setUseStreamCompression(useStreamCompression); - switch(useTLS) { - case UseTLSWhenAvailable: + session_->setUseStreamCompression(options.useStreamCompression); + session_->setAllowPLAINOverNonTLS(options.allowPLAINWithoutTLS); + switch(options.useTLS) { + case ClientOptions::UseTLSWhenAvailable: session_->setUseTLS(ClientSession::UseTLSWhenAvailable); break; - case NeverUseTLS: + case ClientOptions::NeverUseTLS: session_->setUseTLS(ClientSession::NeverUseTLS); break; + case ClientOptions::RequireTLS: + session_->setUseTLS(ClientSession::RequireTLS); + break; } + session_->setUseAcks(options.useAcks); stanzaChannel_->setSession(session_); session_->onFinished.connect(boost::bind(&CoreClient::handleSessionFinished, this, _1)); session_->onNeedCredentials.connect(boost::bind(&CoreClient::handleNeedCredentials, this)); @@ -116,6 +148,9 @@ void CoreClient::setCertificate(const std::string& certificate) { } void CoreClient::handleSessionFinished(boost::shared_ptr<Error> error) { + if (options.forgetPassword) { + purgePassword(); + } session_->onFinished.disconnect(boost::bind(&CoreClient::handleSessionFinished, this, _1)); session_->onNeedCredentials.disconnect(boost::bind(&CoreClient::handleNeedCredentials, this)); @@ -227,18 +262,22 @@ void CoreClient::handleSessionFinished(boost::shared_ptr<Error> error) { void CoreClient::handleNeedCredentials() { assert(session_); session_->sendCredentials(password_); + if (options.forgetPassword) { + purgePassword(); + } } -void CoreClient::handleDataRead(const std::string& data) { +void CoreClient::handleDataRead(const SafeByteArray& data) { onDataRead(data); } -void CoreClient::handleDataWritten(const std::string& data) { +void CoreClient::handleDataWritten(const SafeByteArray& data) { onDataWritten(data); } void CoreClient::handleStanzaChannelAvailableChanged(bool available) { if (available) { + handleConnected(); onConnected(); } } @@ -276,13 +315,29 @@ void CoreClient::handleStanzaAcked(Stanza::ref stanza) { onStanzaAcked(stanza); } -void CoreClient::setUseStreamCompression(bool b) { - useStreamCompression = b; +bool CoreClient::isAvailable() const { + return stanzaChannel_->isAvailable(); +} + +bool CoreClient::getStreamManagementEnabled() const { + return stanzaChannel_->getStreamManagementEnabled(); } -void CoreClient::setUseTLS(UseTLS b) { - useTLS = b; +StanzaChannel* CoreClient::getStanzaChannel() const { + return stanzaChannel_; } +const JID& CoreClient::getJID() const { + if (session_) { + return session_->getLocalJID(); + } + else { + return jid_; + } +} + +void CoreClient::purgePassword() { + safeClear(password_); +} } diff --git a/Swiften/Client/CoreClient.h b/Swiften/Client/CoreClient.h index eb9c42c..3472e76 100644 --- a/Swiften/Client/CoreClient.h +++ b/Swiften/Client/CoreClient.h @@ -6,35 +6,34 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <string> #include <boost/shared_ptr.hpp> +#include <Swiften/Base/boost_bsignals.h> -#include "Swiften/Network/PlatformDomainNameResolver.h" -#include "Swiften/Network/Connector.h" -#include "Swiften/Base/Error.h" -#include "Swiften/Client/ClientSession.h" -#include "Swiften/Client/ClientError.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/Message.h" -#include "Swiften/JID/JID.h" -#include <string> -#include "Swiften/Client/StanzaChannel.h" -#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" -#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h" #include <Swiften/Entity/Entity.h> - -#include "Swiften/Client/ClientSessionStanzaChannel.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Client/ClientError.h> +#include <Swiften/Client/ClientOptions.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { + class ChainedConnector; + class Message; + class Presence; + class Error; class IQRouter; class TLSContextFactory; class ConnectionFactory; + class Connection; class TimerFactory; class ClientSession; + class StanzaChannel; + class Stanza; class BasicSessionStream; class PlatformTLSFactories; class CertificateTrustChecker; class NetworkFactories; + class ClientSessionStanzaChannel; /** * The central class for communicating with an XMPP server. @@ -48,16 +47,11 @@ namespace Swift { */ class CoreClient : public Entity { public: - enum UseTLS { - NeverUseTLS, - UseTLSWhenAvailable - }; - /** * Constructs a client for the given JID with the given password. * The given eventLoop will be used to post events to. */ - CoreClient(const JID& jid, const std::string& password, NetworkFactories* networkFactories); + CoreClient(const JID& jid, const SafeByteArray& password, NetworkFactories* networkFactories); ~CoreClient(); void setCertificate(const std::string& certificate); @@ -68,7 +62,7 @@ namespace Swift { * After the connection is established, the client will set * initialize the stream and authenticate. */ - void connect(); + void connect(const ClientOptions& = ClientOptions()); /** * Disconnects the client from the server. @@ -80,12 +74,12 @@ namespace Swift { /** * Sends a message. */ - void sendMessage(Message::ref); + void sendMessage(boost::shared_ptr<Message>); /** * Sends a presence stanza. */ - void sendPresence(Presence::ref); + void sendPresence(boost::shared_ptr<Presence>); /** * Sends raw, unchecked data. @@ -103,9 +97,7 @@ namespace Swift { * Checks whether the client is connected to the server, * and stanzas can be sent. */ - bool isAvailable() const { - return stanzaChannel_->isAvailable(); - } + bool isAvailable() const; /** * Checks whether the client is active. @@ -118,14 +110,7 @@ namespace Swift { * Returns the JID of the client. * After the session was initialized, this returns the bound JID. */ - const JID& getJID() const { - if (session_) { - return session_->getLocalJID(); - } - else { - return jid_; - } - } + const JID& getJID() const; /** * Checks whether stream management is enabled. @@ -135,13 +120,9 @@ namespace Swift { * * \see onStanzaAcked */ - bool getStreamManagementEnabled() const { - return stanzaChannel_->getStreamManagementEnabled(); - } + bool getStreamManagementEnabled() const; - StanzaChannel* getStanzaChannel() const { - return stanzaChannel_; - } + StanzaChannel* getStanzaChannel() const; /** * Sets the certificate trust checker. @@ -153,16 +134,6 @@ namespace Swift { */ void setCertificateTrustChecker(CertificateTrustChecker*); - /** - * Sets whether ZLib stream compression should be used when available. - */ - void setUseStreamCompression(bool b); - - /** - * Sets whether TLS encryption should be used. - */ - void setUseTLS(UseTLS useTLS); - public: /** * Emitted when the client was disconnected from the network. @@ -184,7 +155,7 @@ namespace Swift { * This signal is emitted before the XML data is parsed, * so this data is unformatted. */ - boost::signal<void (const std::string&)> onDataRead; + boost::signal<void (const SafeByteArray&)> onDataRead; /** * Emitted when the client sends data. @@ -192,17 +163,17 @@ namespace Swift { * This signal is emitted after the XML was serialized, and * is unformatted. */ - boost::signal<void (const std::string&)> onDataWritten; + boost::signal<void (const SafeByteArray&)> onDataWritten; /** * Emitted when a message is received. */ - boost::signal<void (Message::ref)> onMessageReceived; + boost::signal<void (boost::shared_ptr<Message>)> onMessageReceived; /** * Emitted when a presence stanza is received. */ - boost::signal<void (Presence::ref) > onPresenceReceived; + boost::signal<void (boost::shared_ptr<Presence>) > onPresenceReceived; /** * Emitted when the server acknowledges receipt of a @@ -210,28 +181,43 @@ namespace Swift { * * \see getStreamManagementEnabled() */ - boost::signal<void (Stanza::ref)> onStanzaAcked; + boost::signal<void (boost::shared_ptr<Stanza>)> onStanzaAcked; + + protected: + boost::shared_ptr<ClientSession> getSession() const { + return session_; + } + + NetworkFactories* getNetworkFactories() const { + return networkFactories; + } + + /** + * Called before onConnected signal is emmitted. + */ + virtual void handleConnected() {}; private: void handleConnectorFinished(boost::shared_ptr<Connection>); void handleStanzaChannelAvailableChanged(bool available); void handleSessionFinished(boost::shared_ptr<Error>); void handleNeedCredentials(); - void handleDataRead(const std::string&); - void handleDataWritten(const std::string&); - void handlePresenceReceived(Presence::ref); - void handleMessageReceived(Message::ref); - void handleStanzaAcked(Stanza::ref); + void handleDataRead(const SafeByteArray&); + void handleDataWritten(const SafeByteArray&); + void handlePresenceReceived(boost::shared_ptr<Presence>); + void handleMessageReceived(boost::shared_ptr<Message>); + void handleStanzaAcked(boost::shared_ptr<Stanza>); + void purgePassword(); private: JID jid_; - std::string password_; + SafeByteArray password_; NetworkFactories* networkFactories; - bool useStreamCompression; - UseTLS useTLS; ClientSessionStanzaChannel* stanzaChannel_; IQRouter* iqRouter_; - Connector::ref connector_; + ClientOptions options; + boost::shared_ptr<ChainedConnector> connector_; + std::vector<ConnectionFactory*> proxyConnectionFactories; PlatformTLSFactories* tlsFactories; boost::shared_ptr<Connection> connection_; boost::shared_ptr<BasicSessionStream> sessionStream_; diff --git a/Swiften/Client/DummyStanzaChannel.h b/Swiften/Client/DummyStanzaChannel.h index b9f05c3..c2f3919 100644 --- a/Swiften/Client/DummyStanzaChannel.h +++ b/Swiften/Client/DummyStanzaChannel.h @@ -8,7 +8,7 @@ #include <vector> -#include "Swiften/Client/StanzaChannel.h" +#include <Swiften/Client/StanzaChannel.h> namespace Swift { class DummyStanzaChannel : public StanzaChannel { @@ -56,6 +56,22 @@ namespace Swift { return iqStanza && iqStanza->getType() == type && iqStanza->getTo() == jid && iqStanza->getPayload<T>(); } + bool isResultAtIndex(size_t index, const std::string& id) { + if (index >= sentStanzas.size()) { + return false; + } + boost::shared_ptr<IQ> iqStanza = boost::dynamic_pointer_cast<IQ>(sentStanzas[index]); + return iqStanza && iqStanza->getType() == IQ::Result && iqStanza->getID() == id; + } + + bool isErrorAtIndex(size_t index, const std::string& id) { + if (index >= sentStanzas.size()) { + return false; + } + boost::shared_ptr<IQ> iqStanza = boost::dynamic_pointer_cast<IQ>(sentStanzas[index]); + return iqStanza && iqStanza->getType() == IQ::Error && iqStanza->getID() == id; + } + template<typename T> boost::shared_ptr<T> getStanzaAtIndex(size_t index) { if (sentStanzas.size() <= index) { return boost::shared_ptr<T>(); diff --git a/Swiften/Client/FileStorages.cpp b/Swiften/Client/FileStorages.cpp deleted file mode 100644 index 3c76c46..0000000 --- a/Swiften/Client/FileStorages.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include "Swiften/Client/FileStorages.h" -#include "Swiften/VCards/VCardFileStorage.h" -#include "Swiften/Avatars/AvatarFileStorage.h" -#include "Swiften/Disco/CapsFileStorage.h" - -namespace Swift { - -FileStorages::FileStorages(const boost::filesystem::path& baseDir, const JID& jid) { - std::string profile = jid.toBare(); - vcardStorage = new VCardFileStorage(baseDir / profile / "vcards"); - capsStorage = new CapsFileStorage(baseDir / "caps"); - avatarStorage = new AvatarFileStorage(baseDir / "avatars", baseDir / profile / "avatars"); -} - -FileStorages::~FileStorages() { - delete avatarStorage; - delete capsStorage; - delete vcardStorage; -} - -VCardStorage* FileStorages::getVCardStorage() const { - return vcardStorage; -} - -CapsStorage* FileStorages::getCapsStorage() const { - return capsStorage; -} - -AvatarStorage* FileStorages::getAvatarStorage() const { - return avatarStorage; -} - -} diff --git a/Swiften/Client/FileStorages.h b/Swiften/Client/FileStorages.h deleted file mode 100644 index 451105f..0000000 --- a/Swiften/Client/FileStorages.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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/filesystem.hpp> - -#include "Swiften/Client/Storages.h" - -namespace Swift { - class VCardFileStorage; - class AvatarFileStorage; - class CapsFileStorage; - class JID; - - /** - * A storages implementation that stores all controller data on disk. - */ - class FileStorages : public Storages { - public: - /** - * Creates the storages interface. - * - * All data will be stored relative to a base directory, and - * for some controllers, in a subdirectory for the given profile. - * The data is stored in the following places: - * - Avatars: <basedir>/avatars - * - VCards: <basedir>/<profile>/vcards - * - Entity capabilities: <basedir>/caps - * - * \param baseDir the base dir to store data relative to - * \param jid the subdir in which profile-specific data will be stored. - * The bare JID will be used as the subdir name. - */ - FileStorages(const boost::filesystem::path& baseDir, const JID& jid); - ~FileStorages(); - - virtual VCardStorage* getVCardStorage() const; - virtual AvatarStorage* getAvatarStorage() const; - virtual CapsStorage* getCapsStorage() const; - - private: - VCardFileStorage* vcardStorage; - AvatarFileStorage* avatarStorage; - CapsFileStorage* capsStorage; - }; -} diff --git a/Swiften/Client/MemoryStorages.cpp b/Swiften/Client/MemoryStorages.cpp index 5f6371b..fe171f7 100644 --- a/Swiften/Client/MemoryStorages.cpp +++ b/Swiften/Client/MemoryStorages.cpp @@ -4,10 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Client/MemoryStorages.h" -#include "Swiften/VCards/VCardMemoryStorage.h" -#include "Swiften/Avatars/AvatarMemoryStorage.h" -#include "Swiften/Disco/CapsMemoryStorage.h" +#include <Swiften/Client/MemoryStorages.h> +#include <Swiften/VCards/VCardMemoryStorage.h> +#include <Swiften/Avatars/AvatarMemoryStorage.h> +#include <Swiften/Disco/CapsMemoryStorage.h> +#include <Swiften/Roster/RosterMemoryStorage.h> namespace Swift { @@ -15,9 +16,11 @@ MemoryStorages::MemoryStorages() { vcardStorage = new VCardMemoryStorage(); capsStorage = new CapsMemoryStorage(); avatarStorage = new AvatarMemoryStorage(); + rosterStorage = new RosterMemoryStorage(); } MemoryStorages::~MemoryStorages() { + delete rosterStorage; delete avatarStorage; delete capsStorage; delete vcardStorage; @@ -35,4 +38,9 @@ AvatarStorage* MemoryStorages::getAvatarStorage() const { return avatarStorage; } +RosterStorage* MemoryStorages::getRosterStorage() const { + return rosterStorage; +} + + } diff --git a/Swiften/Client/MemoryStorages.h b/Swiften/Client/MemoryStorages.h index 67025cd..ca01a7a 100644 --- a/Swiften/Client/MemoryStorages.h +++ b/Swiften/Client/MemoryStorages.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Client/Storages.h" +#include <Swiften/Client/Storages.h> namespace Swift { class VCardMemoryStorage; @@ -23,10 +23,12 @@ namespace Swift { virtual VCardStorage* getVCardStorage() const; virtual AvatarStorage* getAvatarStorage() const; virtual CapsStorage* getCapsStorage() const; + virtual RosterStorage* getRosterStorage() const; private: VCardMemoryStorage* vcardStorage; AvatarStorage* avatarStorage; CapsStorage* capsStorage; + RosterStorage* rosterStorage; }; } diff --git a/Swiften/Client/NickResolver.cpp b/Swiften/Client/NickResolver.cpp index 6d5e742..e6f2e41 100644 --- a/Swiften/Client/NickResolver.cpp +++ b/Swiften/Client/NickResolver.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Client/NickResolver.h" +#include <Swiften/Client/NickResolver.h> #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/Roster/XMPPRoster.h" -#include "Swiften/VCards/VCardManager.h" +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/Roster/XMPPRoster.h> +#include <Swiften/VCards/VCardManager.h> // FIXME: The NickResolver currently relies on the vcard being requested by the client on login. // The VCardManager should get an onConnected() signal (which is signalled when the stanzachannel is available(, and each time this is emitted, diff --git a/Swiften/Client/NickResolver.h b/Swiften/Client/NickResolver.h index 881362a..584f2ce 100644 --- a/Swiften/Client/NickResolver.h +++ b/Swiften/Client/NickResolver.h @@ -5,12 +5,12 @@ */ #include <map> -#include <boost/signals.hpp> #include <boost/shared_ptr.hpp> +#include <Swiften/Base/boost_bsignals.h> #include <string> -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/VCard.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/VCard.h> namespace Swift { class XMPPRoster; diff --git a/Swiften/Client/StanzaChannel.h b/Swiften/Client/StanzaChannel.h index 4d6392c..f1d76e0 100644 --- a/Swiften/Client/StanzaChannel.h +++ b/Swiften/Client/StanzaChannel.h @@ -6,12 +6,12 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Queries/IQChannel.h" -#include "Swiften/Elements/Message.h" -#include "Swiften/Elements/Presence.h" +#include <Swiften/Queries/IQChannel.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/Presence.h> namespace Swift { class StanzaChannel : public IQChannel { diff --git a/Swiften/Client/Storages.cpp b/Swiften/Client/Storages.cpp new file mode 100644 index 0000000..3c2dbc5 --- /dev/null +++ b/Swiften/Client/Storages.cpp @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Client/Storages.h> + +using namespace Swift; + +Storages::~Storages() { +} diff --git a/Swiften/Client/Storages.h b/Swiften/Client/Storages.h index e62f0a9..1c5bbe9 100644 --- a/Swiften/Client/Storages.h +++ b/Swiften/Client/Storages.h @@ -10,6 +10,7 @@ namespace Swift { class VCardStorage; class AvatarStorage; class CapsStorage; + class RosterStorage; /** * An interface to hold storage classes for different @@ -17,10 +18,11 @@ namespace Swift { */ class Storages { public: - virtual ~Storages() {} + virtual ~Storages(); virtual VCardStorage* getVCardStorage() const = 0; virtual AvatarStorage* getAvatarStorage() const = 0; virtual CapsStorage* getCapsStorage() const = 0; + virtual RosterStorage* getRosterStorage() const = 0; }; } diff --git a/Swiften/Client/UnitTest/ClientSessionTest.cpp b/Swiften/Client/UnitTest/ClientSessionTest.cpp index 756287c..e9d1b21 100644 --- a/Swiften/Client/UnitTest/ClientSessionTest.cpp +++ b/Swiften/Client/UnitTest/ClientSessionTest.cpp @@ -11,23 +11,25 @@ #include <boost/optional.hpp> #include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/Session/SessionStream.h" -#include "Swiften/Client/ClientSession.h" -#include "Swiften/Elements/StartTLSRequest.h" -#include "Swiften/Elements/StreamFeatures.h" -#include "Swiften/Elements/StreamError.h" -#include "Swiften/Elements/TLSProceed.h" -#include "Swiften/Elements/StartTLSFailure.h" -#include "Swiften/Elements/AuthRequest.h" -#include "Swiften/Elements/AuthSuccess.h" -#include "Swiften/Elements/AuthFailure.h" -#include "Swiften/Elements/StreamManagementEnabled.h" -#include "Swiften/Elements/StreamManagementFailed.h" -#include "Swiften/Elements/EnableStreamManagement.h" -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/ResourceBind.h" -#include "Swiften/TLS/SimpleCertificate.h" -#include "Swiften/TLS/BlindCertificateTrustChecker.h" +#include <Swiften/Session/SessionStream.h> +#include <Swiften/Client/ClientSession.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/StartTLSRequest.h> +#include <Swiften/Elements/StreamFeatures.h> +#include <Swiften/Elements/StreamError.h> +#include <Swiften/Elements/TLSProceed.h> +#include <Swiften/Elements/StartTLSFailure.h> +#include <Swiften/Elements/AuthRequest.h> +#include <Swiften/Elements/AuthSuccess.h> +#include <Swiften/Elements/AuthFailure.h> +#include <Swiften/Elements/StreamManagementEnabled.h> +#include <Swiften/Elements/StreamManagementFailed.h> +#include <Swiften/Elements/StanzaAck.h> +#include <Swiften/Elements/EnableStreamManagement.h> +#include <Swiften/Elements/IQ.h> +#include <Swiften/Elements/ResourceBind.h> +#include <Swiften/TLS/SimpleCertificate.h> +#include <Swiften/TLS/BlindCertificateTrustChecker.h> using namespace Swift; @@ -43,8 +45,11 @@ class ClientSessionTest : public CppUnit::TestFixture { CPPUNIT_TEST(testAuthenticate); CPPUNIT_TEST(testAuthenticate_Unauthorized); CPPUNIT_TEST(testAuthenticate_NoValidAuthMechanisms); + CPPUNIT_TEST(testAuthenticate_PLAINOverNonTLS); + CPPUNIT_TEST(testAuthenticate_RequireTLS); CPPUNIT_TEST(testStreamManagement); CPPUNIT_TEST(testStreamManagement_Failed); + CPPUNIT_TEST(testFinishAcksStanzas); /* CPPUNIT_TEST(testResourceBind); CPPUNIT_TEST(testResourceBind_ChangeResource); @@ -178,7 +183,7 @@ class ClientSessionTest : public CppUnit::TestFixture { server->sendStreamFeaturesWithPLAINAuthentication(); CPPUNIT_ASSERT(needCredentials); CPPUNIT_ASSERT_EQUAL(ClientSession::WaitingForCredentials, session->getState()); - session->sendCredentials("mypass"); + session->sendCredentials(createSafeByteArray("mypass")); server->receiveAuthRequest("PLAIN"); server->sendAuthSuccess(); server->receiveStreamStart(); @@ -194,7 +199,7 @@ class ClientSessionTest : public CppUnit::TestFixture { server->sendStreamFeaturesWithPLAINAuthentication(); CPPUNIT_ASSERT(needCredentials); CPPUNIT_ASSERT_EQUAL(ClientSession::WaitingForCredentials, session->getState()); - session->sendCredentials("mypass"); + session->sendCredentials(createSafeByteArray("mypass")); server->receiveAuthRequest("PLAIN"); server->sendAuthFailure(); @@ -216,6 +221,20 @@ class ClientSessionTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(sessionFinishedError); } + void testAuthenticate_RequireTLS() { + boost::shared_ptr<ClientSession> session(createSession()); + session->setUseTLS(ClientSession::RequireTLS); + session->setAllowPLAINOverNonTLS(true); + session->start(); + server->receiveStreamStart(); + server->sendStreamStart(); + server->sendStreamFeaturesWithMultipleAuthentication(); + + CPPUNIT_ASSERT_EQUAL(ClientSession::Finished, session->getState()); + CPPUNIT_ASSERT(sessionFinishedReceived); + CPPUNIT_ASSERT(sessionFinishedError); + } + void testAuthenticate_NoValidAuthMechanisms() { boost::shared_ptr<ClientSession> session(createSession()); session->start(); @@ -234,7 +253,7 @@ class ClientSessionTest : public CppUnit::TestFixture { server->receiveStreamStart(); server->sendStreamStart(); server->sendStreamFeaturesWithPLAINAuthentication(); - session->sendCredentials("mypass"); + session->sendCredentials(createSafeByteArray("mypass")); server->receiveAuthRequest("PLAIN"); server->sendAuthSuccess(); server->receiveStreamStart(); @@ -258,7 +277,7 @@ class ClientSessionTest : public CppUnit::TestFixture { server->receiveStreamStart(); server->sendStreamStart(); server->sendStreamFeaturesWithPLAINAuthentication(); - session->sendCredentials("mypass"); + session->sendCredentials(createSafeByteArray("mypass")); server->receiveAuthRequest("PLAIN"); server->sendAuthSuccess(); server->receiveStreamStart(); @@ -275,6 +294,17 @@ class ClientSessionTest : public CppUnit::TestFixture { session->finish(); } + void testFinishAcksStanzas() { + boost::shared_ptr<ClientSession> session(createSession()); + initializeSession(session); + server->sendMessage(); + server->sendMessage(); + server->sendMessage(); + + session->finish(); + + server->receiveAck(3); + } private: boost::shared_ptr<ClientSession> createSession() { @@ -285,6 +315,23 @@ class ClientSessionTest : public CppUnit::TestFixture { return session; } + void initializeSession(boost::shared_ptr<ClientSession> session) { + session->start(); + server->receiveStreamStart(); + server->sendStreamStart(); + server->sendStreamFeaturesWithPLAINAuthentication(); + session->sendCredentials(createSafeByteArray("mypass")); + server->receiveAuthRequest("PLAIN"); + server->sendAuthSuccess(); + server->receiveStreamStart(); + server->sendStreamStart(); + server->sendStreamFeaturesWithBindAndStreamManagement(); + server->receiveBind(); + server->sendBindResult(); + server->receiveStreamManagementEnable(); + server->sendStreamManagementEnabled(); + } + void handleSessionFinished(boost::shared_ptr<Error> error) { sessionFinishedReceived = true; sessionFinishedError = error; @@ -401,6 +448,14 @@ class ClientSessionTest : public CppUnit::TestFixture { onElementReceived(boost::shared_ptr<StartTLSFailure>(new StartTLSFailure())); } + void sendStreamFeaturesWithMultipleAuthentication() { + boost::shared_ptr<StreamFeatures> streamFeatures(new StreamFeatures()); + streamFeatures->addAuthenticationMechanism("PLAIN"); + streamFeatures->addAuthenticationMechanism("DIGEST-MD5"); + streamFeatures->addAuthenticationMechanism("SCRAM-SHA1"); + onElementReceived(streamFeatures); + } + void sendStreamFeaturesWithPLAINAuthentication() { boost::shared_ptr<StreamFeatures> streamFeatures(new StreamFeatures()); streamFeatures->addAuthenticationMechanism("PLAIN"); @@ -447,6 +502,12 @@ class ClientSessionTest : public CppUnit::TestFixture { onElementReceived(iq); } + void sendMessage() { + boost::shared_ptr<Message> message = boost::make_shared<Message>(); + message->setTo(JID("foo@bar.com/bla")); + onElementReceived(message); + } + void receiveStreamStart() { Event event = popEvent(); CPPUNIT_ASSERT(event.header); @@ -481,8 +542,16 @@ class ClientSessionTest : public CppUnit::TestFixture { bindID = iq->getID(); } + void receiveAck(unsigned int n) { + Event event = popEvent(); + CPPUNIT_ASSERT(event.element); + boost::shared_ptr<StanzaAck> ack = boost::dynamic_pointer_cast<StanzaAck>(event.element); + CPPUNIT_ASSERT(ack); + CPPUNIT_ASSERT_EQUAL(n, ack->getHandledStanzasCount()); + } + Event popEvent() { - CPPUNIT_ASSERT(receivedEvents.size() > 0); + CPPUNIT_ASSERT(!receivedEvents.empty()); Event event = receivedEvents.front(); receivedEvents.pop_front(); return event; diff --git a/Swiften/Client/UnitTest/NickResolverTest.cpp b/Swiften/Client/UnitTest/NickResolverTest.cpp index bd778d4..dfc90fe 100644 --- a/Swiften/Client/UnitTest/NickResolverTest.cpp +++ b/Swiften/Client/UnitTest/NickResolverTest.cpp @@ -7,13 +7,13 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Client/NickResolver.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/Roster/XMPPRosterImpl.h" -#include "Swiften/VCards/VCardManager.h" -#include "Swiften/VCards/VCardMemoryStorage.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Client/DummyStanzaChannel.h" +#include <Swiften/Client/NickResolver.h> +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/Roster/XMPPRosterImpl.h> +#include <Swiften/VCards/VCardManager.h> +#include <Swiften/VCards/VCardMemoryStorage.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Client/DummyStanzaChannel.h> using namespace Swift; diff --git a/Swiften/Client/XMLBeautifier.cpp b/Swiften/Client/XMLBeautifier.cpp new file mode 100644 index 0000000..b70fc48 --- /dev/null +++ b/Swiften/Client/XMLBeautifier.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <sstream> +#include <stack> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/Log.h> +#include <Swiften/Client/XMLBeautifier.h> +#include <Swiften/Parser/PlatformXMLParserFactory.h> + +namespace Swift { + +XMLBeautifier::XMLBeautifier(bool indention, bool coloring) : doIndention(indention), doColoring(coloring), intLevel(0), parser(NULL), lastWasStepDown(false) { + factory = new PlatformXMLParserFactory(); +} + +XMLBeautifier::~XMLBeautifier() { + delete factory; +} + +std::string XMLBeautifier::beautify(const std::string &text) { + parser = factory->createXMLParser(this); + intLevel = 0; + buffer.str(std::string()); + parser->parse(text); + delete parser; + return buffer.str(); +} + +void XMLBeautifier::indent() { + for (int i = 0; i < intLevel; ++i) { + buffer << " "; + } +} + +// all bold but reset +const char colorBlue[] = "\x1b[01;34m"; +const char colorCyan[] = "\x1b[01;36m"; +const char colorGreen[] = "\x1b[01;32m"; +const char colorMagenta[] = "\x1b[01;35m"; +const char colorRed[] = "\x1b[01;31m"; +const char colorReset[] = "\x1b[0m"; +const char colorYellow[] = "\x1b[01;33m"; + + + +std::string XMLBeautifier::styleTag(const std::string& text) const { + std::string result; + result += colorYellow; + result += text; + result += colorReset; + return result; +} + +std::string XMLBeautifier::styleNamespace(const std::string& text) const { + std::string result; + result += colorRed; + result += text; + result += colorReset; + return result; +} + +std::string XMLBeautifier::styleAttribute(const std::string& text) const { + std::string result; + result += colorGreen; + result += text; + result += colorReset; + return result; +} +std::string XMLBeautifier::styleValue(const std::string& text) const { + std::string result; + result += colorCyan; + result += text; + result += colorReset; + return result; +} + +void XMLBeautifier::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { + if (doIndention) { + if (intLevel) buffer << std::endl; + } + indent(); + buffer << "<" << (doColoring ? styleTag(element) : element); + if (!ns.empty() && (!parentNSs.empty() && parentNSs.top() != ns)) { + buffer << " "; + buffer << (doColoring ? styleAttribute("xmlns") : "xmlns"); + buffer << "="; + buffer << "\"" << (doColoring ? styleNamespace(ns) : ns) << "\""; + } + if (!attributes.getEntries().empty()) { + foreach(AttributeMap::Entry entry, attributes.getEntries()) { + buffer << " "; + buffer << (doColoring ? styleAttribute(entry.getAttribute().getName()) : entry.getAttribute().getName()); + buffer << "="; + buffer << "\"" << (doColoring ? styleValue(entry.getValue()) : entry.getValue()) << "\""; + } + } + buffer << ">"; + ++intLevel; + lastWasStepDown = false; + parentNSs.push(ns); +} + +void XMLBeautifier::handleEndElement(const std::string& element, const std::string& /* ns */) { + --intLevel; + parentNSs.pop(); + if (/*hadCDATA.top() ||*/ lastWasStepDown) { + if (doIndention) { + buffer << std::endl; + } + indent(); + } + buffer << "</" << (doColoring ? styleTag(element) : element) << ">"; + lastWasStepDown = true; +} + +void XMLBeautifier::handleCharacterData(const std::string& data) { + buffer << data; + lastWasStepDown = false; +} + +} diff --git a/Swiften/Client/XMLBeautifier.h b/Swiften/Client/XMLBeautifier.h new file mode 100644 index 0000000..44dfd20 --- /dev/null +++ b/Swiften/Client/XMLBeautifier.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <string> +#include <stack> + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Parser/XMLParserFactory.h> +#include <Swiften/Parser/XMLParserClient.h> +#include <Swiften/Parser/XMLParser.h> + +namespace Swift { + +class XMLBeautifier : public XMLParserClient { +public: + XMLBeautifier(bool indention, bool coloring); + virtual ~XMLBeautifier(); + + std::string beautify(const std::string&); + +private: + void handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes); + void handleEndElement(const std::string& element, const std::string& ns); + void handleCharacterData(const std::string& data); + +private: + void indent(); + +private: + std::string styleTag(const std::string& text) const; + std::string styleNamespace(const std::string& text) const; + std::string styleAttribute(const std::string& text) const; + std::string styleValue(const std::string& text) const; + +private: + bool doIndention; + bool doColoring; + + int intLevel; + std::string inputBuffer; + std::stringstream buffer; + XMLParserFactory* factory; + XMLParser* parser; + + bool lastWasStepDown; + std::stack<std::string> parentNSs; +}; +} diff --git a/Swiften/Component/Component.cpp b/Swiften/Component/Component.cpp index fb4ba4c..af378a7 100644 --- a/Swiften/Component/Component.cpp +++ b/Swiften/Component/Component.cpp @@ -4,9 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Component/Component.h" +#include <Swiften/Component/Component.h> -#include "Swiften/Queries/Responders/SoftwareVersionResponder.h" +#include <Swiften/Queries/Responders/SoftwareVersionResponder.h> namespace Swift { diff --git a/Swiften/Component/Component.h b/Swiften/Component/Component.h index 0119db0..0b29ff7 100644 --- a/Swiften/Component/Component.h +++ b/Swiften/Component/Component.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Component/CoreComponent.h" +#include <Swiften/Component/CoreComponent.h> namespace Swift { class SoftwareVersionResponder; diff --git a/Swiften/Component/ComponentConnector.cpp b/Swiften/Component/ComponentConnector.cpp index 2af45f6..b7bdd34 100644 --- a/Swiften/Component/ComponentConnector.cpp +++ b/Swiften/Component/ComponentConnector.cpp @@ -4,15 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Component/ComponentConnector.h" +#include <Swiften/Component/ComponentConnector.h> #include <boost/bind.hpp> #include <iostream> -#include "Swiften/Network/ConnectionFactory.h" -#include "Swiften/Network/DomainNameResolver.h" -#include "Swiften/Network/DomainNameAddressQuery.h" -#include "Swiften/Network/TimerFactory.h" +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/DomainNameResolver.h> +#include <Swiften/Network/DomainNameAddressQuery.h> +#include <Swiften/Network/TimerFactory.h> namespace Swift { diff --git a/Swiften/Component/ComponentConnector.h b/Swiften/Component/ComponentConnector.h index c5e8f80..b47f5da 100644 --- a/Swiften/Component/ComponentConnector.h +++ b/Swiften/Component/ComponentConnector.h @@ -7,14 +7,14 @@ #pragma once #include <deque> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Network/Connection.h" -#include "Swiften/Network/Timer.h" -#include "Swiften/Network/HostAddressPort.h" +#include <Swiften/Network/Connection.h> +#include <Swiften/Network/Timer.h> +#include <Swiften/Network/HostAddressPort.h> #include <string> -#include "Swiften/Network/DomainNameResolveError.h" +#include <Swiften/Network/DomainNameResolveError.h> namespace Swift { class DomainNameAddressQuery; @@ -27,7 +27,7 @@ namespace Swift { typedef boost::shared_ptr<ComponentConnector> ref; static ComponentConnector::ref create(const std::string& hostname, int port, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) { - return ComponentConnector::ref(new ComponentConnector(hostname, port, resolver, connectionFactory, timerFactory)); + return ref(new ComponentConnector(hostname, port, resolver, connectionFactory, timerFactory)); } void setTimeoutMilliseconds(int milliseconds); diff --git a/Swiften/Component/ComponentHandshakeGenerator.cpp b/Swiften/Component/ComponentHandshakeGenerator.cpp index 4081420..79ba9b3 100644 --- a/Swiften/Component/ComponentHandshakeGenerator.cpp +++ b/Swiften/Component/ComponentHandshakeGenerator.cpp @@ -4,9 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Component/ComponentHandshakeGenerator.h" -#include "Swiften/StringCodecs/Hexify.h" -#include "Swiften/StringCodecs/SHA1.h" +#include <Swiften/Component/ComponentHandshakeGenerator.h> +#include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/StringCodecs/SHA1.h> #include <Swiften/Base/String.h> namespace Swift { @@ -18,7 +18,7 @@ std::string ComponentHandshakeGenerator::getHandshake(const std::string& streamI String::replaceAll(concatenatedString, '>', ">"); String::replaceAll(concatenatedString, '\'', "'"); String::replaceAll(concatenatedString, '"', """); - return Hexify::hexify(SHA1::getHash(ByteArray(concatenatedString))); + return Hexify::hexify(SHA1::getHash(createByteArray(concatenatedString))); } } diff --git a/Swiften/Component/ComponentSession.cpp b/Swiften/Component/ComponentSession.cpp index 17e0dfd..af11146 100644 --- a/Swiften/Component/ComponentSession.cpp +++ b/Swiften/Component/ComponentSession.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Component/ComponentSession.h" +#include <Swiften/Component/ComponentSession.h> #include <boost/bind.hpp> -#include "Swiften/Elements/ProtocolHeader.h" -#include "Swiften/Elements/ComponentHandshake.h" -#include "Swiften/Session/SessionStream.h" -#include "Swiften/Component/ComponentHandshakeGenerator.h" +#include <Swiften/Elements/ProtocolHeader.h> +#include <Swiften/Elements/ComponentHandshake.h> +#include <Swiften/Session/SessionStream.h> +#include <Swiften/Component/ComponentHandshakeGenerator.h> namespace Swift { diff --git a/Swiften/Component/ComponentSession.h b/Swiften/Component/ComponentSession.h index 168e618..647bad7 100644 --- a/Swiften/Component/ComponentSession.h +++ b/Swiften/Component/ComponentSession.h @@ -9,13 +9,13 @@ #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> -#include "Swiften/JID/JID.h" -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/Base/Error.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Base/Error.h> #include <string> -#include "Swiften/Elements/Element.h" -#include "Swiften/Elements/Stanza.h" -#include "Swiften/Session/SessionStream.h" +#include <Swiften/Elements/Element.h> +#include <Swiften/Elements/Stanza.h> +#include <Swiften/Session/SessionStream.h> namespace Swift { class ComponentAuthenticator; diff --git a/Swiften/Component/ComponentSessionStanzaChannel.cpp b/Swiften/Component/ComponentSessionStanzaChannel.cpp index b9fecb2..3e96dce 100644 --- a/Swiften/Component/ComponentSessionStanzaChannel.cpp +++ b/Swiften/Component/ComponentSessionStanzaChannel.cpp @@ -4,9 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Component/ComponentSessionStanzaChannel.h" +#include <Swiften/Component/ComponentSessionStanzaChannel.h> #include <boost/bind.hpp> +#include <iostream> namespace Swift { diff --git a/Swiften/Component/ComponentSessionStanzaChannel.h b/Swiften/Component/ComponentSessionStanzaChannel.h index 605c8dc..45f90b5 100644 --- a/Swiften/Component/ComponentSessionStanzaChannel.h +++ b/Swiften/Component/ComponentSessionStanzaChannel.h @@ -8,12 +8,12 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Base/IDGenerator.h" -#include "Swiften/Component/ComponentSession.h" -#include "Swiften/Client/StanzaChannel.h" -#include "Swiften/Elements/Message.h" -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/Presence.h" +#include <Swiften/Base/IDGenerator.h> +#include <Swiften/Component/ComponentSession.h> +#include <Swiften/Client/StanzaChannel.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/IQ.h> +#include <Swiften/Elements/Presence.h> namespace Swift { /** diff --git a/Swiften/Component/ComponentXMLTracer.cpp b/Swiften/Component/ComponentXMLTracer.cpp new file mode 100644 index 0000000..d77eef7 --- /dev/null +++ b/Swiften/Component/ComponentXMLTracer.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Component/ComponentXMLTracer.h> + +#include <iostream> +#include <boost/bind.hpp> + +namespace Swift { + +ComponentXMLTracer::ComponentXMLTracer(CoreComponent* client) { + client->onDataRead.connect(boost::bind(&ComponentXMLTracer::printData, '<', _1)); + client->onDataWritten.connect(boost::bind(&ComponentXMLTracer::printData, '>', _1)); +} + +void ComponentXMLTracer::printData(char direction, const SafeByteArray& data) { + printLine(direction); + std::cerr << byteArrayToString(ByteArray(data.begin(), data.end())) << std::endl; +} + +void ComponentXMLTracer::printLine(char c) { + for (unsigned int i = 0; i < 80; ++i) { + std::cerr << c; + } + std::cerr << std::endl; +} + +} diff --git a/Swiften/Component/ComponentXMLTracer.h b/Swiften/Component/ComponentXMLTracer.h index 70a617b..c12ec07 100644 --- a/Swiften/Component/ComponentXMLTracer.h +++ b/Swiften/Component/ComponentXMLTracer.h @@ -6,29 +6,15 @@ #pragma once -#include <boost/bind.hpp> - -#include "Swiften/Component/Component.h" +#include <Swiften/Component/Component.h> namespace Swift { class ComponentXMLTracer { public: - ComponentXMLTracer(Component* component) { - component->onDataRead.connect(boost::bind(&ComponentXMLTracer::printData, '<', _1)); - component->onDataWritten.connect(boost::bind(&ComponentXMLTracer::printData, '>', _1)); - } + ComponentXMLTracer(CoreComponent* component); private: - static void printData(char direction, const std::string& data) { - printLine(direction); - std::cerr << data << std::endl; - } - - static void printLine(char c) { - for (unsigned int i = 0; i < 80; ++i) { - std::cerr << c; - } - std::cerr << std::endl; - } + static void printData(char direction, const SafeByteArray& data); + static void printLine(char c); }; } diff --git a/Swiften/Component/CoreComponent.cpp b/Swiften/Component/CoreComponent.cpp index e79d735..7ee1ff5 100644 --- a/Swiften/Component/CoreComponent.cpp +++ b/Swiften/Component/CoreComponent.cpp @@ -4,18 +4,19 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Component/CoreComponent.h" +#include <Swiften/Component/CoreComponent.h> #include <boost/bind.hpp> +#include <iostream> -#include "Swiften/Component/ComponentSession.h" -#include "Swiften/Network/Connector.h" -#include "Swiften/Network/NetworkFactories.h" -#include "Swiften/TLS/PKCS12Certificate.h" -#include "Swiften/Session/BasicSessionStream.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Base/IDGenerator.h" -#include "Swiften/Component/ComponentSessionStanzaChannel.h" +#include <Swiften/Component/ComponentSession.h> +#include <Swiften/Network/Connector.h> +#include <Swiften/Network/NetworkFactories.h> +#include <Swiften/TLS/PKCS12Certificate.h> +#include <Swiften/Session/BasicSessionStream.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Base/IDGenerator.h> +#include <Swiften/Component/ComponentSessionStanzaChannel.h> namespace Swift { @@ -138,11 +139,11 @@ void CoreComponent::handleSessionFinished(boost::shared_ptr<Error> error) { } } -void CoreComponent::handleDataRead(const std::string& data) { +void CoreComponent::handleDataRead(const SafeByteArray& data) { onDataRead(data); } -void CoreComponent::handleDataWritten(const std::string& data) { +void CoreComponent::handleDataWritten(const SafeByteArray& data) { onDataWritten(data); } diff --git a/Swiften/Component/CoreComponent.h b/Swiften/Component/CoreComponent.h index 64c9071..e7945d1 100644 --- a/Swiften/Component/CoreComponent.h +++ b/Swiften/Component/CoreComponent.h @@ -8,20 +8,21 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/Base/Error.h" -#include "Swiften/Network/PlatformDomainNameResolver.h" -#include "Swiften/Component/ComponentConnector.h" -#include "Swiften/Component/ComponentSession.h" -#include "Swiften/Component/ComponentError.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/Message.h" -#include "Swiften/JID/JID.h" +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Base/Error.h> +#include <Swiften/Network/PlatformDomainNameResolver.h> +#include <Swiften/Component/ComponentConnector.h> +#include <Swiften/Component/ComponentSession.h> +#include <Swiften/Component/ComponentError.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/JID/JID.h> #include <string> -#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" -#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h" -#include "Swiften/Component/ComponentSessionStanzaChannel.h" +#include <Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h> +#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h> +#include <Swiften/Component/ComponentSessionStanzaChannel.h> #include <Swiften/Entity/Entity.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class IQRouter; @@ -72,8 +73,8 @@ namespace Swift { public: boost::signal<void (const ComponentError&)> onError; boost::signal<void ()> onConnected; - boost::signal<void (const std::string&)> onDataRead; - boost::signal<void (const std::string&)> onDataWritten; + boost::signal<void (const SafeByteArray&)> onDataRead; + boost::signal<void (const SafeByteArray&)> onDataWritten; boost::signal<void (boost::shared_ptr<Message>)> onMessageReceived; boost::signal<void (boost::shared_ptr<Presence>) > onPresenceReceived; @@ -82,8 +83,8 @@ namespace Swift { void handleConnectorFinished(boost::shared_ptr<Connection>); void handleStanzaChannelAvailableChanged(bool available); void handleSessionFinished(boost::shared_ptr<Error>); - void handleDataRead(const std::string&); - void handleDataWritten(const std::string&); + void handleDataRead(const SafeByteArray&); + void handleDataWritten(const SafeByteArray&); private: EventLoop* eventLoop; diff --git a/Swiften/Component/SConscript b/Swiften/Component/SConscript index 0a9f250..ef5700c 100644 --- a/Swiften/Component/SConscript +++ b/Swiften/Component/SConscript @@ -7,6 +7,7 @@ sources = [ "ComponentSessionStanzaChannel.cpp", "CoreComponent.cpp", "Component.cpp", + "ComponentXMLTracer.cpp", ] swiften_env.Append(SWIFTEN_OBJECTS = swiften_env.SwiftenObject(sources)) diff --git a/Swiften/Component/UnitTest/ComponentConnectorTest.cpp b/Swiften/Component/UnitTest/ComponentConnectorTest.cpp index 052b5de..1b2a36b 100644 --- a/Swiften/Component/UnitTest/ComponentConnectorTest.cpp +++ b/Swiften/Component/UnitTest/ComponentConnectorTest.cpp @@ -10,13 +10,13 @@ #include <boost/optional.hpp> #include <boost/bind.hpp> -#include "Swiften/Component/ComponentConnector.h" -#include "Swiften/Network/Connection.h" -#include "Swiften/Network/ConnectionFactory.h" -#include "Swiften/Network/HostAddressPort.h" -#include "Swiften/Network/StaticDomainNameResolver.h" -#include "Swiften/Network/DummyTimerFactory.h" -#include "Swiften/EventLoop/DummyEventLoop.h" +#include <Swiften/Component/ComponentConnector.h> +#include <Swiften/Network/Connection.h> +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Network/StaticDomainNameResolver.h> +#include <Swiften/Network/DummyTimerFactory.h> +#include <Swiften/EventLoop/DummyEventLoop.h> using namespace Swift; @@ -174,7 +174,7 @@ class ComponentConnectorTest : public CppUnit::TestFixture { } void disconnect() { assert(false); } - void write(const ByteArray&) { assert(false); } + void write(const SafeByteArray&) { assert(false); } HostAddressPort getLocalAddress() const { return HostAddressPort(); } EventLoop* eventLoop; diff --git a/Swiften/Component/UnitTest/ComponentHandshakeGeneratorTest.cpp b/Swiften/Component/UnitTest/ComponentHandshakeGeneratorTest.cpp index 5366478..fd8f6fc 100644 --- a/Swiften/Component/UnitTest/ComponentHandshakeGeneratorTest.cpp +++ b/Swiften/Component/UnitTest/ComponentHandshakeGeneratorTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Component/ComponentHandshakeGenerator.h" +#include <Swiften/Component/ComponentHandshakeGenerator.h> using namespace Swift; diff --git a/Swiften/Component/UnitTest/ComponentSessionTest.cpp b/Swiften/Component/UnitTest/ComponentSessionTest.cpp index 953973c..c27ade5 100644 --- a/Swiften/Component/UnitTest/ComponentSessionTest.cpp +++ b/Swiften/Component/UnitTest/ComponentSessionTest.cpp @@ -10,10 +10,10 @@ #include <boost/bind.hpp> #include <boost/optional.hpp> -#include "Swiften/Session/SessionStream.h" -#include "Swiften/Component/ComponentSession.h" -#include "Swiften/Elements/ComponentHandshake.h" -#include "Swiften/Elements/AuthFailure.h" +#include <Swiften/Session/SessionStream.h> +#include <Swiften/Component/ComponentSession.h> +#include <Swiften/Elements/ComponentHandshake.h> +#include <Swiften/Elements/AuthFailure.h> using namespace Swift; @@ -187,7 +187,7 @@ class ComponentSessionTest : public CppUnit::TestFixture { } Event popEvent() { - CPPUNIT_ASSERT(receivedEvents.size() > 0); + CPPUNIT_ASSERT(!receivedEvents.empty()); Event event = receivedEvents.front(); receivedEvents.pop_front(); return event; diff --git a/Swiften/Compress/UnitTest/ZLibCompressorTest.cpp b/Swiften/Compress/UnitTest/ZLibCompressorTest.cpp index 0b2fa5a..1de9322 100644 --- a/Swiften/Compress/UnitTest/ZLibCompressorTest.cpp +++ b/Swiften/Compress/UnitTest/ZLibCompressorTest.cpp @@ -4,12 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/SafeByteArray.h> +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Compress/ZLibCompressor.h" +#include <Swiften/Compress/ZLibCompressor.h> using namespace Swift; @@ -26,17 +27,17 @@ class ZLibCompressorTest : public CppUnit::TestFixture void testProcess() { ZLibCompressor testling; - ByteArray result = testling.process("foo"); + SafeByteArray result = testling.process(createSafeByteArray("foo")); - CPPUNIT_ASSERT_EQUAL(ByteArray("\x78\xda\x4a\xcb\xcf\x07\x00\x00\x00\xff\xff", 11), result); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("\x78\xda\x4a\xcb\xcf\x07\x00\x00\x00\xff\xff", 11), result); } void testProcess_Twice() { ZLibCompressor testling; - testling.process("foo"); - ByteArray result = testling.process("bar"); + testling.process(createSafeByteArray("foo")); + SafeByteArray result = testling.process(createSafeByteArray("bar")); - CPPUNIT_ASSERT_EQUAL(ByteArray("\x4a\x4a\x2c\x02\x00\x00\x00\xff\xff",9), result); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("\x4a\x4a\x2c\x02\x00\x00\x00\xff\xff",9), result); } }; diff --git a/Swiften/Compress/UnitTest/ZLibDecompressorTest.cpp b/Swiften/Compress/UnitTest/ZLibDecompressorTest.cpp index 3ee5c4f..906c2dd 100644 --- a/Swiften/Compress/UnitTest/ZLibDecompressorTest.cpp +++ b/Swiften/Compress/UnitTest/ZLibDecompressorTest.cpp @@ -4,14 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Compress/ZLibDecompressor.h" -#include "Swiften/Compress/ZLibCompressor.h" -#include "Swiften/Compress/ZLibException.h" +#include <Swiften/Compress/ZLibDecompressor.h> +#include <Swiften/Compress/ZLibCompressor.h> +#include <Swiften/Compress/ZLibException.h> using namespace Swift; @@ -31,22 +32,22 @@ class ZLibDecompressorTest : public CppUnit::TestFixture void testProcess() { ZLibDecompressor testling; - ByteArray result = testling.process(ByteArray("\x78\xda\x4a\xcb\xcf\x07\x00\x00\x00\xff\xff", 11)); + SafeByteArray result = testling.process(createSafeByteArray("\x78\xda\x4a\xcb\xcf\x07\x00\x00\x00\xff\xff", 11)); - CPPUNIT_ASSERT_EQUAL(ByteArray("foo"), result); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("foo"), result); } void testProcess_Twice() { ZLibDecompressor testling; - testling.process(ByteArray("\x78\xda\x4a\xcb\xcf\x07\x00\x00\x00\xff\xff", 11)); - ByteArray result = testling.process(ByteArray("\x4a\x4a\x2c\x02\x00\x00\x00\xff\xff", 9)); + testling.process(createSafeByteArray("\x78\xda\x4a\xcb\xcf\x07\x00\x00\x00\xff\xff", 11)); + SafeByteArray result = testling.process(createSafeByteArray("\x4a\x4a\x2c\x02\x00\x00\x00\xff\xff", 9)); - CPPUNIT_ASSERT_EQUAL(ByteArray("bar"), result); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("bar"), result); } void testProcess_Invalid() { ZLibDecompressor testling; - CPPUNIT_ASSERT_THROW(testling.process(ByteArray("invalid")), ZLibException); + CPPUNIT_ASSERT_THROW(testling.process(createSafeByteArray("invalid")), ZLibException); } void testProcess_Huge() { @@ -55,9 +56,9 @@ class ZLibDecompressorTest : public CppUnit::TestFixture for (unsigned int i = 0; i < 2048; ++i) { data.push_back(static_cast<char>(i)); } - ByteArray original(&data[0], data.size()); - ByteArray compressed = ZLibCompressor().process(original); - ByteArray decompressed = ZLibDecompressor().process(compressed); + SafeByteArray original(createSafeByteArray(&data[0], data.size())); + SafeByteArray compressed = ZLibCompressor().process(original); + SafeByteArray decompressed = ZLibDecompressor().process(compressed); CPPUNIT_ASSERT_EQUAL(original, decompressed); } @@ -68,9 +69,9 @@ class ZLibDecompressorTest : public CppUnit::TestFixture for (unsigned int i = 0; i < 1024; ++i) { data.push_back(static_cast<char>(i)); } - ByteArray original(&data[0], data.size()); - ByteArray compressed = ZLibCompressor().process(original); - ByteArray decompressed = ZLibDecompressor().process(compressed); + SafeByteArray original(createSafeByteArray(&data[0], data.size())); + SafeByteArray compressed = ZLibCompressor().process(original); + SafeByteArray decompressed = ZLibDecompressor().process(compressed); CPPUNIT_ASSERT_EQUAL(original, decompressed); } diff --git a/Swiften/Compress/ZLibCodecompressor.cpp b/Swiften/Compress/ZLibCodecompressor.cpp index c093fb3..0869d6b 100644 --- a/Swiften/Compress/ZLibCodecompressor.cpp +++ b/Swiften/Compress/ZLibCodecompressor.cpp @@ -4,11 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Compress/ZLibCodecompressor.h" +#include <Swiften/Compress/ZLibCodecompressor.h> #include <cassert> +#include <string.h> -#include "Swiften/Compress/ZLibException.h" +#include <Swiften/Compress/ZLibException.h> namespace Swift { @@ -24,15 +25,15 @@ ZLibCodecompressor::ZLibCodecompressor() { ZLibCodecompressor::~ZLibCodecompressor() { } -ByteArray ZLibCodecompressor::process(const ByteArray& input) { - ByteArray output; - stream_.avail_in = input.getSize(); - stream_.next_in = reinterpret_cast<Bytef*>(const_cast<unsigned char*>(input.getData())); +SafeByteArray ZLibCodecompressor::process(const SafeByteArray& input) { + SafeByteArray output; + stream_.avail_in = input.size(); + stream_.next_in = reinterpret_cast<Bytef*>(const_cast<unsigned char*>(vecptr(input))); int outputPosition = 0; do { output.resize(outputPosition + CHUNK_SIZE); stream_.avail_out = CHUNK_SIZE; - stream_.next_out = reinterpret_cast<Bytef*>(output.getData() + outputPosition); + stream_.next_out = reinterpret_cast<Bytef*>(vecptr(output) + outputPosition); int result = processZStream(); if (result != Z_OK && result != Z_BUF_ERROR) { throw ZLibException(/* stream_.msg */); diff --git a/Swiften/Compress/ZLibCodecompressor.h b/Swiften/Compress/ZLibCodecompressor.h index 289704d..93babf0 100644 --- a/Swiften/Compress/ZLibCodecompressor.h +++ b/Swiften/Compress/ZLibCodecompressor.h @@ -4,12 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_ZLibCodecompressor_H -#define SWIFTEN_ZLibCodecompressor_H +#pragma once #include <zlib.h> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class ZLibCodecompressor { @@ -17,12 +16,10 @@ namespace Swift { ZLibCodecompressor(); virtual ~ZLibCodecompressor(); - ByteArray process(const ByteArray& data); + SafeByteArray process(const SafeByteArray& data); virtual int processZStream() = 0; protected: z_stream stream_; }; } - -#endif diff --git a/Swiften/Compress/ZLibCompressor.cpp b/Swiften/Compress/ZLibCompressor.cpp index 7e3116e..5d98e38 100644 --- a/Swiften/Compress/ZLibCompressor.cpp +++ b/Swiften/Compress/ZLibCompressor.cpp @@ -4,7 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Compress/ZLibCompressor.h" +#include <Swiften/Compress/ZLibCompressor.h> + +#include <cassert> #pragma GCC diagnostic ignored "-Wold-style-cast" diff --git a/Swiften/Compress/ZLibCompressor.h b/Swiften/Compress/ZLibCompressor.h index 7fe5387..1add725 100644 --- a/Swiften/Compress/ZLibCompressor.h +++ b/Swiften/Compress/ZLibCompressor.h @@ -6,10 +6,8 @@ #pragma once -#include <cassert> - -#include "Swiften/Compress/ZLibCodecompressor.h" -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Compress/ZLibCodecompressor.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { class ZLibCompressor : public ZLibCodecompressor { diff --git a/Swiften/Compress/ZLibDecompressor.cpp b/Swiften/Compress/ZLibDecompressor.cpp index af7349b..ab954f4 100644 --- a/Swiften/Compress/ZLibDecompressor.cpp +++ b/Swiften/Compress/ZLibDecompressor.cpp @@ -4,7 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Compress/ZLibDecompressor.h" +#include <Swiften/Compress/ZLibDecompressor.h> + +#include <cassert> #pragma GCC diagnostic ignored "-Wold-style-cast" diff --git a/Swiften/Compress/ZLibDecompressor.h b/Swiften/Compress/ZLibDecompressor.h index ec08a4f..67994d1 100644 --- a/Swiften/Compress/ZLibDecompressor.h +++ b/Swiften/Compress/ZLibDecompressor.h @@ -6,10 +6,8 @@ #pragma once -#include <cassert> - -#include "Swiften/Compress/ZLibCodecompressor.h" -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Compress/ZLibCodecompressor.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { class ZLibDecompressor : public ZLibCodecompressor { diff --git a/Swiften/Compress/ZLibException.h b/Swiften/Compress/ZLibException.h index 8e9fdb3..8e60aa3 100644 --- a/Swiften/Compress/ZLibException.h +++ b/Swiften/Compress/ZLibException.h @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_ZLIBEXCEPTION_H -#define SWIFTEN_ZLIBEXCEPTION_H +#pragma once + namespace Swift { class ZLibException { @@ -13,5 +13,3 @@ namespace Swift { ZLibException() {} }; } - -#endif diff --git a/Swiften/Config/swiften-config.cpp b/Swiften/Config/swiften-config.cpp index b616711..81a8357 100644 --- a/Swiften/Config/swiften-config.cpp +++ b/Swiften/Config/swiften-config.cpp @@ -11,6 +11,7 @@ #include <boost/program_options/variables_map.hpp> #include <boost/program_options.hpp> #include <boost/version.hpp> +#include <boost/filesystem.hpp> #include <string> #include <Swiften/Base/Platform.h> diff --git a/Swiften/Disco/CapsFileStorage.cpp b/Swiften/Disco/CapsFileStorage.cpp deleted file mode 100644 index 1e53854..0000000 --- a/Swiften/Disco/CapsFileStorage.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include "Swiften/Disco/CapsFileStorage.h" - -#include <iostream> -#include <boost/filesystem/fstream.hpp> - -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h" -#include "Swiften/Parser/PayloadParsers/DiscoInfoParser.h" -#include "Swiften/StringCodecs/Hexify.h" -#include "Swiften/StringCodecs/Base64.h" - -namespace Swift { - -CapsFileStorage::CapsFileStorage(const boost::filesystem::path& path) : path(path) { -} - -DiscoInfo::ref CapsFileStorage::getDiscoInfo(const std::string& hash) const { - boost::filesystem::path capsPath(getCapsPath(hash)); - if (boost::filesystem::exists(capsPath)) { - ByteArray data; - data.readFromFile(capsPath.string()); - - DiscoInfoParser parser; - PayloadParserTester tester(&parser); - tester.parse(data.toString()); - return boost::dynamic_pointer_cast<DiscoInfo>(parser.getPayload()); - } - else { - return DiscoInfo::ref(); - } -} - -void CapsFileStorage::setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo) { - boost::filesystem::path capsPath(getCapsPath(hash)); - if (!boost::filesystem::exists(capsPath.parent_path())) { - try { - boost::filesystem::create_directories(capsPath.parent_path()); - } - catch (const boost::filesystem::filesystem_error& e) { - std::cerr << "ERROR: " << e.what() << std::endl; - } - } - DiscoInfo::ref bareDiscoInfo(new DiscoInfo(*discoInfo.get())); - bareDiscoInfo->setNode(""); - boost::filesystem::ofstream file(capsPath); - file << DiscoInfoSerializer().serializePayload(bareDiscoInfo); - file.close(); -} - -boost::filesystem::path CapsFileStorage::getCapsPath(const std::string& hash) const { - return path / (Hexify::hexify(Base64::decode(hash)) + ".xml"); -} - -} diff --git a/Swiften/Disco/CapsFileStorage.h b/Swiften/Disco/CapsFileStorage.h deleted file mode 100644 index 5faf08b..0000000 --- a/Swiften/Disco/CapsFileStorage.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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/filesystem.hpp> - -#include "Swiften/Disco/CapsStorage.h" -#include <string> - -namespace Swift { - class CapsFileStorage : public CapsStorage { - public: - CapsFileStorage(const boost::filesystem::path& path); - - virtual DiscoInfo::ref getDiscoInfo(const std::string& hash) const; - virtual void setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo); - - private: - boost::filesystem::path getCapsPath(const std::string& hash) const; - - private: - boost::filesystem::path path; - }; -} diff --git a/Swiften/Disco/CapsInfoGenerator.cpp b/Swiften/Disco/CapsInfoGenerator.cpp index 5c0e9a7..6d84984 100644 --- a/Swiften/Disco/CapsInfoGenerator.cpp +++ b/Swiften/Disco/CapsInfoGenerator.cpp @@ -4,15 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Disco/CapsInfoGenerator.h" +#include <Swiften/Disco/CapsInfoGenerator.h> #include <algorithm> -#include "Swiften/Base/foreach.h" -#include "Swiften/Elements/DiscoInfo.h" -#include "Swiften/Elements/FormField.h" -#include "Swiften/StringCodecs/SHA1.h" -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Elements/DiscoInfo.h> +#include <Swiften/Elements/FormField.h> +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/StringCodecs/Base64.h> namespace { bool compareFields(Swift::FormField::ref f1, Swift::FormField::ref f2) { @@ -57,7 +57,7 @@ CapsInfo CapsInfoGenerator::generateCapsInfo(const DiscoInfo& discoInfo) const { } } - std::string version(Base64::encode(SHA1::getHash(serializedCaps))); + std::string version(Base64::encode(SHA1::getHash(createByteArray(serializedCaps)))); return CapsInfo(node_, version, "sha-1"); } diff --git a/Swiften/Disco/CapsInfoGenerator.h b/Swiften/Disco/CapsInfoGenerator.h index 41a1d94..d1b2663 100644 --- a/Swiften/Disco/CapsInfoGenerator.h +++ b/Swiften/Disco/CapsInfoGenerator.h @@ -7,7 +7,7 @@ #pragma once #include <string> -#include "Swiften/Elements/CapsInfo.h" +#include <Swiften/Elements/CapsInfo.h> namespace Swift { class DiscoInfo; diff --git a/Swiften/Disco/CapsManager.cpp b/Swiften/Disco/CapsManager.cpp index b08a895..66eb47e 100644 --- a/Swiften/Disco/CapsManager.cpp +++ b/Swiften/Disco/CapsManager.cpp @@ -4,15 +4,16 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Disco/CapsManager.h" +#include <Swiften/Disco/CapsManager.h> #include <boost/bind.hpp> +#include <iostream> -#include "Swiften/Client/StanzaChannel.h" -#include "Swiften/Disco/CapsStorage.h" -#include "Swiften/Disco/CapsInfoGenerator.h" -#include "Swiften/Elements/CapsInfo.h" -#include "Swiften/Disco/GetDiscoInfoRequest.h" +#include <Swiften/Client/StanzaChannel.h> +#include <Swiften/Disco/CapsStorage.h> +#include <Swiften/Disco/CapsInfoGenerator.h> +#include <Swiften/Elements/CapsInfo.h> +#include <Swiften/Disco/GetDiscoInfoRequest.h> namespace Swift { diff --git a/Swiften/Disco/CapsManager.h b/Swiften/Disco/CapsManager.h index 961dae8..ddc7997 100644 --- a/Swiften/Disco/CapsManager.h +++ b/Swiften/Disco/CapsManager.h @@ -9,12 +9,12 @@ #include <set> #include <map> -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/DiscoInfo.h" -#include "Swiften/Elements/CapsInfo.h" -#include "Swiften/Elements/ErrorPayload.h" -#include "Swiften/Disco/CapsProvider.h" +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Elements/DiscoInfo.h> +#include <Swiften/Elements/CapsInfo.h> +#include <Swiften/Elements/ErrorPayload.h> +#include <Swiften/Disco/CapsProvider.h> namespace Swift { class StanzaChannel; diff --git a/Swiften/Disco/CapsMemoryStorage.h b/Swiften/Disco/CapsMemoryStorage.h index 1e2d7be..2503d7d 100644 --- a/Swiften/Disco/CapsMemoryStorage.h +++ b/Swiften/Disco/CapsMemoryStorage.h @@ -10,7 +10,7 @@ #include <map> #include <string> -#include "Swiften/Disco/CapsStorage.h" +#include <Swiften/Disco/CapsStorage.h> namespace Swift { class CapsMemoryStorage : public CapsStorage { diff --git a/Swiften/Disco/CapsProvider.h b/Swiften/Disco/CapsProvider.h index 71e2741..8bb3767 100644 --- a/Swiften/Disco/CapsProvider.h +++ b/Swiften/Disco/CapsProvider.h @@ -6,9 +6,9 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/Elements/DiscoInfo.h" -#include "Swiften/Elements/CapsInfo.h" +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Elements/DiscoInfo.h> +#include <Swiften/Elements/CapsInfo.h> namespace Swift { diff --git a/Swiften/Disco/CapsStorage.cpp b/Swiften/Disco/CapsStorage.cpp index acb58fe..fe4a6ac 100644 --- a/Swiften/Disco/CapsStorage.cpp +++ b/Swiften/Disco/CapsStorage.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Disco/CapsStorage.h" +#include <Swiften/Disco/CapsStorage.h> namespace Swift { diff --git a/Swiften/Disco/CapsStorage.h b/Swiften/Disco/CapsStorage.h index f0a71a3..fb6e442 100644 --- a/Swiften/Disco/CapsStorage.h +++ b/Swiften/Disco/CapsStorage.h @@ -8,7 +8,7 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/DiscoInfo.h" +#include <Swiften/Elements/DiscoInfo.h> namespace Swift { diff --git a/Swiften/Disco/ClientDiscoManager.cpp b/Swiften/Disco/ClientDiscoManager.cpp index fb7cce9..99c0175 100644 --- a/Swiften/Disco/ClientDiscoManager.cpp +++ b/Swiften/Disco/ClientDiscoManager.cpp @@ -4,11 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Disco/ClientDiscoManager.h" +#include <Swiften/Disco/ClientDiscoManager.h> -#include "Swiften/Disco/DiscoInfoResponder.h" -#include "Swiften/Disco/CapsInfoGenerator.h" -#include "Swiften/Presence/PayloadAddingPresenceSender.h" +#include <Swiften/Disco/DiscoInfoResponder.h> +#include <Swiften/Disco/CapsInfoGenerator.h> +#include <Swiften/Presence/PayloadAddingPresenceSender.h> namespace Swift { diff --git a/Swiften/Disco/ClientDiscoManager.h b/Swiften/Disco/ClientDiscoManager.h index 3771044..f8ba9ac 100644 --- a/Swiften/Disco/ClientDiscoManager.h +++ b/Swiften/Disco/ClientDiscoManager.h @@ -6,9 +6,9 @@ #pragma once -#include "Swiften/Elements/CapsInfo.h" -#include "Swiften/Elements/DiscoInfo.h" -#include "Swiften/Presence/PayloadAddingPresenceSender.h" +#include <Swiften/Elements/CapsInfo.h> +#include <Swiften/Elements/DiscoInfo.h> +#include <Swiften/Presence/PayloadAddingPresenceSender.h> namespace Swift { class IQRouter; diff --git a/Swiften/Disco/DiscoInfoResponder.cpp b/Swiften/Disco/DiscoInfoResponder.cpp index 7ba044e..a8dd9f0 100644 --- a/Swiften/Disco/DiscoInfoResponder.cpp +++ b/Swiften/Disco/DiscoInfoResponder.cpp @@ -4,9 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Disco/DiscoInfoResponder.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Elements/DiscoInfo.h" +#include <Swiften/Disco/DiscoInfoResponder.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Elements/DiscoInfo.h> namespace Swift { diff --git a/Swiften/Disco/DiscoInfoResponder.h b/Swiften/Disco/DiscoInfoResponder.h index f114a21..af9f48f 100644 --- a/Swiften/Disco/DiscoInfoResponder.h +++ b/Swiften/Disco/DiscoInfoResponder.h @@ -8,8 +8,8 @@ #include <map> -#include "Swiften/Queries/GetResponder.h" -#include "Swiften/Elements/DiscoInfo.h" +#include <Swiften/Queries/GetResponder.h> +#include <Swiften/Elements/DiscoInfo.h> namespace Swift { class IQRouter; diff --git a/Swiften/Disco/DiscoServiceWalker.cpp b/Swiften/Disco/DiscoServiceWalker.cpp new file mode 100644 index 0000000..c8c3e1b --- /dev/null +++ b/Swiften/Disco/DiscoServiceWalker.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Disco/DiscoServiceWalker.h> + +#include <Swiften/Base/Log.h> +#include <Swiften/Base/foreach.h> + +#include <boost/bind.hpp> + +namespace Swift { + +DiscoServiceWalker::DiscoServiceWalker(const JID& service, IQRouter* iqRouter, size_t maxSteps) : service_(service), iqRouter_(iqRouter), maxSteps_(maxSteps), active_(false) { + +} + +void DiscoServiceWalker::beginWalk() { + SWIFT_LOG(debug) << "Starting walk to " << service_ << std::endl; + assert(!active_); + assert(servicesBeingSearched_.empty()); + active_ = true; + walkNode(service_); +} + +void DiscoServiceWalker::endWalk() { + if (active_) { + SWIFT_LOG(debug) << "Ending walk to " << service_ << std::endl; + foreach (GetDiscoInfoRequest::ref request, pendingDiscoInfoRequests_) { + request->onResponse.disconnect(boost::bind(&DiscoServiceWalker::handleDiscoInfoResponse, this, _1, _2, request)); + } + foreach (GetDiscoItemsRequest::ref request, pendingDiscoItemsRequests_) { + request->onResponse.disconnect(boost::bind(&DiscoServiceWalker::handleDiscoItemsResponse, this, _1, _2, request)); + } + active_ = false; + } +} + +void DiscoServiceWalker::walkNode(const JID& jid) { + SWIFT_LOG(debug) << "Walking node " << jid << std::endl; + servicesBeingSearched_.insert(jid); + searchedServices_.insert(jid); + GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(jid, iqRouter_); + discoInfoRequest->onResponse.connect(boost::bind(&DiscoServiceWalker::handleDiscoInfoResponse, this, _1, _2, discoInfoRequest)); + pendingDiscoInfoRequests_.insert(discoInfoRequest); + discoInfoRequest->send(); +} + +void DiscoServiceWalker::handleDiscoInfoResponse(boost::shared_ptr<DiscoInfo> info, ErrorPayload::ref error, GetDiscoInfoRequest::ref request) { + /* If we got canceled, don't do anything */ + if (!active_) { + return; + } + + SWIFT_LOG(debug) << "Disco info response from " << request->getReceiver() << std::endl; + + pendingDiscoInfoRequests_.erase(request); + if (error) { + handleDiscoError(request->getReceiver(), error); + return; + } + + bool couldContainServices = false; + foreach (DiscoInfo::Identity identity, info->getIdentities()) { + if (identity.getCategory() == "server") { + couldContainServices = true; + } + } + bool completed = false; + if (couldContainServices) { + GetDiscoItemsRequest::ref discoItemsRequest = GetDiscoItemsRequest::create(request->getReceiver(), iqRouter_); + discoItemsRequest->onResponse.connect(boost::bind(&DiscoServiceWalker::handleDiscoItemsResponse, this, _1, _2, discoItemsRequest)); + pendingDiscoItemsRequests_.insert(discoItemsRequest); + discoItemsRequest->send(); + } else { + completed = true; + } + onServiceFound(request->getReceiver(), info); + if (completed) { + markNodeCompleted(request->getReceiver()); + } +} + +void DiscoServiceWalker::handleDiscoItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error, GetDiscoItemsRequest::ref request) { + /* If we got canceled, don't do anything */ + if (!active_) { + return; + } + + SWIFT_LOG(debug) << "Received disco items from " << request->getReceiver() << std::endl; + pendingDiscoItemsRequests_.erase(request); + if (error) { + handleDiscoError(request->getReceiver(), error); + return; + } + foreach (DiscoItems::Item item, items->getItems()) { + if (item.getNode().empty()) { + /* Don't look at noded items. It's possible that this will exclude some services, + * but I've never seen one in the wild, and it's an easy fix for not looping. + */ + if (std::find(searchedServices_.begin(), searchedServices_.end(), item.getJID()) == searchedServices_.end()) { /* Don't recurse infinitely */ + SWIFT_LOG(debug) << "Received disco item " << item.getJID() << std::endl; + walkNode(item.getJID()); + } + } + } + markNodeCompleted(request->getReceiver()); +} + +void DiscoServiceWalker::handleDiscoError(const JID& jid, ErrorPayload::ref /*error*/) { + SWIFT_LOG(debug) << "Disco error from " << jid << std::endl; + markNodeCompleted(jid); +} + +void DiscoServiceWalker::markNodeCompleted(const JID& jid) { + SWIFT_LOG(debug) << "Node completed " << jid << std::endl; + servicesBeingSearched_.erase(jid); + /* All results are in */ + if (servicesBeingSearched_.empty()) { + active_ = false; + onWalkComplete(); + } + /* Check if we're on a rampage */ + else if (searchedServices_.size() >= maxSteps_) { + active_ = false; + onWalkComplete(); + } +} + +} diff --git a/Swiften/Disco/DiscoServiceWalker.h b/Swiften/Disco/DiscoServiceWalker.h new file mode 100644 index 0000000..fd749fc --- /dev/null +++ b/Swiften/Disco/DiscoServiceWalker.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> +#include <set> + +#include <boost/shared_ptr.hpp> +#include <Swiften/Base/boost_bsignals.h> +#include <string> +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/DiscoInfo.h> +#include <Swiften/Elements/DiscoItems.h> +#include <Swiften/Elements/ErrorPayload.h> +#include <Swiften/Disco/GetDiscoInfoRequest.h> +#include <Swiften/Disco/GetDiscoItemsRequest.h> + +namespace Swift { + class IQRouter; + /** + * Recursively walk service discovery trees to find all services offered. + * This stops on any disco item that's not reporting itself as a server. + */ + class DiscoServiceWalker { + public: + DiscoServiceWalker(const JID& service, IQRouter* iqRouter, size_t maxSteps = 200); + + /** + * Start the walk. + * + * Call this exactly once. + */ + void beginWalk(); + + /** + * End the walk. + */ + void endWalk(); + + bool isActive() const { + return active_; + } + + /** Emitted for each service found. */ + boost::signal<void(const JID&, boost::shared_ptr<DiscoInfo>)> onServiceFound; + + /** Emitted when walking is complete.*/ + boost::signal<void()> onWalkComplete; + + private: + void walkNode(const JID& jid); + void markNodeCompleted(const JID& jid); + void handleDiscoInfoResponse(boost::shared_ptr<DiscoInfo> info, ErrorPayload::ref error, GetDiscoInfoRequest::ref request); + void handleDiscoItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error, GetDiscoItemsRequest::ref request); + void handleDiscoError(const JID& jid, ErrorPayload::ref error); + + private: + JID service_; + IQRouter* iqRouter_; + size_t maxSteps_; + bool active_; + std::set<JID> servicesBeingSearched_; + std::set<JID> searchedServices_; + std::set<GetDiscoInfoRequest::ref> pendingDiscoInfoRequests_; + std::set<GetDiscoItemsRequest::ref> pendingDiscoItemsRequests_; + }; +} diff --git a/Swiften/Disco/DummyEntityCapsProvider.cpp b/Swiften/Disco/DummyEntityCapsProvider.cpp new file mode 100644 index 0000000..a906652 --- /dev/null +++ b/Swiften/Disco/DummyEntityCapsProvider.cpp @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Disco/DummyEntityCapsProvider.h> + +#include <iostream> + +namespace Swift { + +DiscoInfo::ref DummyEntityCapsProvider::getCaps(const JID& jid) const { + std::map<JID, DiscoInfo::ref>::const_iterator i = caps.find(jid); + if (i != caps.end()) { + return i->second; + } + return DiscoInfo::ref(); +} + +} diff --git a/Swiften/Disco/DummyEntityCapsProvider.h b/Swiften/Disco/DummyEntityCapsProvider.h index 68cef2f..a1e3db6 100644 --- a/Swiften/Disco/DummyEntityCapsProvider.h +++ b/Swiften/Disco/DummyEntityCapsProvider.h @@ -7,8 +7,8 @@ #pragma once #include <map> -#include <iostream> -#include "Swiften/Disco/EntityCapsProvider.h" + +#include <Swiften/Disco/EntityCapsProvider.h> namespace Swift { class DummyEntityCapsProvider : public EntityCapsProvider { @@ -16,13 +16,7 @@ namespace Swift { DummyEntityCapsProvider() { } - DiscoInfo::ref getCaps(const JID& jid) const { - std::map<JID, DiscoInfo::ref>::const_iterator i = caps.find(jid); - if (i != caps.end()) { - return i->second; - } - return DiscoInfo::ref(); - } + DiscoInfo::ref getCaps(const JID& jid) const; std::map<JID, DiscoInfo::ref> caps; }; diff --git a/Swiften/Disco/EntityCapsManager.cpp b/Swiften/Disco/EntityCapsManager.cpp index 3f2e3d7..1a9f5fb 100644 --- a/Swiften/Disco/EntityCapsManager.cpp +++ b/Swiften/Disco/EntityCapsManager.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Disco/EntityCapsManager.h" +#include <Swiften/Disco/EntityCapsManager.h> #include <boost/bind.hpp> -#include "Swiften/Disco/CapsProvider.h" -#include "Swiften/Client/StanzaChannel.h" +#include <Swiften/Disco/CapsProvider.h> +#include <Swiften/Client/StanzaChannel.h> namespace Swift { diff --git a/Swiften/Disco/EntityCapsManager.h b/Swiften/Disco/EntityCapsManager.h index 190f876..e41c15f 100644 --- a/Swiften/Disco/EntityCapsManager.h +++ b/Swiften/Disco/EntityCapsManager.h @@ -8,11 +8,11 @@ #include <map> -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/DiscoInfo.h" -#include "Swiften/Elements/ErrorPayload.h" -#include "Swiften/Disco/EntityCapsProvider.h" +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Elements/DiscoInfo.h> +#include <Swiften/Elements/ErrorPayload.h> +#include <Swiften/Disco/EntityCapsProvider.h> namespace Swift { class StanzaChannel; diff --git a/Swiften/Disco/EntityCapsProvider.cpp b/Swiften/Disco/EntityCapsProvider.cpp index a337328..e3262b6 100644 --- a/Swiften/Disco/EntityCapsProvider.cpp +++ b/Swiften/Disco/EntityCapsProvider.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Disco/EntityCapsProvider.h" +#include <Swiften/Disco/EntityCapsProvider.h> namespace Swift { diff --git a/Swiften/Disco/EntityCapsProvider.h b/Swiften/Disco/EntityCapsProvider.h index 07fa452..b38992c 100644 --- a/Swiften/Disco/EntityCapsProvider.h +++ b/Swiften/Disco/EntityCapsProvider.h @@ -6,9 +6,9 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/DiscoInfo.h" +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/DiscoInfo.h> namespace Swift { /** diff --git a/Swiften/Disco/GetDiscoInfoRequest.h b/Swiften/Disco/GetDiscoInfoRequest.h index 5cec530..e211632 100644 --- a/Swiften/Disco/GetDiscoInfoRequest.h +++ b/Swiften/Disco/GetDiscoInfoRequest.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Queries/GenericRequest.h" -#include "Swiften/Elements/DiscoInfo.h" +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Elements/DiscoInfo.h> namespace Swift { class GetDiscoInfoRequest : public GenericRequest<DiscoInfo> { diff --git a/Swiften/Disco/GetDiscoItemsRequest.h b/Swiften/Disco/GetDiscoItemsRequest.h index 0a94402..20d18f8 100644 --- a/Swiften/Disco/GetDiscoItemsRequest.h +++ b/Swiften/Disco/GetDiscoItemsRequest.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Queries/GenericRequest.h" -#include "Swiften/Elements/DiscoItems.h" +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Elements/DiscoItems.h> namespace Swift { class GetDiscoItemsRequest : public GenericRequest<DiscoItems> { @@ -18,9 +18,18 @@ namespace Swift { return ref(new GetDiscoItemsRequest(jid, router)); } + static ref create(const JID& jid, const std::string& node, IQRouter* router) { + return ref(new GetDiscoItemsRequest(jid, node, router)); + } + private: GetDiscoItemsRequest(const JID& jid, IQRouter* router) : GenericRequest<DiscoItems>(IQ::Get, jid, boost::shared_ptr<DiscoItems>(new DiscoItems()), router) { } + + GetDiscoItemsRequest(const JID& jid, const std::string& node, IQRouter* router) : + GenericRequest<DiscoItems>(IQ::Get, jid, boost::shared_ptr<DiscoItems>(new DiscoItems()), router) { + getPayloadGeneric()->setNode(node); + } }; } diff --git a/Swiften/Disco/JIDDiscoInfoResponder.cpp b/Swiften/Disco/JIDDiscoInfoResponder.cpp index 1298e5a..0a25bef 100644 --- a/Swiften/Disco/JIDDiscoInfoResponder.cpp +++ b/Swiften/Disco/JIDDiscoInfoResponder.cpp @@ -4,9 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Disco/JIDDiscoInfoResponder.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Elements/DiscoInfo.h" +#include <Swiften/Disco/JIDDiscoInfoResponder.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Elements/DiscoInfo.h> namespace Swift { diff --git a/Swiften/Disco/JIDDiscoInfoResponder.h b/Swiften/Disco/JIDDiscoInfoResponder.h index d532d0f..ebc1452 100644 --- a/Swiften/Disco/JIDDiscoInfoResponder.h +++ b/Swiften/Disco/JIDDiscoInfoResponder.h @@ -8,9 +8,9 @@ #include <map> -#include "Swiften/Queries/GetResponder.h" -#include "Swiften/Elements/DiscoInfo.h" -#include "Swiften/JID/JID.h" +#include <Swiften/Queries/GetResponder.h> +#include <Swiften/Elements/DiscoInfo.h> +#include <Swiften/JID/JID.h> namespace Swift { class IQRouter; diff --git a/Swiften/Disco/SConscript b/Swiften/Disco/SConscript index 9982192..c821b42 100644 --- a/Swiften/Disco/SConscript +++ b/Swiften/Disco/SConscript @@ -5,10 +5,11 @@ objects = swiften_env.SwiftenObject([ "CapsManager.cpp", "EntityCapsManager.cpp", "EntityCapsProvider.cpp", + "DummyEntityCapsProvider.cpp", "CapsStorage.cpp", - "CapsFileStorage.cpp", "ClientDiscoManager.cpp", "DiscoInfoResponder.cpp", "JIDDiscoInfoResponder.cpp", + "DiscoServiceWalker.cpp", ]) swiften_env.Append(SWIFTEN_OBJECTS = [objects]) diff --git a/Swiften/Disco/UnitTest/CapsInfoGeneratorTest.cpp b/Swiften/Disco/UnitTest/CapsInfoGeneratorTest.cpp index d4cb331..52fdbaa 100644 --- a/Swiften/Disco/UnitTest/CapsInfoGeneratorTest.cpp +++ b/Swiften/Disco/UnitTest/CapsInfoGeneratorTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Elements/DiscoInfo.h" -#include "Swiften/Disco/CapsInfoGenerator.h" +#include <Swiften/Elements/DiscoInfo.h> +#include <Swiften/Disco/CapsInfoGenerator.h> using namespace Swift; diff --git a/Swiften/Disco/UnitTest/CapsManagerTest.cpp b/Swiften/Disco/UnitTest/CapsManagerTest.cpp index 793fdba..0681569 100644 --- a/Swiften/Disco/UnitTest/CapsManagerTest.cpp +++ b/Swiften/Disco/UnitTest/CapsManagerTest.cpp @@ -9,13 +9,13 @@ #include <vector> #include <boost/bind.hpp> -#include "Swiften/Disco/CapsManager.h" -#include "Swiften/Disco/CapsMemoryStorage.h" -#include "Swiften/Disco/CapsInfoGenerator.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Elements/CapsInfo.h" -#include "Swiften/Elements/DiscoInfo.h" -#include "Swiften/Client/DummyStanzaChannel.h" +#include <Swiften/Disco/CapsManager.h> +#include <Swiften/Disco/CapsMemoryStorage.h> +#include <Swiften/Disco/CapsInfoGenerator.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Elements/CapsInfo.h> +#include <Swiften/Elements/DiscoInfo.h> +#include <Swiften/Client/DummyStanzaChannel.h> using namespace Swift; @@ -64,7 +64,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveNewHashRequestsDisco() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<DiscoInfo>(0, user1, IQ::Get)); @@ -74,7 +74,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveSameHashDoesNotRequestDisco() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); stanzaChannel->sentStanzas.clear(); sendPresenceWithCaps(user1, capsInfo1); @@ -83,14 +83,14 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveLegacyCapsDoesNotRequestDisco() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, legacyCapsInfo); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(stanzaChannel->sentStanzas.size())); } void testReceiveSameHashAfterSuccesfulDiscoDoesNotRequestDisco() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); sendDiscoInfoResult(discoInfo1); @@ -101,7 +101,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveSameHashFromSameUserAfterFailedDiscoDoesNotRequestDisco() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); stanzaChannel->onIQReceived(IQ::createError(JID("baz@fum.com/foo"), stanzaChannel->sentStanzas[0]->getID())); @@ -112,7 +112,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveSameHashFromSameUserAfterIncorrectVerificationDoesNotRequestDisco() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); sendDiscoInfoResult(discoInfo2); @@ -123,7 +123,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveSameHashFromDifferentUserAfterFailedDiscoRequestsDisco() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); stanzaChannel->onIQReceived(IQ::createError(JID("baz@fum.com/foo"), stanzaChannel->sentStanzas[0]->getTo(), stanzaChannel->sentStanzas[0]->getID())); @@ -133,7 +133,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveSameHashFromDifferentUserAfterIncorrectVerificationRequestsDisco() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); sendDiscoInfoResult(discoInfo2); @@ -143,7 +143,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveDifferentHashFromSameUserAfterFailedDiscoDoesNotRequestDisco() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); stanzaChannel->onIQReceived(IQ::createError(JID("baz@fum.com/foo"), stanzaChannel->sentStanzas[0]->getID())); @@ -154,7 +154,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveSuccesfulDiscoStoresCaps() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); sendDiscoInfoResult(discoInfo1); @@ -164,7 +164,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveIncorrectVerificationDiscoDoesNotStoreCaps() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); sendDiscoInfoResult(discoInfo2); @@ -173,7 +173,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveFailingDiscoFallsBack() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); sendPresenceWithCaps(user2, capsInfo1alt); stanzaChannel->onIQReceived(IQ::createError(JID("baz@fum.com/foo"), stanzaChannel->sentStanzas[0]->getTo(), stanzaChannel->sentStanzas[0]->getID())); @@ -185,7 +185,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveNoDiscoFallsBack() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); sendPresenceWithCaps(user2, capsInfo1alt); stanzaChannel->onIQReceived(IQ::createResult(JID("baz@fum.com/dum"), stanzaChannel->sentStanzas[0]->getTo(), stanzaChannel->sentStanzas[0]->getID(), boost::shared_ptr<DiscoInfo>())); @@ -197,7 +197,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveFailingFallbackDiscoFallsBack() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); sendPresenceWithCaps(user2, capsInfo1alt); sendPresenceWithCaps(user3, capsInfo1); @@ -208,7 +208,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReceiveSameHashFromFailingUserAfterReconnectRequestsDisco() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); stanzaChannel->onIQReceived(IQ::createError(JID("baz@fum.com/foo"), stanzaChannel->sentStanzas[0]->getTo(), stanzaChannel->sentStanzas[0]->getID())); stanzaChannel->setAvailable(false); @@ -221,7 +221,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReconnectResetsFallback() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); sendPresenceWithCaps(user2, capsInfo1alt); stanzaChannel->setAvailable(false); @@ -234,7 +234,7 @@ class CapsManagerTest : public CppUnit::TestFixture { } void testReconnectResetsRequests() { - std::auto_ptr<CapsManager> testling = createManager(); + boost::shared_ptr<CapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); stanzaChannel->sentStanzas.clear(); stanzaChannel->setAvailable(false); @@ -245,8 +245,8 @@ class CapsManagerTest : public CppUnit::TestFixture { } private: - std::auto_ptr<CapsManager> createManager() { - std::auto_ptr<CapsManager> manager(new CapsManager(storage, stanzaChannel, iqRouter)); + boost::shared_ptr<CapsManager> createManager() { + boost::shared_ptr<CapsManager> manager(new CapsManager(storage, stanzaChannel, iqRouter)); manager->setWarnOnInvalidHash(false); //manager->onCapsChanged.connect(boost::bind(&CapsManagerTest::handleCapsChanged, this, _1)); return manager; diff --git a/Swiften/Disco/UnitTest/DiscoInfoResponderTest.cpp b/Swiften/Disco/UnitTest/DiscoInfoResponderTest.cpp index bccf0d4..1477e23 100644 --- a/Swiften/Disco/UnitTest/DiscoInfoResponderTest.cpp +++ b/Swiften/Disco/UnitTest/DiscoInfoResponderTest.cpp @@ -8,9 +8,9 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <typeinfo> -#include "Swiften/Disco/DiscoInfoResponder.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Queries/DummyIQChannel.h" +#include <Swiften/Disco/DiscoInfoResponder.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Queries/DummyIQChannel.h> using namespace Swift; diff --git a/Swiften/Disco/UnitTest/EntityCapsManagerTest.cpp b/Swiften/Disco/UnitTest/EntityCapsManagerTest.cpp index 544bdad..7b61cb5 100644 --- a/Swiften/Disco/UnitTest/EntityCapsManagerTest.cpp +++ b/Swiften/Disco/UnitTest/EntityCapsManagerTest.cpp @@ -9,11 +9,11 @@ #include <vector> #include <boost/bind.hpp> -#include "Swiften/Disco/EntityCapsManager.h" -#include "Swiften/Disco/CapsProvider.h" -#include "Swiften/Elements/CapsInfo.h" -#include "Swiften/Client/DummyStanzaChannel.h" -#include "Swiften/Disco/CapsInfoGenerator.h" +#include <Swiften/Disco/EntityCapsManager.h> +#include <Swiften/Disco/CapsProvider.h> +#include <Swiften/Elements/CapsInfo.h> +#include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/Disco/CapsInfoGenerator.h> using namespace Swift; @@ -52,7 +52,7 @@ class EntityCapsManagerTest : public CppUnit::TestFixture { } void testReceiveKnownHash() { - std::auto_ptr<EntityCapsManager> testling = createManager(); + boost::shared_ptr<EntityCapsManager> testling = createManager(); capsProvider->caps[capsInfo1->getVersion()] = discoInfo1; sendPresenceWithCaps(user1, capsInfo1); @@ -62,7 +62,7 @@ class EntityCapsManagerTest : public CppUnit::TestFixture { } void testReceiveKnownHashTwiceDoesNotTriggerChange() { - std::auto_ptr<EntityCapsManager> testling = createManager(); + boost::shared_ptr<EntityCapsManager> testling = createManager(); capsProvider->caps[capsInfo1->getVersion()] = discoInfo1; sendPresenceWithCaps(user1, capsInfo1); changes.clear(); @@ -73,14 +73,14 @@ class EntityCapsManagerTest : public CppUnit::TestFixture { } void testReceiveUnknownHashDoesNotTriggerChange() { - std::auto_ptr<EntityCapsManager> testling = createManager(); + boost::shared_ptr<EntityCapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changes.size())); } void testHashAvailable() { - std::auto_ptr<EntityCapsManager> testling = createManager(); + boost::shared_ptr<EntityCapsManager> testling = createManager(); sendPresenceWithCaps(user1, capsInfo1); capsProvider->caps[capsInfo1->getVersion()] = discoInfo1; @@ -92,7 +92,7 @@ class EntityCapsManagerTest : public CppUnit::TestFixture { } void testReceiveUnknownHashAfterKnownHashTriggersChangeAndClearsCaps() { - std::auto_ptr<EntityCapsManager> testling = createManager(); + boost::shared_ptr<EntityCapsManager> testling = createManager(); capsProvider->caps[capsInfo1->getVersion()] = discoInfo1; sendPresenceWithCaps(user1, capsInfo1); changes.clear(); @@ -104,7 +104,7 @@ class EntityCapsManagerTest : public CppUnit::TestFixture { } void testReceiveUnavailablePresenceAfterKnownHashTriggersChangeAndClearsCaps() { - std::auto_ptr<EntityCapsManager> testling = createManager(); + boost::shared_ptr<EntityCapsManager> testling = createManager(); capsProvider->caps[capsInfo1->getVersion()] = discoInfo1; sendPresenceWithCaps(user1, capsInfo1); changes.clear(); @@ -116,7 +116,7 @@ class EntityCapsManagerTest : public CppUnit::TestFixture { } void testReconnectTriggersChangeAndClearsCaps() { - std::auto_ptr<EntityCapsManager> testling = createManager(); + boost::shared_ptr<EntityCapsManager> testling = createManager(); capsProvider->caps[capsInfo1->getVersion()] = discoInfo1; capsProvider->caps[capsInfo2->getVersion()] = discoInfo2; sendPresenceWithCaps(user1, capsInfo1); @@ -133,8 +133,8 @@ class EntityCapsManagerTest : public CppUnit::TestFixture { } private: - std::auto_ptr<EntityCapsManager> createManager() { - std::auto_ptr<EntityCapsManager> manager(new EntityCapsManager(capsProvider, stanzaChannel)); + boost::shared_ptr<EntityCapsManager> createManager() { + boost::shared_ptr<EntityCapsManager> manager(new EntityCapsManager(capsProvider, stanzaChannel)); manager->onCapsChanged.connect(boost::bind(&EntityCapsManagerTest::handleCapsChanged, this, _1)); return manager; } diff --git a/Swiften/Disco/UnitTest/JIDDiscoInfoResponderTest.cpp b/Swiften/Disco/UnitTest/JIDDiscoInfoResponderTest.cpp index ef61afa..7e2e3dd 100644 --- a/Swiften/Disco/UnitTest/JIDDiscoInfoResponderTest.cpp +++ b/Swiften/Disco/UnitTest/JIDDiscoInfoResponderTest.cpp @@ -8,9 +8,9 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <typeinfo> -#include "Swiften/Disco/JIDDiscoInfoResponder.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Queries/DummyIQChannel.h" +#include <Swiften/Disco/JIDDiscoInfoResponder.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Queries/DummyIQChannel.h> using namespace Swift; diff --git a/Swiften/Elements/AuthChallenge.h b/Swiften/Elements/AuthChallenge.h index 74d7dba..f7f2796 100644 --- a/Swiften/Elements/AuthChallenge.h +++ b/Swiften/Elements/AuthChallenge.h @@ -7,9 +7,9 @@ #pragma once #include <boost/optional.hpp> +#include <vector> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { class AuthChallenge : public Element { @@ -17,18 +17,18 @@ namespace Swift { AuthChallenge() { } - AuthChallenge(const ByteArray& value) : value(value) { + AuthChallenge(const std::vector<unsigned char>& value) : value(value) { } - const boost::optional<ByteArray>& getValue() const { + const boost::optional< std::vector<unsigned char> >& getValue() const { return value; } - void setValue(const ByteArray& value) { - this->value = boost::optional<ByteArray>(value); + void setValue(const std::vector<unsigned char>& value) { + this->value = boost::optional<std::vector<unsigned char> >(value); } private: - boost::optional<ByteArray> value; + boost::optional< std::vector<unsigned char> > value; }; } diff --git a/Swiften/Elements/AuthFailure.h b/Swiften/Elements/AuthFailure.h index 7ffc762..ac40956 100644 --- a/Swiften/Elements/AuthFailure.h +++ b/Swiften/Elements/AuthFailure.h @@ -8,7 +8,7 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { class AuthFailure : public Element { diff --git a/Swiften/Elements/AuthRequest.h b/Swiften/Elements/AuthRequest.h index ba86900..bfc86c2 100644 --- a/Swiften/Elements/AuthRequest.h +++ b/Swiften/Elements/AuthRequest.h @@ -6,10 +6,12 @@ #pragma once +#include <vector> +#include <string> #include <boost/optional.hpp> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class AuthRequest : public Element { @@ -17,20 +19,20 @@ namespace Swift { AuthRequest(const std::string& mechanism = "") : mechanism_(mechanism) { } - AuthRequest(const std::string& mechanism, const ByteArray& message) : + AuthRequest(const std::string& mechanism, const SafeByteArray& message) : mechanism_(mechanism), message_(message) { } - AuthRequest(const std::string& mechanism, const boost::optional<ByteArray>& message) : + AuthRequest(const std::string& mechanism, const boost::optional<SafeByteArray>& message) : mechanism_(mechanism), message_(message) { } - const boost::optional<ByteArray>& getMessage() const { + const boost::optional<SafeByteArray>& getMessage() const { return message_; } - void setMessage(const ByteArray& message) { - message_ = boost::optional<ByteArray>(message); + void setMessage(const SafeByteArray& message) { + message_ = boost::optional<SafeByteArray>(message); } const std::string& getMechanism() const { @@ -43,6 +45,6 @@ namespace Swift { private: std::string mechanism_; - boost::optional<ByteArray> message_; + boost::optional<SafeByteArray> message_; }; } diff --git a/Swiften/Elements/AuthResponse.h b/Swiften/Elements/AuthResponse.h index 96d1b13..db2dcea 100644 --- a/Swiften/Elements/AuthResponse.h +++ b/Swiften/Elements/AuthResponse.h @@ -6,10 +6,11 @@ #pragma once +#include <vector> #include <boost/optional.hpp> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class AuthResponse : public Element { @@ -17,21 +18,21 @@ namespace Swift { AuthResponse() { } - AuthResponse(const ByteArray& value) : value(value) { + AuthResponse(const SafeByteArray& value) : value(value) { } - AuthResponse(const boost::optional<ByteArray>& value) : value(value) { + AuthResponse(const boost::optional<SafeByteArray>& value) : value(value) { } - const boost::optional<ByteArray>& getValue() const { + const boost::optional<SafeByteArray>& getValue() const { return value; } - void setValue(const ByteArray& value) { - this->value = boost::optional<ByteArray>(value); + void setValue(const SafeByteArray& value) { + this->value = boost::optional<SafeByteArray>(value); } private: - boost::optional<ByteArray> value; + boost::optional<SafeByteArray> value; }; } diff --git a/Swiften/Elements/AuthSuccess.h b/Swiften/Elements/AuthSuccess.h index af5f9bb..3c0f329 100644 --- a/Swiften/Elements/AuthSuccess.h +++ b/Swiften/Elements/AuthSuccess.h @@ -6,25 +6,25 @@ #pragma once +#include <vector> #include <boost/optional.hpp> -#include "Swiften/Elements/Element.h" -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Elements/Element.h> namespace Swift { class AuthSuccess : public Element { public: AuthSuccess() {} - const boost::optional<ByteArray>& getValue() const { + const boost::optional<std::vector<unsigned char> >& getValue() const { return value; } - void setValue(const ByteArray& value) { - this->value = boost::optional<ByteArray>(value); + void setValue(const std::vector<unsigned char>& value) { + this->value = boost::optional<std::vector<unsigned char> >(value); } private: - boost::optional<ByteArray> value; + boost::optional<std::vector<unsigned char> > value; }; } diff --git a/Swiften/Elements/BlockListPayload.h b/Swiften/Elements/BlockListPayload.h new file mode 100644 index 0000000..25cb602 --- /dev/null +++ b/Swiften/Elements/BlockListPayload.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> + +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/Payload.h> + +namespace Swift { + class BlockListPayload : public Payload { + public: + BlockListPayload() { + } + + void addItem(const JID& item) { + items.push_back(item); + } + + const std::vector<JID>& getItems() const { + return items; + } + + private: + std::vector<JID> items; + }; +} diff --git a/Swiften/Elements/BlockPayload.h b/Swiften/Elements/BlockPayload.h new file mode 100644 index 0000000..6dd5170 --- /dev/null +++ b/Swiften/Elements/BlockPayload.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> + +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/Payload.h> + +namespace Swift { + class BlockPayload : public Payload { + public: + BlockPayload() { + } + + void addItem(const JID& jid) { + items.push_back(jid); + } + + const std::vector<JID>& getItems() const { + return items; + } + + private: + std::vector<JID> items; + }; +} diff --git a/Swiften/Elements/Body.h b/Swiften/Elements/Body.h index 2887390..a2497f7 100644 --- a/Swiften/Elements/Body.h +++ b/Swiften/Elements/Body.h @@ -6,14 +6,13 @@ #pragma once -#include "Swiften/Elements/Payload.h" #include <string> +#include <Swiften/Elements/Payload.h> + namespace Swift { class Body : public Payload { public: - typedef boost::shared_ptr<Body> ref; - Body(const std::string& text = "") : text_(text) { } diff --git a/Swiften/Elements/Bytestreams.h b/Swiften/Elements/Bytestreams.h index b493375..9724a54 100644 --- a/Swiften/Elements/Bytestreams.h +++ b/Swiften/Elements/Bytestreams.h @@ -9,10 +9,10 @@ #include <vector> #include <boost/optional.hpp> #include <boost/shared_ptr.hpp> - -#include "Swiften/JID/JID.h" #include <string> -#include "Swiften/Elements/Payload.h" + +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/Payload.h> namespace Swift { class Bytestreams : public Payload { diff --git a/Swiften/Elements/CapsInfo.h b/Swiften/Elements/CapsInfo.h index ccad278..c6d3b64 100644 --- a/Swiften/Elements/CapsInfo.h +++ b/Swiften/Elements/CapsInfo.h @@ -7,9 +7,9 @@ #pragma once #include <boost/shared_ptr.hpp> - #include <string> -#include "Swiften/Elements/Payload.h" + +#include <Swiften/Elements/Payload.h> namespace Swift { class CapsInfo : public Payload { diff --git a/Swiften/Elements/ChatState.h b/Swiften/Elements/ChatState.h index 2896877..477fd27 100644 --- a/Swiften/Elements/ChatState.h +++ b/Swiften/Elements/ChatState.h @@ -7,7 +7,8 @@ #pragma once #include <string> -#include "Swiften/Elements/Payload.h" + +#include <Swiften/Elements/Payload.h> namespace Swift { class ChatState : public Payload { @@ -17,7 +18,7 @@ namespace Swift { state_ = state; } - ChatStateType getChatState() { return state_; } + ChatStateType getChatState() const { return state_; } void setChatState(ChatStateType state) {state_ = state;} private: diff --git a/Swiften/Elements/Command.h b/Swiften/Elements/Command.h index f4059a8..91ae5a3 100644 --- a/Swiften/Elements/Command.h +++ b/Swiften/Elements/Command.h @@ -7,10 +7,10 @@ #pragma once #include <boost/shared_ptr.hpp> - #include <string> -#include "Swiften/Elements/Payload.h" -#include "Swiften/Elements/Form.h" + +#include <Swiften/Elements/Payload.h> +#include <Swiften/Elements/Form.h> namespace Swift { /** diff --git a/Swiften/Elements/ComponentHandshake.h b/Swiften/Elements/ComponentHandshake.h index 6047eab..5992b8c 100644 --- a/Swiften/Elements/ComponentHandshake.h +++ b/Swiften/Elements/ComponentHandshake.h @@ -7,10 +7,10 @@ #pragma once #include <boost/shared_ptr.hpp> - -#include "Swiften/Elements/Element.h" #include <string> +#include <Swiften/Elements/Element.h> + namespace Swift { class ComponentHandshake : public Element { public: diff --git a/Swiften/Elements/CompressFailure.h b/Swiften/Elements/CompressFailure.h index c0d5847..7dd8867 100644 --- a/Swiften/Elements/CompressFailure.h +++ b/Swiften/Elements/CompressFailure.h @@ -4,10 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_CompressFailure_H -#define SWIFTEN_CompressFailure_H +#pragma once -#include "Swiften/Elements/Element.h" + +#include <Swiften/Elements/Element.h> namespace Swift { class CompressFailure : public Element { @@ -15,5 +15,3 @@ namespace Swift { CompressFailure() {} }; } - -#endif diff --git a/Swiften/Elements/CompressRequest.h b/Swiften/Elements/CompressRequest.h index 0eb302a..b6fcc64 100644 --- a/Swiften/Elements/CompressRequest.h +++ b/Swiften/Elements/CompressRequest.h @@ -4,10 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_CompressRequest_H -#define SWIFTEN_CompressRequest_H +#pragma once -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { class CompressRequest : public Element @@ -27,5 +26,3 @@ namespace Swift { std::string method_; }; } - -#endif diff --git a/Swiften/Elements/Compressed.h b/Swiften/Elements/Compressed.h index e50c17e..2affec5 100644 --- a/Swiften/Elements/Compressed.h +++ b/Swiften/Elements/Compressed.h @@ -4,17 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_COMPRESSED_H -#define SWIFTEN_COMPRESSED_H +#pragma once -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { - class Compressed : public Element - { + class Compressed : public Element { public: Compressed() {} }; } - -#endif diff --git a/Swiften/Elements/Delay.h b/Swiften/Elements/Delay.h index 3213037..f7c4570 100644 --- a/Swiften/Elements/Delay.h +++ b/Swiften/Elements/Delay.h @@ -6,11 +6,11 @@ #pragma once -#include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> #include <boost/optional.hpp> -#include "Swiften/Elements/Payload.h" -#include "Swiften/JID/JID.h" +#include <Swiften/Elements/Payload.h> +#include <Swiften/JID/JID.h> namespace Swift { class Delay : public Payload { diff --git a/Swiften/Elements/DiscoInfo.cpp b/Swiften/Elements/DiscoInfo.cpp index f0e728e..35d4d04 100644 --- a/Swiften/Elements/DiscoInfo.cpp +++ b/Swiften/Elements/DiscoInfo.cpp @@ -4,7 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Elements/DiscoInfo.h" +#include <Swiften/Elements/DiscoInfo.h> + +#include <algorithm> namespace Swift { @@ -12,6 +14,13 @@ const std::string DiscoInfo::ChatStatesFeature = std::string("http://jabber.org/ const std::string DiscoInfo::SecurityLabelsFeature = std::string("urn:xmpp:sec-label:0"); const std::string DiscoInfo::SecurityLabelsCatalogFeature = std::string("urn:xmpp:sec-label:catalog:2"); const std::string DiscoInfo::JabberSearchFeature = std::string("jabber:iq:search"); +const std::string DiscoInfo::CommandsFeature = std::string("http://jabber.org/protocol/commands"); +const std::string DiscoInfo::MessageCorrectionFeature = std::string("urn:xmpp:message-correct:0"); +const std::string DiscoInfo::JingleFeature = std::string("urn:xmpp:jingle:1"); +const std::string DiscoInfo::JingleFTFeature = std::string("urn:xmpp:jingle:apps:file-transfer:3"); +const std::string DiscoInfo::JingleTransportsIBBFeature = std::string("urn:xmpp:jingle:transports:ibb:1"); +const std::string DiscoInfo::JingleTransportsS5BFeature = std::string("urn:xmpp:jingle:transports:s5b:1"); +const std::string DiscoInfo::Bytestream = std::string("http://jabber.org/protocol/bytestreams"); bool DiscoInfo::Identity::operator<(const Identity& other) const { @@ -33,4 +42,8 @@ bool DiscoInfo::Identity::operator<(const Identity& other) const { } } +bool DiscoInfo::hasFeature(const std::string& feature) const { + return std::find(features_.begin(), features_.end(), feature) != features_.end(); +} + } diff --git a/Swiften/Elements/DiscoInfo.h b/Swiften/Elements/DiscoInfo.h index b73165e..6d6e722 100644 --- a/Swiften/Elements/DiscoInfo.h +++ b/Swiften/Elements/DiscoInfo.h @@ -7,12 +7,10 @@ #pragma once #include <vector> -#include <algorithm> - -#include "Swiften/Elements/Payload.h" #include <string> -#include "Swiften/Elements/Form.h" +#include <Swiften/Elements/Payload.h> +#include <Swiften/Elements/Form.h> namespace Swift { class DiscoInfo : public Payload { @@ -23,6 +21,13 @@ namespace Swift { static const std::string SecurityLabelsFeature; static const std::string SecurityLabelsCatalogFeature; static const std::string JabberSearchFeature; + static const std::string CommandsFeature; + static const std::string MessageCorrectionFeature; + static const std::string JingleFeature; + static const std::string JingleFTFeature; + static const std::string JingleTransportsIBBFeature; + static const std::string JingleTransportsS5BFeature; + static const std::string Bytestream; class Identity { public: @@ -82,9 +87,7 @@ namespace Swift { features_.push_back(feature); } - bool hasFeature(const std::string& feature) const { - return std::find(features_.begin(), features_.end(), feature) != features_.end(); - } + bool hasFeature(const std::string& feature) const; void addExtension(Form::ref form) { extensions_.push_back(form); diff --git a/Swiften/Elements/DiscoItems.h b/Swiften/Elements/DiscoItems.h index cc5a583..149e41c 100644 --- a/Swiften/Elements/DiscoItems.h +++ b/Swiften/Elements/DiscoItems.h @@ -7,11 +7,10 @@ #pragma once #include <vector> -#include <algorithm> - -#include "Swiften/Elements/Payload.h" #include <string> -#include "Swiften/JID/JID.h" + +#include <Swiften/Elements/Payload.h> +#include <Swiften/JID/JID.h> namespace Swift { class DiscoItems : public Payload { diff --git a/Swiften/Elements/Element.cpp b/Swiften/Elements/Element.cpp index 5407e89..94829ba 100644 --- a/Swiften/Elements/Element.cpp +++ b/Swiften/Elements/Element.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { diff --git a/Swiften/Elements/Element.h b/Swiften/Elements/Element.h index aded528..1e6a9d0 100644 --- a/Swiften/Elements/Element.h +++ b/Swiften/Elements/Element.h @@ -4,8 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_ELEMENT_H -#define SWIFTEN_ELEMENT_H +#pragma once namespace Swift { class Element { @@ -13,5 +12,3 @@ namespace Swift { virtual ~Element(); }; } - -#endif diff --git a/Swiften/Elements/EnableStreamManagement.h b/Swiften/Elements/EnableStreamManagement.h index 807db84..15a091e 100644 --- a/Swiften/Elements/EnableStreamManagement.h +++ b/Swiften/Elements/EnableStreamManagement.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { diff --git a/Swiften/Elements/ErrorPayload.h b/Swiften/Elements/ErrorPayload.h index 12ad574..f21ba98 100644 --- a/Swiften/Elements/ErrorPayload.h +++ b/Swiften/Elements/ErrorPayload.h @@ -7,10 +7,10 @@ #pragma once #include <boost/shared_ptr.hpp> - -#include "Swiften/Elements/Payload.h" #include <string> +#include <Swiften/Elements/Payload.h> + namespace Swift { class ErrorPayload : public Payload { public: @@ -69,9 +69,18 @@ namespace Swift { return text_; } + void setPayload(boost::shared_ptr<Payload> payload) { + payload_ = payload; + } + + boost::shared_ptr<Payload> getPayload() const { + return payload_; + } + private: Type type_; Condition condition_; std::string text_; + boost::shared_ptr<Payload> payload_; }; } diff --git a/Swiften/Elements/Form.cpp b/Swiften/Elements/Form.cpp index 03fd1a4..c34b868 100644 --- a/Swiften/Elements/Form.cpp +++ b/Swiften/Elements/Form.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Elements/Form.h" -#include "Swiften/Base/foreach.h" +#include <Swiften/Elements/Form.h> +#include <Swiften/Base/foreach.h> namespace Swift { diff --git a/Swiften/Elements/Form.h b/Swiften/Elements/Form.h index 1c50f0c..47ff7d4 100644 --- a/Swiften/Elements/Form.h +++ b/Swiften/Elements/Form.h @@ -7,12 +7,11 @@ #pragma once #include <vector> - -#include "Swiften/Elements/Payload.h" -#include "Swiften/Elements/FormField.h" #include <string> -#include "Swiften/JID/JID.h" +#include <Swiften/Elements/Payload.h> +#include <Swiften/Elements/FormField.h> +#include <Swiften/JID/JID.h> namespace Swift { /** @@ -32,12 +31,12 @@ namespace Swift { void addField(boost::shared_ptr<FormField> field) { fields_.push_back(field); } const std::vector<boost::shared_ptr<FormField> >& getFields() const { return fields_; } void setTitle(const std::string& title) { title_ = title; } - const std::string& getTitle() { return title_; } + const std::string& getTitle() const { return title_; } void setInstructions(const std::string& instructions) { instructions_ = instructions; } - const std::string& getInstructions() { return instructions_; } + const std::string& getInstructions() const { return instructions_; } - Type getType() { return type_; } + Type getType() const { return type_; } void setType(Type type) { type_ = type; } std::string getFormType() const; diff --git a/Swiften/Elements/FormField.h b/Swiften/Elements/FormField.h index 517369b..e8fe3a0 100644 --- a/Swiften/Elements/FormField.h +++ b/Swiften/Elements/FormField.h @@ -11,9 +11,9 @@ #include <vector> #include <boost/shared_ptr.hpp> - #include <string> -#include "Swiften/JID/JID.h" + +#include <Swiften/JID/JID.h> namespace Swift { class FormField { @@ -111,5 +111,4 @@ namespace Swift { SWIFTEN_DECLARE_FORM_FIELD(JIDSingle, JID); SWIFTEN_DECLARE_FORM_FIELD(JIDMulti, std::vector<JID>); SWIFTEN_DECLARE_FORM_FIELD(ListMulti, std::vector<std::string>); - SWIFTEN_DECLARE_FORM_FIELD(Untyped, std::vector<std::string>); } diff --git a/Swiften/Elements/IBB.h b/Swiften/Elements/IBB.h index 55f2c4f..64c9f14 100644 --- a/Swiften/Elements/IBB.h +++ b/Swiften/Elements/IBB.h @@ -6,11 +6,12 @@ #pragma once +#include <string> +#include <vector> #include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> -#include <string> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> namespace Swift { class IBB : public Payload { @@ -31,20 +32,20 @@ namespace Swift { } static IBB::ref createIBBOpen(const std::string& streamID, int blockSize) { - IBB::ref result(new IBB(Open, streamID)); + IBB::ref result = boost::make_shared<IBB>(Open, streamID); result->setBlockSize(blockSize); return result; } - static IBB::ref createIBBData(const std::string& streamID, int sequenceNumber, const ByteArray& data) { - IBB::ref result(new IBB(Data, streamID)); + static IBB::ref createIBBData(const std::string& streamID, int sequenceNumber, const std::vector<unsigned char>& data) { + IBB::ref result = boost::make_shared<IBB>(Data, streamID); result->setSequenceNumber(sequenceNumber); result->setData(data); return result; } static IBB::ref createIBBClose(const std::string& streamID) { - return IBB::ref(new IBB(Close, streamID)); + return boost::make_shared<IBB>(Close, streamID); } void setAction(Action action) { @@ -71,11 +72,11 @@ namespace Swift { return streamID; } - const ByteArray& getData() const { + const std::vector<unsigned char>& getData() const { return data; } - void setData(const ByteArray& data) { + void setData(const std::vector<unsigned char>& data) { this->data = data; } @@ -98,7 +99,7 @@ namespace Swift { private: Action action; std::string streamID; - ByteArray data; + std::vector<unsigned char> data; StanzaType stanzaType; int blockSize; int sequenceNumber; diff --git a/Swiften/Elements/IQ.cpp b/Swiften/Elements/IQ.cpp index eb62ee4..8e6d7cc 100644 --- a/Swiften/Elements/IQ.cpp +++ b/Swiften/Elements/IQ.cpp @@ -4,13 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Elements/IQ.h" +#include <Swiften/Elements/IQ.h> + +#include <boost/smart_ptr/make_shared.hpp> namespace Swift { boost::shared_ptr<IQ> IQ::createRequest( Type type, const JID& to, const std::string& id, boost::shared_ptr<Payload> payload) { - boost::shared_ptr<IQ> iq(new IQ(type)); + boost::shared_ptr<IQ> iq = boost::make_shared<IQ>(type); if (to.isValid()) { iq->setTo(to); } @@ -22,7 +24,7 @@ boost::shared_ptr<IQ> IQ::createRequest( } boost::shared_ptr<IQ> IQ::createResult(const JID& to, const std::string& id, boost::shared_ptr<Payload> payload) { - boost::shared_ptr<IQ> iq(new IQ(Result)); + boost::shared_ptr<IQ> iq = boost::make_shared<IQ>(Result); iq->setTo(to); iq->setID(id); if (payload) { @@ -32,7 +34,7 @@ boost::shared_ptr<IQ> IQ::createResult(const JID& to, const std::string& id, boo } boost::shared_ptr<IQ> IQ::createResult(const JID& to, const JID& from, const std::string& id, boost::shared_ptr<Payload> payload) { - boost::shared_ptr<IQ> iq(new IQ(Result)); + boost::shared_ptr<IQ> iq = boost::make_shared<IQ>(Result); iq->setTo(to); iq->setFrom(from); iq->setID(id); @@ -43,19 +45,19 @@ boost::shared_ptr<IQ> IQ::createResult(const JID& to, const JID& from, const std } boost::shared_ptr<IQ> IQ::createError(const JID& to, const std::string& id, ErrorPayload::Condition condition, ErrorPayload::Type type) { - boost::shared_ptr<IQ> iq(new IQ(IQ::Error)); + boost::shared_ptr<IQ> iq = boost::make_shared<IQ>(IQ::Error); iq->setTo(to); iq->setID(id); - iq->addPayload(boost::shared_ptr<Swift::ErrorPayload>(new Swift::ErrorPayload(condition, type))); + iq->addPayload(boost::make_shared<Swift::ErrorPayload>(condition, type)); return iq; } boost::shared_ptr<IQ> IQ::createError(const JID& to, const JID& from, const std::string& id, ErrorPayload::Condition condition, ErrorPayload::Type type) { - boost::shared_ptr<IQ> iq(new IQ(IQ::Error)); + boost::shared_ptr<IQ> iq = boost::make_shared<IQ>(IQ::Error); iq->setTo(to); iq->setFrom(from); iq->setID(id); - iq->addPayload(boost::shared_ptr<Swift::ErrorPayload>(new Swift::ErrorPayload(condition, type))); + iq->addPayload(boost::make_shared<Swift::ErrorPayload>(condition, type)); return iq; } diff --git a/Swiften/Elements/IQ.h b/Swiften/Elements/IQ.h index 78a8bbd..05cd96a 100644 --- a/Swiften/Elements/IQ.h +++ b/Swiften/Elements/IQ.h @@ -8,8 +8,8 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/Stanza.h" -#include "Swiften/Elements/ErrorPayload.h" +#include <Swiften/Elements/Stanza.h> +#include <Swiften/Elements/ErrorPayload.h> namespace Swift { class IQ : public Stanza { diff --git a/Swiften/Elements/InBandRegistrationPayload.h b/Swiften/Elements/InBandRegistrationPayload.h index e4e1e6f..8f6a9f1 100644 --- a/Swiften/Elements/InBandRegistrationPayload.h +++ b/Swiften/Elements/InBandRegistrationPayload.h @@ -8,11 +8,11 @@ #include <boost/shared_ptr.hpp> #include <boost/optional.hpp> - -#include "Swiften/Elements/Payload.h" -#include "Swiften/Elements/Form.h" #include <string> +#include <Swiften/Elements/Payload.h> +#include <Swiften/Elements/Form.h> + namespace Swift { class InBandRegistrationPayload : public Payload { public: diff --git a/Swiften/Elements/JingleContent.h b/Swiften/Elements/JingleContentPayload.h index 4ae908b..183b8eb 100644 --- a/Swiften/Elements/JingleContent.h +++ b/Swiften/Elements/JingleContentPayload.h @@ -8,20 +8,20 @@ #include <vector> #include <boost/optional.hpp> - #include <string> + #include <Swiften/JID/JID.h> #include <Swiften/Elements/Payload.h> #include <Swiften/Elements/JingleDescription.h> -#include <Swiften/Elements/JingleTransport.h> -#include <Swiften/Base/foreach.h> +#include <Swiften/Elements/JingleTransportPayload.h> namespace Swift { - class JingleContent : public Payload { + class JingleContentPayload : public Payload { public: - typedef boost::shared_ptr<JingleContent> ref; + typedef boost::shared_ptr<JingleContentPayload> ref; enum Creator { + UnknownCreator, InitiatorCreator, ResponderCreator, }; @@ -33,10 +33,18 @@ namespace Swift { BothSenders, };*/ + Creator getCreator() const { + return creator; + } + void setCreator(Creator creator) { this->creator = creator; } + const std::string& getName() const { + return name; + } + void setName(const std::string& name) { this->name = name; } @@ -49,18 +57,18 @@ namespace Swift { descriptions.push_back(description); } - const std::vector<JingleTransport::ref>& getTransports() const { + const std::vector<boost::shared_ptr<JingleTransportPayload> >& getTransports() const { return transports; } - void addTransport(JingleTransport::ref transport) { + void addTransport(boost::shared_ptr<JingleTransportPayload> transport) { transports.push_back(transport); } template<typename T> boost::shared_ptr<T> getDescription() const { - foreach (JingleDescription::ref i, descriptions) { - boost::shared_ptr<T> result(boost::dynamic_pointer_cast<T>(i)); + for (size_t i = 0; i < descriptions.size(); ++i) { + boost::shared_ptr<T> result(boost::dynamic_pointer_cast<T>(descriptions[i])); if (result) { return result; } @@ -70,8 +78,8 @@ namespace Swift { template<typename T> boost::shared_ptr<T> getTransport() const { - foreach (JingleTransport::ref i, transports) { - boost::shared_ptr<T> result(boost::dynamic_pointer_cast<T>(i)); + for (size_t i = 0; i < transports.size(); ++i) { + boost::shared_ptr<T> result(boost::dynamic_pointer_cast<T>(transports[i])); if (result) { return result; } @@ -84,6 +92,6 @@ namespace Swift { std::string name; //Senders senders; std::vector<JingleDescription::ref> descriptions; - std::vector<JingleTransport::ref> transports; + std::vector<boost::shared_ptr<JingleTransportPayload> > transports; }; } diff --git a/Swiften/Elements/JingleFileTransferDescription.h b/Swiften/Elements/JingleFileTransferDescription.h index 19644bd..04f3f1f 100644 --- a/Swiften/Elements/JingleFileTransferDescription.h +++ b/Swiften/Elements/JingleFileTransferDescription.h @@ -7,7 +7,7 @@ #pragma once #include <boost/shared_ptr.hpp> -#include <boost/optional.hpp> +#include <vector> #include <Swiften/Elements/JingleDescription.h> #include <Swiften/Elements/StreamInitiationFileInfo.h> @@ -17,15 +17,25 @@ namespace Swift { public: typedef boost::shared_ptr<JingleFileTransferDescription> ref; - void setOffer(const StreamInitiationFileInfo& offer) { - this->offer = offer; + void addOffer(const StreamInitiationFileInfo& offer) { + offers.push_back(offer); } + - const boost::optional<StreamInitiationFileInfo>& getOffer() const { - return offer; + const std::vector<StreamInitiationFileInfo>& getOffers() const { + return offers; + } + + void addRequest(const StreamInitiationFileInfo& request) { + reqeusts.push_back(request); + } + + const std::vector<StreamInitiationFileInfo>& getRequests() const { + return reqeusts; } private: - boost::optional<StreamInitiationFileInfo> offer; + std::vector<StreamInitiationFileInfo> offers; + std::vector<StreamInitiationFileInfo> reqeusts; }; } diff --git a/Swiften/Elements/JingleFileTransferHash.h b/Swiften/Elements/JingleFileTransferHash.h new file mode 100644 index 0000000..5603531 --- /dev/null +++ b/Swiften/Elements/JingleFileTransferHash.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> +#include <map> +#include <string> + +#include <Swiften/Elements/JingleDescription.h> + +namespace Swift { + +class JingleFileTransferHash : public Payload { +public: + typedef std::map<std::string, std::string> HashesMap; +public: + typedef boost::shared_ptr<JingleFileTransferHash> ref; + + void setHash(const std::string& algo, const std::string& hash) { + hashes[algo] = hash; + } + + const HashesMap& getHashes() const { + return hashes; + } + +private: + HashesMap hashes; +}; + +} diff --git a/Swiften/Elements/JingleFileTransferReceived.h b/Swiften/Elements/JingleFileTransferReceived.h new file mode 100644 index 0000000..75c95d9 --- /dev/null +++ b/Swiften/Elements/JingleFileTransferReceived.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> +#include <vector> + +#include <Swiften/Elements/StreamInitiationFileInfo.h> +#include <Swiften/Elements/Payload.h> + +namespace Swift { + +class JingleFileTransferReceived : public Payload { + public: + typedef boost::shared_ptr<JingleFileTransferReceived> ref; + + void setFileInfo(const StreamInitiationFileInfo& fileInfo) { + this->fileInfo = fileInfo; + } + + const StreamInitiationFileInfo& getFileInfo() const { + return this->fileInfo; + } + private: + StreamInitiationFileInfo fileInfo; + +}; + +} diff --git a/Swiften/Elements/JingleIBBTransport.h b/Swiften/Elements/JingleIBBTransportPayload.h index faa5af3..8c174f0 100644 --- a/Swiften/Elements/JingleIBBTransport.h +++ b/Swiften/Elements/JingleIBBTransportPayload.h @@ -6,12 +6,16 @@ #pragma once +#include <boost/shared_ptr.hpp> #include <string> -#include <Swiften/Elements/JingleTransport.h> + +#include <Swiften/Elements/JingleTransportPayload.h> namespace Swift { - class JingleIBBTransport : public JingleTransport { + class JingleIBBTransportPayload : public JingleTransportPayload { public: + typedef boost::shared_ptr<JingleIBBTransportPayload> ref; + enum StanzaType { IQStanza, MessageStanza, @@ -25,14 +29,6 @@ namespace Swift { return stanzaType; } - void setSessionID(const std::string& id) { - sessionID = id; - } - - const std::string& getSessionID() const { - return sessionID; - } - int getBlockSize() const { return blockSize; } @@ -42,7 +38,6 @@ namespace Swift { } private: - std::string sessionID; int blockSize; StanzaType stanzaType; }; diff --git a/Swiften/Elements/JinglePayload.h b/Swiften/Elements/JinglePayload.h index 59fba7b..31d4448 100644 --- a/Swiften/Elements/JinglePayload.h +++ b/Swiften/Elements/JinglePayload.h @@ -7,20 +7,23 @@ #pragma once #include <vector> +#include <boost/shared_ptr.hpp> #include <boost/optional.hpp> #include <string> #include <Swiften/JID/JID.h> #include <Swiften/Elements/Payload.h> -#include <Swiften/Elements/JingleContent.h> +#include <Swiften/Elements/JingleContentPayload.h> +#include <Swiften/Base/Log.h> namespace Swift { class JinglePayload : public Payload { public: typedef boost::shared_ptr<JinglePayload> ref; - struct Reason { + struct Reason : public Payload { enum Type { + UnknownType, AlternativeSession, Busy, Cancel, @@ -39,13 +42,15 @@ namespace Swift { UnsupportedApplications, UnsupportedTransports }; - + Reason() : type(UnknownType), text("") {} Reason(Type type, const std::string& text = "") : type(type), text(text) {} + ~Reason() {} Type type; std::string text; }; enum Action { + UnknownAction, ContentAccept, ContentAdd, ContentModify, @@ -62,8 +67,11 @@ namespace Swift { TransportReject, TransportReplace }; - + JinglePayload() : action(SessionTerminate), sessionID("") { + } + JinglePayload(Action action, const std::string& sessionID) : action(action), sessionID(sessionID) { + } void setAction(Action action) { @@ -98,12 +106,47 @@ namespace Swift { return sessionID; } - void addContent(JingleContent::ref content) { - this->contents.push_back(content); + void addContent(JingleContentPayload::ref content) { + this->payloads.push_back(content); + } + + void addPayload(boost::shared_ptr<Payload> payload) { + this->payloads.push_back(payload); + } + + const std::vector<JingleContentPayload::ref> getContents() const { + return getPayloads<JingleContentPayload>(); + } + + const std::vector<boost::shared_ptr<Payload> > getPayloads() const { + return payloads; + } + + template<typename T> + const std::vector<boost::shared_ptr<T> > getPayloads() const { + std::vector<boost::shared_ptr<T> > matched_payloads; + for (std::vector<boost::shared_ptr<Payload> >::const_iterator i = payloads.begin(); i != payloads.end(); ++i) { + boost::shared_ptr<T> result = boost::dynamic_pointer_cast<T>(*i); + if (result) { + matched_payloads.push_back(result); + } + } + + return matched_payloads; + } - const std::vector<JingleContent::ref>& getContents() const { - return contents; + template<typename T> + const boost::shared_ptr<T> getPayload() const { + boost::shared_ptr<T> result; + for (std::vector<boost::shared_ptr<Payload> >::const_iterator i = payloads.begin(); i != payloads.end(); ++i) { + result = boost::dynamic_pointer_cast<T>(*i); + if (result) { + return result; + } + } + + return result; } void setReason(const Reason& reason) { @@ -119,7 +162,7 @@ namespace Swift { JID initiator; JID responder; std::string sessionID; - std::vector<JingleContent::ref> contents; + std::vector<boost::shared_ptr<Payload> > payloads; boost::optional<Reason> reason; }; } diff --git a/Swiften/Elements/JingleS5BTransport.h b/Swiften/Elements/JingleS5BTransport.h deleted file mode 100644 index 4522417..0000000 --- a/Swiften/Elements/JingleS5BTransport.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2011 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#pragma once - -#include <Swiften/Elements/JingleTransport.h> -#include <Swiften/Elements/Bytestreams.h> - -namespace Swift { - class JingleS5BTransport : public JingleTransport { - public: - const Bytestreams& getInfo() const { - return info; - } - - void setInfo(const Bytestreams& info) { - this->info = info; - } - - private: - Bytestreams info; - }; -} diff --git a/Swiften/Elements/JingleS5BTransportPayload.h b/Swiften/Elements/JingleS5BTransportPayload.h new file mode 100644 index 0000000..995933c --- /dev/null +++ b/Swiften/Elements/JingleS5BTransportPayload.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> + +#include <boost/shared_ptr.hpp> + +#include <Swiften/Elements/JingleTransportPayload.h> +#include <Swiften/Elements/Bytestreams.h> +#include <Swiften/Network/HostAddressPort.h> + + +namespace Swift { + class JingleS5BTransportPayload : public JingleTransportPayload { + public: + enum Mode { + TCPMode, // default case + UDPMode, + }; + + struct Candidate { + enum Type { + DirectType, // default case + AssistedType, + TunnelType, + ProxyType, + }; + + Candidate() : priority(0), type(DirectType) {} + + std::string cid; + JID jid; + HostAddressPort hostPort; + int priority; + Type type; + }; + + struct CompareCandidate { + bool operator() (const JingleS5BTransportPayload::Candidate& c1, const JingleS5BTransportPayload::Candidate& c2) const { + if (c1.priority < c2.priority) return true; + return false; + } + }; + + public: + JingleS5BTransportPayload() : mode(TCPMode), candidateError(false), proxyError(false) {} + + Mode getMode() const { + return mode; + } + + void setMode(Mode mode) { + this->mode = mode; + } + + const std::vector<Candidate>& getCandidates() const { + return candidates; + } + + void addCandidate(const Candidate& candidate) { + candidates.push_back(candidate); + } + + void setCandidateUsed(const std::string& cid) { + candidateUsedCID = cid; + } + + const std::string& getCandidateUsed() const { + return candidateUsedCID; + } + + void setActivated(const std::string& cid) { + activatedCID = cid; + } + + const std::string& getActivated() const { + return activatedCID; + } + + void setCandidateError(bool hasError) { + candidateError = hasError; + } + + bool hasCandidateError() const { + return candidateError; + } + + void setProxyError(bool hasError) { + proxyError = hasError; + } + + bool hasProxyError() const { + return proxyError; + } + public: + typedef boost::shared_ptr<JingleS5BTransportPayload> ref; + + private: + Mode mode; + std::vector<Candidate> candidates; + + std::string candidateUsedCID; + std::string activatedCID; + bool candidateError; + bool proxyError; + }; +} diff --git a/Swiften/Elements/JingleTransportPayload.h b/Swiften/Elements/JingleTransportPayload.h new file mode 100644 index 0000000..b870be9 --- /dev/null +++ b/Swiften/Elements/JingleTransportPayload.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 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/Payload.h> + +namespace Swift { + class JingleTransportPayload : public Payload { + public: + void setSessionID(const std::string& id) { + sessionID = id; + } + + const std::string& getSessionID() const { + return sessionID; + } + + public: + typedef boost::shared_ptr<JingleTransportPayload> ref; + + private: + std::string sessionID; + }; +} diff --git a/Swiften/Elements/Last.h b/Swiften/Elements/Last.h new file mode 100644 index 0000000..fe0323a --- /dev/null +++ b/Swiften/Elements/Last.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/Payload.h> + +namespace Swift { + class Last : public Payload { + public: + Last(int seconds = 0) : seconds_(seconds) {}; + + int getSeconds() const {return seconds_;} + void setSeconds(int seconds) {seconds_ = seconds;} + + private: + int seconds_; + }; +} diff --git a/Swiften/Elements/MUCAdminPayload.h b/Swiften/Elements/MUCAdminPayload.h new file mode 100644 index 0000000..dc09a24 --- /dev/null +++ b/Swiften/Elements/MUCAdminPayload.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/optional.hpp> +#include <boost/shared_ptr.hpp> +#include <string> +#include <vector> + +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/Payload.h> +#include <Swiften/Elements/MUCOccupant.h> +#include <Swiften/Elements/MUCItem.h> + +namespace Swift { + class MUCAdminPayload : public Payload { + public: + typedef boost::shared_ptr<MUCAdminPayload> ref; + + + MUCAdminPayload() { + } + + void addItem(const MUCItem& item) {items_.push_back(item);} + + const std::vector<MUCItem>& getItems() const {return items_;} + + private: + std::vector<MUCItem> items_; + }; +} diff --git a/Swiften/Elements/MUCDestroyPayload.h b/Swiften/Elements/MUCDestroyPayload.h new file mode 100644 index 0000000..f743ad0 --- /dev/null +++ b/Swiften/Elements/MUCDestroyPayload.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <string> + +#include <Swiften/Elements/Payload.h> +#include <Swiften/JID/JID.h> + +namespace Swift { + class MUCDestroyPayload : public Payload { + public: + typedef boost::shared_ptr<MUCDestroyPayload> ref; + + MUCDestroyPayload() { + } + + void setNewVenue(const JID& jid) { + newVenue_ = jid; + } + + const JID& getNewVenue() const { + return newVenue_; + } + + void setReason(const std::string& reason) { + reason_ = reason; + } + + const std::string& getReason() const { + return reason_; + } + + private: + JID newVenue_; + std::string reason_; + }; +} diff --git a/Swiften/Elements/MUCItem.h b/Swiften/Elements/MUCItem.h new file mode 100644 index 0000000..86217ec --- /dev/null +++ b/Swiften/Elements/MUCItem.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/MUCOccupant.h> +#include <Swiften/JID/JID.h> +namespace Swift { +struct MUCItem { + MUCItem() {} + boost::optional<JID> realJID; + boost::optional<std::string> nick; + boost::optional<MUCOccupant::Affiliation> affiliation; + boost::optional<MUCOccupant::Role> role; + boost::optional<JID> actor; + boost::optional<std::string> reason; +}; +} diff --git a/Swiften/Elements/MUCOccupant.cpp b/Swiften/Elements/MUCOccupant.cpp index a5d8f0e..57034ad 100644 --- a/Swiften/Elements/MUCOccupant.cpp +++ b/Swiften/Elements/MUCOccupant.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Elements/MUCOccupant.h" +#include <Swiften/Elements/MUCOccupant.h> namespace Swift { diff --git a/Swiften/Elements/MUCOccupant.h b/Swiften/Elements/MUCOccupant.h index b3ae4aa..931f544 100644 --- a/Swiften/Elements/MUCOccupant.h +++ b/Swiften/Elements/MUCOccupant.h @@ -9,7 +9,7 @@ #include <boost/optional.hpp> #include <string> -#include "Swiften/JID/JID.h" +#include <Swiften/JID/JID.h> namespace Swift { class Client; diff --git a/Swiften/Elements/MUCOwnerPayload.h b/Swiften/Elements/MUCOwnerPayload.h index 6c3e5f0..5ccc755 100644 --- a/Swiften/Elements/MUCOwnerPayload.h +++ b/Swiften/Elements/MUCOwnerPayload.h @@ -8,7 +8,8 @@ #include <boost/optional.hpp> -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> +#include <Swiften/Elements/Form.h> namespace Swift { class MUCOwnerPayload : public Payload { @@ -26,6 +27,10 @@ namespace Swift { payload = p; } + Form::ref getForm() { + return boost::dynamic_pointer_cast<Form>(payload); + } + private: boost::shared_ptr<Payload> payload; }; diff --git a/Swiften/Elements/MUCPayload.h b/Swiften/Elements/MUCPayload.h index c372360..3b99111 100644 --- a/Swiften/Elements/MUCPayload.h +++ b/Swiften/Elements/MUCPayload.h @@ -7,11 +7,11 @@ #pragma once #include <boost/optional.hpp> -#include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> -#include "Swiften/JID/JID.h" +#include <Swiften/JID/JID.h> #include <string> -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> namespace Swift { class MUCPayload : public Payload { @@ -40,19 +40,19 @@ namespace Swift { since_ = since; } - int getMaxChars() { + int getMaxChars() const{ return maxChars_; } - int getMaxStanzas() { + int getMaxStanzas() const{ return maxStanzas_; } - int getSeconds() { + int getSeconds() const { return seconds_; } - boost::posix_time::ptime getSince() { + const boost::posix_time::ptime& getSince() const { return since_; } diff --git a/Swiften/Elements/MUCUserPayload.h b/Swiften/Elements/MUCUserPayload.h index 7460c35..c9ea62c 100644 --- a/Swiften/Elements/MUCUserPayload.h +++ b/Swiften/Elements/MUCUserPayload.h @@ -11,25 +11,19 @@ #include <string> #include <vector> -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/Payload.h" -#include "Swiften/Elements/MUCOccupant.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/Payload.h> +#include <Swiften/Elements/MUCOccupant.h> +#include <Swiften/Elements/MUCItem.h> namespace Swift { class MUCUserPayload : public Payload { public: typedef boost::shared_ptr<MUCUserPayload> ref; - struct Item { - Item(MUCOccupant::Affiliation affiliation = MUCOccupant::NoAffiliation, MUCOccupant::Role role = MUCOccupant::NoRole) : affiliation(affiliation), role(role) {} - boost::optional<JID> realJID; - boost::optional<std::string> nick; - MUCOccupant::Affiliation affiliation; - MUCOccupant::Role role; - }; - struct StatusCode { StatusCode() : code(0) {} + StatusCode(int code) : code(code) {} int code; }; @@ -48,16 +42,25 @@ namespace Swift { MUCUserPayload() { } - void addItem(Item item) {items_.push_back(item);} + void addItem(const MUCItem& item) {items_.push_back(item);} void addStatusCode(StatusCode code) {statusCodes_.push_back(code);} - const std::vector<Item>& getItems() const {return items_;} + const std::vector<MUCItem>& getItems() const {return items_;} const std::vector<StatusCode>& getStatusCodes() const {return statusCodes_;} + boost::shared_ptr<Payload> getPayload() const { + return payload_; + } + + void setPayload(boost::shared_ptr<Payload> p) { + payload_ = p; + } + private: - std::vector<Item> items_; + std::vector<MUCItem> items_; std::vector<StatusCode> statusCodes_; + boost::shared_ptr<Payload> payload_; }; } diff --git a/Swiften/Elements/Message.h b/Swiften/Elements/Message.h index a553eb3..3b9145c 100644 --- a/Swiften/Elements/Message.h +++ b/Swiften/Elements/Message.h @@ -8,12 +8,14 @@ #include <boost/optional.hpp> #include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> #include <string> -#include "Swiften/Elements/Body.h" -#include "Swiften/Elements/Subject.h" -#include "Swiften/Elements/ErrorPayload.h" -#include "Swiften/Elements/Stanza.h" +#include <Swiften/Elements/Body.h> +#include <Swiften/Elements/Subject.h> +#include <Swiften/Elements/ErrorPayload.h> +#include <Swiften/Elements/Stanza.h> +#include <Swiften/Elements/Replace.h> namespace Swift { class Message : public Stanza { @@ -33,7 +35,11 @@ namespace Swift { } void setSubject(const std::string& subject) { - updatePayload(boost::shared_ptr<Subject>(new Subject(subject))); + updatePayload(boost::make_shared<Subject>(subject)); + } + + bool hasSubject() { + return getPayload<Subject>(); } std::string getBody() const { @@ -45,7 +51,7 @@ namespace Swift { } void setBody(const std::string& body) { - updatePayload(boost::shared_ptr<Body>(new Body(body))); + updatePayload(boost::make_shared<Body>(body)); } bool isError() { diff --git a/Swiften/Elements/Nickname.h b/Swiften/Elements/Nickname.h index 540f6da..a244ce3 100644 --- a/Swiften/Elements/Nickname.h +++ b/Swiften/Elements/Nickname.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> #include <string> namespace Swift { diff --git a/Swiften/Elements/Payload.cpp b/Swiften/Elements/Payload.cpp index b66dcdb..b7c3ffe 100644 --- a/Swiften/Elements/Payload.cpp +++ b/Swiften/Elements/Payload.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> namespace Swift { diff --git a/Swiften/Elements/Payload.h b/Swiften/Elements/Payload.h index c87b899..f994ebc 100644 --- a/Swiften/Elements/Payload.h +++ b/Swiften/Elements/Payload.h @@ -12,7 +12,7 @@ namespace Swift { class Payload { public: typedef boost::shared_ptr<Payload> ref; - + public: virtual ~Payload(); }; } diff --git a/Swiften/Elements/Presence.cpp b/Swiften/Elements/Presence.cpp new file mode 100644 index 0000000..38b8a4c --- /dev/null +++ b/Swiften/Elements/Presence.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Elements/Presence.h> + +#include <Swiften/Elements/Priority.h> +#include <Swiften/Elements/Status.h> + +namespace Swift { + +Presence::Presence() : type_(Available) /*, showType_(Online)*/ { +} + +Presence::Presence(const std::string& status) : type_(Available) { + setStatus(status); +} + +Presence::~Presence() { +} + +int Presence::getPriority() const { + boost::shared_ptr<Priority> priority(getPayload<Priority>()); + return (priority ? priority->getPriority() : 0); +} + +void Presence::setPriority(int priority) { + updatePayload(boost::make_shared<Priority>(priority)); +} + +std::string Presence::getStatus() const { + boost::shared_ptr<Status> status(getPayload<Status>()); + if (status) { + return status->getText(); + } + return ""; +} + +void Presence::setStatus(const std::string& status) { + updatePayload(boost::make_shared<Status>(status)); +} + + +} diff --git a/Swiften/Elements/Presence.h b/Swiften/Elements/Presence.h index 7f957ba..28a9ee5 100644 --- a/Swiften/Elements/Presence.h +++ b/Swiften/Elements/Presence.h @@ -6,11 +6,10 @@ #pragma once +#include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/Elements/Stanza.h" -#include "Swiften/Elements/Status.h" -#include "Swiften/Elements/StatusShow.h" -#include "Swiften/Elements/Priority.h" +#include <Swiften/Elements/Stanza.h> +#include <Swiften/Elements/StatusShow.h> namespace Swift { class Presence : public Stanza { @@ -19,21 +18,20 @@ namespace Swift { enum Type { Available, Error, Probe, Subscribe, Subscribed, Unavailable, Unsubscribe, Unsubscribed }; - Presence() : type_(Available) /*, showType_(Online)*/ {} - Presence(const std::string& status) : type_(Available) { - setStatus(status); - } + Presence(); + Presence(const std::string& status); + virtual ~Presence(); static ref create() { - return ref(new Presence()); + return boost::make_shared<Presence>(); } static ref create(const std::string& status) { - return ref(new Presence(status)); + return boost::make_shared<Presence>(status); } static ref create(Presence::ref presence) { - return ref(new Presence(*presence)); + return boost::make_shared<Presence>(*presence); } Type getType() const { return type_; } @@ -48,32 +46,17 @@ namespace Swift { } void setShow(const StatusShow::Type &show) { - updatePayload(boost::shared_ptr<StatusShow>(new StatusShow(show))); - } - - std::string getStatus() const { - boost::shared_ptr<Status> status(getPayload<Status>()); - if (status) { - return status->getText(); - } - return ""; + updatePayload(boost::make_shared<StatusShow>(show)); } - void setStatus(const std::string& status) { - updatePayload(boost::shared_ptr<Status>(new Status(status))); - } - - int getPriority() const { - boost::shared_ptr<Priority> priority(getPayload<Priority>()); - return (priority ? priority->getPriority() : 0); - } + std::string getStatus() const; + void setStatus(const std::string& status); - void setPriority(int priority) { - updatePayload(boost::shared_ptr<Priority>(new Priority(priority))); - } + int getPriority() const; + void setPriority(int priority); boost::shared_ptr<Presence> clone() const { - return boost::shared_ptr<Presence>(new Presence(*this)); + return boost::make_shared<Presence>(*this); } bool isAvailable() const { diff --git a/Swiften/Elements/Priority.h b/Swiften/Elements/Priority.h index 12181d4..2c0cb9b 100644 --- a/Swiften/Elements/Priority.h +++ b/Swiften/Elements/Priority.h @@ -6,13 +6,11 @@ #pragma once -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> namespace Swift { class Priority : public Payload { public: - typedef boost::shared_ptr<Priority> ref; - Priority(int priority = 0) : priority_(priority) { } diff --git a/Swiften/Elements/PrivateStorage.h b/Swiften/Elements/PrivateStorage.h index 34d9185..a8e1b74 100644 --- a/Swiften/Elements/PrivateStorage.h +++ b/Swiften/Elements/PrivateStorage.h @@ -8,7 +8,7 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> namespace Swift { class PrivateStorage : public Payload { diff --git a/Swiften/Elements/Replace.h b/Swiften/Elements/Replace.h new file mode 100644 index 0000000..230bce7 --- /dev/null +++ b/Swiften/Elements/Replace.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Vlad Voicu + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> +#include <string> + +#include <Swiften/Elements/Payload.h> + +namespace Swift { + class Replace : public Payload { + public: + typedef boost::shared_ptr<Replace> ref; + Replace(const std::string& id = std::string()) : replaceID_(id) {}; + const std::string& getID() const { + return replaceID_; + } + void setID(const std::string& id) { + replaceID_ = id; + } + private: + std::string replaceID_; + }; +} diff --git a/Swiften/Elements/ResourceBind.h b/Swiften/Elements/ResourceBind.h index 3569eb3..f67a995 100644 --- a/Swiften/Elements/ResourceBind.h +++ b/Swiften/Elements/ResourceBind.h @@ -4,16 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_ResourceBind_H -#define SWIFTEN_ResourceBind_H +#pragma once #include <string> -#include "Swiften/Elements/Payload.h" -#include "Swiften/JID/JID.h" +#include <Swiften/Elements/Payload.h> +#include <Swiften/JID/JID.h> namespace Swift { - class ResourceBind : public Payload - { + class ResourceBind : public Payload { public: ResourceBind() {} @@ -38,5 +36,3 @@ namespace Swift { std::string resource_; }; } - -#endif diff --git a/Swiften/Elements/RosterItemExchangePayload.cpp b/Swiften/Elements/RosterItemExchangePayload.cpp new file mode 100644 index 0000000..abd5296 --- /dev/null +++ b/Swiften/Elements/RosterItemExchangePayload.cpp @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Elements/RosterItemExchangePayload.h> +#include <Swiften/Base/foreach.h> + +namespace Swift { + +RosterItemExchangePayload::Item::Item(Action action) : action(action) { +} + +RosterItemExchangePayload::RosterItemExchangePayload() { +} + +} diff --git a/Swiften/Elements/RosterItemExchangePayload.h b/Swiften/Elements/RosterItemExchangePayload.h new file mode 100644 index 0000000..f9aa2c8 --- /dev/null +++ b/Swiften/Elements/RosterItemExchangePayload.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <vector> +#include <string> +#include <boost/shared_ptr.hpp> + +#include <Swiften/Elements/Payload.h> +#include <Swiften/JID/JID.h> + + +namespace Swift { + class RosterItemExchangePayload : public Payload { + public: + typedef boost::shared_ptr<RosterItemExchangePayload> ref; + + class Item { + public: + enum Action { Add, Modify, Delete }; + + Item(Action action = Add); + + Action getAction() const { + return action; + } + + void setAction(Action action) { + this->action = action; + } + + const JID& getJID() const { + return jid; + } + + void setJID(const JID& jid) { + this->jid = jid; + } + + const std::string& getName() const { + return name; + } + + void setName(const std::string& name) { + this->name = name; + } + + const std::vector<std::string>& getGroups() const { + return groups; + } + + void setGroups(const std::vector<std::string> &groups) { + this->groups = groups; + } + + void addGroup(const std::string& group) { + groups.push_back(group); + } + + private: + Action action; + JID jid; + std::string name; + std::vector<std::string> groups; + }; + + typedef std::vector<RosterItemExchangePayload::Item> RosterItemExchangePayloadItems; + + public: + RosterItemExchangePayload(); + + void addItem(const RosterItemExchangePayload::Item& item) { + items_.push_back(item); + } + + const RosterItemExchangePayloadItems& getItems() const { + return items_; + } + + private: + RosterItemExchangePayloadItems items_; + }; +} diff --git a/Swiften/Elements/RosterItemPayload.h b/Swiften/Elements/RosterItemPayload.h index b8a1b10..915ae31 100644 --- a/Swiften/Elements/RosterItemPayload.h +++ b/Swiften/Elements/RosterItemPayload.h @@ -4,22 +4,20 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_RosterItemPayloadPayload_H -#define SWIFTEN_RosterItemPayloadPayload_H +#pragma once #include <vector> - -#include "Swiften/JID/JID.h" #include <string> +#include <Swiften/JID/JID.h> + namespace Swift { - class RosterItemPayload - { + class RosterItemPayload { public: enum Subscription { None, To, From, Both, Remove }; RosterItemPayload() : subscription_(None), ask_(false) {} - RosterItemPayload(const JID& jid, const std::string& name, Subscription subscription) : jid_(jid), name_(name), subscription_(subscription), ask_(false) { } + RosterItemPayload(const JID& jid, const std::string& name, Subscription subscription, const std::vector<std::string>& groups = std::vector<std::string>()) : jid_(jid), name_(name), subscription_(subscription), groups_(groups), ask_(false) { } void setJID(const JID& jid) { jid_ = jid; } const JID& getJID() const { return jid_; } @@ -51,5 +49,3 @@ namespace Swift { std::string unknownContent_; }; } - -#endif diff --git a/Swiften/Elements/RosterPayload.cpp b/Swiften/Elements/RosterPayload.cpp index 5453ae8..6071cbc 100644 --- a/Swiften/Elements/RosterPayload.cpp +++ b/Swiften/Elements/RosterPayload.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Elements/RosterPayload.h" -#include "Swiften/Base/foreach.h" +#include <Swiften/Elements/RosterPayload.h> +#include <Swiften/Base/foreach.h> namespace Swift { diff --git a/Swiften/Elements/RosterPayload.h b/Swiften/Elements/RosterPayload.h index b46b384..c4907cb 100644 --- a/Swiften/Elements/RosterPayload.h +++ b/Swiften/Elements/RosterPayload.h @@ -10,8 +10,8 @@ #include <boost/optional.hpp> #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/RosterItemPayload.h" -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/RosterItemPayload.h> +#include <Swiften/Elements/Payload.h> namespace Swift { @@ -33,7 +33,16 @@ namespace Swift { return items_; } + const boost::optional<std::string>& getVersion() const { + return version_; + } + + void setVersion(const std::string& version) { + version_ = version; + } + private: RosterItemPayloads items_; + boost::optional<std::string> version_; }; } diff --git a/Swiften/Elements/S5BProxyRequest.h b/Swiften/Elements/S5BProxyRequest.h new file mode 100644 index 0000000..fcd0cb2 --- /dev/null +++ b/Swiften/Elements/S5BProxyRequest.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <string> + +#include <boost/optional.hpp> + +#include <Swiften/Elements/Payload.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Network/HostAddressPort.h> + +namespace Swift { + +class S5BProxyRequest : public Payload { +public: + typedef boost::shared_ptr<S5BProxyRequest> ref; + +public: + struct StreamHost { + HostAddressPort addressPort; + JID jid; + }; + +public: + const boost::optional<StreamHost>& getStreamHost() const { + return streamHost; + } + + void setStreamHost(const StreamHost& streamHost) { + this->streamHost = boost::optional<StreamHost>(streamHost); + } + + const std::string& getSID() const { + return sid; + } + + void setSID(const std::string& sid) { + this->sid = sid; + } + + const boost::optional<JID>& getActivate() const { + return activate; + } + + void setActivate(const JID& activate) { + this->activate = activate; + } + +private: + boost::optional<StreamHost> streamHost; + + std::string sid; + boost::optional<JID> activate; +}; + +} diff --git a/Swiften/Elements/SearchPayload.h b/Swiften/Elements/SearchPayload.h index d6d7ed1..202007b 100644 --- a/Swiften/Elements/SearchPayload.h +++ b/Swiften/Elements/SearchPayload.h @@ -9,8 +9,8 @@ #include <boost/shared_ptr.hpp> #include <boost/optional.hpp> -#include "Swiften/Elements/Payload.h" -#include "Swiften/Elements/Form.h" +#include <Swiften/Elements/Payload.h> +#include <Swiften/Elements/Form.h> #include <string> namespace Swift { diff --git a/Swiften/Elements/SecurityLabel.h b/Swiften/Elements/SecurityLabel.h index ca38e32..0487977 100644 --- a/Swiften/Elements/SecurityLabel.h +++ b/Swiften/Elements/SecurityLabel.h @@ -4,13 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_SecurityLabel_H -#define SWIFTEN_SecurityLabel_H +#pragma once #include <vector> #include <string> -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> namespace Swift { class SecurityLabel : public Payload { @@ -59,5 +58,3 @@ namespace Swift { std::vector<std::string> equivalentLabels_; }; } - -#endif diff --git a/Swiften/Elements/SecurityLabelsCatalog.h b/Swiften/Elements/SecurityLabelsCatalog.h index 10ef459..0f40c13 100644 --- a/Swiften/Elements/SecurityLabelsCatalog.h +++ b/Swiften/Elements/SecurityLabelsCatalog.h @@ -4,15 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_SecurityLabelsCatalog_H -#define SWIFTEN_SecurityLabelsCatalog_H +#pragma once #include <vector> - -#include "Swiften/JID/JID.h" #include <string> -#include "Swiften/Elements/Payload.h" -#include "Swiften/Elements/SecurityLabel.h" +#include <boost/shared_ptr.hpp> + +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/Payload.h> +#include <Swiften/Elements/SecurityLabel.h> namespace Swift { class SecurityLabelsCatalog : public Payload { @@ -85,5 +85,3 @@ namespace Swift { std::vector<Item> items_; }; } - -#endif diff --git a/Swiften/Elements/SoftwareVersion.h b/Swiften/Elements/SoftwareVersion.h index 5863b38..c49b47b 100644 --- a/Swiften/Elements/SoftwareVersion.h +++ b/Swiften/Elements/SoftwareVersion.h @@ -6,8 +6,10 @@ #pragma once -#include "Swiften/Elements/Payload.h" #include <string> +#include <boost/shared_ptr.hpp> + +#include <Swiften/Elements/Payload.h> namespace Swift { class SoftwareVersion : public Payload { diff --git a/Swiften/Elements/Stanza.cpp b/Swiften/Elements/Stanza.cpp index d15d778..23f2d89 100644 --- a/Swiften/Elements/Stanza.cpp +++ b/Swiften/Elements/Stanza.cpp @@ -4,13 +4,18 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Elements/Stanza.h" -#include "Swiften/Elements/Delay.h" +#include <Swiften/Elements/Stanza.h> +#include <Swiften/Elements/Delay.h> #include <typeinfo> +#include <Swiften/Base/foreach.h> + namespace Swift { +Stanza::Stanza() { +} + Stanza::~Stanza() { payloads_.clear(); } diff --git a/Swiften/Elements/Stanza.h b/Swiften/Elements/Stanza.h index 9b934e4..9e082cc 100644 --- a/Swiften/Elements/Stanza.h +++ b/Swiften/Elements/Stanza.h @@ -7,27 +7,28 @@ #pragma once #include <vector> +#include <string> #include <boost/shared_ptr.hpp> -#include <boost/optional.hpp> -#include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/optional/optional_fwd.hpp> +#include <boost/date_time/posix_time/ptime.hpp> -#include "Swiften/Elements/Element.h" -#include "Swiften/Elements/Payload.h" -#include <string> -#include "Swiften/Base/foreach.h" -#include "Swiften/JID/JID.h" +#include <Swiften/Elements/Element.h> +#include <Swiften/JID/JID.h> namespace Swift { + class Payload; + class Stanza : public Element { public: typedef boost::shared_ptr<Stanza> ref; + Stanza(); virtual ~Stanza(); template<typename T> boost::shared_ptr<T> getPayload() const { - foreach (const boost::shared_ptr<Payload>& i, payloads_) { - boost::shared_ptr<T> result(boost::dynamic_pointer_cast<T>(i)); + for (size_t i = 0; i < payloads_.size(); ++i) { + boost::shared_ptr<T> result(boost::dynamic_pointer_cast<T>(payloads_[i])); if (result) { return result; } @@ -38,8 +39,8 @@ namespace Swift { template<typename T> std::vector< boost::shared_ptr<T> > getPayloads() const { std::vector< boost::shared_ptr<T> > results; - foreach (const boost::shared_ptr<Payload>& i, payloads_) { - boost::shared_ptr<T> result(boost::dynamic_pointer_cast<T>(i)); + for (size_t i = 0; i < payloads_.size(); ++i) { + boost::shared_ptr<T> result(boost::dynamic_pointer_cast<T>(payloads_[i])); if (result) { results.push_back(result); } @@ -78,8 +79,6 @@ namespace Swift { std::string id_; JID from_; JID to_; - - typedef std::vector< boost::shared_ptr<Payload> > Payloads; - Payloads payloads_; + std::vector< boost::shared_ptr<Payload> > payloads_; }; } diff --git a/Swiften/Elements/StanzaAck.h b/Swiften/Elements/StanzaAck.h index 8a57442..3aa2dfd 100644 --- a/Swiften/Elements/StanzaAck.h +++ b/Swiften/Elements/StanzaAck.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { diff --git a/Swiften/Elements/StanzaAckRequest.h b/Swiften/Elements/StanzaAckRequest.h index 024ebc9..81b3871 100644 --- a/Swiften/Elements/StanzaAckRequest.h +++ b/Swiften/Elements/StanzaAckRequest.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { diff --git a/Swiften/Elements/StartSession.h b/Swiften/Elements/StartSession.h index 0586f40..7aeb611 100644 --- a/Swiften/Elements/StartSession.h +++ b/Swiften/Elements/StartSession.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StartSession_H -#define SWIFTEN_StartSession_H +#pragma once #include <string> -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> namespace Swift { class StartSession : public Payload { @@ -16,5 +15,3 @@ namespace Swift { StartSession() {} }; } - -#endif diff --git a/Swiften/Elements/StartTLSFailure.h b/Swiften/Elements/StartTLSFailure.h index bb70204..5e233fb 100644 --- a/Swiften/Elements/StartTLSFailure.h +++ b/Swiften/Elements/StartTLSFailure.h @@ -4,10 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StartTLSFailure_H -#define SWIFTEN_StartTLSFailure_H +#pragma once -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { class StartTLSFailure : public Element { @@ -15,5 +14,3 @@ namespace Swift { StartTLSFailure() {} }; } - -#endif diff --git a/Swiften/Elements/StartTLSRequest.h b/Swiften/Elements/StartTLSRequest.h index 8ce40ec..e284f75 100644 --- a/Swiften/Elements/StartTLSRequest.h +++ b/Swiften/Elements/StartTLSRequest.h @@ -4,17 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StartTLSRequest_H -#define SWIFTEN_StartTLSRequest_H +#pragma once -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { - class StartTLSRequest : public Element - { + class StartTLSRequest : public Element { public: StartTLSRequest() {} }; } - -#endif diff --git a/Swiften/Elements/Status.h b/Swiften/Elements/Status.h index 3ef6401..956f33d 100644 --- a/Swiften/Elements/Status.h +++ b/Swiften/Elements/Status.h @@ -4,10 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_Status_H -#define SWIFTEN_Status_H +#pragma once -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> #include <string> namespace Swift { @@ -28,5 +27,3 @@ namespace Swift { std::string text_; }; } - -#endif diff --git a/Swiften/Elements/StatusShow.cpp b/Swiften/Elements/StatusShow.cpp new file mode 100644 index 0000000..656e5c4 --- /dev/null +++ b/Swiften/Elements/StatusShow.cpp @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Elements/StatusShow.h> + +using namespace Swift; + +StatusShow::StatusShow(const Type& type) : type_(type) { +} diff --git a/Swiften/Elements/StatusShow.h b/Swiften/Elements/StatusShow.h index a158239..cd3477e 100644 --- a/Swiften/Elements/StatusShow.h +++ b/Swiften/Elements/StatusShow.h @@ -4,19 +4,16 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StatusShow_H -#define SWIFTEN_StatusShow_H +#pragma once -#include "Swiften/Elements/Payload.h" -#include <string> +#include <Swiften/Elements/Payload.h> namespace Swift { class StatusShow : public Payload { public: enum Type { Online, Away, FFC, XA, DND, None }; - StatusShow(const Type& type = Online) : type_(type) { - } + StatusShow(const Type& type = Online); void setType(const Type& type) { type_ = type; @@ -32,19 +29,17 @@ namespace Swift { */ static int typeToAvailabilityOrdering(Type type) { switch (type) { - case Online: return 4; - case FFC: return 5; - case Away: return 2; - case XA: return 1; - case DND: return 3; - case None: return 0; + case Online: return 4; + case FFC: return 5; + case Away: return 2; + case XA: return 1; + case DND: return 3; + case None: return 0; } - return -1; + return 0; } private: Type type_; }; } - -#endif diff --git a/Swiften/Elements/Storage.h b/Swiften/Elements/Storage.h index a2f244c..8118b3b 100644 --- a/Swiften/Elements/Storage.h +++ b/Swiften/Elements/Storage.h @@ -8,9 +8,9 @@ #include <vector> -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> #include <string> -#include "Swiften/JID/JID.h" +#include <Swiften/JID/JID.h> namespace Swift { class Storage : public Payload { diff --git a/Swiften/Elements/StreamFeatures.cpp b/Swiften/Elements/StreamFeatures.cpp new file mode 100644 index 0000000..c6f6c04 --- /dev/null +++ b/Swiften/Elements/StreamFeatures.cpp @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Elements/StreamFeatures.h> + +#include <algorithm> + +namespace Swift { + +bool StreamFeatures::hasCompressionMethod(const std::string& mechanism) const { + return std::find(compressionMethods_.begin(), compressionMethods_.end(), mechanism) != compressionMethods_.end(); +} + +bool StreamFeatures::hasAuthenticationMechanism(const std::string& mechanism) const { + return std::find(authenticationMechanisms_.begin(), authenticationMechanisms_.end(), mechanism) != authenticationMechanisms_.end(); +} + +} diff --git a/Swiften/Elements/StreamFeatures.h b/Swiften/Elements/StreamFeatures.h index fbc0bb8..cae5532 100644 --- a/Swiften/Elements/StreamFeatures.h +++ b/Swiften/Elements/StreamFeatures.h @@ -7,17 +7,17 @@ #pragma once #include <vector> -#include <algorithm> - #include <string> -#include "Swiften/Elements/Element.h" +#include <boost/shared_ptr.hpp> + +#include <Swiften/Elements/Element.h> namespace Swift { class StreamFeatures : public Element { public: typedef boost::shared_ptr<StreamFeatures> ref; - StreamFeatures() : hasStartTLS_(false), hasResourceBind_(false), hasSession_(false), hasStreamManagement_(false) {} + StreamFeatures() : hasStartTLS_(false), hasResourceBind_(false), hasSession_(false), hasStreamManagement_(false), hasRosterVersioning_(false) {} void setHasStartTLS() { hasStartTLS_ = true; @@ -51,9 +51,7 @@ namespace Swift { compressionMethods_.push_back(mechanism); } - bool hasCompressionMethod(const std::string& mechanism) const { - return std::find(compressionMethods_.begin(), compressionMethods_.end(), mechanism) != compressionMethods_.end(); - } + bool hasCompressionMethod(const std::string& mechanism) const; const std::vector<std::string>& getAuthenticationMechanisms() const { return authenticationMechanisms_; @@ -63,9 +61,7 @@ namespace Swift { authenticationMechanisms_.push_back(mechanism); } - bool hasAuthenticationMechanism(const std::string& mechanism) const { - return std::find(authenticationMechanisms_.begin(), authenticationMechanisms_.end(), mechanism) != authenticationMechanisms_.end(); - } + bool hasAuthenticationMechanism(const std::string& mechanism) const; bool hasAuthenticationMechanisms() const { return !authenticationMechanisms_.empty(); @@ -79,6 +75,14 @@ namespace Swift { hasStreamManagement_ = true; } + bool hasRosterVersioning() const { + return hasRosterVersioning_; + } + + void setHasRosterVersioning() { + hasRosterVersioning_ = true; + } + private: bool hasStartTLS_; std::vector<std::string> compressionMethods_; @@ -86,5 +90,6 @@ namespace Swift { bool hasResourceBind_; bool hasSession_; bool hasStreamManagement_; + bool hasRosterVersioning_; }; } diff --git a/Swiften/Elements/StreamInitiation.h b/Swiften/Elements/StreamInitiation.h index 6217cbb..c1f0b4d 100644 --- a/Swiften/Elements/StreamInitiation.h +++ b/Swiften/Elements/StreamInitiation.h @@ -11,7 +11,7 @@ #include <boost/shared_ptr.hpp> #include <string> -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> #include <Swiften/Elements/StreamInitiationFileInfo.h> namespace Swift { diff --git a/Swiften/Elements/StreamInitiationFileInfo.h b/Swiften/Elements/StreamInitiationFileInfo.h index 92b9824..9484bc0 100644 --- a/Swiften/Elements/StreamInitiationFileInfo.h +++ b/Swiften/Elements/StreamInitiationFileInfo.h @@ -6,14 +6,97 @@ #pragma once +#include <Swiften/Elements/Payload.h> +#include <boost/shared_ptr.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> + #include <string> namespace Swift { - struct StreamInitiationFileInfo { - StreamInitiationFileInfo(const std::string& name = "", const std::string& description = "", int size = -1) : name(name), description(description), size(size) {} - std::string name; - std::string description; - int size; - }; +class StreamInitiationFileInfo : public Payload { +public: + typedef boost::shared_ptr<StreamInitiationFileInfo> ref; + +public: + StreamInitiationFileInfo(const std::string& name = "", const std::string& description = "", int size = 0, + const std::string& hash = "", const boost::posix_time::ptime &date = boost::posix_time::ptime(), const std::string& algo="md5") : + name(name), description(description), size(size), hash(hash), date(date), algo(algo), supportsRangeRequests(false), rangeOffset(0) {} + + void setName(const std::string& name) { + this->name = name;; + } + + const std::string& getName() const { + return this->name; + } + + void setDescription(const std::string& description) { + this->description = description; + } + + const std::string& getDescription() const { + return this->description; + } + + void setSize(const boost::uintmax_t size) { + this->size = size; + } + + boost::uintmax_t getSize() const { + return this->size; + } + + void setHash(const std::string& hash) { + this->hash = hash; + } + + const std::string& getHash() const { + return this->hash; + } + + void setDate(const boost::posix_time::ptime& date) { + this->date = date; + } + + const boost::posix_time::ptime& getDate() const { + return this->date; + } + + void setAlgo(const std::string& algo) { + this->algo = algo; + } + + const std::string& getAlgo() const { + return this->algo; + } + + void setSupportsRangeRequests(const bool supportsIt) { + supportsRangeRequests = supportsIt; + } + + bool getSupportsRangeRequests() const { + return supportsRangeRequests; + } + + void setRangeOffset(const int offset) { + supportsRangeRequests = offset >= 0 ? true : false; + rangeOffset = offset; + } + + int getRangeOffset() const { + return rangeOffset; + } + +private: + std::string name; + std::string description; + boost::uintmax_t size; + std::string hash; + boost::posix_time::ptime date; + std::string algo; + bool supportsRangeRequests; + boost::uintmax_t rangeOffset; +}; + } diff --git a/Swiften/Elements/StreamManagementEnabled.cpp b/Swiften/Elements/StreamManagementEnabled.cpp new file mode 100644 index 0000000..bab7516 --- /dev/null +++ b/Swiften/Elements/StreamManagementEnabled.cpp @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Elements/StreamManagementEnabled.h> + +using namespace Swift; + +StreamManagementEnabled::StreamManagementEnabled() { +} + +StreamManagementEnabled::~StreamManagementEnabled() { +} diff --git a/Swiften/Elements/StreamManagementEnabled.h b/Swiften/Elements/StreamManagementEnabled.h index 0c72b84..02e77f3 100644 --- a/Swiften/Elements/StreamManagementEnabled.h +++ b/Swiften/Elements/StreamManagementEnabled.h @@ -1,17 +1,39 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2011 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once -#include "Swiften/Elements/Element.h" +#include <string> +#include <Swiften/Elements/Element.h> namespace Swift { class StreamManagementEnabled : public Element { public: - StreamManagementEnabled() {} + StreamManagementEnabled(); + ~StreamManagementEnabled(); + + void setResumeSupported() { + resumeSupported = true; + } + + bool getResumeSupported() const { + return resumeSupported; + } + + void setResumeID(const std::string& id) { + resumeID = id; + } + + const std::string& getResumeID() const { + return resumeID; + } + + private: + bool resumeSupported; + std::string resumeID; }; } diff --git a/Swiften/Elements/StreamManagementFailed.h b/Swiften/Elements/StreamManagementFailed.h index 8302c94..7c6d1b7 100644 --- a/Swiften/Elements/StreamManagementFailed.h +++ b/Swiften/Elements/StreamManagementFailed.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { diff --git a/Swiften/Elements/StreamResume.cpp b/Swiften/Elements/StreamResume.cpp new file mode 100644 index 0000000..d55ef78 --- /dev/null +++ b/Swiften/Elements/StreamResume.cpp @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Elements/StreamResume.h> + +using namespace Swift; + +StreamResume::StreamResume() { +} + +StreamResume::~StreamResume() { +} diff --git a/Swiften/Elements/StreamResume.h b/Swiften/Elements/StreamResume.h new file mode 100644 index 0000000..aec0909 --- /dev/null +++ b/Swiften/Elements/StreamResume.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <string> +#include <boost/optional.hpp> + +#include <Swiften/Elements/Element.h> + +namespace Swift { + class StreamResume : public Element { + public: + StreamResume(); + ~StreamResume(); + + void setResumeID(const std::string& id) { + resumeID = id; + } + + const std::string& getResumeID() const { + return resumeID; + } + + const boost::optional<unsigned int> getHandledStanzasCount() const { + return handledStanzasCount; + } + + void setHandledStanzasCount(unsigned int i) { + handledStanzasCount = i; + } + + private: + std::string resumeID; + boost::optional<unsigned int> handledStanzasCount; + }; +} diff --git a/Swiften/Elements/StreamResumed.cpp b/Swiften/Elements/StreamResumed.cpp new file mode 100644 index 0000000..552e654 --- /dev/null +++ b/Swiften/Elements/StreamResumed.cpp @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Elements/StreamResumed.h> + +using namespace Swift; + +StreamResumed::StreamResumed() { +} + +StreamResumed::~StreamResumed() { +} diff --git a/Swiften/Elements/StreamResumed.h b/Swiften/Elements/StreamResumed.h new file mode 100644 index 0000000..cf9a755 --- /dev/null +++ b/Swiften/Elements/StreamResumed.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <string> +#include <boost/optional.hpp> + +#include <Swiften/Elements/Element.h> + +namespace Swift { + class StreamResumed : public Element { + public: + StreamResumed(); + ~StreamResumed(); + + void setResumeID(const std::string& id) { + resumeID = id; + } + + const std::string& getResumeID() const { + return resumeID; + } + + const boost::optional<unsigned int> getHandledStanzasCount() const { + return handledStanzasCount; + } + + void setHandledStanzasCount(unsigned int i) { + handledStanzasCount = i; + } + + private: + std::string resumeID; + boost::optional<unsigned int> handledStanzasCount; + }; +} diff --git a/Swiften/Elements/Subject.h b/Swiften/Elements/Subject.h index 6b5a916..bc757af 100644 --- a/Swiften/Elements/Subject.h +++ b/Swiften/Elements/Subject.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> #include <string> namespace Swift { diff --git a/Swiften/Elements/TLSProceed.h b/Swiften/Elements/TLSProceed.h index fbcab04..4bd790a 100644 --- a/Swiften/Elements/TLSProceed.h +++ b/Swiften/Elements/TLSProceed.h @@ -4,17 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_TLSProceed_H -#define SWIFTEN_TLSProceed_H +#pragma once -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { - class TLSProceed : public Element - { + class TLSProceed : public Element { public: TLSProceed() {} }; } - -#endif diff --git a/Swiften/Elements/UnblockPayload.h b/Swiften/Elements/UnblockPayload.h new file mode 100644 index 0000000..b6593ab --- /dev/null +++ b/Swiften/Elements/UnblockPayload.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> + +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/Payload.h> + +namespace Swift { + class UnblockPayload : public Payload { + public: + UnblockPayload() { + } + + void addItem(const JID& item) { + items.push_back(item); + } + + const std::vector<JID>& getItems() const { + return items; + } + + private: + std::vector<JID> items; + }; +} diff --git a/Swiften/Elements/UnitTest/FormTest.cpp b/Swiften/Elements/UnitTest/FormTest.cpp index de92d70..1134182 100644 --- a/Swiften/Elements/UnitTest/FormTest.cpp +++ b/Swiften/Elements/UnitTest/FormTest.cpp @@ -8,7 +8,7 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/Form.h" +#include <Swiften/Elements/Form.h> using namespace Swift; diff --git a/Swiften/Elements/UnitTest/IQTest.cpp b/Swiften/Elements/UnitTest/IQTest.cpp index c170d61..23255b8 100644 --- a/Swiften/Elements/UnitTest/IQTest.cpp +++ b/Swiften/Elements/UnitTest/IQTest.cpp @@ -8,8 +8,8 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/SoftwareVersion.h" +#include <Swiften/Elements/IQ.h> +#include <Swiften/Elements/SoftwareVersion.h> using namespace Swift; diff --git a/Swiften/Elements/UnitTest/StanzaTest.cpp b/Swiften/Elements/UnitTest/StanzaTest.cpp index 4020f8b..0319b52 100644 --- a/Swiften/Elements/UnitTest/StanzaTest.cpp +++ b/Swiften/Elements/UnitTest/StanzaTest.cpp @@ -7,11 +7,12 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/shared_ptr.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> -#include "Swiften/Elements/Stanza.h" -#include "Swiften/Elements/Payload.h" -#include "Swiften/Elements/Message.h" -#include "Swiften/Elements/Delay.h" +#include <Swiften/Elements/Stanza.h> +#include <Swiften/Elements/Payload.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/Delay.h> using namespace Swift; diff --git a/Swiften/Elements/UnknownElement.h b/Swiften/Elements/UnknownElement.h index 549a922..100ba92 100644 --- a/Swiften/Elements/UnknownElement.h +++ b/Swiften/Elements/UnknownElement.h @@ -4,10 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_UnknownElement_H -#define SWIFTEN_UnknownElement_H +#pragma once -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { class UnknownElement : public Element { @@ -15,5 +14,3 @@ namespace Swift { UnknownElement() {} }; } - -#endif diff --git a/Swiften/Elements/VCard.cpp b/Swiften/Elements/VCard.cpp index 8262e07..8bf3eb9 100644 --- a/Swiften/Elements/VCard.cpp +++ b/Swiften/Elements/VCard.cpp @@ -4,9 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Elements/VCard.h" +#include <Swiften/Elements/VCard.h> -#include "Swiften/Base/foreach.h" +#include <Swiften/Base/foreach.h> namespace Swift { @@ -16,7 +16,7 @@ VCard::EMailAddress VCard::getPreferredEMailAddress() const { return address; } } - if (emailAddresses_.size() > 0) { + if (!emailAddresses_.empty()) { return emailAddresses_[0]; } return EMailAddress(); diff --git a/Swiften/Elements/VCard.h b/Swiften/Elements/VCard.h index d2423e1..f9822c9 100644 --- a/Swiften/Elements/VCard.h +++ b/Swiften/Elements/VCard.h @@ -9,8 +9,8 @@ #include <boost/shared_ptr.hpp> #include <string> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Elements/Payload.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Elements/Payload.h> namespace Swift { class VCard : public Payload { @@ -60,10 +60,10 @@ namespace Swift { const std::string& getNickname() const { return nick_; } void setPhoto(const ByteArray& photo) { photo_ = photo; } - const ByteArray& getPhoto() { return photo_; } + const ByteArray& getPhoto() const { return photo_; } void setPhotoType(const std::string& photoType) { photoType_ = photoType; } - const std::string& getPhotoType() { return photoType_; } + const std::string& getPhotoType() const { return photoType_; } const std::string& getUnknownContent() const { return unknownContent_; } void addUnknownContent(const std::string& c) { diff --git a/Swiften/Elements/VCardUpdate.h b/Swiften/Elements/VCardUpdate.h index bbfd31e..782106c 100644 --- a/Swiften/Elements/VCardUpdate.h +++ b/Swiften/Elements/VCardUpdate.h @@ -7,7 +7,7 @@ #pragma once #include <string> -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> namespace Swift { class VCardUpdate : public Payload { @@ -15,7 +15,7 @@ namespace Swift { VCardUpdate(const std::string& photoHash = "") : photoHash_(photoHash) {} void setPhotoHash(const std::string& photoHash) { photoHash_ = photoHash; } - const std::string& getPhotoHash() { return photoHash_; } + const std::string& getPhotoHash() const { return photoHash_; } private: std::string photoHash_; diff --git a/Swiften/Elements/Version.h b/Swiften/Elements/Version.h index 0a65573..350fd91 100644 --- a/Swiften/Elements/Version.h +++ b/Swiften/Elements/Version.h @@ -4,15 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_STANZAS_VERSION_H -#define SWIFTEN_STANZAS_VERSION_H +#pragma once #include <string> -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> namespace Swift { - class Version : public Payload - { + class Version : public Payload { public: Version(const std::string& name = "", const std::string& version = "", const std::string& os = "") : name_(name), version_(version), os_(os) { } @@ -26,5 +24,3 @@ namespace Swift { std::string os_; }; } - -#endif diff --git a/Swiften/Entity/Entity.cpp b/Swiften/Entity/Entity.cpp index da2ecaf..44f9fbf 100644 --- a/Swiften/Entity/Entity.cpp +++ b/Swiften/Entity/Entity.cpp @@ -4,28 +4,47 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Entity/Entity.h" +#include <Swiften/Entity/Entity.h> + +#include <Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h> +#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h> + namespace Swift { +Entity::Entity() { + payloadParserFactories = new FullPayloadParserFactoryCollection(); + payloadSerializers = new FullPayloadSerializerCollection(); +} + Entity::~Entity() { + delete payloadSerializers; + delete payloadParserFactories; } void Entity::addPayloadParserFactory(PayloadParserFactory* payloadParserFactory) { - payloadParserFactories.addFactory(payloadParserFactory); + payloadParserFactories->addFactory(payloadParserFactory); } void Entity::removePayloadParserFactory(PayloadParserFactory* payloadParserFactory) { - payloadParserFactories.removeFactory(payloadParserFactory); + payloadParserFactories->removeFactory(payloadParserFactory); } void Entity::addPayloadSerializer(PayloadSerializer* payloadSerializer) { - payloadSerializers.addSerializer(payloadSerializer); + payloadSerializers->addSerializer(payloadSerializer); } void Entity::removePayloadSerializer(PayloadSerializer* payloadSerializer) { - payloadSerializers.removeSerializer(payloadSerializer); + payloadSerializers->removeSerializer(payloadSerializer); +} + +PayloadParserFactoryCollection* Entity::getPayloadParserFactories() { + return payloadParserFactories; +} + +PayloadSerializerCollection* Entity::getPayloadSerializers() { + return payloadSerializers; } } diff --git a/Swiften/Entity/Entity.h b/Swiften/Entity/Entity.h index 20d02ba..65480d0 100644 --- a/Swiften/Entity/Entity.h +++ b/Swiften/Entity/Entity.h @@ -6,21 +6,20 @@ #pragma once -#include <Swiften/Base/boost_bsignals.h> -#include <boost/shared_ptr.hpp> - -#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" -#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h" - namespace Swift { class PayloadParserFactory; class PayloadSerializer; + class FullPayloadParserFactoryCollection; + class FullPayloadSerializerCollection; + class PayloadParserFactoryCollection; + class PayloadSerializerCollection; /** * The base class for XMPP entities (Clients, Components). */ class Entity { public: + Entity(); virtual ~Entity(); void addPayloadParserFactory(PayloadParserFactory* payloadParserFactory); @@ -30,16 +29,11 @@ namespace Swift { void removePayloadSerializer(PayloadSerializer* payloadSerializer); protected: - PayloadParserFactoryCollection* getPayloadParserFactories() { - return &payloadParserFactories; - } - - PayloadSerializerCollection* getPayloadSerializers() { - return &payloadSerializers; - } + PayloadParserFactoryCollection* getPayloadParserFactories(); + PayloadSerializerCollection* getPayloadSerializers(); private: - FullPayloadParserFactoryCollection payloadParserFactories; - FullPayloadSerializerCollection payloadSerializers; + FullPayloadParserFactoryCollection* payloadParserFactories; + FullPayloadSerializerCollection* payloadSerializers; }; } diff --git a/Swiften/Entity/GenericPayloadPersister.h b/Swiften/Entity/GenericPayloadPersister.h new file mode 100644 index 0000000..63553de --- /dev/null +++ b/Swiften/Entity/GenericPayloadPersister.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Entity/PayloadPersister.h> +#include <Swiften/Parser/GenericPayloadParserFactory.h> + +namespace Swift { + template<typename PAYLOAD, typename PARSER, typename SERIALIZER> + class GenericPayloadPersister : public PayloadPersister { + public: + GenericPayloadPersister() { + } + + public: + boost::shared_ptr<PAYLOAD> loadPayloadGeneric(const boost::filesystem::path& path) { + return boost::dynamic_pointer_cast<PAYLOAD>(loadPayload(path)); + } + + protected: + virtual const PayloadSerializer* getSerializer() const { + return &serializer; + } + + virtual PayloadParser* createParser() const { + return new PARSER(); + } + + private: + SERIALIZER serializer; + }; +} diff --git a/Swiften/Entity/PayloadPersister.cpp b/Swiften/Entity/PayloadPersister.cpp new file mode 100644 index 0000000..729d36a --- /dev/null +++ b/Swiften/Entity/PayloadPersister.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Entity/PayloadPersister.h> + +#include <boost/filesystem/fstream.hpp> +#include <boost/filesystem.hpp> +#include <iostream> + +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Parser/PayloadParser.h> +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Serializer/PayloadSerializer.h> + +using namespace Swift; + +PayloadPersister::PayloadPersister() { +} + +PayloadPersister::~PayloadPersister() { +} + +void PayloadPersister::savePayload(boost::shared_ptr<Payload> payload, const boost::filesystem::path& path) { + try { + if (!boost::filesystem::exists(path.parent_path())) { + boost::filesystem::create_directories(path.parent_path()); + } + boost::filesystem::ofstream file(path); + file << getSerializer()->serialize(payload); + file.close(); + } + catch (const boost::filesystem::filesystem_error& e) { + std::cerr << "ERROR: " << e.what() << std::endl; + } +} + +boost::shared_ptr<Payload> PayloadPersister::loadPayload(const boost::filesystem::path& path) { + try { + if (boost::filesystem::exists(path)) { + ByteArray data; + readByteArrayFromFile(data, path.string()); + boost::shared_ptr<PayloadParser> parser(createParser()); + PayloadParserTester tester(parser.get()); + tester.parse(byteArrayToString(data)); + return parser->getPayload(); + } + } + catch (const boost::filesystem::filesystem_error& e) { + std::cerr << "ERROR: " << e.what() << std::endl; + } + return boost::shared_ptr<Payload>(); +} diff --git a/Swiften/Entity/PayloadPersister.h b/Swiften/Entity/PayloadPersister.h new file mode 100644 index 0000000..ea7c74c --- /dev/null +++ b/Swiften/Entity/PayloadPersister.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 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 <boost/filesystem/path.hpp> + +namespace Swift { + class Payload; + class PayloadSerializer; + class PayloadParser; + + class PayloadPersister { + public: + PayloadPersister(); + virtual ~PayloadPersister(); + + void savePayload(boost::shared_ptr<Payload>, const boost::filesystem::path&); + boost::shared_ptr<Payload> loadPayload(const boost::filesystem::path&); + + protected: + + virtual const PayloadSerializer* getSerializer() const = 0; + virtual PayloadParser* createParser() const = 0; + }; +} diff --git a/Swiften/EventLoop/Cocoa/CocoaEvent.mm b/Swiften/EventLoop/Cocoa/CocoaEvent.mm index 8a90983..049e3b6 100644 --- a/Swiften/EventLoop/Cocoa/CocoaEvent.mm +++ b/Swiften/EventLoop/Cocoa/CocoaEvent.mm @@ -1,6 +1,6 @@ -#include "Swiften/EventLoop/Cocoa/CocoaEvent.h" -#include "Swiften/EventLoop/Event.h" -#include "Swiften/EventLoop/Cocoa/CocoaEventLoop.h" +#include <Swiften/EventLoop/Cocoa/CocoaEvent.h> +#include <Swiften/EventLoop/Event.h> +#include <Swiften/EventLoop/Cocoa/CocoaEventLoop.h> @implementation CocoaEvent diff --git a/Swiften/EventLoop/Cocoa/CocoaEventLoop.h b/Swiften/EventLoop/Cocoa/CocoaEventLoop.h index 2b60741..60ef32b 100644 --- a/Swiften/EventLoop/Cocoa/CocoaEventLoop.h +++ b/Swiften/EventLoop/Cocoa/CocoaEventLoop.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { class CocoaEventLoop : public EventLoop { diff --git a/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm b/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm index b90f3c6..ba73884 100644 --- a/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm +++ b/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm @@ -1,5 +1,5 @@ -#include "Swiften/EventLoop/Cocoa/CocoaEventLoop.h" -#include "Swiften/EventLoop/Cocoa/CocoaEvent.h" +#include <Swiften/EventLoop/Cocoa/CocoaEventLoop.h> +#include <Swiften/EventLoop/Cocoa/CocoaEvent.h> #pragma GCC diagnostic ignored "-Wold-style-cast" diff --git a/Swiften/EventLoop/DummyEventLoop.cpp b/Swiften/EventLoop/DummyEventLoop.cpp new file mode 100644 index 0000000..3741eec --- /dev/null +++ b/Swiften/EventLoop/DummyEventLoop.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/EventLoop/DummyEventLoop.h> + +#include <iostream> + +namespace Swift { + +DummyEventLoop::DummyEventLoop() { +} + +DummyEventLoop::~DummyEventLoop() { + if (!events_.empty()) { + std::cerr << "DummyEventLoop: Unhandled events at destruction time" << std::endl; + } + events_.clear(); +} + + +} diff --git a/Swiften/EventLoop/DummyEventLoop.h b/Swiften/EventLoop/DummyEventLoop.h index b7ef516..4c01c16 100644 --- a/Swiften/EventLoop/DummyEventLoop.h +++ b/Swiften/EventLoop/DummyEventLoop.h @@ -7,24 +7,14 @@ #pragma once #include <deque> -#include <iostream> -#include <boost/function.hpp> -#include "Swiften/EventLoop/EventLoop.h" -#include "Swiften/Base/foreach.h" +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { class DummyEventLoop : public EventLoop { public: - DummyEventLoop() { - } - - ~DummyEventLoop() { - if (!events_.empty()) { - std::cerr << "DummyEventLoop: Unhandled events at destruction time" << std::endl; - } - events_.clear(); - } + DummyEventLoop(); + ~DummyEventLoop(); void processEvents() { while (!events_.empty()) { @@ -34,7 +24,7 @@ namespace Swift { } bool hasEvents() { - return events_.size() > 0; + return !events_.empty(); } virtual void post(const Event& event) { diff --git a/Swiften/EventLoop/Event.h b/Swiften/EventLoop/Event.h index 6f5a9e5..b1d7cac 100644 --- a/Swiften/EventLoop/Event.h +++ b/Swiften/EventLoop/Event.h @@ -9,7 +9,7 @@ #include <boost/shared_ptr.hpp> #include <boost/function.hpp> -#include "Swiften/EventLoop/EventOwner.h" +#include <Swiften/EventLoop/EventOwner.h> namespace Swift { class Event { diff --git a/Swiften/EventLoop/EventLoop.cpp b/Swiften/EventLoop/EventLoop.cpp index 56bb6ac..2b8f00d 100644 --- a/Swiften/EventLoop/EventLoop.cpp +++ b/Swiften/EventLoop/EventLoop.cpp @@ -4,11 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/EventLoop/EventLoop.h> #include <algorithm> #include <boost/bind.hpp> #include <iostream> +#include <cassert> #include <Swiften/Base/Log.h> @@ -17,6 +18,7 @@ namespace Swift { inline void invokeCallback(const Event& event) { try { + assert(!event.callback.empty()); event.callback(); } catch (const std::exception& e) { diff --git a/Swiften/EventLoop/EventLoop.h b/Swiften/EventLoop/EventLoop.h index ab58ffc..9e47112 100644 --- a/Swiften/EventLoop/EventLoop.h +++ b/Swiften/EventLoop/EventLoop.h @@ -11,7 +11,7 @@ #include <list> #include <deque> -#include "Swiften/EventLoop/Event.h" +#include <Swiften/EventLoop/Event.h> namespace Swift { class EventOwner; @@ -35,7 +35,7 @@ namespace Swift { private: struct HasOwner { HasOwner(boost::shared_ptr<EventOwner> owner) : owner(owner) {} - bool operator()(const Event& event) { return event.owner == owner; } + bool operator()(const Event& event) const { return event.owner == owner; } boost::shared_ptr<EventOwner> owner; }; boost::mutex eventsMutex_; diff --git a/Swiften/EventLoop/EventOwner.cpp b/Swiften/EventLoop/EventOwner.cpp index 275f1d1..9970499 100644 --- a/Swiften/EventLoop/EventOwner.cpp +++ b/Swiften/EventLoop/EventOwner.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/EventLoop/EventOwner.h" +#include <Swiften/EventLoop/EventOwner.h> namespace Swift { diff --git a/Swiften/EventLoop/Qt/QtEventLoop.h b/Swiften/EventLoop/Qt/QtEventLoop.h index 8f6c709..0097cf9 100644 --- a/Swiften/EventLoop/Qt/QtEventLoop.h +++ b/Swiften/EventLoop/Qt/QtEventLoop.h @@ -10,7 +10,7 @@ #include <QEvent> #include <QCoreApplication> -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { class QtEventLoop : public QObject, public EventLoop { diff --git a/Swiften/EventLoop/SConscript b/Swiften/EventLoop/SConscript index 21ae8b9..e448f43 100644 --- a/Swiften/EventLoop/SConscript +++ b/Swiften/EventLoop/SConscript @@ -5,6 +5,7 @@ sources = [ "EventOwner.cpp", "Event.cpp", "SimpleEventLoop.cpp", + "DummyEventLoop.cpp", ] objects = swiften_env.SwiftenObject(sources) diff --git a/Swiften/EventLoop/SimpleEventLoop.cpp b/Swiften/EventLoop/SimpleEventLoop.cpp index b77639c..63b8ba5 100644 --- a/Swiften/EventLoop/SimpleEventLoop.cpp +++ b/Swiften/EventLoop/SimpleEventLoop.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/EventLoop/SimpleEventLoop.h" +#include <Swiften/EventLoop/SimpleEventLoop.h> #include <boost/bind.hpp> #include <iostream> -#include "Swiften/Base/foreach.h" +#include <Swiften/Base/foreach.h> namespace Swift { @@ -30,7 +30,7 @@ void SimpleEventLoop::doRun(bool breakAfterEvents) { std::vector<Event> events; { boost::unique_lock<boost::mutex> lock(eventsMutex_); - while (events_.size() == 0) { + while (events_.empty()) { eventsAvailable_.wait(lock); } events.swap(events_); diff --git a/Swiften/EventLoop/SimpleEventLoop.h b/Swiften/EventLoop/SimpleEventLoop.h index 6fb3f53..72bd6a6 100644 --- a/Swiften/EventLoop/SimpleEventLoop.h +++ b/Swiften/EventLoop/SimpleEventLoop.h @@ -11,7 +11,7 @@ #include <boost/thread/mutex.hpp> #include <boost/thread/condition_variable.hpp> -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { class SimpleEventLoop : public EventLoop { diff --git a/Swiften/EventLoop/UnitTest/EventLoopTest.cpp b/Swiften/EventLoop/UnitTest/EventLoopTest.cpp index b777c1b..58396e6 100644 --- a/Swiften/EventLoop/UnitTest/EventLoopTest.cpp +++ b/Swiften/EventLoop/UnitTest/EventLoopTest.cpp @@ -9,10 +9,10 @@ #include <boost/thread.hpp> #include <boost/bind.hpp> -#include "Swiften/EventLoop/EventOwner.h" -#include "Swiften/EventLoop/SimpleEventLoop.h" -#include "Swiften/EventLoop/DummyEventLoop.h" -#include "Swiften/Base/sleep.h" +#include <Swiften/EventLoop/EventOwner.h> +#include <Swiften/EventLoop/SimpleEventLoop.h> +#include <Swiften/EventLoop/DummyEventLoop.h> +#include <Swiften/Base/sleep.h> using namespace Swift; diff --git a/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp b/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp index b779bed..475b6b5 100644 --- a/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp +++ b/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp @@ -9,8 +9,8 @@ #include <boost/thread.hpp> #include <boost/bind.hpp> -#include "Swiften/EventLoop/SimpleEventLoop.h" -#include "Swiften/Base/sleep.h" +#include <Swiften/EventLoop/SimpleEventLoop.h> +#include <Swiften/Base/sleep.h> using namespace Swift; diff --git a/Swiften/Examples/BenchTool/BenchTool.cpp b/Swiften/Examples/BenchTool/BenchTool.cpp index 9e54ed9..ba6cf84 100644 --- a/Swiften/Examples/BenchTool/BenchTool.cpp +++ b/Swiften/Examples/BenchTool/BenchTool.cpp @@ -6,14 +6,15 @@ #include <boost/bind.hpp> #include <boost/thread.hpp> +#include <iostream> -#include "Swiften/Client/Client.h" -#include "Swiften/Network/TimerFactory.h" -#include "Swiften/Network/BoostNetworkFactories.h" -#include "Swiften/EventLoop/EventLoop.h" -#include "Swiften/EventLoop/SimpleEventLoop.h" -#include "Swiften/Roster/GetRosterRequest.h" -#include "Swiften/Client/ClientXMLTracer.h" +#include <Swiften/Client/Client.h> +#include <Swiften/Network/TimerFactory.h> +#include <Swiften/Network/BoostNetworkFactories.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/EventLoop/SimpleEventLoop.h> +#include <Swiften/Roster/GetRosterRequest.h> +#include <Swiften/Client/ClientXMLTracer.h> #include <Swiften/Base/sleep.h> #include <Swiften/TLS/BlindCertificateTrustChecker.h> @@ -45,7 +46,7 @@ int main(int, char**) { BlindCertificateTrustChecker trustChecker; std::vector<CoreClient*> clients; for (int i = 0; i < numberOfInstances; ++i) { - CoreClient* client = new Swift::CoreClient(JID(jid), std::string(pass), &networkFactories); + CoreClient* client = new Swift::CoreClient(JID(jid), createSafeByteArray(std::string(pass)), &networkFactories); client->setCertificateTrustChecker(&trustChecker); client->onConnected.connect(&handleConnected); clients.push_back(client); diff --git a/Swiften/Examples/ConnectivityTest/ConnectivityTest.cpp b/Swiften/Examples/ConnectivityTest/ConnectivityTest.cpp index fda203a..c957481 100644 --- a/Swiften/Examples/ConnectivityTest/ConnectivityTest.cpp +++ b/Swiften/Examples/ConnectivityTest/ConnectivityTest.cpp @@ -6,15 +6,16 @@ #include <boost/bind.hpp> #include <boost/thread.hpp> +#include <iostream> -#include "Swiften/Client/Client.h" -#include "Swiften/Network/Timer.h" -#include "Swiften/Network/TimerFactory.h" -#include "Swiften/Network/BoostNetworkFactories.h" -#include "Swiften/EventLoop/EventLoop.h" -#include "Swiften/Client/ClientXMLTracer.h" -#include "Swiften/EventLoop/SimpleEventLoop.h" -#include "Swiften/Disco/GetDiscoInfoRequest.h" +#include <Swiften/Client/Client.h> +#include <Swiften/Network/Timer.h> +#include <Swiften/Network/TimerFactory.h> +#include <Swiften/Network/BoostNetworkFactories.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/Client/ClientXMLTracer.h> +#include <Swiften/EventLoop/SimpleEventLoop.h> +#include <Swiften/Disco/GetDiscoInfoRequest.h> using namespace Swift; @@ -43,7 +44,7 @@ void handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo> /*info*/, ErrorP void handleConnected() { exitCode = NO_RESPONSE; GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(JID(), client->getIQRouter()); - discoInfoRequest->onResponse.connect(handleServerDiscoInfoResponse); + discoInfoRequest->onResponse.connect(&handleServerDiscoInfoResponse); discoInfoRequest->send(); } diff --git a/Swiften/Examples/ConnectivityTest/SConscript b/Swiften/Examples/ConnectivityTest/SConscript index f66c57f..7bc3892 100644 --- a/Swiften/Examples/ConnectivityTest/SConscript +++ b/Swiften/Examples/ConnectivityTest/SConscript @@ -2,12 +2,6 @@ Import("env") myenv = env.Clone() myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) -myenv.MergeFlags(myenv["LIBIDN_FLAGS"]) -myenv.MergeFlags(myenv["BOOST_FLAGS"]) -myenv.MergeFlags(myenv.get("SQLITE_FLAGS", {})) -myenv.MergeFlags(myenv["ZLIB_FLAGS"]) -myenv.MergeFlags(myenv["OPENSSL_FLAGS"]) -myenv.MergeFlags(myenv.get("LIBXML_FLAGS", "")) -myenv.MergeFlags(myenv.get("EXPAT_FLAGS", "")) -myenv.MergeFlags(myenv["PLATFORM_FLAGS"]) +myenv.MergeFlags(myenv["SWIFTEN_DEP_FLAGS"]) + tester = myenv.Program("ConnectivityTest", ["ConnectivityTest.cpp"]) diff --git a/Swiften/Examples/LinkLocalTool/main.cpp b/Swiften/Examples/LinkLocalTool/main.cpp index d63ef53..18e282b 100644 --- a/Swiften/Examples/LinkLocalTool/main.cpp +++ b/Swiften/Examples/LinkLocalTool/main.cpp @@ -8,11 +8,11 @@ #include <iostream> -#include "Swiften/EventLoop/SimpleEventLoop.h" -#include "Swiften/LinkLocal/DNSSD/PlatformDNSSDQuerierFactory.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" +#include <Swiften/EventLoop/SimpleEventLoop.h> +#include <Swiften/LinkLocal/DNSSD/PlatformDNSSDQuerierFactory.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDQuerier.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h> using namespace Swift; diff --git a/Swiften/Examples/NetworkTool/.gitignore b/Swiften/Examples/NetworkTool/.gitignore new file mode 100644 index 0000000..ab9c4e7 --- /dev/null +++ b/Swiften/Examples/NetworkTool/.gitignore @@ -0,0 +1 @@ +NetworkTool diff --git a/Swiften/Examples/NetworkTool/SConscript b/Swiften/Examples/NetworkTool/SConscript new file mode 100644 index 0000000..38622ff --- /dev/null +++ b/Swiften/Examples/NetworkTool/SConscript @@ -0,0 +1,10 @@ +Import("env") + +if env["experimental"] : + myenv = env.Clone() + myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) + myenv.MergeFlags(myenv["SWIFTEN_DEP_FLAGS"]) + + linkLocalTool = myenv.Program("NetworkTool", [ + "main.cpp" + ]) diff --git a/Swiften/Examples/NetworkTool/main.cpp b/Swiften/Examples/NetworkTool/main.cpp new file mode 100644 index 0000000..ace38fd --- /dev/null +++ b/Swiften/Examples/NetworkTool/main.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <iostream> +#include <boost/lexical_cast.hpp> + +#include <Swiften/EventLoop/SimpleEventLoop.h> +#include <Swiften/Network/PlatformNATTraversalWorker.h> +#include <Swiften/Network/NATTraversalGetPublicIPRequest.h> +#include <Swiften/Network/NATTraversalForwardPortRequest.h> +#include <Swiften/Network/NATTraversalRemovePortForwardingRequest.h> +#include <Swiften/Network/PlatformNetworkEnvironment.h> + +using namespace Swift; + +SimpleEventLoop eventLoop; + +void handleGetPublicIPRequestResponse(const boost::optional<HostAddress>& result) { + if (result) { + std::cerr << "Result: " << result->toString() << std::endl;; + } + else { + std::cerr << "No result" << std::endl; + } + eventLoop.stop(); +} + +void handleGetForwardPortRequestResponse(const boost::optional<NATPortMapping>& result) { + if (result) { + std::cerr << "Result: " << result->publicPort << " -> " << result->localPort << std::endl;; + } + else { + std::cerr << "No result" << std::endl; + } + eventLoop.stop(); +} + +void handleRemovePortForwardingRequestResponse(bool result) { + if (result) { + std::cerr << "Result: OK" << std::endl; + } + else { + std::cerr << "Result: ERROR" << std::endl; + } + eventLoop.stop(); +} + +int main(int argc, char* argv[]) { + if (argc < 2) { + std::cerr << "Invalid parameters" << std::endl; + return -1; + } + + PlatformNATTraversalWorker natTraverser(&eventLoop); + if (std::string(argv[1]) == "get-public-ip") { + boost::shared_ptr<NATTraversalGetPublicIPRequest> query = natTraverser.createGetPublicIPRequest(); + query->onResult.connect(boost::bind(&handleGetPublicIPRequestResponse, _1)); + query->run(); + eventLoop.run(); + } + else if (std::string(argv[1]) == "add-port-forward") { + if (argc < 4) { + std::cerr << "Invalid parameters" << std::endl; + } + boost::shared_ptr<NATTraversalForwardPortRequest> query = natTraverser.createForwardPortRequest(boost::lexical_cast<int>(argv[2]), boost::lexical_cast<int>(argv[3])); + query->onResult.connect(boost::bind(&handleGetForwardPortRequestResponse, _1)); + query->run(); + eventLoop.run(); + } + else if (std::string(argv[1]) == "remove-port-forward") { + if (argc < 4) { + std::cerr << "Invalid parameters" << std::endl; + } + boost::shared_ptr<NATTraversalRemovePortForwardingRequest> query = natTraverser.createRemovePortForwardingRequest(boost::lexical_cast<int>(argv[2]), boost::lexical_cast<int>(argv[3])); + query->onResult.connect(boost::bind(&handleRemovePortForwardingRequestResponse, _1)); + query->run(); + eventLoop.run(); + } + else if (std::string(argv[1]) == "get-local-ip") { + std::cout << PlatformNetworkEnvironment().getLocalAddress().toString() << std::endl; + } +} diff --git a/Swiften/Examples/ParserTester/ParserTester.cpp b/Swiften/Examples/ParserTester/ParserTester.cpp index 61c0eae..211d44f 100644 --- a/Swiften/Examples/ParserTester/ParserTester.cpp +++ b/Swiften/Examples/ParserTester/ParserTester.cpp @@ -8,10 +8,10 @@ #include <fstream> #include <typeinfo> -#include "Swiften/Parser/UnitTest/ParserTester.h" -#include "Swiften/Parser/XMPPParser.h" -#include "Swiften/Parser/XMPPParserClient.h" -#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" +#include <Swiften/Parser/UnitTest/ParserTester.h> +#include <Swiften/Parser/XMPPParser.h> +#include <Swiften/Parser/XMPPParserClient.h> +#include <Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h> using namespace Swift; diff --git a/Swiften/Examples/SConscript b/Swiften/Examples/SConscript index 9b9a35a..fb568fc 100644 --- a/Swiften/Examples/SConscript +++ b/Swiften/Examples/SConscript @@ -7,6 +7,7 @@ SConscript(dirs = [ "SendFile", "ConnectivityTest", "LinkLocalTool", + "NetworkTool", "ParserTester", "BenchTool", ]) diff --git a/Swiften/Examples/SendFile/ReceiveFile.cpp b/Swiften/Examples/SendFile/ReceiveFile.cpp index b46d790..f80f03a 100644 --- a/Swiften/Examples/SendFile/ReceiveFile.cpp +++ b/Swiften/Examples/SendFile/ReceiveFile.cpp @@ -7,14 +7,23 @@ #include <boost/bind.hpp> #include <boost/filesystem.hpp> #include <boost/smart_ptr/make_shared.hpp> +#include <iostream> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Base/foreach.h> #include <Swiften/Client/Client.h> +#include <Swiften/Elements/DiscoInfo.h> #include <Swiften/Network/BoostNetworkFactories.h> #include <Swiften/EventLoop/SimpleEventLoop.h> #include <Swiften/Client/ClientXMLTracer.h> +#include <Swiften/Disco/ClientDiscoManager.h> #include <Swiften/FileTransfer/IncomingFileTransferManager.h> #include <Swiften/FileTransfer/FileWriteBytestream.h> #include <Swiften/Jingle/JingleSessionManager.h> +#include <Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.h> +#include <Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> +#include <Swiften/FileTransfer/FileTransferManager.h> using namespace Swift; @@ -23,19 +32,20 @@ BoostNetworkFactories networkFactories(&eventLoop); int exitCode = 2; +static const std::string CLIENT_NAME = "Swiften FT Test"; +static const std::string CLIENT_NODE = "http://swift.im"; + class FileReceiver { public: FileReceiver(const JID& jid, const std::string& password) : jid(jid), password(password), jingleSessionManager(NULL), incomingFileTransferManager(NULL) { client = new Swift::Client(jid, password, &networkFactories); client->onConnected.connect(boost::bind(&FileReceiver::handleConnected, this)); client->onDisconnected.connect(boost::bind(&FileReceiver::handleDisconnected, this, _1)); - //tracer = new ClientXMLTracer(client); + tracer = new ClientXMLTracer(client); } ~FileReceiver() { - delete incomingFileTransferManager; - delete jingleSessionManager; - //delete tracer; + delete tracer; client->onDisconnected.disconnect(boost::bind(&FileReceiver::handleDisconnected, this, _1)); client->onConnected.disconnect(boost::bind(&FileReceiver::handleConnected, this)); delete client; @@ -54,13 +64,24 @@ class FileReceiver { private: void handleConnected() { - client->sendPresence(Presence::create()); - jingleSessionManager = new JingleSessionManager(client->getIQRouter()); - incomingFileTransferManager = new IncomingFileTransferManager(jingleSessionManager, client->getIQRouter()); - incomingFileTransferManager->onIncomingFileTransfer.connect(boost::bind(&FileReceiver::handleIncomingFileTransfer, this, _1)); + Swift::logging = true; + client->getFileTransferManager()->startListeningOnPort(9999); + client->getFileTransferManager()->onIncomingFileTransfer.connect(boost::bind(&FileReceiver::handleIncomingFileTransfer, this, _1)); + + DiscoInfo discoInfo; + discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc")); + discoInfo.addFeature(DiscoInfo::JingleFeature); + discoInfo.addFeature(DiscoInfo::JingleFTFeature); + discoInfo.addFeature(DiscoInfo::Bytestream); + discoInfo.addFeature(DiscoInfo::JingleTransportsIBBFeature); + discoInfo.addFeature(DiscoInfo::JingleTransportsS5BFeature); + client->getDiscoManager()->setCapsNode(CLIENT_NODE); + client->getDiscoManager()->setDiscoInfo(discoInfo); + client->getPresenceSender()->sendPresence(Presence::create()); } void handleIncomingFileTransfer(IncomingFileTransfer::ref transfer) { + SWIFT_LOG(debug) << "foo" << std::endl; incomingFileTransfers.push_back(transfer); transfer->accept(boost::make_shared<FileWriteBytestream>("out")); //transfer->onFinished.connect(boost::bind(&FileReceiver::handleFileTransferFinished, this, _1)); @@ -97,6 +118,9 @@ class FileReceiver { JingleSessionManager* jingleSessionManager; IncomingFileTransferManager* incomingFileTransferManager; std::vector<IncomingFileTransfer::ref> incomingFileTransfers; + DefaultLocalJingleTransportCandidateGeneratorFactory *localFactory; + DefaultRemoteJingleTransportCandidateSelectorFactory *remoteFactory; + SOCKS5BytestreamRegistry* bytestreamRegistry; }; diff --git a/Swiften/Examples/SendFile/SConscript b/Swiften/Examples/SendFile/SConscript index 6986f22..d335513 100644 --- a/Swiften/Examples/SendFile/SConscript +++ b/Swiften/Examples/SendFile/SConscript @@ -2,14 +2,7 @@ Import("env") myenv = env.Clone() myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) -myenv.MergeFlags(myenv["LIBIDN_FLAGS"]) -myenv.MergeFlags(myenv["BOOST_FLAGS"]) -myenv.MergeFlags(myenv["ZLIB_FLAGS"]) -myenv.MergeFlags(myenv["OPENSSL_FLAGS"]) -myenv.MergeFlags(myenv.get("SQLITE_FLAGS", {})) -myenv.MergeFlags(myenv.get("LIBXML_FLAGS", "")) -myenv.MergeFlags(myenv.get("EXPAT_FLAGS", "")) -myenv.MergeFlags(myenv["PLATFORM_FLAGS"]) +myenv.MergeFlags(myenv["SWIFTEN_DEP_FLAGS"]) myenv.Program("SendFile", ["SendFile.cpp"]) myenv.Program("ReceiveFile", ["ReceiveFile.cpp"]) diff --git a/Swiften/Examples/SendFile/SendFile.cpp b/Swiften/Examples/SendFile/SendFile.cpp index 5ec00a9..9b2105b 100644 --- a/Swiften/Examples/SendFile/SendFile.cpp +++ b/Swiften/Examples/SendFile/SendFile.cpp @@ -4,20 +4,34 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ +#include <boost/date_time/posix_time/posix_time.hpp> #include <boost/bind.hpp> #include <boost/filesystem.hpp> - -#include "Swiften/Client/Client.h" -#include "Swiften/Network/BoostTimer.h" -#include "Swiften/Network/TimerFactory.h" -#include "Swiften/Network/BoostNetworkFactories.h" -#include "Swiften/EventLoop/EventLoop.h" -#include "Swiften/Client/ClientXMLTracer.h" -#include "Swiften/EventLoop/SimpleEventLoop.h" -#include "Swiften/FileTransfer/OutgoingFileTransfer.h" -#include "Swiften/FileTransfer/FileReadBytestream.h" -#include "Swiften/FileTransfer/SOCKS5BytestreamServer.h" -#include "Swiften/Network/BoostConnectionServer.h" +#include <iostream> + +#include <Swiften/Client/Client.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Network/BoostTimer.h> +#include <Swiften/Network/TimerFactory.h> +#include <Swiften/Network/BoostNetworkFactories.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/Client/ClientXMLTracer.h> +#include <Swiften/EventLoop/SimpleEventLoop.h> +#include <Swiften/FileTransfer/OutgoingSIFileTransfer.h> +#include <Swiften/FileTransfer/FileReadBytestream.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h> +#include <Swiften/Network/BoostConnectionServer.h> +#include <Swiften/FileTransfer/OutgoingFileTransferManager.h> +#include <Swiften/FileTransfer/OutgoingFileTransfer.h> +#include <Swiften/Jingle/JingleSessionManager.h> +#include <Swiften/Disco/EntityCapsManager.h> +#include <Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.h> +#include <Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/StringCodecs/MD5.h> +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/FileTransfer/FileTransferManager.h> using namespace Swift; @@ -28,45 +42,65 @@ int exitCode = 2; class FileSender { public: - FileSender(const JID& jid, const std::string& password, const JID& recipient, const boost::filesystem::path& file, int port) : jid(jid), password(password), recipient(recipient), file(file), transfer(NULL) { - connectionServer = BoostConnectionServer::create(port, networkFactories.getIOServiceThread()->getIOService(), &eventLoop); - socksBytestreamServer = new SOCKS5BytestreamServer(connectionServer); + FileSender(const JID& jid, const std::string& password, const JID& recipient, const boost::filesystem::path& file) : jid(jid), password(password), recipient(recipient), file(file) { client = new Swift::Client(jid, password, &networkFactories); client->onConnected.connect(boost::bind(&FileSender::handleConnected, this)); client->onDisconnected.connect(boost::bind(&FileSender::handleDisconnected, this, _1)); - //tracer = new ClientXMLTracer(client); + tracer = new ClientXMLTracer(client); + client->getEntityCapsProvider()->onCapsChanged.connect(boost::bind(&FileSender::handleCapsChanged, this, _1)); } ~FileSender() { - //delete tracer; + delete tracer; client->onDisconnected.disconnect(boost::bind(&FileSender::handleDisconnected, this, _1)); client->onConnected.disconnect(boost::bind(&FileSender::handleConnected, this)); delete client; - delete socksBytestreamServer; } - + void start() { - connectionServer->start(); - socksBytestreamServer->start(); client->connect(); } - void stop() { - if (transfer) { - transfer->stop(); - } - client->disconnect(); - socksBytestreamServer->stop(); - connectionServer->stop(); - } - private: void handleConnected() { client->sendPresence(Presence::create()); - transfer = new OutgoingFileTransfer("myid", client->getJID(), recipient, file.filename(), boost::filesystem::file_size(file), "A file", boost::shared_ptr<FileReadBytestream>(new FileReadBytestream(file)), client->getIQRouter(), socksBytestreamServer); + + client->getFileTransferManager()->startListeningOnPort(19999); + //ByteArray fileData; + //readByteArrayFromFile(fileData, file.string()); + + // gather file information + /*StreamInitiationFileInfo fileInfo; + + fileInfo.setName(file.filename()); + fileInfo.setSize(boost::filesystem::file_size(file)); + fileInfo.setDescription("Some file!"); + fileInfo.setDate(boost::posix_time::from_time_t(boost::filesystem::last_write_time(file)));*/ + //fileInfo.setHash(Hexify::hexify(MD5::getHash(fileData))); + /* + transfer = new OutgoingSIFileTransfer("myid", client->getJID(), recipient, file.filename(), boost::filesystem::file_size(file), "A file", boost::shared_ptr<FileReadBytestream>(new FileReadBytestream(file)), client->getIQRouter(), socksBytestreamServer); transfer->onFinished.connect(boost::bind(&FileSender::handleFileTransferFinished, this, _1)); transfer->start(); + */ + } + + void handleCapsChanged(JID jid) { + if (jid.toBare() == recipient) { + // create ReadBytestream from file + boost::shared_ptr<FileReadBytestream> fileStream = boost::make_shared<FileReadBytestream>(file); + + outgoingFileTransfer = client->getFileTransferManager()->createOutgoingFileTransfer(recipient, file, "Some File!", fileStream); + + if (outgoingFileTransfer) { + std::cout << "started FT" << std::endl; + outgoingFileTransfer->start(); + // TODO: getting notified about FT status and end + } else { + std::cout << "[ ERROR ] " << recipient << " doesn't support any kind of file transfer!" << std::endl; + //client->disconnect(); + } + } } void handleDisconnected(const boost::optional<ClientError>&) { @@ -83,23 +117,23 @@ class FileSender { exit(0); } } - + void exit(int code) { exitCode = code; - stop(); eventLoop.stop(); } private: BoostConnectionServer::ref connectionServer; SOCKS5BytestreamServer* socksBytestreamServer; + SOCKS5BytestreamRegistry* registry; + OutgoingFileTransfer::ref outgoingFileTransfer; JID jid; std::string password; JID recipient; boost::filesystem::path file; Client* client; ClientXMLTracer* tracer; - OutgoingFileTransfer* transfer; }; @@ -111,9 +145,9 @@ int main(int argc, char* argv[]) { JID sender(argv[1]); JID recipient(argv[3]); - FileSender fileSender(sender, std::string(argv[2]), recipient, boost::filesystem::path(argv[4]), 8888); + Swift::logging = true; + FileSender fileSender(sender, std::string(argv[2]), recipient, boost::filesystem::path(argv[4])); fileSender.start(); - { /*BoostTimer::ref timer(BoostTimer::create(30000, &MainBoostIOServiceThread::getInstance().getIOService())); timer->onTick.connect(boost::bind(&SimpleEventLoop::stop, &eventLoop)); diff --git a/Swiften/Examples/SendMessage/SConscript b/Swiften/Examples/SendMessage/SConscript index 05ab4c3..8907d25 100644 --- a/Swiften/Examples/SendMessage/SConscript +++ b/Swiften/Examples/SendMessage/SConscript @@ -2,12 +2,6 @@ Import("env") myenv = env.Clone() myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) -myenv.MergeFlags(myenv["LIBIDN_FLAGS"]) -myenv.MergeFlags(myenv["BOOST_FLAGS"]) -myenv.MergeFlags(myenv["ZLIB_FLAGS"]) -myenv.MergeFlags(myenv["OPENSSL_FLAGS"]) -myenv.MergeFlags(myenv.get("SQLITE_FLAGS", {})) -myenv.MergeFlags(myenv.get("LIBXML_FLAGS", "")) -myenv.MergeFlags(myenv.get("EXPAT_FLAGS", "")) -myenv.MergeFlags(myenv["PLATFORM_FLAGS"]) +myenv.MergeFlags(myenv["SWIFTEN_DEP_FLAGS"]) + tester = myenv.Program("SendMessage", ["SendMessage.cpp"]) diff --git a/Swiften/Examples/SendMessage/SendMessage.cpp b/Swiften/Examples/SendMessage/SendMessage.cpp index d7f7333..f4dbf53 100644 --- a/Swiften/Examples/SendMessage/SendMessage.cpp +++ b/Swiften/Examples/SendMessage/SendMessage.cpp @@ -6,13 +6,15 @@ #include <boost/bind.hpp> #include <boost/thread.hpp> - -#include "Swiften/Client/Client.h" -#include "Swiften/Network/BoostNetworkFactories.h" -#include "Swiften/Network/TimerFactory.h" -#include "Swiften/EventLoop/EventLoop.h" -#include "Swiften/Client/ClientXMLTracer.h" -#include "Swiften/EventLoop/SimpleEventLoop.h" +#include <iostream> + +#include <Swiften/Client/Client.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/Network/BoostNetworkFactories.h> +#include <Swiften/Network/TimerFactory.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/Client/ClientXMLTracer.h> +#include <Swiften/EventLoop/SimpleEventLoop.h> using namespace Swift; diff --git a/Swiften/FileTransfer/ByteArrayReadBytestream.h b/Swiften/FileTransfer/ByteArrayReadBytestream.h index d459658..9311099 100644 --- a/Swiften/FileTransfer/ByteArrayReadBytestream.h +++ b/Swiften/FileTransfer/ByteArrayReadBytestream.h @@ -6,31 +6,47 @@ #pragma once -#include "Swiften/FileTransfer/ReadBytestream.h" -#include "Swiften/Base/ByteArray.h" +#include <vector> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/Algorithm.h> +#include <Swiften/FileTransfer/ReadBytestream.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { class ByteArrayReadBytestream : public ReadBytestream { public: - ByteArrayReadBytestream(const ByteArray& data) : data(data), position(0) { + ByteArrayReadBytestream(const std::vector<unsigned char>& data) : data(data), position(0), dataComplete(true) { } - virtual ByteArray read(size_t size) { + virtual boost::shared_ptr<ByteArray> read(size_t size) { size_t readSize = size; - if (position + readSize > data.getSize()) { - readSize = data.getSize() - position; + if (position + readSize > data.size()) { + readSize = data.size() - position; } - ByteArray result(data.getData() + position, readSize); + boost::shared_ptr<ByteArray> result = boost::make_shared<ByteArray>(data.begin() + position, data.begin() + position + readSize); + + onRead(*result); position += readSize; return result; } virtual bool isFinished() const { - return position >= data.getSize(); + return position >= data.size() && dataComplete; + } + + virtual void setDataComplete(bool b) { + dataComplete = b; + } + + void addData(const std::vector<unsigned char>& moreData) { + append(data, moreData); + onDataAvailable(); } private: - ByteArray data; + std::vector<unsigned char> data; size_t position; + bool dataComplete; }; } diff --git a/Swiften/FileTransfer/ByteArrayWriteBytestream.h b/Swiften/FileTransfer/ByteArrayWriteBytestream.h new file mode 100644 index 0000000..ef97ed9 --- /dev/null +++ b/Swiften/FileTransfer/ByteArrayWriteBytestream.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/FileTransfer/WriteBytestream.h> + +namespace Swift { + class ByteArrayWriteBytestream : public WriteBytestream { + public: + ByteArrayWriteBytestream() { + } + + virtual void write(const std::vector<unsigned char>& bytes) { + data.insert(data.end(), bytes.begin(), bytes.end()); + onWrite(bytes); + } + + const std::vector<unsigned char>& getData() const { + return data; + } + + private: + std::vector<unsigned char> data; + }; +} diff --git a/Swiften/FileTransfer/BytestreamsRequest.h b/Swiften/FileTransfer/BytestreamsRequest.h index 9757bfa..fee09ee 100644 --- a/Swiften/FileTransfer/BytestreamsRequest.h +++ b/Swiften/FileTransfer/BytestreamsRequest.h @@ -8,8 +8,8 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Queries/GenericRequest.h" -#include "Swiften/Elements/Bytestreams.h" +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Elements/Bytestreams.h> namespace Swift { class BytestreamsRequest : public GenericRequest<Bytestreams> { @@ -20,8 +20,15 @@ namespace Swift { return ref(new BytestreamsRequest(jid, payload, router)); } + static ref create(const JID& from, const JID& to, boost::shared_ptr<Bytestreams> payload, IQRouter* router) { + return ref(new BytestreamsRequest(from, to, payload, router)); + } + private: BytestreamsRequest(const JID& jid, boost::shared_ptr<Bytestreams> payload, IQRouter* router) : GenericRequest<Bytestreams>(IQ::Set, jid, payload, router) { } + + BytestreamsRequest(const JID& from, const JID& to, boost::shared_ptr<Bytestreams> payload, IQRouter* router) : GenericRequest<Bytestreams>(IQ::Set, from, to, payload, router) { + } }; } diff --git a/Swiften/FileTransfer/ConnectivityManager.cpp b/Swiften/FileTransfer/ConnectivityManager.cpp new file mode 100644 index 0000000..7d25991 --- /dev/null +++ b/Swiften/FileTransfer/ConnectivityManager.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "ConnectivityManager.h" + +#include <boost/bind.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/Log.h> +#include <Swiften/Network/NetworkInterface.h> +#include <Swiften/Network/NATTraversalGetPublicIPRequest.h> +#include <Swiften/Network/NATTraversalRemovePortForwardingRequest.h> +#include <Swiften/Network/NATTraverser.h> +#include <Swiften/Network/PlatformNetworkEnvironment.h> + +namespace Swift { + +ConnectivityManager::ConnectivityManager(NATTraverser* worker) : natTraversalWorker(worker) { + +} + +ConnectivityManager::~ConnectivityManager() { + std::set<int> leftOpenPorts = ports; + foreach(int port, leftOpenPorts) { + removeListeningPort(port); + } +} + +void ConnectivityManager::addListeningPort(int port) { + ports.insert(port); + boost::shared_ptr<NATTraversalGetPublicIPRequest> getIPRequest = natTraversalWorker->createGetPublicIPRequest(); + if (getIPRequest) { + getIPRequest->onResult.connect(boost::bind(&ConnectivityManager::natTraversalGetPublicIPResult, this, _1)); + getIPRequest->run(); + } + + boost::shared_ptr<NATTraversalForwardPortRequest> forwardPortRequest = natTraversalWorker->createForwardPortRequest(port, port); + if (forwardPortRequest) { + forwardPortRequest->onResult.connect(boost::bind(&ConnectivityManager::natTraversalForwardPortResult, this, _1)); + forwardPortRequest->run(); + } +} + +void ConnectivityManager::removeListeningPort(int port) { + SWIFT_LOG(debug) << "remove listening port " << port << std::endl; + ports.erase(port); + boost::shared_ptr<NATTraversalRemovePortForwardingRequest> removePortForwardingRequest = natTraversalWorker->createRemovePortForwardingRequest(port, port); + if (removePortForwardingRequest) { + removePortForwardingRequest->run(); + } +} + +std::vector<HostAddressPort> ConnectivityManager::getHostAddressPorts() const { + PlatformNetworkEnvironment env; + std::vector<HostAddressPort> results; + + std::vector<HostAddress> addresses; + + std::vector<NetworkInterface> networkInterfaces; + foreach (const NetworkInterface& iface, networkInterfaces) { + foreach (const HostAddress& address, iface.getAddresses()) { + foreach (int port, ports) { + results.push_back(HostAddressPort(address, port)); + } + } + } + + return results; +} + +std::vector<HostAddressPort> ConnectivityManager::getAssistedHostAddressPorts() const { + std::vector<HostAddressPort> results; + + if (publicAddress) { + foreach (int port, ports) { + results.push_back(HostAddressPort(publicAddress.get(), port)); + } + } + + return results; +} + +void ConnectivityManager::natTraversalGetPublicIPResult(boost::optional<HostAddress> address) { + if (address) { + publicAddress = address; + SWIFT_LOG(debug) << "Public IP discovered as " << publicAddress.get().toString() << "." << std::endl; + } else { + SWIFT_LOG(debug) << "No public IP discoverable." << std::endl; + } +} + +void ConnectivityManager::natTraversalForwardPortResult(boost::optional<NATPortMapping> mapping) { + if (mapping) { + SWIFT_LOG(debug) << "Mapping port was successful." << std::endl; + } else { + SWIFT_LOG(debug) << "Mapping port has failed." << std::endl; + } +} + + +} diff --git a/Swiften/FileTransfer/ConnectivityManager.h b/Swiften/FileTransfer/ConnectivityManager.h new file mode 100644 index 0000000..c094c02 --- /dev/null +++ b/Swiften/FileTransfer/ConnectivityManager.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <vector> +#include <set> + +#include <boost/optional.hpp> + +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Network/NATTraverser.h> +#include <Swiften/Network/NATTraversalForwardPortRequest.h> +#include <Swiften/Network/NATPortMapping.h> + +namespace Swift { + +class NATTraverser; + +class ConnectivityManager { +public: + ConnectivityManager(NATTraverser*); + ~ConnectivityManager(); +public: + void addListeningPort(int port); + void removeListeningPort(int port); + + std::vector<HostAddressPort> getHostAddressPorts() const; + std::vector<HostAddressPort> getAssistedHostAddressPorts() const; + +private: + void natTraversalGetPublicIPResult(boost::optional<HostAddress> address); + void natTraversalForwardPortResult(boost::optional<NATPortMapping> mapping); + +private: + NATTraverser* natTraversalWorker; + + std::set<int> ports; + boost::optional<HostAddress> publicAddress; +}; + +} diff --git a/Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGenerator.cpp b/Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGenerator.cpp new file mode 100644 index 0000000..4b205cb --- /dev/null +++ b/Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGenerator.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "DefaultLocalJingleTransportCandidateGenerator.h" + +#include <vector> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/Log.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/FileTransfer/ConnectivityManager.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h> + +namespace Swift { + +DefaultLocalJingleTransportCandidateGenerator::DefaultLocalJingleTransportCandidateGenerator(ConnectivityManager* connectivityManager, SOCKS5BytestreamRegistry* s5bRegistry, SOCKS5BytestreamProxy* s5bProxy, JID& ownJID) : connectivityManager(connectivityManager), s5bRegistry(s5bRegistry), s5bProxy(s5bProxy), ownJID(ownJID) { +} + +DefaultLocalJingleTransportCandidateGenerator::~DefaultLocalJingleTransportCandidateGenerator() { +} + +void DefaultLocalJingleTransportCandidateGenerator::generateLocalTransportCandidates(JingleTransportPayload::ref transportPayload) { + if (boost::dynamic_pointer_cast<JingleIBBTransportPayload>(transportPayload)) { + JingleTransportPayload::ref payL = boost::make_shared<JingleTransportPayload>(); + payL->setSessionID(transportPayload->getSessionID()); + onLocalTransportCandidatesGenerated(payL); + } + if (boost::dynamic_pointer_cast<JingleS5BTransportPayload>(transportPayload)) { + JingleS5BTransportPayload::ref payL = boost::make_shared<JingleS5BTransportPayload>(); + payL->setSessionID(transportPayload->getSessionID()); + payL->setMode(JingleS5BTransportPayload::TCPMode); + + const unsigned long localPreference = 0; + + // get direct candidates + std::vector<HostAddressPort> directCandidates = connectivityManager->getHostAddressPorts(); + foreach(HostAddressPort addressPort, directCandidates) { + JingleS5BTransportPayload::Candidate candidate; + candidate.type = JingleS5BTransportPayload::Candidate::DirectType; + candidate.jid = ownJID; + candidate.hostPort = addressPort; + candidate.priority = 65536 * 126 + localPreference; + candidate.cid = idGenerator.generateID(); + payL->addCandidate(candidate); + } + + // get assissted candidates + std::vector<HostAddressPort> assisstedCandidates = connectivityManager->getAssistedHostAddressPorts(); + foreach(HostAddressPort addressPort, assisstedCandidates) { + JingleS5BTransportPayload::Candidate candidate; + candidate.type = JingleS5BTransportPayload::Candidate::AssistedType; + candidate.jid = ownJID; + candidate.hostPort = addressPort; + candidate.priority = 65536 * 120 + localPreference; + candidate.cid = idGenerator.generateID(); + payL->addCandidate(candidate); + } + + // get proxy candidates + std::vector<S5BProxyRequest::ref> proxyCandidates = s5bProxy->getS5BProxies(); + foreach(S5BProxyRequest::ref proxy, proxyCandidates) { + if (proxy->getStreamHost()) { // FIXME: Added this test, because there were cases where this wasn't initialized. Investigate this. (Remko) + JingleS5BTransportPayload::Candidate candidate; + candidate.type = JingleS5BTransportPayload::Candidate::ProxyType; + candidate.jid = (*proxy->getStreamHost()).jid; + candidate.hostPort = (*proxy->getStreamHost()).addressPort; + candidate.priority = 65536 * 10 + localPreference; + candidate.cid = idGenerator.generateID(); + payL->addCandidate(candidate); + } + } + + onLocalTransportCandidatesGenerated(payL); + } + +} + +bool DefaultLocalJingleTransportCandidateGenerator::isActualCandidate(JingleTransportPayload::ref transportPayload) { + if (!transportPayload.get()) return false; + return false; +} + +int DefaultLocalJingleTransportCandidateGenerator::getPriority(JingleTransportPayload::ref /* transportPayload */) { + return 0; +} + +JingleTransport::ref DefaultLocalJingleTransportCandidateGenerator::selectTransport(JingleTransportPayload::ref /* transportPayload */) { + return JingleTransport::ref(); +} + +} diff --git a/Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGenerator.h b/Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGenerator.h new file mode 100644 index 0000000..7d45491 --- /dev/null +++ b/Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGenerator.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h> + +#include <Swiften/Base/IDGenerator.h> +#include <Swiften/JID/JID.h> + +namespace Swift { + +class SOCKS5BytestreamRegistry; +class SOCKS5BytestreamProxy; +class ConnectivityManager; + +class DefaultLocalJingleTransportCandidateGenerator : public LocalJingleTransportCandidateGenerator { +public: + DefaultLocalJingleTransportCandidateGenerator(ConnectivityManager* connectivityManager, SOCKS5BytestreamRegistry* s5bRegistry, SOCKS5BytestreamProxy* s5bProxy, JID& ownJID); + virtual ~DefaultLocalJingleTransportCandidateGenerator(); + + virtual void generateLocalTransportCandidates(JingleTransportPayload::ref); + + virtual bool isActualCandidate(JingleTransportPayload::ref); + virtual int getPriority(JingleTransportPayload::ref); + virtual JingleTransport::ref selectTransport(JingleTransportPayload::ref); + +private: + IDGenerator idGenerator; + ConnectivityManager* connectivityManager; + SOCKS5BytestreamRegistry* s5bRegistry; + SOCKS5BytestreamProxy* s5bProxy; + JID ownJID; +}; + +} diff --git a/Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.cpp b/Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.cpp new file mode 100644 index 0000000..ed0386e --- /dev/null +++ b/Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "DefaultLocalJingleTransportCandidateGeneratorFactory.h" + +#include <Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGenerator.h> +#include <Swiften/Base/Log.h> + +namespace Swift { + +DefaultLocalJingleTransportCandidateGeneratorFactory::DefaultLocalJingleTransportCandidateGeneratorFactory(ConnectivityManager* connectivityManager, SOCKS5BytestreamRegistry* s5bRegistry, SOCKS5BytestreamProxy* s5bProxy, const JID& ownJID) : connectivityManager(connectivityManager), s5bRegistry(s5bRegistry), s5bProxy(s5bProxy), ownJID(ownJID) { +} + +DefaultLocalJingleTransportCandidateGeneratorFactory::~DefaultLocalJingleTransportCandidateGeneratorFactory() { +} + +LocalJingleTransportCandidateGenerator* DefaultLocalJingleTransportCandidateGeneratorFactory::createCandidateGenerator() { + return new DefaultLocalJingleTransportCandidateGenerator(connectivityManager, s5bRegistry, s5bProxy, ownJID); +} + + +} diff --git a/Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.h b/Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.h new file mode 100644 index 0000000..511d0a1 --- /dev/null +++ b/Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h> + +#include <Swiften/JID/JID.h> + +namespace Swift { + +class ConnectivityManager; +class SOCKS5BytestreamRegistry; +class SOCKS5BytestreamProxy; + +class DefaultLocalJingleTransportCandidateGeneratorFactory : public LocalJingleTransportCandidateGeneratorFactory{ +public: + DefaultLocalJingleTransportCandidateGeneratorFactory(ConnectivityManager* connectivityManager, SOCKS5BytestreamRegistry* s5bRegistry, SOCKS5BytestreamProxy* s5bProxy, const JID& ownJID); + virtual ~DefaultLocalJingleTransportCandidateGeneratorFactory(); + + LocalJingleTransportCandidateGenerator* createCandidateGenerator(); + +private: + ConnectivityManager* connectivityManager; + SOCKS5BytestreamRegistry* s5bRegistry; + SOCKS5BytestreamProxy* s5bProxy; + JID ownJID; +}; + +} diff --git a/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.cpp b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.cpp new file mode 100644 index 0000000..32b4df8 --- /dev/null +++ b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "DefaultRemoteJingleTransportCandidateSelector.h" + +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/bind.hpp> + +#include <Swiften/Base/Log.h> +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> + +namespace Swift { + +DefaultRemoteJingleTransportCandidateSelector::DefaultRemoteJingleTransportCandidateSelector(ConnectionFactory* connectionFactory, TimerFactory* timerFactory) : connectionFactory(connectionFactory), timerFactory(timerFactory) { +} + +DefaultRemoteJingleTransportCandidateSelector::~DefaultRemoteJingleTransportCandidateSelector() { +} + +void DefaultRemoteJingleTransportCandidateSelector::addRemoteTransportCandidates(JingleTransportPayload::ref transportPayload) { + JingleS5BTransportPayload::ref s5bPayload; + transportSID = transportPayload->getSessionID(); + if ((s5bPayload = boost::dynamic_pointer_cast<JingleS5BTransportPayload>(transportPayload))) { + foreach(JingleS5BTransportPayload::Candidate c, s5bPayload->getCandidates()) { + candidates.push(c); + } + } +} + +void DefaultRemoteJingleTransportCandidateSelector::selectCandidate() { + tryNextCandidate(true); +} + +void DefaultRemoteJingleTransportCandidateSelector::tryNextCandidate(bool error) { + if (error) { + if (s5bSession) { + SWIFT_LOG(debug) << "failed to connect" << std::endl; + } + if (candidates.empty()) { + // failed to connect to any of the candidates + // issue an error + SWIFT_LOG(debug) << "out of candidates )=" << std::endl; + JingleS5BTransportPayload::ref failed = boost::make_shared<JingleS5BTransportPayload>(); + failed->setCandidateError(true); + failed->setSessionID(transportSID); + onRemoteTransportCandidateSelectFinished(failed); + } else { + lastCandidate = candidates.top(); + // only try direct or assisted for now + if (lastCandidate.type == JingleS5BTransportPayload::Candidate::DirectType || + lastCandidate.type == JingleS5BTransportPayload::Candidate::AssistedType || lastCandidate.type == JingleS5BTransportPayload::Candidate::ProxyType ) { + // create connection + connection = connectionFactory->createConnection(); + s5bSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, lastCandidate.hostPort, SOCKS5BytestreamRegistry::getHostname(transportSID, requester, target), timerFactory); + + // bind onReady to this method + s5bSession->onSessionReady.connect(boost::bind(&DefaultRemoteJingleTransportCandidateSelector::tryNextCandidate, this, _1)); + + std::string candidateType; + if (lastCandidate.type == JingleS5BTransportPayload::Candidate::DirectType) { + candidateType = "direct"; + } else if (lastCandidate.type == JingleS5BTransportPayload::Candidate::AssistedType) { + candidateType = "assisted"; + } else if (lastCandidate.type == JingleS5BTransportPayload::Candidate::ProxyType) { + candidateType = "proxy"; + } + + // initiate connect + SWIFT_LOG(debug) << "try to connect to candidate of type " << candidateType << " : " << lastCandidate.hostPort.toString() << std::endl; + s5bSession->start(); + + // that's it. we're gonna be called back + candidates.pop(); + } else { + s5bSession.reset(); + candidates.pop(); + tryNextCandidate(true); + } + } + } else { + // we have a working connection, hooray + JingleS5BTransportPayload::ref success = boost::make_shared<JingleS5BTransportPayload>(); + success->setCandidateUsed(lastCandidate.cid); + success->setSessionID(transportSID); + onRemoteTransportCandidateSelectFinished(success); + } +} + +void DefaultRemoteJingleTransportCandidateSelector::setMinimumPriority(int priority) { + SWIFT_LOG(debug) << "priority: " << priority << std::endl; +} + +void DefaultRemoteJingleTransportCandidateSelector::setRequesterTargtet(const JID& requester, const JID& target) { + this->requester = requester; + this->target = target; +} + +SOCKS5BytestreamClientSession::ref DefaultRemoteJingleTransportCandidateSelector::getS5BSession() { + return s5bSession; +} + +bool DefaultRemoteJingleTransportCandidateSelector::isActualCandidate(JingleTransportPayload::ref /* transportPayload */) { + return false; +} + +int DefaultRemoteJingleTransportCandidateSelector::getPriority(JingleTransportPayload::ref /* transportPayload */) { + return 0; +} + +JingleTransport::ref DefaultRemoteJingleTransportCandidateSelector::selectTransport(JingleTransportPayload::ref /* transportPayload */) { + return JingleTransport::ref(); +} + +} diff --git a/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.h b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.h new file mode 100644 index 0000000..255acd9 --- /dev/null +++ b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <queue> +#include <vector> + +#include <boost/shared_ptr.hpp> + +#include <Swiften/JID/JID.h> +#include <Swiften/Network/Connection.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> + + +namespace Swift { + +class ConnectionFactory; +class TimerFactory; + +class DefaultRemoteJingleTransportCandidateSelector : public RemoteJingleTransportCandidateSelector { +public: + DefaultRemoteJingleTransportCandidateSelector(ConnectionFactory*, TimerFactory*); + virtual ~DefaultRemoteJingleTransportCandidateSelector(); + + virtual void addRemoteTransportCandidates(JingleTransportPayload::ref); + virtual void selectCandidate(); + virtual void setMinimumPriority(int); + void setRequesterTargtet(const JID& requester, const JID& target); + virtual SOCKS5BytestreamClientSession::ref getS5BSession(); + + virtual bool isActualCandidate(JingleTransportPayload::ref); + virtual int getPriority(JingleTransportPayload::ref); + virtual JingleTransport::ref selectTransport(JingleTransportPayload::ref); + +private: + void tryNextCandidate(bool error); + +private: + ConnectionFactory* connectionFactory; + TimerFactory* timerFactory; + + std::priority_queue<JingleS5BTransportPayload::Candidate, std::vector<JingleS5BTransportPayload::Candidate>, JingleS5BTransportPayload::CompareCandidate> candidates; + + std::string transportSID; + boost::shared_ptr<Connection> connection; + boost::shared_ptr<SOCKS5BytestreamClientSession> s5bSession; + JingleS5BTransportPayload::Candidate lastCandidate; + JID requester; + JID target; +}; + +} diff --git a/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.cpp b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.cpp new file mode 100644 index 0000000..8ebbf46 --- /dev/null +++ b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "DefaultRemoteJingleTransportCandidateSelectorFactory.h" + +#include <Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.h> + +#include <Swiften/Base/Log.h> + +namespace Swift { + +DefaultRemoteJingleTransportCandidateSelectorFactory::DefaultRemoteJingleTransportCandidateSelectorFactory(ConnectionFactory* connectionFactory, TimerFactory* timerFactory) : connectionFactory(connectionFactory), timerFactory(timerFactory) { +} + +DefaultRemoteJingleTransportCandidateSelectorFactory::~DefaultRemoteJingleTransportCandidateSelectorFactory() { +} + +RemoteJingleTransportCandidateSelector* DefaultRemoteJingleTransportCandidateSelectorFactory::createCandidateSelector() { + return new DefaultRemoteJingleTransportCandidateSelector(connectionFactory, timerFactory); +} + +} diff --git a/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h new file mode 100644 index 0000000..ca29e1f --- /dev/null +++ b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h> + +namespace Swift { + +class ConnectionFactory; +class TimerFactory; + +class DefaultRemoteJingleTransportCandidateSelectorFactory : public RemoteJingleTransportCandidateSelectorFactory { +public: + DefaultRemoteJingleTransportCandidateSelectorFactory(ConnectionFactory*, TimerFactory*); + virtual ~DefaultRemoteJingleTransportCandidateSelectorFactory(); + + RemoteJingleTransportCandidateSelector* createCandidateSelector(); + +private: + ConnectionFactory* connectionFactory; + TimerFactory* timerFactory; +}; + +} diff --git a/Swiften/FileTransfer/FileReadBytestream.cpp b/Swiften/FileTransfer/FileReadBytestream.cpp index c08747b..a8946a0 100644 --- a/Swiften/FileTransfer/FileReadBytestream.cpp +++ b/Swiften/FileTransfer/FileReadBytestream.cpp @@ -6,8 +6,10 @@ #include <boost/filesystem/fstream.hpp> #include <cassert> +#include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/FileTransfer/FileReadBytestream.h" +#include <Swiften/FileTransfer/FileReadBytestream.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { @@ -21,15 +23,16 @@ FileReadBytestream::~FileReadBytestream() { } } -ByteArray FileReadBytestream::read(size_t size) { +boost::shared_ptr<ByteArray> FileReadBytestream::read(size_t size) { if (!stream) { stream = new boost::filesystem::ifstream(file, std::ios_base::in|std::ios_base::binary); } - ByteArray result; - result.resize(size); + boost::shared_ptr<ByteArray> result = boost::make_shared<ByteArray>(); + result->resize(size); assert(stream->good()); - stream->read(reinterpret_cast<char*>(result.getData()), size); - result.resize(stream->gcount()); + stream->read(reinterpret_cast<char*>(vecptr(*result)), size); + result->resize(stream->gcount()); + onRead(*result); return result; } diff --git a/Swiften/FileTransfer/FileReadBytestream.h b/Swiften/FileTransfer/FileReadBytestream.h index 055e194..e9db2a4 100644 --- a/Swiften/FileTransfer/FileReadBytestream.h +++ b/Swiften/FileTransfer/FileReadBytestream.h @@ -6,10 +6,10 @@ #pragma once -#include <boost/filesystem.hpp> +#include <boost/filesystem/path.hpp> #include <boost/filesystem/fstream.hpp> -#include "Swiften/FileTransfer/ReadBytestream.h" +#include <Swiften/FileTransfer/ReadBytestream.h> namespace Swift { class FileReadBytestream : public ReadBytestream { @@ -17,7 +17,7 @@ namespace Swift { FileReadBytestream(const boost::filesystem::path& file); ~FileReadBytestream(); - virtual ByteArray read(size_t size) ; + virtual boost::shared_ptr< std::vector<unsigned char> > read(size_t size); virtual bool isFinished() const; private: diff --git a/Swiften/FileTransfer/FileTransfer.h b/Swiften/FileTransfer/FileTransfer.h new file mode 100644 index 0000000..336c51c --- /dev/null +++ b/Swiften/FileTransfer/FileTransfer.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/cstdint.hpp> +#include <boost/optional.hpp> +#include <boost/shared_ptr.hpp> + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/FileTransfer/FileTransferError.h> + +namespace Swift { + +class FileTransfer { +public: + struct State { + enum FTState { + Canceled, + Failed, + Finished, + Negotiating, + Transferring, + WaitingForStart, + WaitingForAccept, + }; + + FTState state; + std::string message; + + State(FTState state) : state(state), message("") {} + State(FTState state, std::string message) : state(state), message(message) {} + }; + +public: + typedef boost::shared_ptr<FileTransfer> ref; + +public: + boost::uintmax_t fileSizeInBytes; + std::string filename; + std::string algo; + std::string hash; + +public: + virtual void cancel() = 0; + +public: + boost::signal<void (int /* proccessedBytes */)> onProcessedBytes; + boost::signal<void (State)> onStateChange; + boost::signal<void (boost::optional<FileTransferError>)> onFinished; + +public: + virtual ~FileTransfer() {} +}; + +} diff --git a/Swiften/FileTransfer/FileTransferManager.cpp b/Swiften/FileTransfer/FileTransferManager.cpp new file mode 100644 index 0000000..69be852 --- /dev/null +++ b/Swiften/FileTransfer/FileTransferManager.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/FileTransfer/FileTransferManager.h> + +namespace Swift { + +FileTransferManager::~FileTransferManager() { +} + +} diff --git a/Swiften/FileTransfer/FileTransferManager.h b/Swiften/FileTransfer/FileTransferManager.h new file mode 100644 index 0000000..d59f029 --- /dev/null +++ b/Swiften/FileTransfer/FileTransferManager.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <string> +#include <boost/filesystem.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/JID/JID.h> +#include <Swiften/FileTransfer/OutgoingFileTransfer.h> +#include <Swiften/FileTransfer/IncomingFileTransfer.h> + +namespace Swift { + class ReadBytestream; + class S5BProxyRequest; + + class FileTransferManager { + public: + virtual ~FileTransferManager(); + + virtual void startListeningOnPort(int port) = 0; + + virtual OutgoingFileTransfer::ref createOutgoingFileTransfer(const JID& to, const boost::filesystem::path& filepath, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream) = 0; + virtual OutgoingFileTransfer::ref createOutgoingFileTransfer(const JID& to, const std::string& filename, const std::string& description, const boost::uintmax_t sizeInBytes, const boost::posix_time::ptime& lastModified, boost::shared_ptr<ReadBytestream> bytestream) = 0; + + boost::signal<void (IncomingFileTransfer::ref)> onIncomingFileTransfer; + }; +} diff --git a/Swiften/FileTransfer/FileTransferManagerImpl.cpp b/Swiften/FileTransfer/FileTransferManagerImpl.cpp new file mode 100644 index 0000000..83320b2 --- /dev/null +++ b/Swiften/FileTransfer/FileTransferManagerImpl.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/FileTransfer/FileTransferManagerImpl.h> + +#include <boost/bind.hpp> +#include <boost/cstdint.hpp> + +#include <Swiften/Base/foreach.h> +#include "Swiften/Disco/EntityCapsProvider.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/StreamInitiationFileInfo.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h> +#include <Swiften/FileTransfer/ConnectivityManager.h> +#include <Swiften/FileTransfer/OutgoingFileTransferManager.h> +#include <Swiften/FileTransfer/IncomingFileTransferManager.h> +#include <Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.h> +#include <Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h> +#include <Swiften/Presence/PresenceOracle.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/ConnectionServerFactory.h> +#include <Swiften/Network/HostAddress.h> +#include <Swiften/Network/NATTraverser.h> + +namespace Swift { + +FileTransferManagerImpl::FileTransferManagerImpl(const JID& ownFullJID, JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, PresenceOracle* presOracle, ConnectionFactory* connectionFactory, ConnectionServerFactory* connectionServerFactory, TimerFactory* timerFactory, NATTraverser* natTraverser) : ownJID(ownFullJID), jingleSM(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), presenceOracle(presOracle), timerFactory(timerFactory), connectionFactory(connectionFactory), connectionServerFactory(connectionServerFactory), natTraverser(natTraverser), bytestreamServer(NULL), s5bProxyFinder(NULL) { + assert(!ownFullJID.isBare()); + + connectivityManager = new ConnectivityManager(natTraverser); + bytestreamRegistry = new SOCKS5BytestreamRegistry(); + bytestreamProxy = new SOCKS5BytestreamProxy(connectionFactory, timerFactory); + + localCandidateGeneratorFactory = new DefaultLocalJingleTransportCandidateGeneratorFactory(connectivityManager, bytestreamRegistry, bytestreamProxy, ownFullJID); + remoteCandidateSelectorFactory = new DefaultRemoteJingleTransportCandidateSelectorFactory(connectionFactory, timerFactory); + outgoingFTManager = new OutgoingFileTransferManager(jingleSM, iqRouter, capsProvider, remoteCandidateSelectorFactory, localCandidateGeneratorFactory, bytestreamRegistry, bytestreamProxy); + incomingFTManager = new IncomingFileTransferManager(jingleSM, iqRouter, remoteCandidateSelectorFactory, localCandidateGeneratorFactory, bytestreamRegistry, bytestreamProxy, timerFactory); + incomingFTManager->onIncomingFileTransfer.connect(onIncomingFileTransfer); +} + +FileTransferManagerImpl::~FileTransferManagerImpl() { + if (s5bProxyFinder) { + s5bProxyFinder->stop(); + delete s5bProxyFinder; + } + if (bytestreamServer) { + bytestreamServer->stop(); + delete bytestreamServer; + } + delete incomingFTManager; + delete outgoingFTManager; + delete remoteCandidateSelectorFactory; + delete localCandidateGeneratorFactory; + delete connectivityManager; +} + +void FileTransferManagerImpl::startListeningOnPort(int port) { + // TODO: create a server for each interface we're on + SWIFT_LOG(debug) << "Start listening on port " << port << " and hope it's not in use." << std::endl; + boost::shared_ptr<ConnectionServer> server = connectionServerFactory->createConnectionServer(HostAddress("0.0.0.0"), port); + server->start(); + bytestreamServer = new SOCKS5BytestreamServer(server, bytestreamRegistry); + bytestreamServer->start(); + connectivityManager->addListeningPort(port); + + s5bProxyFinder = new SOCKS5BytestreamProxyFinder(ownJID.getDomain(), iqRouter); + s5bProxyFinder->onProxyFound.connect(boost::bind(&FileTransferManagerImpl::addS5BProxy, this, _1)); + s5bProxyFinder->start(); +} + +void FileTransferManagerImpl::addS5BProxy(S5BProxyRequest::ref proxy) { + bytestreamProxy->addS5BProxy(proxy); +} + +boost::optional<JID> FileTransferManagerImpl::highestPriorityJIDSupportingFileTransfer(const JID& bareJID) { + JID fullReceipientJID; + int priority = INT_MIN; + + //getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11 + std::vector<Presence::ref> presences = presenceOracle->getAllPresence(bareJID); + + //iterate over them + foreach(Presence::ref pres, presences) { + if (pres->getPriority() > priority) { + // look up caps from the jid + DiscoInfo::ref info = capsProvider->getCaps(pres->getFrom()); + if (info && info->hasFeature(DiscoInfo::JingleFeature) && info->hasFeature(DiscoInfo::JingleFTFeature) && (info->hasFeature(DiscoInfo::JingleTransportsIBBFeature) || info->hasFeature(DiscoInfo::JingleTransportsS5BFeature))) { + + priority = pres->getPriority(); + fullReceipientJID = pres->getFrom(); + } + } + } + + return fullReceipientJID.isValid() ? boost::optional<JID>(fullReceipientJID) : boost::optional<JID>(); +} + +OutgoingFileTransfer::ref FileTransferManagerImpl::createOutgoingFileTransfer(const JID& to, const boost::filesystem::path& filepath, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream) { + std::string filename = filepath.filename(); + boost::uintmax_t sizeInBytes = boost::filesystem::file_size(filepath); + boost::posix_time::ptime lastModified = boost::posix_time::from_time_t(boost::filesystem::last_write_time(filepath)); + return createOutgoingFileTransfer(to, filename, description, sizeInBytes, lastModified, bytestream); +} + +OutgoingFileTransfer::ref FileTransferManagerImpl::createOutgoingFileTransfer(const JID& to, const std::string& filename, const std::string& description, const boost::uintmax_t sizeInBytes, const boost::posix_time::ptime& lastModified, boost::shared_ptr<ReadBytestream> bytestream) { + StreamInitiationFileInfo fileInfo; + fileInfo.setDate(lastModified); + fileInfo.setSize(sizeInBytes); + fileInfo.setName(filename); + fileInfo.setDescription(description); + + JID receipient = to; + + if(receipient.isBare()) { + boost::optional<JID> fullJID = highestPriorityJIDSupportingFileTransfer(receipient); + if (fullJID.is_initialized()) { + receipient = fullJID.get(); + } else { + return OutgoingFileTransfer::ref(); + } + } + + return outgoingFTManager->createOutgoingFileTransfer(ownJID, receipient, bytestream, fileInfo); +} + +} diff --git a/Swiften/FileTransfer/FileTransferManagerImpl.h b/Swiften/FileTransfer/FileTransferManagerImpl.h new file mode 100644 index 0000000..248b437 --- /dev/null +++ b/Swiften/FileTransfer/FileTransferManagerImpl.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <vector> +#include <string> + +#include <boost/filesystem.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/optional.hpp> + +#include <Swiften/FileTransfer/FileTransferManager.h> +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/JID/JID.h> +#include <Swiften/FileTransfer/OutgoingFileTransfer.h> +#include <Swiften/FileTransfer/IncomingFileTransfer.h> +#include <Swiften/Elements/S5BProxyRequest.h> + +namespace Swift { + class Client; + class ConnectionFactory; + class ConnectionServerFactory; + class ConnectivityManager; + class EntityCapsProvider; + class IQRouter; + class IncomingFileTransferManager; + class JingleSessionManager; + class LocalJingleTransportCandidateGeneratorFactory; + class OutgoingFileTransferManager; + class NATTraverser; + class PresenceOracle; + class ReadBytestream; + class RemoteJingleTransportCandidateSelectorFactory; + class SOCKS5BytestreamRegistry; + class SOCKS5BytestreamServer; + class SOCKS5BytestreamProxy; + class TimerFactory; + class SOCKS5BytestreamProxyFinder; + + class FileTransferManagerImpl : public FileTransferManager { + public: + FileTransferManagerImpl(const JID& ownFullJID, JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, PresenceOracle* presOracle, ConnectionFactory* connectionFactory, ConnectionServerFactory* connectionServerFactory, TimerFactory* timerFactory, NATTraverser* natTraverser); + ~FileTransferManagerImpl(); + + void startListeningOnPort(int port); + void addS5BProxy(S5BProxyRequest::ref proxy); + + OutgoingFileTransfer::ref createOutgoingFileTransfer(const JID& to, const boost::filesystem::path& filepath, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream); + OutgoingFileTransfer::ref createOutgoingFileTransfer(const JID& to, const std::string& filename, const std::string& description, const boost::uintmax_t sizeInBytes, const boost::posix_time::ptime& lastModified, boost::shared_ptr<ReadBytestream> bytestream); + + private: + boost::optional<JID> highestPriorityJIDSupportingFileTransfer(const JID& bareJID); + + private: + JID ownJID; + + OutgoingFileTransferManager* outgoingFTManager; + IncomingFileTransferManager* incomingFTManager; + RemoteJingleTransportCandidateSelectorFactory* remoteCandidateSelectorFactory; + LocalJingleTransportCandidateGeneratorFactory* localCandidateGeneratorFactory; + JingleSessionManager* jingleSM; + IQRouter* iqRouter; + EntityCapsProvider* capsProvider; + PresenceOracle* presenceOracle; + + TimerFactory* timerFactory; + ConnectionFactory* connectionFactory; + ConnectionServerFactory* connectionServerFactory; + NATTraverser* natTraverser; + SOCKS5BytestreamRegistry* bytestreamRegistry; + SOCKS5BytestreamServer* bytestreamServer; + SOCKS5BytestreamProxy* bytestreamProxy; + ConnectivityManager* connectivityManager; + SOCKS5BytestreamProxyFinder* s5bProxyFinder; + }; + +} diff --git a/Swiften/FileTransfer/FileWriteBytestream.cpp b/Swiften/FileTransfer/FileWriteBytestream.cpp index 4d29bd1..6a22c6a 100644 --- a/Swiften/FileTransfer/FileWriteBytestream.cpp +++ b/Swiften/FileTransfer/FileWriteBytestream.cpp @@ -7,7 +7,7 @@ #include <boost/filesystem/fstream.hpp> #include <cassert> -#include "Swiften/FileTransfer/FileWriteBytestream.h" +#include <Swiften/FileTransfer/FileWriteBytestream.h> namespace Swift { @@ -21,12 +21,20 @@ FileWriteBytestream::~FileWriteBytestream() { } } -void FileWriteBytestream::write(const ByteArray& data) { +void FileWriteBytestream::write(const std::vector<unsigned char>& data) { if (!stream) { stream = new boost::filesystem::ofstream(file, std::ios_base::out|std::ios_base::binary); } assert(stream->good()); - stream->write(reinterpret_cast<const char*>(data.getData()), data.getSize()); + stream->write(reinterpret_cast<const char*>(&data[0]), data.size()); + onWrite(data); +} + +void FileWriteBytestream::close() { + if (stream) { + stream->close(); + stream = NULL; + } } } diff --git a/Swiften/FileTransfer/FileWriteBytestream.h b/Swiften/FileTransfer/FileWriteBytestream.h index c6f7b39..82c4a65 100644 --- a/Swiften/FileTransfer/FileWriteBytestream.h +++ b/Swiften/FileTransfer/FileWriteBytestream.h @@ -6,10 +6,10 @@ #pragma once -#include <boost/filesystem.hpp> +#include <boost/filesystem/path.hpp> #include <boost/filesystem/fstream.hpp> -#include "Swiften/FileTransfer/WriteBytestream.h" +#include <Swiften/FileTransfer/WriteBytestream.h> namespace Swift { class FileWriteBytestream : public WriteBytestream { @@ -17,7 +17,8 @@ namespace Swift { FileWriteBytestream(const boost::filesystem::path& file); ~FileWriteBytestream(); - virtual void write(const ByteArray&); + virtual void write(const std::vector<unsigned char>&); + void close(); private: boost::filesystem::path file; diff --git a/Swiften/FileTransfer/IBBReceiveSession.cpp b/Swiften/FileTransfer/IBBReceiveSession.cpp index 5c90757..1a2bb3a 100644 --- a/Swiften/FileTransfer/IBBReceiveSession.cpp +++ b/Swiften/FileTransfer/IBBReceiveSession.cpp @@ -4,31 +4,107 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/FileTransfer/IBBReceiveSession.h" +#include <Swiften/FileTransfer/IBBReceiveSession.h> #include <boost/bind.hpp> -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/FileTransfer/IBBRequest.h" -#include "Swiften/FileTransfer/BytestreamException.h" +#include <Swiften/Base/Log.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/FileTransfer/IBBRequest.h> +#include <Swiften/FileTransfer/BytestreamException.h> +#include <Swiften/Queries/SetResponder.h> + +#include <cassert> namespace Swift { -IBBReceiveSession::IBBReceiveSession(const std::string& id, const JID& from, size_t size, WriteBytestream::ref bytestream, IQRouter* router) : SetResponder<IBB>(router), id(id), from(from), size(size), bytestream(bytestream), router(router), sequenceNumber(0), active(false), receivedSize(0) { +class IBBReceiveSession::IBBResponder : public SetResponder<IBB> { + public: + IBBResponder(IBBReceiveSession* session, IQRouter* router) : SetResponder<IBB>(router), session(session), sequenceNumber(0), receivedSize(0) { + } + + virtual bool handleSetRequest(const JID& from, const JID&, const std::string& id, IBB::ref ibb) { + if (from == session->from && ibb->getStreamID() == session->id) { + if (ibb->getAction() == IBB::Data) { + if (sequenceNumber == ibb->getSequenceNumber()) { + session->onDataReceived(ibb->getData()); + receivedSize += ibb->getData().size(); + sequenceNumber++; + sendResponse(from, id, IBB::ref()); + if (receivedSize >= session->size) { + if (receivedSize > session->size) { + std::cerr << "Warning: Received more data than expected" << std::endl; + } + session->finish(boost::optional<FileTransferError>()); + } + } + else { + SWIFT_LOG(warning) << "Received data out of order" << std::endl; + sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Cancel); + session->finish(FileTransferError(FileTransferError::ClosedError)); + } + } + else if (ibb->getAction() == IBB::Open) { + SWIFT_LOG(debug) << "IBB open received" << std::endl; + sendResponse(from, id, IBB::ref()); + } + else if (ibb->getAction() == IBB::Close) { + SWIFT_LOG(debug) << "IBB close received" << std::endl; + sendResponse(from, id, IBB::ref()); + session->finish(FileTransferError(FileTransferError::ClosedError)); + } + return true; + } + SWIFT_LOG(debug) << "wrong from/sessionID: " << from << " == " << session->from << " / " <<ibb->getStreamID() << " == " << session->id << std::endl; + return false; + } + + private: + IBBReceiveSession* session; + int sequenceNumber; + size_t receivedSize; +}; + + +IBBReceiveSession::IBBReceiveSession( + const std::string& id, + const JID& from, + const JID& to, + size_t size, + IQRouter* router) : + id(id), + from(from), + to(to), + size(size), + router(router), + active(false) { + assert(!id.empty()); + assert(from.isValid()); + responder = new IBBResponder(this, router); } IBBReceiveSession::~IBBReceiveSession() { + if (active) { + SWIFT_LOG(warning) << "Session still active" << std::endl; + } + delete responder; } void IBBReceiveSession::start() { + SWIFT_LOG(debug) << "receive session started" << std::endl; active = true; + responder->start(); } void IBBReceiveSession::stop() { - if (active && router->isAvailable()) { - IBBRequest::create(from, IBB::createIBBClose(id), router)->send(); + SWIFT_LOG(debug) << "receive session stopped" << std::endl; + responder->stop(); + if (active) { + if (router->isAvailable()) { + IBBRequest::create(to, from, IBB::createIBBClose(id), router)->send(); + } + finish(boost::optional<FileTransferError>()); } - finish(boost::optional<FileTransferError>()); } void IBBReceiveSession::finish(boost::optional<FileTransferError> error) { @@ -36,34 +112,4 @@ void IBBReceiveSession::finish(boost::optional<FileTransferError> error) { onFinished(error); } -bool IBBReceiveSession::handleSetRequest(const JID& from, const JID&, const std::string& id, IBB::ref ibb) { - if (from == this->from && ibb->getStreamID() == id) { - if (ibb->getAction() == IBB::Data) { - if (sequenceNumber == ibb->getSequenceNumber()) { - bytestream->write(ibb->getData()); - receivedSize += ibb->getData().getSize(); - if (receivedSize >= size) { - if (receivedSize > size) { - std::cerr << "Warning: Received more data than expected" << std::endl; - } - finish(boost::optional<FileTransferError>()); - } - } - else { - sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Cancel); - finish(FileTransferError(FileTransferError::ClosedError)); - } - } - else if (ibb->getAction() == IBB::Open) { - sendResponse(from, id, IBB::ref()); - } - else if (ibb->getAction() == IBB::Close) { - sendResponse(from, id, IBB::ref()); - finish(FileTransferError(FileTransferError::ClosedError)); - } - return true; - } - return false; -} - } diff --git a/Swiften/FileTransfer/IBBReceiveSession.h b/Swiften/FileTransfer/IBBReceiveSession.h index 6d936de..d1c47bf 100644 --- a/Swiften/FileTransfer/IBBReceiveSession.h +++ b/Swiften/FileTransfer/IBBReceiveSession.h @@ -7,27 +7,39 @@ #pragma once #include <boost/shared_ptr.hpp> -#include <boost/optional.hpp> +#include <boost/optional/optional_fwd.hpp> -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/FileTransfer/WriteBytestream.h" -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/IBB.h" -#include "Swiften/Elements/ErrorPayload.h" -#include "Swiften/FileTransfer/FileTransferError.h" -#include "Swiften/Queries/SetResponder.h" +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/FileTransfer/WriteBytestream.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/IBB.h> +#include <Swiften/FileTransfer/FileTransferError.h> namespace Swift { class IQRouter; - class IBBReceiveSession : public SetResponder<IBB> { + class IBBReceiveSession { public: - IBBReceiveSession(const std::string& id, const JID& from, size_t size, WriteBytestream::ref bytestream, IQRouter* router); + IBBReceiveSession( + const std::string& id, + const JID& from, + const JID& to, + size_t size, + IQRouter* router); ~IBBReceiveSession(); void start(); void stop(); + const JID& getSender() const { + return from; + } + + const JID& getReceiver() const { + return to; + } + + boost::signal<void (const std::vector<unsigned char>&)> onDataReceived; boost::signal<void (boost::optional<FileTransferError>)> onFinished; private: @@ -35,13 +47,15 @@ namespace Swift { void finish(boost::optional<FileTransferError>); private: + class IBBResponder; + friend class IBBResponder; + std::string id; JID from; + JID to; size_t size; - WriteBytestream::ref bytestream; IQRouter* router; - int sequenceNumber; + IBBResponder* responder; bool active; - size_t receivedSize; }; } diff --git a/Swiften/FileTransfer/IBBRequest.h b/Swiften/FileTransfer/IBBRequest.h index f104277..58be173 100644 --- a/Swiften/FileTransfer/IBBRequest.h +++ b/Swiften/FileTransfer/IBBRequest.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Queries/GenericRequest.h" -#include "Swiften/Elements/IBB.h" +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Elements/IBB.h> namespace Swift { @@ -15,12 +15,12 @@ namespace Swift { public: typedef boost::shared_ptr<IBBRequest> ref; - static ref create(const JID& jid, boost::shared_ptr<IBB> payload, IQRouter* router) { - return ref(new IBBRequest(jid, payload, router)); + static ref create(const JID& from, const JID& to, boost::shared_ptr<IBB> payload, IQRouter* router) { + return ref(new IBBRequest(from, to, payload, router)); } private: - IBBRequest(const JID& jid, boost::shared_ptr<IBB> payload, IQRouter* router) : GenericRequest<IBB>(IQ::Set, jid, payload, router) { + IBBRequest(const JID& from, const JID& to, boost::shared_ptr<IBB> payload, IQRouter* router) : GenericRequest<IBB>(IQ::Set, from, to, payload, router) { } }; } diff --git a/Swiften/FileTransfer/IBBSendSession.cpp b/Swiften/FileTransfer/IBBSendSession.cpp index 0fb47d3..c24cc0a 100644 --- a/Swiften/FileTransfer/IBBSendSession.cpp +++ b/Swiften/FileTransfer/IBBSendSession.cpp @@ -4,24 +4,27 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/FileTransfer/IBBSendSession.h" +#include <Swiften/FileTransfer/IBBSendSession.h> #include <boost/bind.hpp> -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/FileTransfer/IBBRequest.h" -#include "Swiften/FileTransfer/BytestreamException.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/FileTransfer/IBBRequest.h> +#include <Swiften/FileTransfer/BytestreamException.h> namespace Swift { -IBBSendSession::IBBSendSession(const std::string& id, const JID& to, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* router) : id(id), to(to), bytestream(bytestream), router(router), blockSize(4096), sequenceNumber(0), active(false) { +IBBSendSession::IBBSendSession(const std::string& id, const JID& from, const JID& to, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* router) : id(id), from(from), to(to), bytestream(bytestream), router(router), blockSize(4096), sequenceNumber(0), active(false), waitingForData(false) { + bytestream->onDataAvailable.connect(boost::bind(&IBBSendSession::handleDataAvailable, this)); } IBBSendSession::~IBBSendSession() { + bytestream->onDataAvailable.disconnect(boost::bind(&IBBSendSession::handleDataAvailable, this)); } void IBBSendSession::start() { - IBBRequest::ref request = IBBRequest::create(to, IBB::createIBBOpen(id, blockSize), router); + IBBRequest::ref request = IBBRequest::create(from, to, IBB::createIBBOpen(id, blockSize), router); request->onResponse.connect(boost::bind(&IBBSendSession::handleIBBResponse, this, _1, _2)); active = true; request->send(); @@ -29,24 +32,15 @@ void IBBSendSession::start() { void IBBSendSession::stop() { if (active && router->isAvailable()) { - IBBRequest::create(to, IBB::createIBBClose(id), router)->send(); + IBBRequest::create(from, to, IBB::createIBBClose(id), router)->send(); } finish(boost::optional<FileTransferError>()); } void IBBSendSession::handleIBBResponse(IBB::ref, ErrorPayload::ref error) { - if (!error) { + if (!error && active) { if (!bytestream->isFinished()) { - try { - ByteArray data = bytestream->read(blockSize); - IBBRequest::ref request = IBBRequest::create(to, IBB::createIBBData(id, sequenceNumber, data), router); - sequenceNumber++; - request->onResponse.connect(boost::bind(&IBBSendSession::handleIBBResponse, this, _1, _2)); - request->send(); - } - catch (const BytestreamException& e) { - finish(FileTransferError(FileTransferError::ReadError)); - } + sendMoreData(); } else { finish(boost::optional<FileTransferError>()); @@ -57,9 +51,35 @@ void IBBSendSession::handleIBBResponse(IBB::ref, ErrorPayload::ref error) { } } +void IBBSendSession::sendMoreData() { + try { + boost::shared_ptr<ByteArray> data = bytestream->read(blockSize); + if (!data->empty()) { + waitingForData = false; + IBBRequest::ref request = IBBRequest::create(from, to, IBB::createIBBData(id, sequenceNumber, *data), router); + sequenceNumber++; + request->onResponse.connect(boost::bind(&IBBSendSession::handleIBBResponse, this, _1, _2)); + request->send(); + onBytesSent(data->size()); + } + else { + waitingForData = true; + } + } + catch (const BytestreamException&) { + finish(FileTransferError(FileTransferError::ReadError)); + } +} + void IBBSendSession::finish(boost::optional<FileTransferError> error) { active = false; onFinished(error); } +void IBBSendSession::handleDataAvailable() { + if (waitingForData) { + sendMoreData(); + } +} + } diff --git a/Swiften/FileTransfer/IBBSendSession.h b/Swiften/FileTransfer/IBBSendSession.h index bef7bec..abd217b 100644 --- a/Swiften/FileTransfer/IBBSendSession.h +++ b/Swiften/FileTransfer/IBBSendSession.h @@ -9,41 +9,54 @@ #include <boost/shared_ptr.hpp> #include <boost/optional.hpp> -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/FileTransfer/ReadBytestream.h" -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/IBB.h" -#include "Swiften/Elements/ErrorPayload.h" -#include "Swiften/FileTransfer/FileTransferError.h" +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/FileTransfer/ReadBytestream.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/IBB.h> +#include <Swiften/Elements/ErrorPayload.h> +#include <Swiften/FileTransfer/FileTransferError.h> namespace Swift { class IQRouter; class IBBSendSession { public: - IBBSendSession(const std::string& id, const JID& to, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* router); + IBBSendSession(const std::string& id, const JID& from, const JID& to, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* router); ~IBBSendSession(); void start(); void stop(); + const JID& getSender() const { + return from; + } + + const JID& getReceiver() const { + return to; + } + void setBlockSize(int blockSize) { this->blockSize = blockSize; } boost::signal<void (boost::optional<FileTransferError>)> onFinished; + boost::signal<void (int)> onBytesSent; private: void handleIBBResponse(IBB::ref, ErrorPayload::ref); void finish(boost::optional<FileTransferError>); + void sendMoreData(); + void handleDataAvailable(); private: std::string id; + JID from; JID to; boost::shared_ptr<ReadBytestream> bytestream; IQRouter* router; int blockSize; int sequenceNumber; bool active; + bool waitingForData; }; } diff --git a/Swiften/FileTransfer/IncomingFileTransfer.cpp b/Swiften/FileTransfer/IncomingFileTransfer.cpp index 238ccce..7c97e4d 100644 --- a/Swiften/FileTransfer/IncomingFileTransfer.cpp +++ b/Swiften/FileTransfer/IncomingFileTransfer.cpp @@ -4,20 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/FileTransfer/IncomingFileTransfer.h" +#include <Swiften/FileTransfer/IncomingFileTransfer.h> namespace Swift { IncomingFileTransfer::~IncomingFileTransfer() { - -} - -/*void IncomingFileTransfer::accept(WriteBytestream::ref) { - } -void IncomingFileTransfer::stop() { - -}*/ - } diff --git a/Swiften/FileTransfer/IncomingFileTransfer.h b/Swiften/FileTransfer/IncomingFileTransfer.h index 4286ef0..5b53d54 100644 --- a/Swiften/FileTransfer/IncomingFileTransfer.h +++ b/Swiften/FileTransfer/IncomingFileTransfer.h @@ -8,16 +8,21 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/FileTransfer/WriteBytestream.h" +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/JID/JID.h> +#include <Swiften/FileTransfer/FileTransfer.h> +#include <Swiften/FileTransfer/WriteBytestream.h> namespace Swift { - class IncomingFileTransfer { + class IncomingFileTransfer : public FileTransfer { public: typedef boost::shared_ptr<IncomingFileTransfer> ref; virtual ~IncomingFileTransfer(); virtual void accept(WriteBytestream::ref) = 0; + + virtual const JID& getSender() const = 0; + virtual const JID& getRecipient() const = 0; }; } diff --git a/Swiften/FileTransfer/IncomingFileTransferManager.cpp b/Swiften/FileTransfer/IncomingFileTransferManager.cpp index 5535840..22e8bf9 100644 --- a/Swiften/FileTransfer/IncomingFileTransferManager.cpp +++ b/Swiften/FileTransfer/IncomingFileTransferManager.cpp @@ -10,13 +10,17 @@ #include <Swiften/Elements/JingleDescription.h> #include <Swiften/Elements/JingleFileTransferDescription.h> -#include <Swiften/Elements/JingleIBBTransport.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> #include <Swiften/Jingle/JingleSessionManager.h> +#include <Swiften/Jingle/Jingle.h> #include <Swiften/FileTransfer/IncomingJingleFileTransfer.h> namespace Swift { -IncomingFileTransferManager::IncomingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router) : jingleSessionManager(jingleSessionManager), router(router) { +IncomingFileTransferManager::IncomingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, + RemoteJingleTransportCandidateSelectorFactory* remoteFactory, + LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, TimerFactory* timerFactory) : jingleSessionManager(jingleSessionManager), router(router), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy), timerFactory(timerFactory) { jingleSessionManager->addIncomingSessionHandler(this); } @@ -24,16 +28,22 @@ IncomingFileTransferManager::~IncomingFileTransferManager() { jingleSessionManager->removeIncomingSessionHandler(this); } -bool IncomingFileTransferManager::handleIncomingJingleSession(IncomingJingleSession::ref session) { - JingleContent::ref content = session->getContentWithDescription<JingleFileTransferDescription>(); - if (content) { - // Check for supported transports - if (content->getTransport<JingleIBBTransport>()) { - IncomingJingleFileTransfer::ref transfer = boost::make_shared<IncomingJingleFileTransfer>(session); - onIncomingFileTransfer(transfer); +bool IncomingFileTransferManager::handleIncomingJingleSession(JingleSession::ref session, const std::vector<JingleContentPayload::ref>& contents, const JID& recipient) { + if (JingleContentPayload::ref content = Jingle::getContentWithDescription<JingleFileTransferDescription>(contents)) { + if (content->getTransport<JingleIBBTransportPayload>() || content->getTransport<JingleS5BTransportPayload>()) { + + JingleFileTransferDescription::ref description = content->getDescription<JingleFileTransferDescription>(); + + if (description && description->getOffers().size() == 1) { + IncomingJingleFileTransfer::ref transfer = boost::make_shared<IncomingJingleFileTransfer>(recipient, session, content, remoteFactory, localFactory, router, bytestreamRegistry, bytestreamProxy, timerFactory); + onIncomingFileTransfer(transfer); + } else { + std::cerr << "Received a file-transfer request with no description or more than one file!" << std::endl; + session->sendTerminate(JinglePayload::Reason::FailedApplication); + } } else { - session->terminate(JinglePayload::Reason::UnsupportedTransports); + session->sendTerminate(JinglePayload::Reason::UnsupportedTransports); } return true; } diff --git a/Swiften/FileTransfer/IncomingFileTransferManager.h b/Swiften/FileTransfer/IncomingFileTransferManager.h index a54b5cd..2d1c07f 100644 --- a/Swiften/FileTransfer/IncomingFileTransferManager.h +++ b/Swiften/FileTransfer/IncomingFileTransferManager.h @@ -15,19 +15,29 @@ namespace Swift { class IQRouter; class JingleSessionManager; + class RemoteJingleTransportCandidateSelectorFactory; + class LocalJingleTransportCandidateGeneratorFactory; + class SOCKS5BytestreamRegistry; + class SOCKS5BytestreamProxy; + class TimerFactory; class IncomingFileTransferManager : public IncomingJingleSessionHandler { public: - IncomingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router); + IncomingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, TimerFactory* timerFactory); ~IncomingFileTransferManager(); boost::signal<void (IncomingFileTransfer::ref)> onIncomingFileTransfer; private: - bool handleIncomingJingleSession(IncomingJingleSession::ref session); + bool handleIncomingJingleSession(JingleSession::ref session, const std::vector<JingleContentPayload::ref>& contents, const JID& recipient); private: JingleSessionManager* jingleSessionManager; IQRouter* router; + RemoteJingleTransportCandidateSelectorFactory* remoteFactory; + LocalJingleTransportCandidateGeneratorFactory* localFactory; + SOCKS5BytestreamRegistry* bytestreamRegistry; + SOCKS5BytestreamProxy* bytestreamProxy; + TimerFactory* timerFactory; }; } diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp index cb2f65c..0871568 100644 --- a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp +++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp @@ -6,14 +6,516 @@ #include <Swiften/FileTransfer/IncomingJingleFileTransfer.h> +#include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/Log.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/Elements/JingleFileTransferHash.h> +#include <Swiften/Elements/S5BProxyRequest.h> +#include <Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h> +#include <Swiften/FileTransfer/JingleIncomingIBBTransport.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h> +#include <Swiften/Network/TimerFactory.h> +#include <Swiften/Queries/GenericRequest.h> + namespace Swift { -IncomingJingleFileTransfer::IncomingJingleFileTransfer(IncomingJingleSession::ref session) : session(session) { +IncomingJingleFileTransfer::IncomingJingleFileTransfer( + const JID& ourJID, + JingleSession::ref session, + JingleContentPayload::ref content, + RemoteJingleTransportCandidateSelectorFactory* candidateSelectorFactory, + LocalJingleTransportCandidateGeneratorFactory* candidateGeneratorFactory, + IQRouter* router, + SOCKS5BytestreamRegistry* registry, + SOCKS5BytestreamProxy* proxy, + TimerFactory* timerFactory) : + ourJID(ourJID), + session(session), + router(router), + timerFactory(timerFactory), + initialContent(content), + state(Initial), + receivedBytes(0), + s5bRegistry(registry), + s5bProxy(proxy), + remoteTransportCandidateSelectFinished(false), + localTransportCandidateSelectFinished(false), + serverSession(0) { + + candidateSelector = candidateSelectorFactory->createCandidateSelector(); + candidateSelector->onRemoteTransportCandidateSelectFinished.connect(boost::bind(&IncomingJingleFileTransfer::handleRemoteTransportCandidateSelectFinished, this, _1)); + + candidateGenerator = candidateGeneratorFactory->createCandidateGenerator(); + candidateGenerator->onLocalTransportCandidatesGenerated.connect(boost::bind(&IncomingJingleFileTransfer::handleLocalTransportCandidatesGenerated, this, _1)); + + session->onTransportInfoReceived.connect(boost::bind(&IncomingJingleFileTransfer::handleTransportInfoReceived, this, _1, _2)); + session->onTransportReplaceReceived.connect(boost::bind(&IncomingJingleFileTransfer::handleTransportReplaceReceived, this, _1, _2)); + session->onSessionTerminateReceived.connect(boost::bind(&IncomingJingleFileTransfer::handleSessionTerminateReceived, this, _1)); + session->onSessionInfoReceived.connect(boost::bind(&IncomingJingleFileTransfer::handleSessionInfoReceived, this, _1)); + + description = initialContent->getDescription<JingleFileTransferDescription>(); + assert(description); + assert(description->getOffers().size() == 1); + StreamInitiationFileInfo fileInfo = description->getOffers().front(); + fileSizeInBytes = fileInfo.getSize(); + filename = fileInfo.getName(); + hash = fileInfo.getHash(); + algo = fileInfo.getAlgo(); + + waitOnHashTimer = timerFactory->createTimer(5000); + waitOnHashTimer->onTick.connect(boost::bind(&IncomingJingleFileTransfer::finishOffTransfer, this)); +} + +IncomingJingleFileTransfer::~IncomingJingleFileTransfer() { + stream->onWrite.disconnect(boost::bind(&IncrementalBytestreamHashCalculator::feedData, hashCalculator, _1)); + delete hashCalculator; + + session->onSessionTerminateReceived.disconnect(boost::bind(&IncomingJingleFileTransfer::handleSessionTerminateReceived, this)); + session->onTransportReplaceReceived.disconnect(boost::bind(&IncomingJingleFileTransfer::handleTransportReplaceReceived, this, _1, _2)); + session->onTransportInfoReceived.disconnect(boost::bind(&IncomingJingleFileTransfer::handleTransportInfoReceived, this, _1, _2)); + + candidateGenerator->onLocalTransportCandidatesGenerated.disconnect(boost::bind(&IncomingJingleFileTransfer::handleLocalTransportCandidatesGenerated, this, _1)); + delete candidateGenerator; + candidateSelector->onRemoteTransportCandidateSelectFinished.disconnect(boost::bind(&IncomingJingleFileTransfer::handleRemoteTransportCandidateSelectFinished, this, _1)); + delete candidateSelector; } void IncomingJingleFileTransfer::accept(WriteBytestream::ref stream) { + assert(!this->stream); this->stream = stream; + + hashCalculator = new IncrementalBytestreamHashCalculator( algo == "md5" || hash.empty() , algo == "sha-1" || hash.empty() ); + stream->onWrite.connect(boost::bind(&IncrementalBytestreamHashCalculator::feedData, hashCalculator, _1)); + stream->onWrite.connect(boost::bind(&IncomingJingleFileTransfer::handleWriteStreamDataReceived, this, _1)); + onStateChange(FileTransfer::State(FileTransfer::State::Negotiating)); + if (JingleIBBTransportPayload::ref ibbTransport = initialContent->getTransport<JingleIBBTransportPayload>()) { + SWIFT_LOG(debug) << "Got IBB transport payload!" << std::endl; + setActiveTransport(createIBBTransport(ibbTransport)); + session->sendAccept(getContentID(), initialContent->getDescriptions()[0], ibbTransport); + } + else if (JingleS5BTransportPayload::ref s5bTransport = initialContent->getTransport<JingleS5BTransportPayload>()) { + SWIFT_LOG(debug) << "Got S5B transport payload!" << std::endl; + state = CreatingInitialTransports; + s5bSessionID = s5bTransport->getSessionID().empty() ? idGenerator.generateID() : s5bTransport->getSessionID(); + s5bDestination = SOCKS5BytestreamRegistry::getHostname(s5bSessionID, ourJID, session->getInitiator()); + s5bRegistry->addWriteBytestream(s5bDestination, stream); + fillCandidateMap(theirCandidates, s5bTransport); + candidateSelector->addRemoteTransportCandidates(s5bTransport); + candidateSelector->setRequesterTargtet(session->getInitiator(), ourJID); + s5bTransport->setSessionID(s5bSessionID); + candidateGenerator->generateLocalTransportCandidates(s5bTransport); + } + else { + assert(false); + } +} + +const JID& IncomingJingleFileTransfer::getSender() const { + return session->getInitiator(); +} + +const JID& IncomingJingleFileTransfer::getRecipient() const { + return ourJID; +} + +void IncomingJingleFileTransfer::cancel() { + session->sendTerminate(JinglePayload::Reason::Cancel); + + if (activeTransport) activeTransport->stop(); + if (serverSession) serverSession->stop(); + if (clientSession) clientSession->stop(); + onStateChange(FileTransfer::State(FileTransfer::State::Canceled)); +} + +void IncomingJingleFileTransfer::handleLocalTransportCandidatesGenerated(JingleTransportPayload::ref candidates) { + if (state == CreatingInitialTransports) { + if (JingleS5BTransportPayload::ref s5bCandidates = boost::dynamic_pointer_cast<JingleS5BTransportPayload>(candidates)) { + //localTransportCandidateSelectFinished = true; + //JingleS5BTransportPayload::ref emptyCandidates = boost::make_shared<JingleS5BTransportPayload>(); + //emptyCandidates->setSessionID(s5bCandidates->getSessionID()); + fillCandidateMap(ourCandidates, s5bCandidates); + session->sendAccept(getContentID(), initialContent->getDescriptions()[0], s5bCandidates); + + state = NegotiatingTransport; + candidateSelector->selectCandidate(); + } + } + else { + SWIFT_LOG(debug) << "Unhandled state!" << std::endl; + } +} + + +void IncomingJingleFileTransfer::handleRemoteTransportCandidateSelectFinished(JingleTransportPayload::ref transport) { + SWIFT_LOG(debug) << std::endl; + if (state == Terminated) { + return; + } + if (JingleS5BTransportPayload::ref s5bPayload = boost::dynamic_pointer_cast<JingleS5BTransportPayload>(transport)) { + //remoteTransportCandidateSelectFinished = true; + //selectedRemoteTransportCandidate = transport; + ourCandidate = s5bPayload; + //checkCandidateSelected(); + decideOnUsedTransport(); + session->sendTransportInfo(getContentID(), s5bPayload); + } + else { + SWIFT_LOG(debug) << "Expected something different here." << std::endl; + } +} + +void IncomingJingleFileTransfer::checkCandidateSelected() { + assert(false); + if (localTransportCandidateSelectFinished && remoteTransportCandidateSelectFinished) { + if (candidateGenerator->isActualCandidate(selectedLocalTransportCandidate) && candidateSelector->isActualCandidate(selectedRemoteTransportCandidate)) { + if (candidateGenerator->getPriority(selectedLocalTransportCandidate) > candidateSelector->getPriority(selectedRemoteTransportCandidate)) { + setActiveTransport(candidateGenerator->selectTransport(selectedLocalTransportCandidate)); + } + else { + setActiveTransport(candidateSelector->selectTransport(selectedRemoteTransportCandidate)); + } + } + else if (candidateSelector->isActualCandidate(selectedRemoteTransportCandidate)) { + setActiveTransport(candidateSelector->selectTransport(selectedRemoteTransportCandidate)); + } + else if (candidateGenerator->isActualCandidate(selectedLocalTransportCandidate)) { + setActiveTransport(candidateGenerator->selectTransport(selectedLocalTransportCandidate)); + } + else { + state = WaitingForFallbackOrTerminate; + } + } +} + +void IncomingJingleFileTransfer::setActiveTransport(JingleTransport::ref transport) { + state = Transferring; + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); + activeTransport = transport; + activeTransport->onDataReceived.connect(boost::bind(&IncomingJingleFileTransfer::handleTransportDataReceived, this, _1)); + activeTransport->onFinished.connect(boost::bind(&IncomingJingleFileTransfer::handleTransferFinished, this, _1)); + activeTransport->start(); +} + +bool IncomingJingleFileTransfer::verifyReceviedData() { + if (algo.empty() || hash.empty()) { + SWIFT_LOG(debug) << "no verification possible, skipping" << std::endl; + return true; + } else { + if (algo == "sha-1") { + SWIFT_LOG(debug) << "verify data via SHA-1 hash: " << (hash == hashCalculator->getSHA1String()) << std::endl; + return hash == hashCalculator->getSHA1String(); + } + else if (algo == "md5") { + SWIFT_LOG(debug) << "verify data via MD5 hash: " << (hash == hashCalculator->getMD5String()) << std::endl; + return hash == hashCalculator->getMD5String(); + } + else { + SWIFT_LOG(debug) << "no verification possible, skipping" << std::endl; + return true; + } + } +} + +void IncomingJingleFileTransfer::finishOffTransfer() { + if (verifyReceviedData()) { + onStateChange(FileTransfer::State(FileTransfer::State::Finished)); + session->sendTerminate(JinglePayload::Reason::Success); + } else { + onStateChange(FileTransfer::State(FileTransfer::State::Failed, "Verification failed.")); + session->sendTerminate(JinglePayload::Reason::MediaError); + } + state = Terminated; + waitOnHashTimer->stop(); +} + +void IncomingJingleFileTransfer::handleSessionInfoReceived(JinglePayload::ref jinglePayload) { + if (state == Terminated) { + return; + } + JingleFileTransferHash::ref transferHash = jinglePayload->getPayload<JingleFileTransferHash>(); + if (transferHash) { + SWIFT_LOG(debug) << "Recevied hash information." << std::endl; + if (transferHash->getHashes().find("sha-1") != transferHash->getHashes().end()) { + algo = "sha-1"; + hash = transferHash->getHashes().find("sha-1")->second; + } + else if (transferHash->getHashes().find("md5") != transferHash->getHashes().end()) { + algo = "md5"; + hash = transferHash->getHashes().find("md5")->second; + } + checkIfAllDataReceived(); + } +} + +void IncomingJingleFileTransfer::handleSessionTerminateReceived(boost::optional<JinglePayload::Reason> reason) { + SWIFT_LOG(debug) << "session terminate received" << std::endl; + if (activeTransport) activeTransport->stop(); + if (reason && reason.get().type == JinglePayload::Reason::Cancel) { + onStateChange(FileTransfer::State(FileTransfer::State::Canceled, "Other user canceled the transfer.")); + } + else if (reason && reason.get().type == JinglePayload::Reason::Success) { + /*if (verifyReceviedData()) { + onStateChange(FileTransfer::State(FileTransfer::State::Finished)); + } else { + onStateChange(FileTransfer::State(FileTransfer::State::Failed, "Verification failed.")); + }*/ + } + state = Terminated; +} + +void IncomingJingleFileTransfer::checkIfAllDataReceived() { + if (receivedBytes == fileSizeInBytes) { + SWIFT_LOG(debug) << "All data received." << std::endl; + if (hash.empty()) { + SWIFT_LOG(debug) << "No hash information yet. Waiting 5 seconds on hash info." << std::endl; + waitOnHashTimer->start(); + } else { + SWIFT_LOG(debug) << "We already have hash info using " << algo << " algorithm. Finishing off transfer." << std::endl; + finishOffTransfer(); + } + } + else if (receivedBytes > fileSizeInBytes) { + SWIFT_LOG(debug) << "We got more than we could handle!" << std::endl; + } +} + +void IncomingJingleFileTransfer::handleTransportDataReceived(const std::vector<unsigned char>& data) { + SWIFT_LOG(debug) << data.size() << " bytes received" << std::endl; + onProcessedBytes(data.size()); + stream->write(data); + receivedBytes += data.size(); + checkIfAllDataReceived(); +} + +void IncomingJingleFileTransfer::handleWriteStreamDataReceived(const std::vector<unsigned char>& data) { + receivedBytes += data.size(); + checkIfAllDataReceived(); +} + +void IncomingJingleFileTransfer::useOurCandidateChoiceForTransfer(JingleS5BTransportPayload::Candidate candidate) { + SWIFT_LOG(debug) << std::endl; + if (candidate.type == JingleS5BTransportPayload::Candidate::ProxyType) { + // get proxy client session from remoteCandidateSelector + clientSession = candidateSelector->getS5BSession(); + + // wait on <activated/> transport-info + } else { + // ask s5b client + clientSession = candidateSelector->getS5BSession(); + if (clientSession) { + state = Transferring; + SWIFT_LOG(debug) << clientSession->getAddressPort().toString() << std::endl; + clientSession->onBytesReceived.connect(boost::bind(boost::ref(onProcessedBytes), _1)); + clientSession->onFinished.connect(boost::bind(&IncomingJingleFileTransfer::handleTransferFinished, this, _1)); + clientSession->startReceiving(stream); + } else { + SWIFT_LOG(debug) << "No S5B client session found!!!" << std::endl; + } + } +} + +void IncomingJingleFileTransfer::useTheirCandidateChoiceForTransfer(JingleS5BTransportPayload::Candidate candidate) { + SWIFT_LOG(debug) << std::endl; + + if (candidate.type == JingleS5BTransportPayload::Candidate::ProxyType) { + // get proxy client session from s5bRegistry + clientSession = s5bProxy->createSOCKS5BytestreamClientSession(candidate.hostPort, SOCKS5BytestreamRegistry::getHostname(s5bSessionID, ourJID, session->getInitiator())); + clientSession->onSessionReady.connect(boost::bind(&IncomingJingleFileTransfer::proxySessionReady, this, candidate.jid, _1)); + clientSession->start(); + + // on reply send activate + } else { + // ask s5b server + serverSession = s5bRegistry->getConnectedSession(s5bDestination); + if (serverSession) { + state = Transferring; + serverSession->onBytesReceived.connect(boost::bind(boost::ref(onProcessedBytes), _1)); + serverSession->onFinished.connect(boost::bind(&IncomingJingleFileTransfer::handleTransferFinished, this, _1)); + serverSession->startTransfer(); + } else { + SWIFT_LOG(debug) << "No S5B server session found!!!" << std::endl; + } + } +} + +void IncomingJingleFileTransfer::fillCandidateMap(CandidateMap& map, JingleS5BTransportPayload::ref s5bPayload) { + map.clear(); + foreach (JingleS5BTransportPayload::Candidate candidate, s5bPayload->getCandidates()) { + map[candidate.cid] = candidate; + } +} + + +void IncomingJingleFileTransfer::decideOnUsedTransport() { + if (ourCandidate && theirCandidate) { + if (ourCandidate->hasCandidateError() && theirCandidate->hasCandidateError()) { + state = WaitingForFallbackOrTerminate; + return; + } + std::string our_cid = ourCandidate->getCandidateUsed(); + std::string their_cid = theirCandidate->getCandidateUsed(); + if (ourCandidate->hasCandidateError() && !their_cid.empty()) { + useTheirCandidateChoiceForTransfer(ourCandidates[their_cid]); + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); + } + else if (theirCandidate->hasCandidateError() && !our_cid.empty()) { + useOurCandidateChoiceForTransfer(theirCandidates[our_cid]); + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); + } + else if (!our_cid.empty() && !their_cid.empty()) { + // compare priorites, if same they win + if (ourCandidates.find(their_cid) == ourCandidates.end() || theirCandidates.find(our_cid) == theirCandidates.end()) { + SWIFT_LOG(debug) << "Didn't recognize candidate IDs!" << std::endl; + session->sendTerminate(JinglePayload::Reason::FailedTransport); + onStateChange(FileTransfer::State(FileTransfer::State::Canceled, "Failed to negotiate candidate.")); + onFinished(FileTransferError(FileTransferError::PeerError)); + return; + } + + JingleS5BTransportPayload::Candidate our_candidate = theirCandidates[our_cid]; + JingleS5BTransportPayload::Candidate their_candidate = ourCandidates[their_cid]; + if (our_candidate.priority > their_candidate.priority) { + useOurCandidateChoiceForTransfer(our_candidate); + } + else if (our_candidate.priority < their_candidate.priority) { + useTheirCandidateChoiceForTransfer(their_candidate); + } + else { + useTheirCandidateChoiceForTransfer(their_candidate); + } + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); + } + else { + assert(false); + } + } else { + SWIFT_LOG(debug) << "Can't make a transport decision yet." << std::endl; + } +} + +void IncomingJingleFileTransfer::proxySessionReady(const JID& proxy, bool error) { + if (error) { + // indicate proxy error + } else { + // activate proxy + activateProxySession(proxy); + } +} + +void IncomingJingleFileTransfer::activateProxySession(const JID &proxy) { + S5BProxyRequest::ref proxyRequest = boost::make_shared<S5BProxyRequest>(); + proxyRequest->setSID(s5bSessionID); + proxyRequest->setActivate(session->getInitiator()); + + boost::shared_ptr<GenericRequest<S5BProxyRequest> > request = boost::make_shared<GenericRequest<S5BProxyRequest> >(IQ::Set, proxy, proxyRequest, router); + request->onResponse.connect(boost::bind(&IncomingJingleFileTransfer::handleActivateProxySessionResult, this, _1, _2)); + request->send(); +} + +void IncomingJingleFileTransfer::handleActivateProxySessionResult(boost::shared_ptr<S5BProxyRequest> /*request*/, ErrorPayload::ref error) { + SWIFT_LOG(debug) << std::endl; + if (error) { + SWIFT_LOG(debug) << "ERROR" << std::endl; + } else { + // send activated to other jingle party + JingleS5BTransportPayload::ref proxyActivate = boost::make_shared<JingleS5BTransportPayload>(); + proxyActivate->setActivated(theirCandidate->getCandidateUsed()); + session->sendTransportInfo(getContentID(), proxyActivate); + + // start transferring + clientSession->onBytesReceived.connect(boost::bind(boost::ref(onProcessedBytes), _1)); + clientSession->onFinished.connect(boost::bind(&IncomingJingleFileTransfer::handleTransferFinished, this, _1)); + clientSession->startReceiving(stream); + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); + } +} + +void IncomingJingleFileTransfer::handleTransportInfoReceived(const JingleContentID&, JingleTransportPayload::ref transport) { + SWIFT_LOG(debug) << "transport info received" << std::endl; + if (state == Terminated) { + return; + } + if (JingleS5BTransportPayload::ref s5bPayload = boost::dynamic_pointer_cast<JingleS5BTransportPayload>(transport)) { + if (!s5bPayload->getActivated().empty()) { + if (ourCandidate->getCandidateUsed() == s5bPayload->getActivated()) { + clientSession->onBytesReceived.connect(boost::bind(boost::ref(onProcessedBytes), _1)); + clientSession->onFinished.connect(boost::bind(&IncomingJingleFileTransfer::handleTransferFinished, this, _1)); + clientSession->startReceiving(stream); + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); + } else { + SWIFT_LOG(debug) << "ourCandidateChoice doesn't match activated proxy candidate!" << std::endl; + JingleS5BTransportPayload::ref proxyError = boost::make_shared<JingleS5BTransportPayload>(); + proxyError->setProxyError(true); + proxyError->setSessionID(s5bSessionID); + session->sendTransportInfo(getContentID(), proxyError); + } + } else { + theirCandidate = s5bPayload; + decideOnUsedTransport(); + } + } + else { + SWIFT_LOG(debug) << "Expected something different here." << std::endl; + } + /*localTransportCandidateSelectFinished = true; + selectedLocalTransportCandidate = transport; + if (candidateGenerator->isActualCandidate(transport)) { + candidateSelector->setMinimumPriority(candidateGenerator->getPriority(transport)); + }*/ + //checkCandidateSelected(); +} + +void IncomingJingleFileTransfer::handleTransportReplaceReceived(const JingleContentID& content, JingleTransportPayload::ref transport) { + if (state == Terminated) { + return; + } + if (JingleIBBTransportPayload::ref ibbTransport = boost::dynamic_pointer_cast<JingleIBBTransportPayload>(transport)) { + SWIFT_LOG(debug) << "transport replaced with IBB" << std::endl; + setActiveTransport(createIBBTransport(ibbTransport)); + session->sendTransportAccept(content, ibbTransport); + } else { + SWIFT_LOG(debug) << "transport replaced failed" << std::endl; + session->sendTransportReject(content, transport); + } +} + +void IncomingJingleFileTransfer::stopActiveTransport() { + if (activeTransport) { + activeTransport->stop(); + activeTransport->onDataReceived.disconnect(boost::bind(&IncomingJingleFileTransfer::handleTransportDataReceived, this, _1)); + } +} + +JingleIncomingIBBTransport::ref IncomingJingleFileTransfer::createIBBTransport(JingleIBBTransportPayload::ref ibbTransport) { + // TODO: getOffer() -> getOffers correction + return boost::make_shared<JingleIncomingIBBTransport>(session->getInitiator(), getRecipient(), ibbTransport->getSessionID(), description->getOffers()[0].getSize(), router); +} + +JingleContentID IncomingJingleFileTransfer::getContentID() const { + return JingleContentID(initialContent->getName(), initialContent->getCreator()); +} + +void IncomingJingleFileTransfer::handleTransferFinished(boost::optional<FileTransferError> error) { + if (state == Terminated) { + return; + } + + if (error) { + session->sendTerminate(JinglePayload::Reason::ConnectivityError); + onStateChange(FileTransfer::State(FileTransfer::State::Failed)); + onFinished(error); + } + // } } diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.h b/Swiften/FileTransfer/IncomingJingleFileTransfer.h index d69449e..4ae0bfb 100644 --- a/Swiften/FileTransfer/IncomingJingleFileTransfer.h +++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.h @@ -7,21 +7,128 @@ #pragma once #include <boost/shared_ptr.hpp> +#include <boost/cstdint.hpp> -#include <Swiften/Jingle/IncomingJingleSession.h> +#include <Swiften/Base/IDGenerator.h> +#include <Swiften/Network/Timer.h> +#include <Swiften/Jingle/JingleSession.h> +#include <Swiften/Jingle/JingleContentID.h> #include <Swiften/FileTransfer/IncomingFileTransfer.h> +#include <Swiften/FileTransfer/JingleTransport.h> +#include <Swiften/FileTransfer/JingleIncomingIBBTransport.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamServerSession.h> +#include <Swiften/Elements/JingleContentPayload.h> +#include <Swiften/Elements/JingleFileTransferDescription.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/Elements/S5BProxyRequest.h> +#include <Swiften/Elements/ErrorPayload.h> namespace Swift { + class IQRouter; + class RemoteJingleTransportCandidateSelectorFactory; + class LocalJingleTransportCandidateGeneratorFactory; + class RemoteJingleTransportCandidateSelector; + class LocalJingleTransportCandidateGenerator; + class SOCKS5BytestreamRegistry; + class SOCKS5BytestreamProxy; + class IncrementalBytestreamHashCalculator; + class IncomingJingleFileTransfer : public IncomingFileTransfer { public: typedef boost::shared_ptr<IncomingJingleFileTransfer> ref; + enum State { + Initial, + CreatingInitialTransports, + NegotiatingTransport, + Transferring, + WaitingForFallbackOrTerminate, + Terminated + }; - IncomingJingleFileTransfer(IncomingJingleSession::ref session); + IncomingJingleFileTransfer( + const JID& recipient, + JingleSession::ref, + JingleContentPayload::ref content, + RemoteJingleTransportCandidateSelectorFactory*, + LocalJingleTransportCandidateGeneratorFactory*, + IQRouter* router, + SOCKS5BytestreamRegistry* bytestreamRegistry, + SOCKS5BytestreamProxy* bytestreamProxy, + TimerFactory*); + ~IncomingJingleFileTransfer(); virtual void accept(WriteBytestream::ref); + virtual const JID& getSender() const; + virtual const JID& getRecipient() const; + void cancel(); + + private: + void handleSessionTerminateReceived(boost::optional<JinglePayload::Reason>); + void handleSessionInfoReceived(JinglePayload::ref); + void handleTransportReplaceReceived(const JingleContentID&, JingleTransportPayload::ref); + void handleTransportInfoReceived(const JingleContentID&, JingleTransportPayload::ref); + void handleLocalTransportCandidatesGenerated(JingleTransportPayload::ref candidates); + void handleRemoteTransportCandidateSelectFinished(JingleTransportPayload::ref candidate); + void setActiveTransport(JingleTransport::ref transport); + void handleTransportDataReceived(const std::vector<unsigned char>& data); + void handleWriteStreamDataReceived(const std::vector<unsigned char>& data); + void stopActiveTransport(); + void checkCandidateSelected(); + JingleIncomingIBBTransport::ref createIBBTransport(JingleIBBTransportPayload::ref ibbTransport); + JingleContentID getContentID() const; + void checkIfAllDataReceived(); + bool verifyReceviedData(); + void finishOffTransfer(); + void handleTransferFinished(boost::optional<FileTransferError>); + + private: + typedef std::map<std::string, JingleS5BTransportPayload::Candidate> CandidateMap; + + private: + void activateProxySession(const JID &proxy); + void handleActivateProxySessionResult(boost::shared_ptr<S5BProxyRequest> request, ErrorPayload::ref error); + void proxySessionReady(const JID& proxy, bool error); + + private: + void useOurCandidateChoiceForTransfer(JingleS5BTransportPayload::Candidate candidate); + void useTheirCandidateChoiceForTransfer(JingleS5BTransportPayload::Candidate candidate); + void decideOnUsedTransport(); + void fillCandidateMap(CandidateMap& map, JingleS5BTransportPayload::ref s5bPayload); private: - IncomingJingleSession::ref session; + JID ourJID; + JingleSession::ref session; + IQRouter* router; + TimerFactory* timerFactory; + JingleContentPayload::ref initialContent; + State state; + JingleFileTransferDescription::ref description; WriteBytestream::ref stream; + boost::uintmax_t receivedBytes; + IncrementalBytestreamHashCalculator* hashCalculator; + Timer::ref waitOnHashTimer; + IDGenerator idGenerator; + + RemoteJingleTransportCandidateSelector* candidateSelector; + LocalJingleTransportCandidateGenerator* candidateGenerator; + SOCKS5BytestreamRegistry* s5bRegistry; + SOCKS5BytestreamProxy* s5bProxy; + bool remoteTransportCandidateSelectFinished; + JingleTransportPayload::ref selectedRemoteTransportCandidate; + bool localTransportCandidateSelectFinished; + JingleTransportPayload::ref selectedLocalTransportCandidate; + + JingleS5BTransportPayload::ref ourCandidate; + JingleS5BTransportPayload::ref theirCandidate; + CandidateMap ourCandidates; + CandidateMap theirCandidates; + SOCKS5BytestreamClientSession::ref clientSession; + std::string s5bDestination; + std::string s5bSessionID; + SOCKS5BytestreamServerSession* serverSession; + + JingleTransport::ref activeTransport; }; } diff --git a/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.cpp b/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.cpp new file mode 100644 index 0000000..6b53a1b --- /dev/null +++ b/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h> + +#include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/StringCodecs/MD5.h> +#include <Swiften/StringCodecs/SHA1.h> + +namespace Swift { + +IncrementalBytestreamHashCalculator::IncrementalBytestreamHashCalculator(bool doMD5, bool doSHA1) { + md5Hasher = doMD5 ? new MD5() : NULL; + sha1Hasher = doSHA1 ? new SHA1() : NULL; +} + +IncrementalBytestreamHashCalculator::~IncrementalBytestreamHashCalculator() { + delete md5Hasher; + delete sha1Hasher; +} + +void IncrementalBytestreamHashCalculator::feedData(const ByteArray& data) { + if (md5Hasher) { + md5Hasher->update(data); + } + if (sha1Hasher) { + sha1Hasher->update(data); + } +} +/* +void IncrementalBytestreamHashCalculator::feedData(const SafeByteArray& data) { + if (md5Hasher) { + md5Hasher->update(createByteArray(data.data(), data.size())); + } + if (sha1Hasher) { + sha1Hasher->update(createByteArray(data.data(), data.size())); + } +}*/ + +std::string IncrementalBytestreamHashCalculator::getSHA1String() { + if (sha1Hasher) { + ByteArray result = sha1Hasher->getHash(); + return Hexify::hexify(result); + } else { + return std::string(); + } +} + +std::string IncrementalBytestreamHashCalculator::getMD5String() { + if (md5Hasher) { + ByteArray result = md5Hasher->getHash(); + return Hexify::hexify(result); + } else { + return std::string(); + } +} + +} diff --git a/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h b/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h new file mode 100644 index 0000000..64f4b5f --- /dev/null +++ b/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h> + +namespace Swift { + +class MD5; +class SHA1; + +class IncrementalBytestreamHashCalculator { +public: + IncrementalBytestreamHashCalculator(bool doMD5, bool doSHA1); + ~IncrementalBytestreamHashCalculator(); + + void feedData(const ByteArray& data); + //void feedData(const SafeByteArray& data); + + std::string getSHA1String(); + std::string getMD5String(); + +private: + MD5* md5Hasher; + SHA1* sha1Hasher; +}; + +} diff --git a/Swiften/FileTransfer/JingleIncomingIBBTransport.cpp b/Swiften/FileTransfer/JingleIncomingIBBTransport.cpp new file mode 100644 index 0000000..ccca641 --- /dev/null +++ b/Swiften/FileTransfer/JingleIncomingIBBTransport.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/FileTransfer/JingleIncomingIBBTransport.h> + +namespace Swift { + +JingleIncomingIBBTransport::JingleIncomingIBBTransport(const JID& from, const JID& to, const std::string& id, size_t size, IQRouter* router) : ibbSession(id, from, to, size, router) { + ibbSession.onDataReceived.connect(boost::ref(onDataReceived)); + ibbSession.onFinished.connect(boost::ref(onFinished)); +} + +void JingleIncomingIBBTransport::start() { + ibbSession.start(); +} + +void JingleIncomingIBBTransport::stop() { + ibbSession.stop(); +} + +} diff --git a/Swiften/FileTransfer/JingleIncomingIBBTransport.h b/Swiften/FileTransfer/JingleIncomingIBBTransport.h new file mode 100644 index 0000000..be18a2d --- /dev/null +++ b/Swiften/FileTransfer/JingleIncomingIBBTransport.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 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/FileTransfer/JingleTransport.h> +#include <Swiften/FileTransfer/IBBReceiveSession.h> + +namespace Swift { + class JingleIncomingIBBTransport : public JingleTransport { + public: + typedef boost::shared_ptr<JingleIncomingIBBTransport> ref; + + JingleIncomingIBBTransport(const JID& from, const JID& to, const std::string& id, size_t size, IQRouter* router); + + virtual void start(); + virtual void stop(); + + private: + IBBReceiveSession ibbSession; + }; +} diff --git a/Swiften/Elements/JingleTransport.h b/Swiften/FileTransfer/JingleTransport.cpp index ecd2a34..c507922 100644 --- a/Swiften/Elements/JingleTransport.h +++ b/Swiften/FileTransfer/JingleTransport.cpp @@ -4,11 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#pragma once - -#include <Swiften/Elements/Payload.h> +#include <Swiften/FileTransfer/JingleTransport.h> namespace Swift { - class JingleTransport : public Payload { - }; + +JingleTransport::~JingleTransport() { + +} + } diff --git a/Swiften/FileTransfer/JingleTransport.h b/Swiften/FileTransfer/JingleTransport.h new file mode 100644 index 0000000..fa296e8 --- /dev/null +++ b/Swiften/FileTransfer/JingleTransport.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 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/Base/boost_bsignals.h> +#include <Swiften/FileTransfer/FileTransfer.h> + +namespace Swift { + class JingleTransport { + public: + typedef boost::shared_ptr<JingleTransport> ref; + + virtual ~JingleTransport(); + + virtual void start() = 0; + virtual void stop() = 0; + + boost::signal<void (const std::vector<unsigned char>&)> onDataReceived; + boost::signal<void (boost::optional<FileTransferError>)> onFinished; + }; +} diff --git a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp new file mode 100644 index 0000000..852902b --- /dev/null +++ b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h> + +namespace Swift { + +LocalJingleTransportCandidateGenerator::~LocalJingleTransportCandidateGenerator() { +} + +} diff --git a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h new file mode 100644 index 0000000..041afe3 --- /dev/null +++ b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Base/boost_bsignals.h> + +#include <Swiften/Elements/JingleTransportPayload.h> +#include <Swiften/FileTransfer/JingleTransport.h> + +namespace Swift { + class LocalJingleTransportCandidateGenerator { + public: + virtual ~LocalJingleTransportCandidateGenerator(); + /** + * Should call onLocalTransportCandidatesGenerated if it has finished discovering local candidates. + */ + virtual void generateLocalTransportCandidates(JingleTransportPayload::ref) = 0; + + virtual bool isActualCandidate(JingleTransportPayload::ref) = 0; + virtual int getPriority(JingleTransportPayload::ref) = 0; + virtual JingleTransport::ref selectTransport(JingleTransportPayload::ref) = 0; + + boost::signal<void (JingleTransportPayload::ref)> onLocalTransportCandidatesGenerated; + }; +} diff --git a/Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.cpp b/Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.cpp new file mode 100644 index 0000000..a1e3874 --- /dev/null +++ b/Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h> + +namespace Swift { + +LocalJingleTransportCandidateGeneratorFactory::~LocalJingleTransportCandidateGeneratorFactory() { +} + +} diff --git a/Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h b/Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h new file mode 100644 index 0000000..c969fc7 --- /dev/null +++ b/Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +namespace Swift { + class LocalJingleTransportCandidateGenerator; + + class LocalJingleTransportCandidateGeneratorFactory { + public: + virtual ~LocalJingleTransportCandidateGeneratorFactory(); + + virtual LocalJingleTransportCandidateGenerator* createCandidateGenerator() = 0; + }; +} diff --git a/Swiften/FileTransfer/OutgoingFileTransfer.cpp b/Swiften/FileTransfer/OutgoingFileTransfer.cpp index 32f7e17..94d4348 100644 --- a/Swiften/FileTransfer/OutgoingFileTransfer.cpp +++ b/Swiften/FileTransfer/OutgoingFileTransfer.cpp @@ -4,75 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/FileTransfer/OutgoingFileTransfer.h" - -#include <boost/bind.hpp> - -#include "Swiften/FileTransfer/StreamInitiationRequest.h" -#include "Swiften/FileTransfer/BytestreamsRequest.h" -#include "Swiften/FileTransfer/SOCKS5BytestreamServer.h" -#include "Swiften/FileTransfer/IBBSendSession.h" +#include <Swiften/FileTransfer/OutgoingFileTransfer.h> namespace Swift { -OutgoingFileTransfer::OutgoingFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer) : id(id), from(from), to(to), name(name), size(size), description(description), bytestream(bytestream), iqRouter(iqRouter), socksServer(socksServer) { -} - -void OutgoingFileTransfer::start() { - StreamInitiation::ref streamInitiation(new StreamInitiation()); - streamInitiation->setID(id); - streamInitiation->setFileInfo(StreamInitiationFileInfo(name, description, size)); - //streamInitiation->addProvidedMethod("http://jabber.org/protocol/bytestreams"); - streamInitiation->addProvidedMethod("http://jabber.org/protocol/ibb"); - StreamInitiationRequest::ref request = StreamInitiationRequest::create(to, streamInitiation, iqRouter); - request->onResponse.connect(boost::bind(&OutgoingFileTransfer::handleStreamInitiationRequestResponse, this, _1, _2)); - request->send(); -} - -void OutgoingFileTransfer::stop() { -} - -void OutgoingFileTransfer::handleStreamInitiationRequestResponse(StreamInitiation::ref response, ErrorPayload::ref error) { - if (error) { - finish(FileTransferError()); - } - else { - if (response->getRequestedMethod() == "http://jabber.org/protocol/bytestreams") { - socksServer->addBytestream(id, from, to, bytestream); - Bytestreams::ref bytestreams(new Bytestreams()); - bytestreams->setStreamID(id); - HostAddressPort addressPort = socksServer->getAddressPort(); - bytestreams->addStreamHost(Bytestreams::StreamHost(addressPort.getAddress().toString(), from, addressPort.getPort())); - BytestreamsRequest::ref request = BytestreamsRequest::create(to, bytestreams, iqRouter); - request->onResponse.connect(boost::bind(&OutgoingFileTransfer::handleBytestreamsRequestResponse, this, _1, _2)); - request->send(); - } - else if (response->getRequestedMethod() == "http://jabber.org/protocol/ibb") { - ibbSession = boost::shared_ptr<IBBSendSession>(new IBBSendSession(id, to, bytestream, iqRouter)); - ibbSession->onFinished.connect(boost::bind(&OutgoingFileTransfer::handleIBBSessionFinished, this, _1)); - ibbSession->start(); - } - } -} - -void OutgoingFileTransfer::handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref error) { - if (error) { - finish(FileTransferError()); - } - //socksServer->onTransferFinished.connect(); -} - -void OutgoingFileTransfer::finish(boost::optional<FileTransferError> error) { - if (ibbSession) { - ibbSession->onFinished.disconnect(boost::bind(&OutgoingFileTransfer::handleIBBSessionFinished, this, _1)); - ibbSession.reset(); - } - socksServer->removeBytestream(id, from, to); - onFinished(error); -} - -void OutgoingFileTransfer::handleIBBSessionFinished(boost::optional<FileTransferError> error) { - finish(error); +OutgoingFileTransfer::~OutgoingFileTransfer() { } } diff --git a/Swiften/FileTransfer/OutgoingFileTransfer.h b/Swiften/FileTransfer/OutgoingFileTransfer.h index a694c13..1ec1ae3 100644 --- a/Swiften/FileTransfer/OutgoingFileTransfer.h +++ b/Swiften/FileTransfer/OutgoingFileTransfer.h @@ -8,45 +8,16 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/FileTransfer/ReadBytestream.h" -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/FileTransfer/FileTransferError.h" -#include "Swiften/FileTransfer/SOCKS5BytestreamServer.h" -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/StreamInitiation.h" -#include "Swiften/Elements/Bytestreams.h" -#include "Swiften/Elements/ErrorPayload.h" -#include "Swiften/FileTransfer/IBBSendSession.h" +#include <Swiften/FileTransfer/FileTransfer.h> namespace Swift { - class IQRouter; - class SOCKS5BytestreamServer; - - class OutgoingFileTransfer { + class OutgoingFileTransfer : public FileTransfer { public: - OutgoingFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer); - - void start(); - void stop(); - - boost::signal<void (const boost::optional<FileTransferError>&)> onFinished; - - private: - void handleStreamInitiationRequestResponse(StreamInitiation::ref, ErrorPayload::ref); - void handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref); - void finish(boost::optional<FileTransferError> error); - void handleIBBSessionFinished(boost::optional<FileTransferError> error); + typedef boost::shared_ptr<OutgoingFileTransfer> ref; + public: + virtual ~OutgoingFileTransfer(); - private: - std::string id; - JID from; - JID to; - std::string name; - int size; - std::string description; - boost::shared_ptr<ReadBytestream> bytestream; - IQRouter* iqRouter; - SOCKS5BytestreamServer* socksServer; - boost::shared_ptr<IBBSendSession> ibbSession; + virtual void start() = 0; + virtual void stop() = 0; }; } diff --git a/Swiften/FileTransfer/OutgoingFileTransferManager.cpp b/Swiften/FileTransfer/OutgoingFileTransferManager.cpp new file mode 100644 index 0000000..6f23bb7 --- /dev/null +++ b/Swiften/FileTransfer/OutgoingFileTransferManager.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "OutgoingFileTransferManager.h" + +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/JID/JID.h> +#include <Swiften/Jingle/JingleSessionManager.h> +#include <Swiften/Jingle/JingleSessionImpl.h> +#include <Swiften/Jingle/JingleContentID.h> +#include <Swiften/FileTransfer/OutgoingJingleFileTransfer.h> +#include <Swiften/Base/IDGenerator.h> + +namespace Swift { + +OutgoingFileTransferManager::OutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy) : jsManager(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy) { + idGenerator = new IDGenerator(); +} + +OutgoingFileTransferManager::~OutgoingFileTransferManager() { + delete idGenerator; +} + +boost::shared_ptr<OutgoingFileTransfer> OutgoingFileTransferManager::createOutgoingFileTransfer(const JID& from, const JID& receipient, boost::shared_ptr<ReadBytestream> readBytestream, const StreamInitiationFileInfo& fileInfo) { + // check if receipient support Jingle FT + + + JingleSessionImpl::ref jingleSession = boost::make_shared<JingleSessionImpl>(from, receipient, idGenerator->generateID(), iqRouter); + + //jsManager->getSession(receipient, idGenerator->generateID()); + assert(jingleSession); + jsManager->registerOutgoingSession(from, jingleSession); + boost::shared_ptr<OutgoingJingleFileTransfer> jingleFT = boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(jingleSession, remoteFactory, localFactory, iqRouter, idGenerator, from, receipient, readBytestream, fileInfo, bytestreamRegistry, bytestreamProxy)); + + // otherwise try SI + + // else fail + + return jingleFT; +} + +} diff --git a/Swiften/FileTransfer/OutgoingFileTransferManager.h b/Swiften/FileTransfer/OutgoingFileTransferManager.h new file mode 100644 index 0000000..c686001 --- /dev/null +++ b/Swiften/FileTransfer/OutgoingFileTransferManager.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> + +#include <Swiften/JID/JID.h> + +namespace Swift { + +class JingleSessionManager; +class IQRouter; +class EntityCapsProvider; +class RemoteJingleTransportCandidateSelectorFactory; +class LocalJingleTransportCandidateGeneratorFactory; +class OutgoingFileTransfer; +class JID; +class IDGenerator; +class ReadBytestream; +class StreamInitiationFileInfo; +class SOCKS5BytestreamRegistry; +class SOCKS5BytestreamProxy; + +class OutgoingFileTransferManager { +public: + OutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy); + ~OutgoingFileTransferManager(); + + boost::shared_ptr<OutgoingFileTransfer> createOutgoingFileTransfer(const JID& from, const JID& to, boost::shared_ptr<ReadBytestream>, const StreamInitiationFileInfo&); + +private: + JingleSessionManager* jsManager; + IQRouter* iqRouter; + EntityCapsProvider* capsProvider; + RemoteJingleTransportCandidateSelectorFactory* remoteFactory; + LocalJingleTransportCandidateGeneratorFactory* localFactory; + IDGenerator *idGenerator; + SOCKS5BytestreamRegistry* bytestreamRegistry; + SOCKS5BytestreamProxy* bytestreamProxy; +}; + +} diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp new file mode 100644 index 0000000..5e2a1c3 --- /dev/null +++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp @@ -0,0 +1,402 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "OutgoingJingleFileTransfer.h" + +#include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/IDGenerator.h> +#include <Swiften/Jingle/JingleContentID.h> +#include <Swiften/Elements/JingleFileTransferDescription.h> +#include <Swiften/Elements/JingleFileTransferHash.h> +#include <Swiften/Elements/JingleTransportPayload.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/FileTransfer/IBBSendSession.h> +#include <Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h> +#include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/StringCodecs/SHA1.h> + +#include <Swiften/Base/Log.h> + +namespace Swift { + +OutgoingJingleFileTransfer::OutgoingJingleFileTransfer(JingleSession::ref session, + RemoteJingleTransportCandidateSelectorFactory* remoteFactory, + LocalJingleTransportCandidateGeneratorFactory* localFactory, + IQRouter* router, + IDGenerator *idGenerator, + const JID& fromJID, + const JID& toJID, + boost::shared_ptr<ReadBytestream> readStream, + const StreamInitiationFileInfo &fileInfo, + SOCKS5BytestreamRegistry* bytestreamRegistry, + SOCKS5BytestreamProxy* bytestreamProxy) : + session(session), remoteFactory(remoteFactory), localFactory(localFactory), router(router), idGenerator(idGenerator), fromJID(fromJID), toJID(toJID), readStream(readStream), fileInfo(fileInfo), s5bRegistry(bytestreamRegistry), s5bProxy(bytestreamProxy), serverSession(NULL), contentID(JingleContentID(idGenerator->generateID(), JingleContentPayload::InitiatorCreator)), canceled(false) { + session->onSessionAcceptReceived.connect(boost::bind(&OutgoingJingleFileTransfer::handleSessionAcceptReceived, this, _1, _2, _3)); + session->onSessionTerminateReceived.connect(boost::bind(&OutgoingJingleFileTransfer::handleSessionTerminateReceived, this, _1)); + session->onTransportInfoReceived.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransportInfoReceived, this, _1, _2)); + session->onTransportAcceptReceived.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransportAcceptReceived, this, _1, _2)); + fileSizeInBytes = fileInfo.getSize(); + filename = fileInfo.getName(); + + localCandidateGenerator = localFactory->createCandidateGenerator(); + localCandidateGenerator->onLocalTransportCandidatesGenerated.connect(boost::bind(&OutgoingJingleFileTransfer::handleLocalTransportCandidatesGenerated, this, _1)); + + remoteCandidateSelector = remoteFactory->createCandidateSelector(); + remoteCandidateSelector->onRemoteTransportCandidateSelectFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleRemoteTransportCandidateSelectFinished, this, _1)); + // calculate both, MD5 and SHA-1 since we don't know which one the other side supports + hashCalculator = new IncrementalBytestreamHashCalculator(true, true); + this->readStream->onRead.connect(boost::bind(&IncrementalBytestreamHashCalculator::feedData, hashCalculator, _1)); +} + +OutgoingJingleFileTransfer::~OutgoingJingleFileTransfer() { + readStream->onRead.disconnect(boost::bind(&IncrementalBytestreamHashCalculator::feedData, hashCalculator, _1)); + delete hashCalculator; +} + +void OutgoingJingleFileTransfer::start() { + onStateChange(FileTransfer::State(FileTransfer::State::WaitingForStart)); + + s5bSessionID = s5bRegistry->generateSessionID(); + SWIFT_LOG(debug) << "S5B SessionID: " << s5bSessionID << std::endl; + + //s5bProxy->connectToProxies(s5bSessionID); + + JingleS5BTransportPayload::ref transport = boost::make_shared<JingleS5BTransportPayload>(); + localCandidateGenerator->generateLocalTransportCandidates(transport); +} + +void OutgoingJingleFileTransfer::stop() { + +} + +void OutgoingJingleFileTransfer::cancel() { + canceled = true; + session->sendTerminate(JinglePayload::Reason::Cancel); + + if (ibbSession) { + ibbSession->stop(); + } + SOCKS5BytestreamServerSession *serverSession = s5bRegistry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(s5bSessionID, session->getInitiator(), toJID)); + if (serverSession) { + serverSession->stop(); + } + if (clientSession) { + clientSession->stop(); + } + onStateChange(FileTransfer::State(FileTransfer::State::Canceled)); +} + +void OutgoingJingleFileTransfer::handleSessionAcceptReceived(const JingleContentID& id, JingleDescription::ref /* decription */, JingleTransportPayload::ref transportPayload) { + if (canceled) { + return; + } + onStateChange(FileTransfer::State(FileTransfer::State::Negotiating)); + + JingleIBBTransportPayload::ref ibbPayload; + JingleS5BTransportPayload::ref s5bPayload; + if ((ibbPayload = boost::dynamic_pointer_cast<JingleIBBTransportPayload>(transportPayload))) { + ibbSession = boost::make_shared<IBBSendSession>(ibbPayload->getSessionID(), fromJID, toJID, readStream, router); + ibbSession->setBlockSize(ibbPayload->getBlockSize()); + ibbSession->onBytesSent.connect(boost::bind(boost::ref(onProcessedBytes), _1)); + ibbSession->onFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransferFinished, this, _1)); + ibbSession->start(); + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); + } + else if ((s5bPayload = boost::dynamic_pointer_cast<JingleS5BTransportPayload>(transportPayload))) { + fillCandidateMap(theirCandidates, s5bPayload); + remoteCandidateSelector->setRequesterTargtet(toJID, session->getInitiator()); + remoteCandidateSelector->addRemoteTransportCandidates(s5bPayload); + remoteCandidateSelector->selectCandidate(); + } + else { + // TODO: error handling + SWIFT_LOG(debug) << "Unknown transport payload! Try replaceing with IBB." << std::endl; + replaceTransportWithIBB(id); + } +} + +void OutgoingJingleFileTransfer::handleSessionTerminateReceived(boost::optional<JinglePayload::Reason> reason) { + if (canceled) { + return; + } + + if (ibbSession) { + ibbSession->stop(); + } + if (clientSession) { + clientSession->stop(); + } + if (serverSession) { + serverSession->stop(); + } + + if (reason.is_initialized() && reason.get().type == JinglePayload::Reason::Cancel) { + onStateChange(FileTransfer::State(FileTransfer::State::Canceled)); + onFinished(FileTransferError(FileTransferError::PeerError)); + } else if (reason.is_initialized() && reason.get().type == JinglePayload::Reason::Success) { + onStateChange(FileTransfer::State(FileTransfer::State::Finished)); + onFinished(boost::optional<FileTransferError>()); + } else { + onStateChange(FileTransfer::State(FileTransfer::State::Failed)); + onFinished(FileTransferError(FileTransferError::PeerError)); + } + canceled = true; +} + +void OutgoingJingleFileTransfer::handleTransportAcceptReceived(const JingleContentID& /* contentID */, JingleTransportPayload::ref transport) { + if (canceled) { + return; + } + + if (JingleIBBTransportPayload::ref ibbPayload = boost::dynamic_pointer_cast<JingleIBBTransportPayload>(transport)) { + ibbSession = boost::make_shared<IBBSendSession>(ibbPayload->getSessionID(), fromJID, toJID, readStream, router); + ibbSession->setBlockSize(ibbPayload->getBlockSize()); + ibbSession->onBytesSent.connect(boost::bind(boost::ref(onProcessedBytes), _1)); + ibbSession->onFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransferFinished, this, _1)); + ibbSession->start(); + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); + } else { + // error handling + SWIFT_LOG(debug) << "Replacing with anything other than IBB isn't supported yet." << std::endl; + session->sendTerminate(JinglePayload::Reason::FailedTransport); + onStateChange(FileTransfer::State(FileTransfer::State::Failed)); + } +} + +void OutgoingJingleFileTransfer::startTransferViaOurCandidateChoice(JingleS5BTransportPayload::Candidate candidate) { + SWIFT_LOG(debug) << "Transferring data using our candidate." << std::endl; + if (candidate.type == JingleS5BTransportPayload::Candidate::ProxyType) { + // get proxy client session from remoteCandidateSelector + clientSession = remoteCandidateSelector->getS5BSession(); + + // wait on <activated/> transport-info + } else { + clientSession = remoteCandidateSelector->getS5BSession(); + clientSession->onBytesSent.connect(boost::bind(boost::ref(onProcessedBytes), _1)); + clientSession->onFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransferFinished, this, _1)); + clientSession->startSending(readStream); + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); + } + assert(clientSession); +} + +void OutgoingJingleFileTransfer::startTransferViaTheirCandidateChoice(JingleS5BTransportPayload::Candidate candidate) { + SWIFT_LOG(debug) << "Transferring data using their candidate." << std::endl; + if (candidate.type == JingleS5BTransportPayload::Candidate::ProxyType) { + // connect to proxy + clientSession = s5bProxy->createSOCKS5BytestreamClientSession(candidate.hostPort, SOCKS5BytestreamRegistry::getHostname(s5bSessionID, session->getInitiator(), toJID)); + clientSession->onSessionReady.connect(boost::bind(&OutgoingJingleFileTransfer::proxySessionReady, this, candidate.jid, _1)); + clientSession->start(); + + // on reply send activate + + } else { + serverSession = s5bRegistry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(s5bSessionID, session->getInitiator(), toJID)); + serverSession->onBytesSent.connect(boost::bind(boost::ref(onProcessedBytes), _1)); + serverSession->onFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransferFinished, this, _1)); + serverSession->startTransfer(); + } + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); +} + +// decide on candidates according to http://xmpp.org/extensions/xep-0260.html#complete +void OutgoingJingleFileTransfer::decideOnCandidates() { + if (ourCandidateChoice && theirCandidateChoice) { + std::string our_cid = ourCandidateChoice->getCandidateUsed(); + std::string their_cid = theirCandidateChoice->getCandidateUsed(); + if (ourCandidateChoice->hasCandidateError() && theirCandidateChoice->hasCandidateError()) { + replaceTransportWithIBB(contentID); + } + else if (!our_cid.empty() && theirCandidateChoice->hasCandidateError()) { + // use our candidate + startTransferViaOurCandidateChoice(theirCandidates[our_cid]); + } + else if (!their_cid.empty() && ourCandidateChoice->hasCandidateError()) { + // use their candidate + startTransferViaTheirCandidateChoice(ourCandidates[their_cid]); + } + else if (!our_cid.empty() && !their_cid.empty()) { + // compare priorites, if same we win + if (ourCandidates.find(their_cid) == ourCandidates.end() || theirCandidates.find(our_cid) == theirCandidates.end()) { + SWIFT_LOG(debug) << "Didn't recognize candidate IDs!" << std::endl; + session->sendTerminate(JinglePayload::Reason::FailedTransport); + onStateChange(FileTransfer::State(FileTransfer::State::Failed)); + onFinished(FileTransferError(FileTransferError::PeerError)); + return; + } + + JingleS5BTransportPayload::Candidate ourCandidate = theirCandidates[our_cid]; + JingleS5BTransportPayload::Candidate theirCandidate = ourCandidates[their_cid]; + if (ourCandidate.priority > theirCandidate.priority) { + startTransferViaOurCandidateChoice(ourCandidate); + } + else if (ourCandidate.priority < theirCandidate.priority) { + startTransferViaTheirCandidateChoice(theirCandidate); + } + else { + startTransferViaOurCandidateChoice(ourCandidate); + } + } + } else { + SWIFT_LOG(debug) << "Can't make a decision yet!" << std::endl; + } +} + +void OutgoingJingleFileTransfer::fillCandidateMap(CandidateMap& map, JingleS5BTransportPayload::ref s5bPayload) { + map.clear(); + foreach (JingleS5BTransportPayload::Candidate candidate, s5bPayload->getCandidates()) { + map[candidate.cid] = candidate; + } +} + +void OutgoingJingleFileTransfer::proxySessionReady(const JID& proxy, bool error) { + if (error) { + // indicate proxy error + } else { + // activate proxy + activateProxySession(proxy); + } +} + +void OutgoingJingleFileTransfer::activateProxySession(const JID& proxy) { + S5BProxyRequest::ref proxyRequest = boost::make_shared<S5BProxyRequest>(); + proxyRequest->setSID(s5bSessionID); + proxyRequest->setActivate(toJID); + + boost::shared_ptr<GenericRequest<S5BProxyRequest> > request = boost::make_shared<GenericRequest<S5BProxyRequest> >(IQ::Set, proxy, proxyRequest, router); + request->onResponse.connect(boost::bind(&OutgoingJingleFileTransfer::handleActivateProxySessionResult, this, _1, _2)); + request->send(); +} + +void OutgoingJingleFileTransfer::handleActivateProxySessionResult(boost::shared_ptr<S5BProxyRequest> /*request*/, ErrorPayload::ref error) { + if (error) { + SWIFT_LOG(debug) << "ERROR" << std::endl; + } else { + // send activated to other jingle party + JingleS5BTransportPayload::ref proxyActivate = boost::make_shared<JingleS5BTransportPayload>(); + proxyActivate->setActivated(theirCandidateChoice->getCandidateUsed()); + session->sendTransportInfo(contentID, proxyActivate); + + // start transferring + clientSession->onBytesSent.connect(boost::bind(boost::ref(onProcessedBytes), _1)); + clientSession->onFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransferFinished, this, _1)); + clientSession->startSending(readStream); + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); + } +} + +void OutgoingJingleFileTransfer::sendSessionInfoHash() { + SWIFT_LOG(debug) << std::endl; + JingleFileTransferHash::ref hashElement = boost::make_shared<JingleFileTransferHash>(); + hashElement->setHash("sha-1", hashCalculator->getSHA1String()); + hashElement->setHash("md5", hashCalculator->getMD5String()); + session->sendInfo(hashElement); +} + +void OutgoingJingleFileTransfer::handleTransportInfoReceived(const JingleContentID& /* contentID */, JingleTransportPayload::ref transport) { + if (canceled) { + return; + } + if (JingleS5BTransportPayload::ref s5bPayload = boost::dynamic_pointer_cast<JingleS5BTransportPayload>(transport)) { + if (s5bPayload->hasCandidateError() || !s5bPayload->getCandidateUsed().empty()) { + theirCandidateChoice = s5bPayload; + decideOnCandidates(); + } else if(!s5bPayload->getActivated().empty()) { + if (ourCandidateChoice->getCandidateUsed() == s5bPayload->getActivated()) { + clientSession->onBytesSent.connect(boost::bind(boost::ref(onProcessedBytes), _1)); + clientSession->onFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransferFinished, this, _1)); + clientSession->startSending(readStream); + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); + } else { + SWIFT_LOG(debug) << "ourCandidateChoice doesn't match activated proxy candidate!" << std::endl; + JingleS5BTransportPayload::ref proxyError = boost::make_shared<JingleS5BTransportPayload>(); + proxyError->setProxyError(true); + proxyError->setSessionID(s5bSessionID); + session->sendTransportInfo(contentID, proxyError); + } + } + } +} + +void OutgoingJingleFileTransfer::handleLocalTransportCandidatesGenerated(JingleTransportPayload::ref payload) { + if (canceled) { + return; + } + JingleFileTransferDescription::ref description = boost::make_shared<JingleFileTransferDescription>(); + description->addOffer(fileInfo); + + JingleTransportPayload::ref transport; + if (JingleIBBTransportPayload::ref ibbTransport = boost::dynamic_pointer_cast<JingleIBBTransportPayload>(payload)) { + ibbTransport->setBlockSize(4096); + ibbTransport->setSessionID(idGenerator->generateID()); + transport = ibbTransport; + } + else if (JingleS5BTransportPayload::ref s5bTransport = boost::dynamic_pointer_cast<JingleS5BTransportPayload>(payload)) { + //fillCandidateMap(ourCandidates, s5bTransport); + //s5bTransport->setSessionID(s5bSessionID); + + JingleS5BTransportPayload::ref emptyCandidates = boost::make_shared<JingleS5BTransportPayload>(); + emptyCandidates->setSessionID(s5bTransport->getSessionID()); + fillCandidateMap(ourCandidates, emptyCandidates); + + transport = emptyCandidates; + s5bRegistry->addReadBytestream(SOCKS5BytestreamRegistry::getHostname(s5bSessionID, session->getInitiator(), toJID), readStream); + } + else { + SWIFT_LOG(debug) << "Unknown tranport payload: " << typeid(*payload).name() << std::endl; + return; + } + session->sendInitiate(contentID, description, transport); + onStateChange(FileTransfer::State(FileTransfer::State::WaitingForAccept)); +} + +void OutgoingJingleFileTransfer::handleRemoteTransportCandidateSelectFinished(JingleTransportPayload::ref payload) { + if (canceled) { + return; + } + if (JingleS5BTransportPayload::ref s5bPayload = boost::dynamic_pointer_cast<JingleS5BTransportPayload>(payload)) { + ourCandidateChoice = s5bPayload; + session->sendTransportInfo(contentID, s5bPayload); + decideOnCandidates(); + } +} + +void OutgoingJingleFileTransfer::replaceTransportWithIBB(const JingleContentID& id) { + SWIFT_LOG(debug) << "Both parties failed. Replace transport with IBB." << std::endl; + JingleIBBTransportPayload::ref ibbTransport = boost::make_shared<JingleIBBTransportPayload>(); + ibbTransport->setBlockSize(4096); + ibbTransport->setSessionID(idGenerator->generateID()); + session->sendTransportReplace(id, ibbTransport); +} + +void OutgoingJingleFileTransfer::handleTransferFinished(boost::optional<FileTransferError> error) { + if (error) { + session->sendTerminate(JinglePayload::Reason::ConnectivityError); + onStateChange(FileTransfer::State(FileTransfer::State::Failed)); + onFinished(error); + } else { + sendSessionInfoHash(); + /* + session->terminate(JinglePayload::Reason::Success); + onStateChange(FileTransfer::State(FileTransfer::State::Finished)); + */ + } + // +} + +} diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.h b/Swiften/FileTransfer/OutgoingJingleFileTransfer.h new file mode 100644 index 0000000..ff7bfc7 --- /dev/null +++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> + +#include <Swiften/Elements/JingleContentPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/Elements/StreamInitiationFileInfo.h> +#include <Swiften/Elements/S5BProxyRequest.h> +#include <Swiften/Elements/ErrorPayload.h> +#include <Swiften/FileTransfer/OutgoingFileTransfer.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamServerSession.h> +#include <Swiften/Jingle/JingleContentID.h> +#include <Swiften/Jingle/JingleSession.h> +#include <Swiften/StringCodecs/SHA1.h> + +namespace Swift { + +class RemoteJingleTransportCandidateSelectorFactory; +class RemoteJingleTransportCandidateSelector; +class LocalJingleTransportCandidateGeneratorFactory; +class LocalJingleTransportCandidateGenerator; +class IQRouter; +class ReadBytestream; +class IBBSendSession; +class IDGenerator; +class IncrementalBytestreamHashCalculator; +class SOCKS5BytestreamRegistry; +class SOCKS5BytestreamProxy; + +class OutgoingJingleFileTransfer : public OutgoingFileTransfer { +public: + OutgoingJingleFileTransfer(JingleSession::ref, + RemoteJingleTransportCandidateSelectorFactory*, + LocalJingleTransportCandidateGeneratorFactory*, + IQRouter*, + IDGenerator*, + const JID& from, + const JID& to, + boost::shared_ptr<ReadBytestream>, + const StreamInitiationFileInfo&, + SOCKS5BytestreamRegistry*, + SOCKS5BytestreamProxy*); + virtual ~OutgoingJingleFileTransfer(); + + void start(); + void stop(); + + void cancel(); + +private: + void handleSessionAcceptReceived(const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref); + void handleSessionTerminateReceived(boost::optional<JinglePayload::Reason> reason); + void handleTransportAcceptReceived(const JingleContentID&, JingleTransportPayload::ref); + void handleTransportInfoReceived(const JingleContentID&, JingleTransportPayload::ref); + + void handleLocalTransportCandidatesGenerated(JingleTransportPayload::ref); + void handleRemoteTransportCandidateSelectFinished(JingleTransportPayload::ref); + +private: + void replaceTransportWithIBB(const JingleContentID&); + void handleTransferFinished(boost::optional<FileTransferError>); + void activateProxySession(const JID &proxy); + void handleActivateProxySessionResult(boost::shared_ptr<S5BProxyRequest> request, ErrorPayload::ref error); + void proxySessionReady(const JID& proxy, bool error); + +private: + typedef std::map<std::string, JingleS5BTransportPayload::Candidate> CandidateMap; + +private: + void startTransferViaOurCandidateChoice(JingleS5BTransportPayload::Candidate); + void startTransferViaTheirCandidateChoice(JingleS5BTransportPayload::Candidate); + void decideOnCandidates(); + void fillCandidateMap(CandidateMap& map, JingleS5BTransportPayload::ref s5bPayload); + +private: + void sendSessionInfoHash(); + +private: + JingleSession::ref session; + RemoteJingleTransportCandidateSelector* remoteCandidateSelector; + RemoteJingleTransportCandidateSelectorFactory* remoteFactory; + LocalJingleTransportCandidateGenerator* localCandidateGenerator; + LocalJingleTransportCandidateGeneratorFactory* localFactory; + + IQRouter* router; + IDGenerator* idGenerator; + JID fromJID; + JID toJID; + boost::shared_ptr<ReadBytestream> readStream; + StreamInitiationFileInfo fileInfo; + IncrementalBytestreamHashCalculator *hashCalculator; + + boost::shared_ptr<IBBSendSession> ibbSession; + + JingleS5BTransportPayload::ref ourCandidateChoice; + JingleS5BTransportPayload::ref theirCandidateChoice; + CandidateMap ourCandidates; + CandidateMap theirCandidates; + + SOCKS5BytestreamRegistry* s5bRegistry; + SOCKS5BytestreamProxy* s5bProxy; + SOCKS5BytestreamClientSession::ref clientSession; + SOCKS5BytestreamServerSession* serverSession; + JingleContentID contentID; + std::string s5bSessionID; + + bool canceled; +}; + +} diff --git a/Swiften/FileTransfer/OutgoingSIFileTransfer.cpp b/Swiften/FileTransfer/OutgoingSIFileTransfer.cpp new file mode 100644 index 0000000..8a8237a --- /dev/null +++ b/Swiften/FileTransfer/OutgoingSIFileTransfer.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/FileTransfer/OutgoingSIFileTransfer.h> + +#include <boost/bind.hpp> + +#include <Swiften/FileTransfer/StreamInitiationRequest.h> +#include <Swiften/FileTransfer/BytestreamsRequest.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h> +#include <Swiften/FileTransfer/IBBSendSession.h> + +namespace Swift { + +OutgoingSIFileTransfer::OutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer) : id(id), from(from), to(to), name(name), size(size), description(description), bytestream(bytestream), iqRouter(iqRouter), socksServer(socksServer) { +} + +void OutgoingSIFileTransfer::start() { + StreamInitiation::ref streamInitiation(new StreamInitiation()); + streamInitiation->setID(id); + streamInitiation->setFileInfo(StreamInitiationFileInfo(name, description, size)); + //streamInitiation->addProvidedMethod("http://jabber.org/protocol/bytestreams"); + streamInitiation->addProvidedMethod("http://jabber.org/protocol/ibb"); + StreamInitiationRequest::ref request = StreamInitiationRequest::create(to, streamInitiation, iqRouter); + request->onResponse.connect(boost::bind(&OutgoingSIFileTransfer::handleStreamInitiationRequestResponse, this, _1, _2)); + request->send(); +} + +void OutgoingSIFileTransfer::stop() { +} + +void OutgoingSIFileTransfer::handleStreamInitiationRequestResponse(StreamInitiation::ref response, ErrorPayload::ref error) { + if (error) { + finish(FileTransferError()); + } + else { + if (response->getRequestedMethod() == "http://jabber.org/protocol/bytestreams") { + socksServer->addReadBytestream(id, from, to, bytestream); + Bytestreams::ref bytestreams(new Bytestreams()); + bytestreams->setStreamID(id); + HostAddressPort addressPort = socksServer->getAddressPort(); + bytestreams->addStreamHost(Bytestreams::StreamHost(addressPort.getAddress().toString(), from, addressPort.getPort())); + BytestreamsRequest::ref request = BytestreamsRequest::create(to, bytestreams, iqRouter); + request->onResponse.connect(boost::bind(&OutgoingSIFileTransfer::handleBytestreamsRequestResponse, this, _1, _2)); + request->send(); + } + else if (response->getRequestedMethod() == "http://jabber.org/protocol/ibb") { + ibbSession = boost::shared_ptr<IBBSendSession>(new IBBSendSession(id, from, to, bytestream, iqRouter)); + ibbSession->onFinished.connect(boost::bind(&OutgoingSIFileTransfer::handleIBBSessionFinished, this, _1)); + ibbSession->start(); + } + } +} + +void OutgoingSIFileTransfer::handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref error) { + if (error) { + finish(FileTransferError()); + } + //socksServer->onTransferFinished.connect(); +} + +void OutgoingSIFileTransfer::finish(boost::optional<FileTransferError> error) { + if (ibbSession) { + ibbSession->onFinished.disconnect(boost::bind(&OutgoingSIFileTransfer::handleIBBSessionFinished, this, _1)); + ibbSession.reset(); + } + socksServer->removeReadBytestream(id, from, to); + onFinished(error); +} + +void OutgoingSIFileTransfer::handleIBBSessionFinished(boost::optional<FileTransferError> error) { + finish(error); +} + +} diff --git a/Swiften/FileTransfer/OutgoingSIFileTransfer.h b/Swiften/FileTransfer/OutgoingSIFileTransfer.h new file mode 100644 index 0000000..584eb60 --- /dev/null +++ b/Swiften/FileTransfer/OutgoingSIFileTransfer.h @@ -0,0 +1,53 @@ +/* + * 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/FileTransfer/OutgoingFileTransfer.h> +#include <Swiften/FileTransfer/ReadBytestream.h> +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/FileTransfer/FileTransferError.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/StreamInitiation.h> +#include <Swiften/Elements/Bytestreams.h> +#include <Swiften/Elements/ErrorPayload.h> +#include <Swiften/FileTransfer/IBBSendSession.h> + +namespace Swift { + class IQRouter; + class SOCKS5BytestreamServer; + + class OutgoingSIFileTransfer : public OutgoingFileTransfer { + public: + OutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer); + + virtual void start(); + virtual void stop(); + + boost::signal<void (const boost::optional<FileTransferError>&)> onFinished; + + private: + void handleStreamInitiationRequestResponse(StreamInitiation::ref, ErrorPayload::ref); + void handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref); + void finish(boost::optional<FileTransferError> error); + void handleIBBSessionFinished(boost::optional<FileTransferError> error); + + private: + std::string id; + JID from; + JID to; + std::string name; + int size; + std::string description; + boost::shared_ptr<ReadBytestream> bytestream; + IQRouter* iqRouter; + SOCKS5BytestreamServer* socksServer; + boost::shared_ptr<IBBSendSession> ibbSession; + }; +} diff --git a/Swiften/FileTransfer/ReadBytestream.cpp b/Swiften/FileTransfer/ReadBytestream.cpp index 705906c..5fa10d8 100644 --- a/Swiften/FileTransfer/ReadBytestream.cpp +++ b/Swiften/FileTransfer/ReadBytestream.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/FileTransfer/ReadBytestream.h" +#include <Swiften/FileTransfer/ReadBytestream.h> namespace Swift { diff --git a/Swiften/FileTransfer/ReadBytestream.h b/Swiften/FileTransfer/ReadBytestream.h index 4da2bc2..c94e4d3 100644 --- a/Swiften/FileTransfer/ReadBytestream.h +++ b/Swiften/FileTransfer/ReadBytestream.h @@ -6,13 +6,26 @@ #pragma once -#include "Swiften/Base/ByteArray.h" +#include <boost/shared_ptr.hpp> +#include <vector> + +#include <Swiften/Base/boost_bsignals.h> namespace Swift { class ReadBytestream { public: virtual ~ReadBytestream(); - virtual ByteArray read(size_t size) = 0; + + /** + * Return an empty vector if no more data is available. + * Use onDataAvailable signal for signaling there is data available again. + */ + virtual boost::shared_ptr< std::vector<unsigned char> > read(size_t size) = 0; + virtual bool isFinished() const = 0; + + public: + boost::signal<void ()> onDataAvailable; + boost::signal<void (const std::vector<unsigned char>&)> onRead; }; } diff --git a/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.cpp b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.cpp new file mode 100644 index 0000000..338f221 --- /dev/null +++ b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h> + +namespace Swift { + +RemoteJingleTransportCandidateSelector::~RemoteJingleTransportCandidateSelector() { +} + +} diff --git a/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h new file mode 100644 index 0000000..f8df8f9 --- /dev/null +++ b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Base/boost_bsignals.h> + +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/JingleTransportPayload.h> +#include <Swiften/FileTransfer/JingleTransport.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h> + +namespace Swift { + class RemoteJingleTransportCandidateSelector { + public: + virtual ~RemoteJingleTransportCandidateSelector(); + + virtual void addRemoteTransportCandidates(JingleTransportPayload::ref) = 0; + virtual void selectCandidate() = 0; + virtual void setMinimumPriority(int) = 0; + virtual void setRequesterTargtet(const JID&, const JID&) {} + virtual SOCKS5BytestreamClientSession::ref getS5BSession() { return SOCKS5BytestreamClientSession::ref(); } + + virtual bool isActualCandidate(JingleTransportPayload::ref) = 0; + virtual int getPriority(JingleTransportPayload::ref) = 0; + virtual JingleTransport::ref selectTransport(JingleTransportPayload::ref) = 0; + + boost::signal<void (JingleTransportPayload::ref)> onRemoteTransportCandidateSelectFinished; + }; +} diff --git a/Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.cpp b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.cpp new file mode 100644 index 0000000..36b7cba --- /dev/null +++ b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h> + +namespace Swift { + +RemoteJingleTransportCandidateSelectorFactory::~RemoteJingleTransportCandidateSelectorFactory() { +} + +} diff --git a/Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h new file mode 100644 index 0000000..caa3097 --- /dev/null +++ b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +namespace Swift { + class RemoteJingleTransportCandidateSelector; + + class RemoteJingleTransportCandidateSelectorFactory { + public: + virtual ~RemoteJingleTransportCandidateSelectorFactory(); + + virtual RemoteJingleTransportCandidateSelector* createCandidateSelector() = 0; + }; +} diff --git a/Swiften/FileTransfer/SConscript b/Swiften/FileTransfer/SConscript index ea9e7bb..4e79992 100644 --- a/Swiften/FileTransfer/SConscript +++ b/Swiften/FileTransfer/SConscript @@ -1,19 +1,48 @@ -Import("swiften_env") +Import("swiften_env", "env") sources = [ "OutgoingFileTransfer.cpp", + "OutgoingSIFileTransfer.cpp", + "OutgoingJingleFileTransfer.cpp", + "OutgoingFileTransferManager.cpp", "IncomingFileTransfer.cpp", "IncomingJingleFileTransfer.cpp", - "IncomingFileTransferManager.cpp", + "IncomingFileTransferManager.cpp", + "RemoteJingleTransportCandidateSelector.cpp", + "RemoteJingleTransportCandidateSelectorFactory.cpp", + "LocalJingleTransportCandidateGenerator.cpp", + "LocalJingleTransportCandidateGeneratorFactory.cpp", + "DefaultRemoteJingleTransportCandidateSelectorFactory.cpp", + "DefaultLocalJingleTransportCandidateGeneratorFactory.cpp", + "DefaultRemoteJingleTransportCandidateSelector.cpp", + "DefaultLocalJingleTransportCandidateGenerator.cpp", + "JingleTransport.cpp", + "JingleIncomingIBBTransport.cpp", "ReadBytestream.cpp", "WriteBytestream.cpp", "FileReadBytestream.cpp", "FileWriteBytestream.cpp", + "SOCKS5BytestreamClientSession.cpp", "SOCKS5BytestreamServer.cpp", "SOCKS5BytestreamServerSession.cpp", "SOCKS5BytestreamRegistry.cpp", + "SOCKS5BytestreamProxy.cpp", + "SOCKS5BytestreamProxyFinder.cpp", "IBBSendSession.cpp", "IBBReceiveSession.cpp", + "FileTransferManager.cpp", + "FileTransferManagerImpl.cpp", + "IncrementalBytestreamHashCalculator.cpp", + "ConnectivityManager.cpp", ] swiften_env.Append(SWIFTEN_OBJECTS = swiften_env.SwiftenObject(sources)) + +env.Append(UNITTEST_SOURCES = [ + File("UnitTest/SOCKS5BytestreamServerSessionTest.cpp"), + File("UnitTest/SOCKS5BytestreamClientSessionTest.cpp"), + File("UnitTest/IBBSendSessionTest.cpp"), + File("UnitTest/IBBReceiveSessionTest.cpp"), + File("UnitTest/IncomingJingleFileTransferTest.cpp"), + File("UnitTest/OutgoingJingleFileTransferTest.cpp"), + ]) diff --git a/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp new file mode 100644 index 0000000..cd555e5 --- /dev/null +++ b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "SOCKS5BytestreamClientSession.h" + +#include <boost/bind.hpp> + +#include <Swiften/Base/Algorithm.h> +#include <Swiften/Base/SafeByteArray.h> +#include <Swiften/Base/Concat.h> +#include <Swiften/Base/Log.h> +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/FileTransfer/BytestreamException.h> +#include <Swiften/Network/TimerFactory.h> +#include <Swiften/Base/ByteArray.h> + +namespace Swift { + +SOCKS5BytestreamClientSession::SOCKS5BytestreamClientSession(boost::shared_ptr<Connection> connection, const HostAddressPort& addressPort, const std::string& destination, TimerFactory* timerFactory) : + connection(connection), addressPort(addressPort), destination(destination), state(Initial), chunkSize(131072) { + connection->onConnectFinished.connect(boost::bind(&SOCKS5BytestreamClientSession::handleConnectFinished, this, _1)); + connection->onDisconnected.connect(boost::bind(&SOCKS5BytestreamClientSession::handleDisconnected, this, _1)); + weFailedTimeout = timerFactory->createTimer(2000); + weFailedTimeout->onTick.connect(boost::bind(&SOCKS5BytestreamClientSession::handleWeFailedTimeout, this)); +} + +void SOCKS5BytestreamClientSession::start() { + assert(state == Initial); + SWIFT_LOG(debug) << "Trying to connect via TCP to " << addressPort.toString() << "." << std::endl; + weFailedTimeout->start(); + connection->connect(addressPort); +} + +void SOCKS5BytestreamClientSession::stop() { + connection->disconnect(); + connection->onDataWritten.disconnect(boost::bind(&SOCKS5BytestreamClientSession::sendData, this)); + connection->onDataRead.disconnect(boost::bind(&SOCKS5BytestreamClientSession::handleDataRead, this, _1)); + readBytestream.reset(); + state = Finished; +} + +void SOCKS5BytestreamClientSession::process() { + SWIFT_LOG(debug) << "unprocessedData.size(): " << unprocessedData.size() << std::endl; + ByteArray bndAddress; + switch(state) { + case Initial: + hello(); + break; + case Hello: + if (unprocessedData.size() > 1) { + unsigned char version = unprocessedData[0]; + unsigned char authMethod = unprocessedData[1]; + if (version != 5 || authMethod != 0) { + // signal failure to upper level + finish(true); + return; + } + unprocessedData.clear(); + authenticate(); + } + break; + case Authenticating: + if (unprocessedData.size() < 5) { + // need more data to start progressing + break; + } + if (unprocessedData[0] != '\x05') { + // wrong version + // disconnect & signal failure + finish(true); + break; + } + if (unprocessedData[1] != '\x00') { + // no success + // disconnect & signal failure + finish(true); + break; + } + if (unprocessedData[3] != '\x03') { + // we expect x'03' = DOMAINNAME here + // discconect & signal failure + finish(true); + break; + } + if (static_cast<size_t>(unprocessedData[4]) + 1 > unprocessedData.size() + 5) { + // complete domainname and port not available yet + break; + } + bndAddress = createByteArray(&vecptr(unprocessedData)[5], unprocessedData[4]); + if (unprocessedData[unprocessedData[4] + 5] != 0 && bndAddress == createByteArray(destination)) { + // we expect a 0 as port + // disconnect and fail + finish(true); + } + unprocessedData.clear(); + state = Ready; + SWIFT_LOG(debug) << "session ready" << std::endl; + // issue ready signal so the bytestream can be used for reading or writing + weFailedTimeout->stop(); + onSessionReady(false); + break; + case Ready: + SWIFT_LOG(debug) << "Received further data in Ready state." << std::endl; + break; + case Reading: + case Writing: + case Finished: + SWIFT_LOG(debug) << "Unexpected receive of data. Current state: " << state << std::endl; + SWIFT_LOG(debug) << "Data: " << Hexify::hexify(unprocessedData) << std::endl; + unprocessedData.clear(); + //assert(false); + } +} + +void SOCKS5BytestreamClientSession::hello() { + // Version 5, 1 auth method, No authentication + const SafeByteArray hello = createSafeByteArray("\x05\x01\x00", 3); + connection->write(hello); + state = Hello; +} + +void SOCKS5BytestreamClientSession::authenticate() { + SWIFT_LOG(debug) << std::endl; + SafeByteArray header = createSafeByteArray("\x05\x01\x00\x03", 4); + SafeByteArray message = header; + append(message, createSafeByteArray(destination.size())); + authenticateAddress = createByteArray(destination); + append(message, authenticateAddress); + append(message, createSafeByteArray("\x00\x00", 2)); // 2 byte for port + connection->write(message); + state = Authenticating; +} + +void SOCKS5BytestreamClientSession::startReceiving(boost::shared_ptr<WriteBytestream> writeStream) { + if (state == Ready) { + state = Reading; + writeBytestream = writeStream; + writeBytestream->write(unprocessedData); + onBytesReceived(unprocessedData.size()); + unprocessedData.clear(); + } else { + SWIFT_LOG(debug) << "Session isn't ready for transfer yet!" << std::endl; + } +} + +void SOCKS5BytestreamClientSession::startSending(boost::shared_ptr<ReadBytestream> readStream) { + if (state == Ready) { + state = Writing; + readBytestream = readStream; + connection->onDataWritten.connect(boost::bind(&SOCKS5BytestreamClientSession::sendData, this)); + sendData(); + } else { + SWIFT_LOG(debug) << "Session isn't ready for transfer yet!" << std::endl; + } +} + +HostAddressPort SOCKS5BytestreamClientSession::getAddressPort() const { + return addressPort; +} + +void SOCKS5BytestreamClientSession::sendData() { + if (!readBytestream->isFinished()) { + try { + boost::shared_ptr<ByteArray> dataToSend = readBytestream->read(chunkSize); + connection->write(createSafeByteArray(*dataToSend)); + onBytesSent(dataToSend->size()); + } + catch (const BytestreamException&) { + finish(true); + } + } + else { + finish(false); + } +} + +void SOCKS5BytestreamClientSession::finish(bool error) { + weFailedTimeout->stop(); + connection->disconnect(); + connection->onDataWritten.disconnect(boost::bind(&SOCKS5BytestreamClientSession::sendData, this)); + connection->onDataRead.disconnect(boost::bind(&SOCKS5BytestreamClientSession::handleDataRead, this, _1)); + readBytestream.reset(); + if (state == Initial || state == Hello || state == Authenticating) { + onSessionReady(true); + } + else { + state = Finished; + if (error) { + onFinished(boost::optional<FileTransferError>(FileTransferError::ReadError)); + } else { + onFinished(boost::optional<FileTransferError>()); + } + } +} + +void SOCKS5BytestreamClientSession::handleConnectFinished(bool error) { + if (error) { + SWIFT_LOG(debug) << "Failed to connect via TCP to " << addressPort.toString() << "." << std::endl; + finish(true); + } else { + SWIFT_LOG(debug) << "Successfully connected via TCP" << addressPort.toString() << "." << std::endl; + weFailedTimeout->start(); + connection->onDataRead.connect(boost::bind(&SOCKS5BytestreamClientSession::handleDataRead, this, _1)); + process(); + } +} + +void SOCKS5BytestreamClientSession::handleDataRead(boost::shared_ptr<SafeByteArray> data) { + SWIFT_LOG(debug) << "state: " << state << " data.size() = " << data->size() << std::endl; + if (state != Reading) { + append(unprocessedData, *data); + process(); + } + else { + writeBytestream->write(createByteArray(vecptr(*data), data->size())); + onBytesReceived(data->size()); + } +} + +void SOCKS5BytestreamClientSession::handleDisconnected(const boost::optional<Connection::Error>& error) { + SWIFT_LOG(debug) << (error ? (error == Connection::ReadError ? "Read Error" : "Write Error") : "No Error") << std::endl; + if (error) { + finish(true); + } +} + +void SOCKS5BytestreamClientSession::handleWeFailedTimeout() { + SWIFT_LOG(debug) << "Failed due to timeout!" << std::endl; + finish(true); +} + +} diff --git a/Swiften/FileTransfer/SOCKS5BytestreamClientSession.h b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.h new file mode 100644 index 0000000..ea45955 --- /dev/null +++ b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> +#include <boost/optional.hpp> + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/FileTransfer/FileTransferError.h> +#include <Swiften/FileTransfer/WriteBytestream.h> +#include <Swiften/FileTransfer/ReadBytestream.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Network/Connection.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Network/Timer.h> + +namespace Swift { + +class SOCKS5BytestreamRegistry; +class Connection; +class TimerFactory; + +/** + * A session which has been connected to a SOCKS5 server (requester). + * + */ +class SOCKS5BytestreamClientSession { +public: + enum State { + Initial, + Hello, + Authenticating, + Ready, + Writing, + Reading, + Finished, + }; + +public: + typedef boost::shared_ptr<SOCKS5BytestreamClientSession> ref; + +public: + SOCKS5BytestreamClientSession(boost::shared_ptr<Connection> connection, const HostAddressPort&, const std::string&, TimerFactory*); + + void start(); + void stop(); + + void startReceiving(boost::shared_ptr<WriteBytestream>); + void startSending(boost::shared_ptr<ReadBytestream>); + + HostAddressPort getAddressPort() const; + + boost::signal<void (bool /*error*/)> onSessionReady; + + boost::signal<void (boost::optional<FileTransferError>)> onFinished; + boost::signal<void (int)> onBytesSent; + boost::signal<void (int)> onBytesReceived; + +private: + void process(); + void hello(); + void authenticate(); + + void handleConnectFinished(bool error); + void handleDataRead(boost::shared_ptr<SafeByteArray>); + void handleDisconnected(const boost::optional<Connection::Error>&); + void handleWeFailedTimeout(); + + void finish(bool error); + void sendData(); + +private: + boost::shared_ptr<Connection> connection; + HostAddressPort addressPort; + std::string destination; // hexify(SHA1(sessionID + requester + target)) + + State state; + int destinationPort; + + ByteArray unprocessedData; + ByteArray authenticateAddress; + + int chunkSize; + boost::shared_ptr<WriteBytestream> writeBytestream; + boost::shared_ptr<ReadBytestream> readBytestream; + + Timer::ref weFailedTimeout; +}; + +} diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxy.cpp b/Swiften/FileTransfer/SOCKS5BytestreamProxy.cpp new file mode 100644 index 0000000..9599fd1 --- /dev/null +++ b/Swiften/FileTransfer/SOCKS5BytestreamProxy.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "SOCKS5BytestreamProxy.h" + +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h> +#include <Swiften/Base/Log.h> + +namespace Swift { + +SOCKS5BytestreamProxy::SOCKS5BytestreamProxy(ConnectionFactory *connFactory, TimerFactory *timeFactory) : connectionFactory(connFactory), timerFactory(timeFactory) { + +} + +void SOCKS5BytestreamProxy::addS5BProxy(S5BProxyRequest::ref proxy) { + localS5BProxies.push_back(proxy); +} + +const std::vector<S5BProxyRequest::ref>& SOCKS5BytestreamProxy::getS5BProxies() const { + return localS5BProxies; +} + +void SOCKS5BytestreamProxy::connectToProxies(const std::string& sessionID) { + SWIFT_LOG(debug) << "session ID: " << sessionID << std::endl; + ProxyJIDClientSessionMap clientSessions; + + foreach(S5BProxyRequest::ref proxy, localS5BProxies) { + boost::shared_ptr<Connection> conn = connectionFactory->createConnection(); + + boost::shared_ptr<SOCKS5BytestreamClientSession> session = boost::make_shared<SOCKS5BytestreamClientSession>(conn, proxy->getStreamHost().get().addressPort, sessionID, timerFactory); + clientSessions[proxy->getStreamHost().get().jid] = session; + session->start(); + } + + proxySessions[sessionID] = clientSessions; +} + +boost::shared_ptr<SOCKS5BytestreamClientSession> SOCKS5BytestreamProxy::getProxySessionAndCloseOthers(const JID& proxyJID, const std::string& sessionID) { + // checking parameters + if (proxySessions.find(sessionID) == proxySessions.end()) { + return boost::shared_ptr<SOCKS5BytestreamClientSession>(); + } + if (proxySessions[sessionID].find(proxyJID) == proxySessions[sessionID].end()) { + return boost::shared_ptr<SOCKS5BytestreamClientSession>(); + } + + // get active session + boost::shared_ptr<SOCKS5BytestreamClientSession> activeSession = proxySessions[sessionID][proxyJID]; + proxySessions[sessionID].erase(proxyJID); + + // close other sessions + foreach(const ProxyJIDClientSessionMap::value_type& myPair, proxySessions[sessionID]) { + myPair.second->stop(); + } + + proxySessions.erase(sessionID); + + return activeSession; +} + +boost::shared_ptr<SOCKS5BytestreamClientSession> SOCKS5BytestreamProxy::createSOCKS5BytestreamClientSession(HostAddressPort addressPort, const std::string& destAddr) { + SOCKS5BytestreamClientSession::ref connection = boost::make_shared<SOCKS5BytestreamClientSession>(connectionFactory->createConnection(), addressPort, destAddr, timerFactory); + return connection; +} + +} diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxy.h b/Swiften/FileTransfer/SOCKS5BytestreamProxy.h new file mode 100644 index 0000000..8f80cea --- /dev/null +++ b/Swiften/FileTransfer/SOCKS5BytestreamProxy.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <string> +#include <vector> + +#include <Swiften/Elements/S5BProxyRequest.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/TimerFactory.h> + +namespace Swift { + +/** + * - manages list of working S5B proxies + * - creates initial connections (for the candidates you provide) + */ +class SOCKS5BytestreamProxy { +public: + SOCKS5BytestreamProxy(ConnectionFactory*, TimerFactory*); + + void addS5BProxy(S5BProxyRequest::ref); + const std::vector<S5BProxyRequest::ref>& getS5BProxies() const; + + void connectToProxies(const std::string& sessionID); + boost::shared_ptr<SOCKS5BytestreamClientSession> getProxySessionAndCloseOthers(const JID& proxyJID, const std::string& sessionID); + + boost::shared_ptr<SOCKS5BytestreamClientSession> createSOCKS5BytestreamClientSession(HostAddressPort addressPort, const std::string& destAddr); + +private: + ConnectionFactory* connectionFactory; + TimerFactory* timerFactory; + + typedef std::map<JID, boost::shared_ptr<SOCKS5BytestreamClientSession> > ProxyJIDClientSessionMap; + std::map<std::string, ProxyJIDClientSessionMap> proxySessions; + + std::vector<S5BProxyRequest::ref> localS5BProxies; +}; + +} diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.cpp b/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.cpp new file mode 100644 index 0000000..9d7505b --- /dev/null +++ b/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h> + +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/bind.hpp> + +#include <Swiften/Base/Log.h> +#include <Swiften/Elements/S5BProxyRequest.h> +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Queries/IQRouter.h> + +namespace Swift { + +SOCKS5BytestreamProxyFinder::SOCKS5BytestreamProxyFinder(const JID& service, IQRouter *iqRouter) : service(service), iqRouter(iqRouter) { +} + +SOCKS5BytestreamProxyFinder::~SOCKS5BytestreamProxyFinder() { +} + +void SOCKS5BytestreamProxyFinder::start() { + serviceWalker = boost::make_shared<DiscoServiceWalker>(service, iqRouter); + serviceWalker->onServiceFound.connect(boost::bind(&SOCKS5BytestreamProxyFinder::handleServiceFound, this, _1, _2)); + serviceWalker->beginWalk(); +} + +void SOCKS5BytestreamProxyFinder::stop() { + serviceWalker->endWalk(); + serviceWalker->onServiceFound.disconnect(boost::bind(&SOCKS5BytestreamProxyFinder::handleServiceFound, this, _1, _2)); + serviceWalker.reset(); +} + +void SOCKS5BytestreamProxyFinder::sendBytestreamQuery(const JID& jid) { + S5BProxyRequest::ref proxyRequest = boost::make_shared<S5BProxyRequest>(); + boost::shared_ptr<GenericRequest<S5BProxyRequest> > request = boost::make_shared<GenericRequest<S5BProxyRequest> >(IQ::Get, jid, proxyRequest, iqRouter); + request->onResponse.connect(boost::bind(&SOCKS5BytestreamProxyFinder::handleProxyResponse, this, _1, _2)); + request->send(); +} + +void SOCKS5BytestreamProxyFinder::handleServiceFound(const JID& jid, boost::shared_ptr<DiscoInfo> discoInfo) { + if (discoInfo->hasFeature(DiscoInfo::Bytestream)) { + sendBytestreamQuery(jid); + } +} + +void SOCKS5BytestreamProxyFinder::handleProxyResponse(boost::shared_ptr<S5BProxyRequest> request, ErrorPayload::ref error) { + if (error) { + SWIFT_LOG(debug) << "ERROR" << std::endl; + } else { + if (request) { + onProxyFound(request); + } else { + //assert(false); + } + } +} + +} diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h b/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h new file mode 100644 index 0000000..071e03a --- /dev/null +++ b/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> + +#include <Swiften/Disco/DiscoServiceWalker.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Elements/S5BProxyRequest.h> + +namespace Swift { + +class JID; +class IQRouter; + +class SOCKS5BytestreamProxyFinder { +public: + SOCKS5BytestreamProxyFinder(const JID& service, IQRouter *iqRouter); + ~SOCKS5BytestreamProxyFinder(); + + void start(); + void stop(); + + boost::signal<void(boost::shared_ptr<S5BProxyRequest>)> onProxyFound; + +private: + void sendBytestreamQuery(const JID&); + + void handleServiceFound(const JID&, boost::shared_ptr<DiscoInfo>); + void handleProxyResponse(boost::shared_ptr<S5BProxyRequest>, ErrorPayload::ref); +private: + JID service; + IQRouter* iqRouter; + boost::shared_ptr<DiscoServiceWalker> serviceWalker; + std::vector<boost::shared_ptr<GenericRequest<S5BProxyRequest> > > requests; +}; + +} diff --git a/Swiften/FileTransfer/SOCKS5BytestreamRegistry.cpp b/Swiften/FileTransfer/SOCKS5BytestreamRegistry.cpp index 7f889b1..ffc4298 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamRegistry.cpp +++ b/Swiften/FileTransfer/SOCKS5BytestreamRegistry.cpp @@ -4,29 +4,69 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/FileTransfer/SOCKS5BytestreamRegistry.h" +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> + +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/Algorithm.h> +#include <Swiften/Base/Log.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/StringCodecs/Hexify.h> namespace Swift { SOCKS5BytestreamRegistry::SOCKS5BytestreamRegistry() { } -void SOCKS5BytestreamRegistry::addBytestream(const std::string& destination, boost::shared_ptr<ReadBytestream> byteStream) { - byteStreams[destination] = byteStream; +void SOCKS5BytestreamRegistry::addReadBytestream(const std::string& destination, boost::shared_ptr<ReadBytestream> byteStream) { + readBytestreams[destination] = byteStream; } -void SOCKS5BytestreamRegistry::removeBytestream(const std::string& destination) { - byteStreams.erase(destination); +void SOCKS5BytestreamRegistry::removeReadBytestream(const std::string& destination) { + readBytestreams.erase(destination); } -boost::shared_ptr<ReadBytestream> SOCKS5BytestreamRegistry::getBytestream(const std::string& destination) const { - BytestreamMap::const_iterator i = byteStreams.find(destination); - if (i != byteStreams.end()) { +boost::shared_ptr<ReadBytestream> SOCKS5BytestreamRegistry::getReadBytestream(const std::string& destination) const { + ReadBytestreamMap::const_iterator i = readBytestreams.find(destination); + if (i != readBytestreams.end()) { return i->second; } return boost::shared_ptr<ReadBytestream>(); } +void SOCKS5BytestreamRegistry::addWriteBytestream(const std::string& destination, boost::shared_ptr<WriteBytestream> byteStream) { + writeBytestreams[destination] = byteStream; +} + +void SOCKS5BytestreamRegistry::removeWriteBytestream(const std::string& destination) { + writeBytestreams.erase(destination); +} + +boost::shared_ptr<WriteBytestream> SOCKS5BytestreamRegistry::getWriteBytestream(const std::string& destination) const { + WriteBytestreamMap::const_iterator i = writeBytestreams.find(destination); + if (i != writeBytestreams.end()) { + return i->second; + } + return boost::shared_ptr<WriteBytestream>(); +} + +std::string SOCKS5BytestreamRegistry::generateSessionID() { + return idGenerator.generateID(); +} + +SOCKS5BytestreamServerSession* SOCKS5BytestreamRegistry::getConnectedSession(const std::string& destination) { + if (serverSessions.find(destination) != serverSessions.end()) { + return serverSessions[destination]; + } else { + SWIFT_LOG(debug) << "No active connction for stream ID " << destination << " found!" << std::endl; + return NULL; + } +} + +std::string SOCKS5BytestreamRegistry::getHostname(const std::string& sessionID, const JID& requester, const JID& target) { + return Hexify::hexify(SHA1::getHash(createSafeByteArray(sessionID + requester.toString() + target.toString()))); +} } diff --git a/Swiften/FileTransfer/SOCKS5BytestreamRegistry.h b/Swiften/FileTransfer/SOCKS5BytestreamRegistry.h index 7cee256..779aabb 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamRegistry.h +++ b/Swiften/FileTransfer/SOCKS5BytestreamRegistry.h @@ -7,23 +7,58 @@ #pragma once #include <boost/shared_ptr.hpp> -#include <map> +#include <map> #include <string> -#include "Swiften/FileTransfer/ReadBytestream.h" +#include <vector> +#include <set> + +#include <Swiften/Base/IDGenerator.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/S5BProxyRequest.h> +#include <Swiften/FileTransfer/ReadBytestream.h> +#include <Swiften/FileTransfer/WriteBytestream.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamServerSession.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h> +#include <Swiften/Network/HostAddressPort.h> namespace Swift { class SOCKS5BytestreamRegistry { public: SOCKS5BytestreamRegistry(); - boost::shared_ptr<ReadBytestream> getBytestream(const std::string& destination) const; - void addBytestream(const std::string& destination, boost::shared_ptr<ReadBytestream> byteStream); - void removeBytestream(const std::string& destination); + boost::shared_ptr<ReadBytestream> getReadBytestream(const std::string& destination) const; + void addReadBytestream(const std::string& destination, boost::shared_ptr<ReadBytestream> byteStream); + void removeReadBytestream(const std::string& destination); + + boost::shared_ptr<WriteBytestream> getWriteBytestream(const std::string& destination) const; + void addWriteBytestream(const std::string& destination, boost::shared_ptr<WriteBytestream> byteStream); + void removeWriteBytestream(const std::string& destination); + + /** + * Generate a new session ID to use for new S5B streams. + */ + std::string generateSessionID(); + + /** + * Start an actual transfer. + */ + SOCKS5BytestreamServerSession* getConnectedSession(const std::string& destination); + + public: + static std::string getHostname(const std::string& sessionID, const JID& requester, const JID& target); private: - typedef std::map<std::string, boost::shared_ptr<ReadBytestream> > BytestreamMap; - BytestreamMap byteStreams; + friend class SOCKS5BytestreamServerSession; + + typedef std::map<std::string, boost::shared_ptr<ReadBytestream> > ReadBytestreamMap; + ReadBytestreamMap readBytestreams; + + typedef std::map<std::string, boost::shared_ptr<WriteBytestream> > WriteBytestreamMap; + WriteBytestreamMap writeBytestreams; + + std::map<std::string, SOCKS5BytestreamServerSession*> serverSessions; + + IDGenerator idGenerator; }; } - diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServer.cpp b/Swiften/FileTransfer/SOCKS5BytestreamServer.cpp index 9bc49ae..90fed7a 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamServer.cpp +++ b/Swiften/FileTransfer/SOCKS5BytestreamServer.cpp @@ -4,17 +4,19 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/FileTransfer/SOCKS5BytestreamServer.h" +#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h> #include <boost/bind.hpp> -#include "Swiften/StringCodecs/Hexify.h" -#include "Swiften/StringCodecs/SHA1.h" -#include "Swiften/FileTransfer/SOCKS5BytestreamServerSession.h" +#include <Swiften/Base/Log.h> +#include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamServerSession.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> namespace Swift { -SOCKS5BytestreamServer::SOCKS5BytestreamServer(boost::shared_ptr<ConnectionServer> connectionServer) : connectionServer(connectionServer) { +SOCKS5BytestreamServer::SOCKS5BytestreamServer(boost::shared_ptr<ConnectionServer> connectionServer, SOCKS5BytestreamRegistry* registry) : connectionServer(connectionServer), registry(registry) { } void SOCKS5BytestreamServer::start() { @@ -25,20 +27,20 @@ void SOCKS5BytestreamServer::stop() { connectionServer->onNewConnection.disconnect(boost::bind(&SOCKS5BytestreamServer::handleNewConnection, this, _1)); } -void SOCKS5BytestreamServer::addBytestream(const std::string& id, const JID& from, const JID& to, boost::shared_ptr<ReadBytestream> byteStream) { - bytestreams.addBytestream(getSOCKSDestinationAddress(id, from, to), byteStream); +void SOCKS5BytestreamServer::addReadBytestream(const std::string& id, const JID& from, const JID& to, boost::shared_ptr<ReadBytestream> byteStream) { + registry->addReadBytestream(getSOCKSDestinationAddress(id, from, to), byteStream); } -void SOCKS5BytestreamServer::removeBytestream(const std::string& id, const JID& from, const JID& to) { - bytestreams.removeBytestream(getSOCKSDestinationAddress(id, from, to)); +void SOCKS5BytestreamServer::removeReadBytestream(const std::string& id, const JID& from, const JID& to) { + registry->removeReadBytestream(getSOCKSDestinationAddress(id, from, to)); } std::string SOCKS5BytestreamServer::getSOCKSDestinationAddress(const std::string& id, const JID& from, const JID& to) { - return Hexify::hexify(SHA1::getHash(ByteArray(id + from.toString() + to.toString()))); + return Hexify::hexify(SHA1::getHash(createByteArray(id + from.toString() + to.toString()))); } void SOCKS5BytestreamServer::handleNewConnection(boost::shared_ptr<Connection> connection) { - boost::shared_ptr<SOCKS5BytestreamServerSession> session(new SOCKS5BytestreamServerSession(connection, &bytestreams)); + boost::shared_ptr<SOCKS5BytestreamServerSession> session(new SOCKS5BytestreamServerSession(connection, registry)); sessions.push_back(session); session->start(); } diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServer.h b/Swiften/FileTransfer/SOCKS5BytestreamServer.h index d5a62bb..6bb598e 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamServer.h +++ b/Swiften/FileTransfer/SOCKS5BytestreamServer.h @@ -9,26 +9,26 @@ #include <boost/shared_ptr.hpp> #include <map> -#include "Swiften/Network/ConnectionServer.h" +#include <Swiften/Network/ConnectionServer.h> #include <string> -#include "Swiften/JID/JID.h" -#include "Swiften/FileTransfer/ReadBytestream.h" -#include "Swiften/FileTransfer/SOCKS5BytestreamRegistry.h" +#include <Swiften/JID/JID.h> +#include <Swiften/FileTransfer/ReadBytestream.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> namespace Swift { class SOCKS5BytestreamServerSession; class SOCKS5BytestreamServer { public: - SOCKS5BytestreamServer(boost::shared_ptr<ConnectionServer> connectionServer); + SOCKS5BytestreamServer(boost::shared_ptr<ConnectionServer> connectionServer, SOCKS5BytestreamRegistry* registry); HostAddressPort getAddressPort() const; void start(); void stop(); - void addBytestream(const std::string& id, const JID& from, const JID& to, boost::shared_ptr<ReadBytestream> byteStream); - void removeBytestream(const std::string& id, const JID& from, const JID& to); + void addReadBytestream(const std::string& id, const JID& from, const JID& to, boost::shared_ptr<ReadBytestream> byteStream); + void removeReadBytestream(const std::string& id, const JID& from, const JID& to); /*protected: boost::shared_ptr<ReadBytestream> getBytestream(const std::string& dest);*/ @@ -42,7 +42,7 @@ namespace Swift { friend class SOCKS5BytestreamServerSession; boost::shared_ptr<ConnectionServer> connectionServer; - SOCKS5BytestreamRegistry bytestreams; + SOCKS5BytestreamRegistry* registry; std::vector<boost::shared_ptr<SOCKS5BytestreamServerSession> > sessions; }; } diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp b/Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp index 9951f7a..f660fda 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp +++ b/Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp @@ -4,17 +4,23 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/FileTransfer/SOCKS5BytestreamServerSession.h" +#include <Swiften/FileTransfer/SOCKS5BytestreamServerSession.h> #include <boost/bind.hpp> +#include <iostream> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/FileTransfer/SOCKS5BytestreamRegistry.h" -#include "Swiften/FileTransfer/BytestreamException.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h> +#include <Swiften/Base/Algorithm.h> +#include <Swiften/Base/Concat.h> +#include <Swiften/Base/Log.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> +#include <Swiften/FileTransfer/BytestreamException.h> namespace Swift { -SOCKS5BytestreamServerSession::SOCKS5BytestreamServerSession(boost::shared_ptr<Connection> connection, SOCKS5BytestreamRegistry* bytestreams) : connection(connection), bytestreams(bytestreams), state(Initial), chunkSize(4096) { +SOCKS5BytestreamServerSession::SOCKS5BytestreamServerSession(boost::shared_ptr<Connection> connection, SOCKS5BytestreamRegistry* bytestreams) : connection(connection), bytestreams(bytestreams), state(Initial), chunkSize(131072) { + connection->onDisconnected.connect(boost::bind(&SOCKS5BytestreamServerSession::handleDisconnected, this, _1)); } SOCKS5BytestreamServerSession::~SOCKS5BytestreamServerSession() { @@ -25,68 +31,111 @@ SOCKS5BytestreamServerSession::~SOCKS5BytestreamServerSession() { } void SOCKS5BytestreamServerSession::start() { + SWIFT_LOG(debug) << std::endl; connection->onDataRead.connect(boost::bind(&SOCKS5BytestreamServerSession::handleDataRead, this, _1)); state = WaitingForAuthentication; } void SOCKS5BytestreamServerSession::stop() { - finish(false); + connection->onDataWritten.disconnect(boost::bind(&SOCKS5BytestreamServerSession::sendData, this)); + connection->onDataRead.disconnect(boost::bind(&SOCKS5BytestreamServerSession::handleDataRead, this, _1)); + connection->disconnect(); + state = Finished; +} + +void SOCKS5BytestreamServerSession::startTransfer() { + if (state == ReadyForTransfer) { + if (readBytestream) { + state = WritingData; + connection->onDataWritten.connect(boost::bind(&SOCKS5BytestreamServerSession::sendData, this)); + sendData(); + } + else if(writeBytestream) { + state = ReadingData; + writeBytestream->write(unprocessedData); + onBytesReceived(unprocessedData.size()); + unprocessedData.clear(); + } + } else { + SWIFT_LOG(debug) << "Not ready for transfer!" << std::endl; + } } -void SOCKS5BytestreamServerSession::handleDataRead(const ByteArray& data) { - unprocessedData += data; - process(); +HostAddressPort SOCKS5BytestreamServerSession::getAddressPort() const { + return connection->getLocalAddress(); +} + +void SOCKS5BytestreamServerSession::handleDataRead(boost::shared_ptr<SafeByteArray> data) { + if (state != ReadingData) { + append(unprocessedData, *data); + process(); + } else { + writeBytestream->write(createByteArray(vecptr(*data), data->size())); + onBytesReceived(data->size()); + } +} + +void SOCKS5BytestreamServerSession::handleDisconnected(const boost::optional<Connection::Error>& error) { + SWIFT_LOG(debug) << (error ? (error == Connection::ReadError ? "Read Error" : "Write Error") : "No Error") << std::endl; + if (error) { + finish(true); + } } void SOCKS5BytestreamServerSession::process() { if (state == WaitingForAuthentication) { - if (unprocessedData.getSize() >= 2) { + if (unprocessedData.size() >= 2) { size_t authCount = unprocessedData[1]; size_t i = 2; - while (i < 2 + authCount && i < unprocessedData.getSize()) { + while (i < 2 + authCount && i < unprocessedData.size()) { // Skip authentication mechanism ++i; } if (i == 2 + authCount) { // Authentication message is complete - if (i != unprocessedData.getSize()) { - std::cerr << "SOCKS5BytestreamServerSession: Junk after authentication mechanism"; + if (i != unprocessedData.size()) { + SWIFT_LOG(debug) << "Junk after authentication mechanism" << std::endl; } unprocessedData.clear(); - connection->write(ByteArray("\x05\x00", 2)); + connection->write(createSafeByteArray("\x05\x00", 2)); state = WaitingForRequest; } } } else if (state == WaitingForRequest) { - if (unprocessedData.getSize() >= 5) { + if (unprocessedData.size() >= 5) { ByteArray requestID; size_t i = 5; size_t hostnameSize = unprocessedData[4]; - while (i < 5 + hostnameSize && i < unprocessedData.getSize()) { - requestID += unprocessedData[i]; + while (i < 5 + hostnameSize && i < unprocessedData.size()) { + requestID.push_back(unprocessedData[i]); ++i; } - // Skip the port: + // Skip the port: 2 byte large, one already skipped. Add one for comparison with size i += 2; - if (i >= unprocessedData.getSize()) { - if (i != unprocessedData.getSize()) { - std::cerr << "SOCKS5BytestreamServerSession: Junk after authentication mechanism"; + if (i <= unprocessedData.size()) { + if (i != unprocessedData.size()) { + SWIFT_LOG(debug) << "Junk after authentication mechanism" << std::endl; } - bytestream = bytestreams->getBytestream(requestID.toString()); - ByteArray result("\x05", 1); - result += bytestream ? 0x0 : 0x4; - result += ByteArray("\x00\x03", 2); - result += static_cast<char>(requestID.getSize()); - result += requestID + ByteArray("\x00\x00", 2); - if (!bytestream) { + unprocessedData.clear(); + std::string streamID = byteArrayToString(requestID); + readBytestream = bytestreams->getReadBytestream(streamID); + writeBytestream = bytestreams->getWriteBytestream(streamID); + SafeByteArray result = createSafeByteArray("\x05", 1); + result.push_back((readBytestream || writeBytestream) ? 0x0 : 0x4); + append(result, createByteArray("\x00\x03", 2)); + result.push_back(static_cast<char>(requestID.size())); + append(result, concat(requestID, createByteArray("\x00\x00", 2))); + if (!readBytestream && !writeBytestream) { + SWIFT_LOG(debug) << "Readstream or Wrtiestream with ID " << streamID << " not found!" << std::endl; connection->write(result); finish(true); } else { - state = SendingData; - connection->onDataWritten.connect(boost::bind(&SOCKS5BytestreamServerSession::sendData, this)); + SWIFT_LOG(deubg) << "Found " << (readBytestream ? "Readstream" : "Writestream") << ". Sent OK." << std::endl; connection->write(result); + bytestreams->serverSessions[streamID] = this; + state = ReadyForTransfer; } } } @@ -94,11 +143,13 @@ void SOCKS5BytestreamServerSession::process() { } void SOCKS5BytestreamServerSession::sendData() { - if (!bytestream->isFinished()) { + if (!readBytestream->isFinished()) { try { - connection->write(bytestream->read(chunkSize)); + SafeByteArray dataToSend = createSafeByteArray(*readBytestream->read(chunkSize)); + connection->write(dataToSend); + onBytesSent(dataToSend.size()); } - catch (const BytestreamException& e) { + catch (const BytestreamException&) { finish(true); } } @@ -110,9 +161,14 @@ void SOCKS5BytestreamServerSession::sendData() { void SOCKS5BytestreamServerSession::finish(bool error) { connection->onDataWritten.disconnect(boost::bind(&SOCKS5BytestreamServerSession::sendData, this)); connection->onDataRead.disconnect(boost::bind(&SOCKS5BytestreamServerSession::handleDataRead, this, _1)); - bytestream.reset(); + connection->onDisconnected.disconnect(boost::bind(&SOCKS5BytestreamServerSession::handleDisconnected, this, _1)); + readBytestream.reset(); state = Finished; - onFinished(error); + if (error) { + onFinished(boost::optional<FileTransferError>(FileTransferError::PeerError)); + } else { + onFinished(boost::optional<FileTransferError>()); + } } } diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerSession.h b/Swiften/FileTransfer/SOCKS5BytestreamServerSession.h index f430f5d..4557a36 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamServerSession.h +++ b/Swiften/FileTransfer/SOCKS5BytestreamServerSession.h @@ -8,20 +8,27 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/Network/Connection.h" -#include "Swiften/FileTransfer/ReadBytestream.h" +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Network/Connection.h> +#include <Swiften/FileTransfer/ReadBytestream.h> +#include <Swiften/FileTransfer/WriteBytestream.h> +#include <Swiften/FileTransfer/FileTransferError.h> namespace Swift { class SOCKS5BytestreamRegistry; class SOCKS5BytestreamServerSession { public: + typedef boost::shared_ptr<SOCKS5BytestreamServerSession> ref; + + public: enum State { Initial, WaitingForAuthentication, WaitingForRequest, - SendingData, + ReadyForTransfer, + ReadingData, + WritingData, Finished, }; @@ -35,12 +42,18 @@ namespace Swift { void start(); void stop(); - boost::signal<void (bool /* error */)> onFinished; + void startTransfer(); + HostAddressPort getAddressPort() const; + + boost::signal<void (boost::optional<FileTransferError>)> onFinished; + boost::signal<void (int)> onBytesSent; + boost::signal<void (int)> onBytesReceived; private: void finish(bool error); void process(); - void handleDataRead(const ByteArray&); + void handleDataRead(boost::shared_ptr<SafeByteArray>); + void handleDisconnected(const boost::optional<Connection::Error>&); void sendData(); private: @@ -49,6 +62,7 @@ namespace Swift { ByteArray unprocessedData; State state; int chunkSize; - boost::shared_ptr<ReadBytestream> bytestream; + boost::shared_ptr<ReadBytestream> readBytestream; + boost::shared_ptr<WriteBytestream> writeBytestream; }; } diff --git a/Swiften/FileTransfer/StreamInitiationRequest.h b/Swiften/FileTransfer/StreamInitiationRequest.h index f516d4b..658a8a9 100644 --- a/Swiften/FileTransfer/StreamInitiationRequest.h +++ b/Swiften/FileTransfer/StreamInitiationRequest.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Queries/GenericRequest.h" -#include "Swiften/Elements/StreamInitiation.h" +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Elements/StreamInitiation.h> namespace Swift { @@ -19,8 +19,15 @@ namespace Swift { return ref(new StreamInitiationRequest(jid, payload, router)); } + static ref create(const JID& from, const JID& to, boost::shared_ptr<StreamInitiation> payload, IQRouter* router) { + return ref(new StreamInitiationRequest(from, to, payload, router)); + } + private: StreamInitiationRequest(const JID& jid, boost::shared_ptr<StreamInitiation> payload, IQRouter* router) : GenericRequest<StreamInitiation>(IQ::Set, jid, payload, router) { } + + StreamInitiationRequest(const JID& from, const JID& to, boost::shared_ptr<StreamInitiation> payload, IQRouter* router) : GenericRequest<StreamInitiation>(IQ::Set, from, to, payload, router) { + } }; } diff --git a/Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h b/Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h new file mode 100644 index 0000000..ae06cd3 --- /dev/null +++ b/Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <string> +#include <boost/filesystem.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> + +#include <Swiften/FileTransfer/FileTransferManager.h> + +namespace Swift { + class DummyFileTransferManager : public FileTransferManager { + public: + DummyFileTransferManager() : FileTransferManager() { + } + + virtual OutgoingFileTransfer::ref createOutgoingFileTransfer(const JID&, const boost::filesystem::path&, const std::string&, boost::shared_ptr<ReadBytestream>) { + return OutgoingFileTransfer::ref(); + } + + virtual OutgoingFileTransfer::ref createOutgoingFileTransfer(const JID&, const std::string&, const std::string&, const boost::uintmax_t, const boost::posix_time::ptime&, boost::shared_ptr<ReadBytestream>) { + return OutgoingFileTransfer::ref(); + } + + virtual void startListeningOnPort(int) { + } + + virtual void addS5BProxy(boost::shared_ptr<S5BProxyRequest>) { + } + + }; +} diff --git a/Swiften/FileTransfer/UnitTest/IBBReceiveSessionTest.cpp b/Swiften/FileTransfer/UnitTest/IBBReceiveSessionTest.cpp new file mode 100644 index 0000000..c62636d --- /dev/null +++ b/Swiften/FileTransfer/UnitTest/IBBReceiveSessionTest.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <vector> +#include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/FileTransfer/IBBReceiveSession.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Client/DummyStanzaChannel.h> + +using namespace Swift; + +class IBBReceiveSessionTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(IBBReceiveSessionTest); + CPPUNIT_TEST(testOpen); + CPPUNIT_TEST(testReceiveData); + CPPUNIT_TEST(testReceiveMultipleData); + CPPUNIT_TEST(testReceiveDataForOtherSession); + CPPUNIT_TEST(testReceiveDataOutOfOrder); + CPPUNIT_TEST(testReceiveLastData); + CPPUNIT_TEST(testReceiveClose); + CPPUNIT_TEST(testStopWhileActive); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + stanzaChannel = new DummyStanzaChannel(); + iqRouter = new IQRouter(stanzaChannel); + finished = false; + } + + void tearDown() { + delete iqRouter; + delete stanzaChannel; + } + + void testOpen() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + + CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(0, "id-open")); + CPPUNIT_ASSERT(!finished); + + testling->stop(); + } + + void testReceiveData() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, createByteArray("abc")), "foo@bar.com/baz", "id-a")); + + CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(1, "id-a")); + CPPUNIT_ASSERT(createByteArray("abc") == receivedData); + CPPUNIT_ASSERT(!finished); + + testling->stop(); + } + + void testReceiveMultipleData() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, createByteArray("abc")), "foo@bar.com/baz", "id-a")); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 1, createByteArray("def")), "foo@bar.com/baz", "id-b")); + + CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(2, "id-b")); + CPPUNIT_ASSERT(createByteArray("abcdef") == receivedData); + CPPUNIT_ASSERT(!finished); + + testling->stop(); + } + + void testReceiveDataForOtherSession() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("othersession", 0, createByteArray("abc")), "foo@bar.com/baz", "id-a")); + + CPPUNIT_ASSERT(stanzaChannel->isErrorAtIndex(1, "id-a")); + + testling->stop(); + } + + void testReceiveDataOutOfOrder() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, createByteArray("abc")), "foo@bar.com/baz", "id-a")); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, createByteArray("def")), "foo@bar.com/baz", "id-b")); + + CPPUNIT_ASSERT(stanzaChannel->isErrorAtIndex(2, "id-b")); + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(error); + + testling->stop(); + } + + void testReceiveLastData() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession", 6)); + testling->start(); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, createByteArray("abc")), "foo@bar.com/baz", "id-a")); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 1, createByteArray("def")), "foo@bar.com/baz", "id-b")); + + CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(2, "id-b")); + CPPUNIT_ASSERT(createByteArray("abcdef") == receivedData); + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(!error); + + testling->stop(); + } + + void testReceiveClose() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBClose("mysession"), "foo@bar.com/baz", "id-close")); + + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(error); + + testling->stop(); + } + + void testStopWhileActive() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + + testling->stop(); + + CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(1, JID("foo@bar.com/baz"), IQ::Set)); + IBB::ref ibb = stanzaChannel->sentStanzas[1]->getPayload<IBB>(); + CPPUNIT_ASSERT_EQUAL(IBB::Close, ibb->getAction()); + CPPUNIT_ASSERT_EQUAL(std::string("mysession"), ibb->getStreamID()); + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(!error); + } + + private: + IQ::ref createIBBRequest(IBB::ref ibb, const JID& from, const std::string& id) { + IQ::ref request = IQ::createRequest(IQ::Set, JID("baz@fum.com/dum"), id, ibb); + request->setFrom(from); + return request; + } + + IBBReceiveSession* createSession(const std::string& from, const std::string& id, size_t size = 0x1000) { + IBBReceiveSession* session = new IBBReceiveSession(id, JID(from), JID(), size, iqRouter); + session->onDataReceived.connect(boost::bind(&IBBReceiveSessionTest::handleDataReceived, this, _1)); + session->onFinished.connect(boost::bind(&IBBReceiveSessionTest::handleFinished, this, _1)); + return session; + } + + + void handleFinished(boost::optional<FileTransferError> error) { + finished = true; + this->error = error; + } + + void handleDataReceived(const std::vector<unsigned char>& data) { + receivedData.insert(receivedData.end(), data.begin(), data.end()); + } + + private: + DummyStanzaChannel* stanzaChannel; + IQRouter* iqRouter; + bool finished; + boost::optional<FileTransferError> error; + std::vector<unsigned char> receivedData; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(IBBReceiveSessionTest); diff --git a/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp b/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp index e89ef93..d12f99e 100644 --- a/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp +++ b/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp @@ -4,17 +4,16 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" - #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <vector> #include <boost/bind.hpp> -#include "Swiften/FileTransfer/IBBSendSession.h" -#include "Swiften/FileTransfer/ByteArrayReadBytestream.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Client/DummyStanzaChannel.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/FileTransfer/IBBSendSession.h> +#include <Swiften/FileTransfer/ByteArrayReadBytestream.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Client/DummyStanzaChannel.h> using namespace Swift; @@ -27,13 +26,19 @@ class IBBSendSessionTest : public CppUnit::TestFixture { CPPUNIT_TEST(testErrorResponseFinishesWithError); CPPUNIT_TEST(testStopDuringSessionCloses); CPPUNIT_TEST(testStopAfterFinishedDoesNotClose); + CPPUNIT_TEST(testDataStreamPauseStopsSendingData); + CPPUNIT_TEST(testDataStreamResumeAfterPauseSendsData); + CPPUNIT_TEST(testDataStreamResumeBeforePauseDoesNotSendData); + CPPUNIT_TEST(testDataStreamResumeAfterResumeDoesNotSendData); + CPPUNIT_TEST_SUITE_END(); public: void setUp() { stanzaChannel = new DummyStanzaChannel(); iqRouter = new IQRouter(stanzaChannel); - bytestream = boost::shared_ptr<ByteArrayReadBytestream>(new ByteArrayReadBytestream(ByteArray("abcdefg"))); + bytestream = boost::shared_ptr<ByteArrayReadBytestream>(new ByteArrayReadBytestream(createByteArray("abcdefg"))); + finished = false; } void tearDown() { @@ -42,7 +47,7 @@ class IBBSendSessionTest : public CppUnit::TestFixture { } void testStart() { - std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); testling->setBlockSize(1234); testling->start(); @@ -56,7 +61,7 @@ class IBBSendSessionTest : public CppUnit::TestFixture { } void testStart_ResponseStartsSending() { - std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); testling->setBlockSize(3); testling->start(); @@ -66,13 +71,13 @@ class IBBSendSessionTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(1, JID("foo@bar.com/baz"), IQ::Set)); IBB::ref ibb = stanzaChannel->sentStanzas[1]->getPayload<IBB>(); CPPUNIT_ASSERT_EQUAL(IBB::Data, ibb->getAction()); - CPPUNIT_ASSERT_EQUAL(ByteArray("abc"), ibb->getData()); + CPPUNIT_ASSERT(createByteArray("abc") == ibb->getData()); CPPUNIT_ASSERT_EQUAL(0, ibb->getSequenceNumber()); CPPUNIT_ASSERT_EQUAL(std::string("myid"), ibb->getStreamID()); } void testResponseContinuesSending() { - std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); testling->setBlockSize(3); testling->start(); stanzaChannel->onIQReceived(createIBBResult()); @@ -82,13 +87,13 @@ class IBBSendSessionTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(2, JID("foo@bar.com/baz"), IQ::Set)); IBB::ref ibb = stanzaChannel->sentStanzas[2]->getPayload<IBB>(); CPPUNIT_ASSERT_EQUAL(IBB::Data, ibb->getAction()); - CPPUNIT_ASSERT_EQUAL(ByteArray("def"), ibb->getData()); + CPPUNIT_ASSERT(createByteArray("def") == ibb->getData()); CPPUNIT_ASSERT_EQUAL(1, ibb->getSequenceNumber()); CPPUNIT_ASSERT_EQUAL(std::string("myid"), ibb->getStreamID()); } void testRespondToAllFinishes() { - std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); testling->setBlockSize(3); testling->start(); stanzaChannel->onIQReceived(createIBBResult()); @@ -101,7 +106,7 @@ class IBBSendSessionTest : public CppUnit::TestFixture { } void testErrorResponseFinishesWithError() { - std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); testling->setBlockSize(3); testling->start(); stanzaChannel->onIQReceived(IQ::createError(JID("baz@fum.com/foo"), stanzaChannel->sentStanzas[0]->getTo(), stanzaChannel->sentStanzas[0]->getID())); @@ -111,7 +116,7 @@ class IBBSendSessionTest : public CppUnit::TestFixture { } void testStopDuringSessionCloses() { - std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); testling->setBlockSize(3); testling->start(); testling->stop(); @@ -126,7 +131,7 @@ class IBBSendSessionTest : public CppUnit::TestFixture { } void testStopAfterFinishedDoesNotClose() { - std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); testling->setBlockSize(16); testling->start(); stanzaChannel->onIQReceived(createIBBResult()); @@ -137,15 +142,74 @@ class IBBSendSessionTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); } - + + void testDataStreamPauseStopsSendingData() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + bytestream->setDataComplete(false); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + + CPPUNIT_ASSERT(!finished); + CPPUNIT_ASSERT(!error); + + CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(stanzaChannel->sentStanzas.size())); + } + + void testDataStreamResumeAfterPauseSendsData() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + bytestream->setDataComplete(false); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + + bytestream->addData(createByteArray("xyz")); + + CPPUNIT_ASSERT_EQUAL(5, static_cast<int>(stanzaChannel->sentStanzas.size())); + } + + void testDataStreamResumeBeforePauseDoesNotSendData() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + bytestream->setDataComplete(false); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + + bytestream->addData(createByteArray("xyz")); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); + } + + void testDataStreamResumeAfterResumeDoesNotSendData() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + bytestream->setDataComplete(false); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + + bytestream->addData(createByteArray("xyz")); + bytestream->addData(createByteArray("xuv")); + + CPPUNIT_ASSERT_EQUAL(5, static_cast<int>(stanzaChannel->sentStanzas.size())); + } + private: IQ::ref createIBBResult() { return IQ::createResult(JID("baz@fum.com/dum"), stanzaChannel->sentStanzas[stanzaChannel->sentStanzas.size()-1]->getTo(), stanzaChannel->sentStanzas[stanzaChannel->sentStanzas.size()-1]->getID(), boost::shared_ptr<IBB>()); } private: - std::auto_ptr<IBBSendSession> createSession(const std::string& to) { - std::auto_ptr<IBBSendSession> session(new IBBSendSession("myid", JID(to), bytestream, iqRouter)); + boost::shared_ptr<IBBSendSession> createSession(const std::string& to) { + boost::shared_ptr<IBBSendSession> session(new IBBSendSession("myid", JID(), JID(to), bytestream, iqRouter)); session->onFinished.connect(boost::bind(&IBBSendSessionTest::handleFinished, this, _1)); return session; } diff --git a/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp b/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp new file mode 100644 index 0000000..4c6ae72 --- /dev/null +++ b/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/Log.h> +#include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/Elements/IBB.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/FileTransfer/ByteArrayWriteBytestream.h> +#include <Swiften/FileTransfer/IncomingJingleFileTransfer.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h> +#include <Swiften/Jingle/FakeJingleSession.h> +#include <Swiften/Network/DummyTimerFactory.h> +#include <Swiften/EventLoop/DummyEventLoop.h> +#include <Swiften/Network/DummyConnectionFactory.h> +#include <Swiften/Network/PlatformNATTraversalWorker.h> +#include <Swiften/Queries/IQRouter.h> + +#include <iostream> + +using namespace Swift; +using namespace boost; + +class FakeRemoteJingleTransportCandidateSelector : public RemoteJingleTransportCandidateSelector { + void addRemoteTransportCandidates(JingleTransportPayload::ref cand) { + candidate = cand; + } + + void selectCandidate() { + boost::shared_ptr<JingleS5BTransportPayload> payload = make_shared<JingleS5BTransportPayload>(); + payload->setCandidateError(true); + payload->setSessionID(candidate->getSessionID()); + onRemoteTransportCandidateSelectFinished(payload); + } + + void setMinimumPriority(int) { + + } + + bool isActualCandidate(JingleTransportPayload::ref) { + return false; + } + + int getPriority(JingleTransportPayload::ref) { + return 0; + } + + JingleTransport::ref selectTransport(JingleTransportPayload::ref) { + return JingleTransport::ref(); + } + +private: + JingleTransportPayload::ref candidate; +}; + +class FakeRemoteJingleTransportCandidateSelectorFactory : public RemoteJingleTransportCandidateSelectorFactory { +public: + virtual ~FakeRemoteJingleTransportCandidateSelectorFactory() { + + } + + virtual RemoteJingleTransportCandidateSelector* createCandidateSelector() { + return new FakeRemoteJingleTransportCandidateSelector(); + } +}; + +class FakeLocalJingleTransportCandidateGenerator : public LocalJingleTransportCandidateGenerator { +public: + virtual void generateLocalTransportCandidates(JingleTransportPayload::ref payload) { + JingleS5BTransportPayload::ref payL = make_shared<JingleS5BTransportPayload>(); + payL->setSessionID(payload->getSessionID()); + onLocalTransportCandidatesGenerated(payL); + } + + void emitonLocalTransportCandidatesGenerated(JingleTransportPayload::ref payload) { + onLocalTransportCandidatesGenerated(payload); + } + + virtual bool isActualCandidate(JingleTransportPayload::ref) { + return false; + } + + virtual int getPriority(JingleTransportPayload::ref) { + return 0; + } + + virtual JingleTransport::ref selectTransport(JingleTransportPayload::ref) { + return JingleTransport::ref(); + } +}; + +class FakeLocalJingleTransportCandidateGeneratorFactory : public LocalJingleTransportCandidateGeneratorFactory { +public: + virtual LocalJingleTransportCandidateGenerator* createCandidateGenerator() { + return new FakeLocalJingleTransportCandidateGenerator(); + } +}; + +class IncomingJingleFileTransferTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(IncomingJingleFileTransferTest); + CPPUNIT_TEST(test_AcceptOnyIBBSendsSessionAccept); + CPPUNIT_TEST(test_OnlyIBBTransferReceiveWorks); + CPPUNIT_TEST(test_AcceptFailingS5BFallsBackToIBB); + CPPUNIT_TEST_SUITE_END(); +public: + shared_ptr<IncomingJingleFileTransfer> createTestling() { + JID ourJID("our@jid.org/full"); + return make_shared<IncomingJingleFileTransfer>(ourJID, shared_ptr<JingleSession>(fakeJingleSession), jingleContentPayload, fakeRJTCSF.get(), fakeLJTCF.get(), iqRouter, bytestreamRegistry, bytestreamProxy, timerFactory); + } + + IQ::ref createIBBRequest(IBB::ref ibb, const JID& from, const std::string& id) { + IQ::ref request = IQ::createRequest(IQ::Set, JID("foo@bar.com/baz"), id, ibb); + request->setFrom(from); + return request; + } + + void setUp() { + eventLoop = new DummyEventLoop(); + fakeJingleSession = new FakeJingleSession("foo@bar.com/baz", "mysession"); + jingleContentPayload = make_shared<JingleContentPayload>(); + fakeRJTCSF = make_shared<FakeRemoteJingleTransportCandidateSelectorFactory>(); + fakeLJTCF = make_shared<FakeLocalJingleTransportCandidateGeneratorFactory>(); + stanzaChannel = new DummyStanzaChannel(); + iqRouter = new IQRouter(stanzaChannel); + bytestreamRegistry = new SOCKS5BytestreamRegistry(); + timerFactory = new DummyTimerFactory(); + connectionFactory = new DummyConnectionFactory(eventLoop); + bytestreamProxy = new SOCKS5BytestreamProxy(connectionFactory, timerFactory); + } + + void tearDown() { + delete bytestreamProxy; + delete connectionFactory; + delete timerFactory; + delete bytestreamRegistry; + delete iqRouter; + delete stanzaChannel; + delete eventLoop; + } + + // Tests whether IncomingJingleFileTransfer would accept a IBB only file transfer. + void test_AcceptOnyIBBSendsSessionAccept() { + //1. create your test incoming file transfer + shared_ptr<JingleFileTransferDescription> desc = make_shared<JingleFileTransferDescription>(); + desc->addOffer(StreamInitiationFileInfo("foo.txt", "", 10)); + jingleContentPayload->addDescription(desc); + JingleIBBTransportPayload::ref tpRef = make_shared<JingleIBBTransportPayload>(); + tpRef->setSessionID("mysession"); + jingleContentPayload->addTransport(tpRef); + + shared_ptr<IncomingJingleFileTransfer> fileTransfer = createTestling(); + + //2. do 'accept' on a dummy writebytestream (you'll have to look if there already is one) + shared_ptr<ByteArrayWriteBytestream> byteStream = make_shared<ByteArrayWriteBytestream>(); + fileTransfer->accept(byteStream); + + // check whether accept has been called + getCall<FakeJingleSession::AcceptCall>(0); + } + + void test_OnlyIBBTransferReceiveWorks() { + //1. create your test incoming file transfer + shared_ptr<JingleFileTransferDescription> desc = make_shared<JingleFileTransferDescription>(); + desc->addOffer(StreamInitiationFileInfo("file.txt", "", 10)); + jingleContentPayload->addDescription(desc); + JingleIBBTransportPayload::ref tpRef = make_shared<JingleIBBTransportPayload>(); + tpRef->setSessionID("mysession"); + jingleContentPayload->addTransport(tpRef); + + shared_ptr<IncomingJingleFileTransfer> fileTransfer = createTestling(); + + //2. do 'accept' on a dummy writebytestream (you'll have to look if there already is one) + shared_ptr<ByteArrayWriteBytestream> byteStream = make_shared<ByteArrayWriteBytestream>(); + fileTransfer->accept(byteStream); + + // check whether accept has been called + getCall<FakeJingleSession::AcceptCall>(0); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, createByteArray("abc")), "foo@bar.com/baz", "id-a")); + CPPUNIT_ASSERT(createByteArray("abc") == byteStream->getData()); + } + + void test_AcceptFailingS5BFallsBackToIBB() { + //1. create your test incoming file transfer + addFileTransferDescription(); + + // add SOCKS5BytestreamTransportPayload + JingleS5BTransportPayload::ref payLoad = addJingleS5BPayload(); + + shared_ptr<IncomingJingleFileTransfer> fileTransfer = createTestling(); + + //2. do 'accept' on a dummy writebytestream (you'll have to look if there already is one) + shared_ptr<ByteArrayWriteBytestream> byteStream = make_shared<ByteArrayWriteBytestream>(); + fileTransfer->accept(byteStream); + + // check whether accept has been called + FakeJingleSession::AcceptCall acceptCall = getCall<FakeJingleSession::AcceptCall>(0); + CPPUNIT_ASSERT_EQUAL(payLoad->getSessionID(), acceptCall.payload->getSessionID()); + + // check for candidate error + FakeJingleSession::InfoTransportCall infoTransportCall = getCall<FakeJingleSession::InfoTransportCall>(1); + JingleS5BTransportPayload::ref s5bPayload = dynamic_pointer_cast<JingleS5BTransportPayload>(infoTransportCall.payload); + CPPUNIT_ASSERT(s5bPayload->hasCandidateError()); + + // indicate transport replace (Romeo) + fakeJingleSession->onTransportReplaceReceived(getContentID(), addJingleIBBPayload()); + + FakeJingleSession::AcceptTransportCall acceptTransportCall = getCall<FakeJingleSession::AcceptTransportCall>(2); + + // send a bit of data + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, createByteArray("abc")), "foo@bar.com/baz", "id-a")); + CPPUNIT_ASSERT(createByteArray("abc") == byteStream->getData()); + } + + void test_S5BTransferReceiveTest() { + addFileTransferDescription(); + JingleS5BTransportPayload::ref payLoad = addJingleS5BPayload(); + } + +private: + void addFileTransferDescription() { + shared_ptr<JingleFileTransferDescription> desc = make_shared<JingleFileTransferDescription>(); + desc->addOffer(StreamInitiationFileInfo("file.txt", "", 10)); + jingleContentPayload->addDescription(desc); + } + + shared_ptr<JingleS5BTransportPayload> addJingleS5BPayload() { + JingleS5BTransportPayload::ref payLoad = make_shared<JingleS5BTransportPayload>(); + payLoad->setSessionID("mysession"); + jingleContentPayload->addTransport(payLoad); + return payLoad; + } + + shared_ptr<JingleIBBTransportPayload> addJingleIBBPayload() { + JingleIBBTransportPayload::ref payLoad = make_shared<JingleIBBTransportPayload>(); + payLoad->setSessionID("mysession"); + jingleContentPayload->addTransport(payLoad); + return payLoad; + } + + JingleContentID getContentID() const { + return JingleContentID(jingleContentPayload->getName(), jingleContentPayload->getCreator()); + } + + template <typename T> T getCall(int i) const { + size_t index = static_cast<size_t>(i); + CPPUNIT_ASSERT(index < fakeJingleSession->calledCommands.size()); + T* cmd = boost::get<T>(&fakeJingleSession->calledCommands[index]); + CPPUNIT_ASSERT(cmd); + return *cmd; + } + +private: + EventLoop* eventLoop; + FakeJingleSession* fakeJingleSession; + shared_ptr<JingleContentPayload> jingleContentPayload; + shared_ptr<FakeRemoteJingleTransportCandidateSelectorFactory> fakeRJTCSF; + shared_ptr<FakeLocalJingleTransportCandidateGeneratorFactory> fakeLJTCF; + DummyStanzaChannel* stanzaChannel; + IQRouter* iqRouter; + SOCKS5BytestreamRegistry* bytestreamRegistry; + DummyConnectionFactory* connectionFactory; + SOCKS5BytestreamProxy* bytestreamProxy; + DummyTimerFactory* timerFactory; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(IncomingJingleFileTransferTest); diff --git a/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp b/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp new file mode 100644 index 0000000..0c324bf --- /dev/null +++ b/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <boost/bind.hpp> +#include <boost/optional.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/FileTransfer/OutgoingJingleFileTransfer.h> +#include <Swiften/Jingle/FakeJingleSession.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/FileTransfer/ByteArrayReadBytestream.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h> + +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/Elements/JingleFileTransferDescription.h> +#include <Swiften/Elements/IBB.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/IDGenerator.h> +#include <Swiften/EventLoop/DummyEventLoop.h> +#include <Swiften/Network/PlatformNATTraversalWorker.h> +#include <Swiften/Network/DummyTimerFactory.h> +#include <Swiften/Network/DummyConnection.h> +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/DummyConnectionFactory.h> + +#include <Swiften/Base/Log.h> + +#include <iostream> + +using namespace Swift; + +class OFakeRemoteJingleTransportCandidateSelector : public RemoteJingleTransportCandidateSelector { + void addRemoteTransportCandidates(JingleTransportPayload::ref cand) { + candidate = cand; + } + + void selectCandidate() { + JingleS5BTransportPayload::ref payload = boost::make_shared<JingleS5BTransportPayload>(); + payload->setCandidateError(true); + payload->setSessionID(candidate->getSessionID()); + onRemoteTransportCandidateSelectFinished(payload); + } + + void setMinimumPriority(int) { + + } + + bool isActualCandidate(JingleTransportPayload::ref) { + return false; + } + + int getPriority(JingleTransportPayload::ref) { + return 0; + } + + JingleTransport::ref selectTransport(JingleTransportPayload::ref) { + return JingleTransport::ref(); + } + +private: + JingleTransportPayload::ref candidate; +}; + +class OFakeRemoteJingleTransportCandidateSelectorFactory : public RemoteJingleTransportCandidateSelectorFactory { +public: + virtual ~OFakeRemoteJingleTransportCandidateSelectorFactory() { + + } + + virtual RemoteJingleTransportCandidateSelector* createCandidateSelector() { + return new OFakeRemoteJingleTransportCandidateSelector(); + } +}; + +class OFakeLocalJingleTransportCandidateGenerator : public LocalJingleTransportCandidateGenerator { +public: + virtual void generateLocalTransportCandidates(JingleTransportPayload::ref /* payload */) { + //JingleTransportPayload::ref payL = make_shared<JingleTransportPayload>(); + //payL->setSessionID(payload->getSessionID()); + JingleS5BTransportPayload::ref payL = boost::make_shared<JingleS5BTransportPayload>(); + + onLocalTransportCandidatesGenerated(payL); + } + + void emitonLocalTransportCandidatesGenerated(JingleTransportPayload::ref payload) { + onLocalTransportCandidatesGenerated(payload); + } + + virtual bool isActualCandidate(JingleTransportPayload::ref) { + return false; + } + + virtual int getPriority(JingleTransportPayload::ref) { + return 0; + } + + virtual JingleTransport::ref selectTransport(JingleTransportPayload::ref) { + return JingleTransport::ref(); + } +}; + +class OFakeLocalJingleTransportCandidateGeneratorFactory : public LocalJingleTransportCandidateGeneratorFactory { +public: + virtual LocalJingleTransportCandidateGenerator* createCandidateGenerator() { + return new OFakeLocalJingleTransportCandidateGenerator(); + } +}; + +class OutgoingJingleFileTransferTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(OutgoingJingleFileTransferTest); + CPPUNIT_TEST(test_SendSessionInitiateOnStart); + CPPUNIT_TEST(test_IBBStartsAfterSendingSessionAccept); + CPPUNIT_TEST(test_ReceiveSessionTerminateAfterSessionInitiate); + CPPUNIT_TEST_SUITE_END(); + + class FTStatusHelper { + public: + bool finishedCalled; + FileTransferError::Type error; + void handleFileTransferFinished(boost::optional<FileTransferError> error) { + finishedCalled = true; + if (error.is_initialized()) this->error = error.get().getType(); + } + }; +public: + + boost::shared_ptr<OutgoingJingleFileTransfer> createTestling() { + JID to("test@foo.com/bla"); + StreamInitiationFileInfo fileInfo; + fileInfo.setDescription("some file"); + fileInfo.setName("test.bin"); + fileInfo.setHash("asdjasdas"); + fileInfo.setSize(1024 * 1024); + return boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(boost::shared_ptr<JingleSession>(fakeJingleSession), fakeRJTCSF.get(), fakeLJTCF.get(), iqRouter, idGen, JID(), to, stream, fileInfo, s5bRegistry, s5bProxy)); + } + + IQ::ref createIBBRequest(IBB::ref ibb, const JID& from, const std::string& id) { + IQ::ref request = IQ::createRequest(IQ::Set, JID("foo@bar.com/baz"), id, ibb); + request->setFrom(from); + return request; + } + + void setUp() { + fakeJingleSession = new FakeJingleSession("foo@bar.com/baz", "mysession"); + jingleContentPayload = boost::make_shared<JingleContentPayload>(); + fakeRJTCSF = boost::make_shared<OFakeRemoteJingleTransportCandidateSelectorFactory>(); + fakeLJTCF = boost::make_shared<OFakeLocalJingleTransportCandidateGeneratorFactory>(); + stanzaChannel = new DummyStanzaChannel(); + iqRouter = new IQRouter(stanzaChannel); + eventLoop = new DummyEventLoop(); + timerFactory = new DummyTimerFactory(); + connectionFactory = new DummyConnectionFactory(eventLoop); + s5bRegistry = new SOCKS5BytestreamRegistry(); + s5bProxy = new SOCKS5BytestreamProxy(connectionFactory, timerFactory); + + data.clear(); + for (int n=0; n < 1024 * 1024; ++n) { + data.push_back(34); + } + + stream = boost::make_shared<ByteArrayReadBytestream>(data); + + idGen = new IDGenerator(); + } + + void tearDown() { + delete idGen; + delete s5bRegistry; + delete connectionFactory; + delete timerFactory; + delete eventLoop; + delete iqRouter; + delete stanzaChannel; + } + + + void test_SendSessionInitiateOnStart() { + boost::shared_ptr<OutgoingJingleFileTransfer> transfer = createTestling(); + transfer->start(); + FakeJingleSession::InitiateCall call = getCall<FakeJingleSession::InitiateCall>(0); + JingleFileTransferDescription::ref description = boost::dynamic_pointer_cast<JingleFileTransferDescription>(call.description); + CPPUNIT_ASSERT(description); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), description->getOffers().size()); + CPPUNIT_ASSERT(static_cast<size_t>(1048576) == description->getOffers()[0].getSize()); + + JingleS5BTransportPayload::ref transport = boost::dynamic_pointer_cast<JingleS5BTransportPayload>(call.payload); + CPPUNIT_ASSERT(transport); + } + + void test_IBBStartsAfterSendingSessionAccept() { + boost::shared_ptr<OutgoingJingleFileTransfer> transfer = createTestling(); + transfer->start(); + + FakeJingleSession::InitiateCall call = getCall<FakeJingleSession::InitiateCall>(0); + // FIXME: we initiate with SOCSK5 now and not IBB, needs to be fixed. + /* + fakeJingleSession->onSessionAcceptReceived(call.id, call.description, call.payload); + IQ::ref iqOpenStanza = stanzaChannel->getStanzaAtIndex<IQ>(0); + CPPUNIT_ASSERT(iqOpenStanza); + */ + } + + void test_ReceiveSessionTerminateAfterSessionInitiate() { + boost::shared_ptr<OutgoingJingleFileTransfer> transfer = createTestling(); + transfer->start(); + + getCall<FakeJingleSession::InitiateCall>(0); + + FTStatusHelper helper; + helper.finishedCalled = false; + transfer->onFinished.connect(bind(&FTStatusHelper::handleFileTransferFinished, &helper, _1)); + fakeJingleSession->onSessionTerminateReceived(JinglePayload::Reason(JinglePayload::Reason::Busy)); + CPPUNIT_ASSERT_EQUAL(true, helper.finishedCalled); + CPPUNIT_ASSERT(FileTransferError::PeerError == helper.error); + } + + +//TODO: some more testcases + +private: + void addFileTransferDescription() { + boost::shared_ptr<JingleFileTransferDescription> desc = boost::make_shared<JingleFileTransferDescription>(); + desc->addOffer(StreamInitiationFileInfo()); + jingleContentPayload->addDescription(desc); + } + + boost::shared_ptr<JingleS5BTransportPayload> addJingleS5BPayload() { + JingleS5BTransportPayload::ref payLoad = boost::make_shared<JingleS5BTransportPayload>(); + payLoad->setSessionID("mysession"); + jingleContentPayload->addTransport(payLoad); + return payLoad; + } + + boost::shared_ptr<JingleIBBTransportPayload> addJingleIBBPayload() { + JingleIBBTransportPayload::ref payLoad = boost::make_shared<JingleIBBTransportPayload>(); + payLoad->setSessionID("mysession"); + jingleContentPayload->addTransport(payLoad); + return payLoad; + } + + JingleContentID getContentID() const { + return JingleContentID(jingleContentPayload->getName(), jingleContentPayload->getCreator()); + } + + template <typename T> T getCall(int i) const { + size_t index = static_cast<size_t>(i); + CPPUNIT_ASSERT(index < fakeJingleSession->calledCommands.size()); + T* cmd = boost::get<T>(&fakeJingleSession->calledCommands[index]); + CPPUNIT_ASSERT(cmd); + return *cmd; + } + +private: + std::vector<unsigned char> data; + boost::shared_ptr<ByteArrayReadBytestream> stream; + FakeJingleSession* fakeJingleSession; + boost::shared_ptr<JingleContentPayload> jingleContentPayload; + boost::shared_ptr<OFakeRemoteJingleTransportCandidateSelectorFactory> fakeRJTCSF; + boost::shared_ptr<OFakeLocalJingleTransportCandidateGeneratorFactory> fakeLJTCF; + DummyStanzaChannel* stanzaChannel; + IQRouter* iqRouter; + IDGenerator* idGen; + EventLoop *eventLoop; + SOCKS5BytestreamRegistry* s5bRegistry; + SOCKS5BytestreamProxy* s5bProxy; + DummyTimerFactory* timerFactory; + DummyConnectionFactory* connectionFactory; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(OutgoingJingleFileTransferTest); diff --git a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp new file mode 100644 index 0000000..527e0ca --- /dev/null +++ b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <boost/bind.hpp> +#include <boost/random/mersenne_twister.hpp> +#include <boost/random/uniform_int.hpp> +#include <boost/random/variate_generator.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/Algorithm.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/Concat.h> +#include <Swiften/Base/Log.h> +#include <Swiften/Base/StartStopper.h> +#include <Swiften/EventLoop/DummyEventLoop.h> +#include <Swiften/FileTransfer/ByteArrayReadBytestream.h> +#include <Swiften/FileTransfer/ByteArrayWriteBytestream.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Network/DummyConnection.h> +#include <Swiften/Network/DummyTimerFactory.h> +#include <Swiften/StringCodecs/Hexify.h> + +using namespace Swift; + +boost::mt19937 randomGen; + +class SOCKS5BytestreamClientSessionTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(SOCKS5BytestreamClientSessionTest); + CPPUNIT_TEST(testForSessionReady); + CPPUNIT_TEST(testErrorHandlingHello); + CPPUNIT_TEST(testErrorHandlingRequest); + CPPUNIT_TEST(testWriteBytestream); + CPPUNIT_TEST(testReadBytestream); + CPPUNIT_TEST_SUITE_END(); + + const HostAddressPort destinationAddressPort; + const std::string destination; + +public: + SOCKS5BytestreamClientSessionTest() : destinationAddressPort(HostAddressPort(HostAddress("127.0.0.1"), 8888)), + destination(SOCKS5BytestreamRegistry::getHostname("foo", JID("requester@example.com/test"), JID("target@example.com/test"))), eventLoop(NULL), timerFactory(NULL) { } + + void setUp() { + randomGen.seed(time(NULL)); + eventLoop = new DummyEventLoop(); + timerFactory = new DummyTimerFactory(); + connection = boost::make_shared<MockeryConnection>(failingPorts, true, eventLoop); + //connection->onDataSent.connect(boost::bind(&SOCKS5BytestreamServerSessionTest::handleDataWritten, this, _1)); + //stream1 = boost::shared_ptr<ByteArrayReadBytestream>(new ByteArrayReadBytestream(createByteArray("abcdefg"))); +// connection->onDataRead.connect(boost::bind(&SOCKS5BytestreamClientSessionTest::handleDataRead, this, _1)); + } + + void tearDown() { + //connection.reset(); + delete timerFactory; + delete eventLoop; + } + + void testForSessionReady() { + TestHelper helper; + connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); + + SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); + clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); + + clientSession->start(); + eventLoop->processEvents(); + CPPUNIT_ASSERT(createByteArray("\x05\x01\x00", 3) == helper.unprocessedInput); + + helper.unprocessedInput.clear(); + serverRespondHelloOK(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x05\x01\x00\x03", 4), createByteArray(&helper.unprocessedInput[0], 4)); + CPPUNIT_ASSERT_EQUAL(createByteArray(destination.size()), createByteArray(helper.unprocessedInput[4])); + CPPUNIT_ASSERT_EQUAL(createByteArray(destination), createByteArray(&helper.unprocessedInput[5], destination.size())); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x00", 1), createByteArray(&helper.unprocessedInput[5 + destination.size()], 1)); + + helper.unprocessedInput.clear(); + serverRespondRequestOK(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); + CPPUNIT_ASSERT_EQUAL(false, helper.sessionReadyError); + } + + void testErrorHandlingHello() { + TestHelper helper; + connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); + + SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); + clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); + + clientSession->start(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x05\x01\x00", 3), helper.unprocessedInput); + + helper.unprocessedInput.clear(); + serverRespondHelloAuthFail(); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyError); + CPPUNIT_ASSERT_EQUAL(true, connection->disconnectCalled); + } + + void testErrorHandlingRequest() { + TestHelper helper; + connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); + + SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); + clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); + + clientSession->start(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x05\x01\x00", 3), helper.unprocessedInput); + + helper.unprocessedInput.clear(); + serverRespondHelloOK(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x05\x01\x00\x03", 4), createByteArray(&helper.unprocessedInput[0], 4)); + CPPUNIT_ASSERT_EQUAL(createByteArray(destination.size()), createByteArray(helper.unprocessedInput[4])); + CPPUNIT_ASSERT_EQUAL(createByteArray(destination), createByteArray(&helper.unprocessedInput[5], destination.size())); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x00", 1), createByteArray(&helper.unprocessedInput[5 + destination.size()], 1)); + + helper.unprocessedInput.clear(); + serverRespondRequestFail(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyError); + CPPUNIT_ASSERT_EQUAL(true, connection->disconnectCalled); + } + + void testWriteBytestream() { + TestHelper helper; + connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); + + SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); + clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); + + clientSession->start(); + eventLoop->processEvents(); + + helper.unprocessedInput.clear(); + serverRespondHelloOK(); + eventLoop->processEvents(); + + helper.unprocessedInput.clear(); + serverRespondRequestOK(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); + CPPUNIT_ASSERT_EQUAL(false, helper.sessionReadyError); + + boost::shared_ptr<ByteArrayWriteBytestream> output = boost::make_shared<ByteArrayWriteBytestream>(); + clientSession->startReceiving(output); + + ByteArray transferData = generateRandomByteArray(1024); + connection->onDataRead(createSafeByteArrayRef(transferData.data(), transferData.size())); + CPPUNIT_ASSERT_EQUAL(transferData, output->getData()); + } + + void testReadBytestream() { + TestHelper helper; + connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); + + SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); + clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); + + clientSession->start(); + eventLoop->processEvents(); + + helper.unprocessedInput.clear(); + serverRespondHelloOK(); + eventLoop->processEvents(); + + helper.unprocessedInput.clear(); + serverRespondRequestOK(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); + CPPUNIT_ASSERT_EQUAL(false, helper.sessionReadyError); + + helper.unprocessedInput.clear(); + ByteArray transferData = generateRandomByteArray(1024); + boost::shared_ptr<ByteArrayReadBytestream> input = boost::make_shared<ByteArrayReadBytestream>(transferData); + clientSession->startSending(input); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(createByteArray(transferData.data(), transferData.size()), helper.unprocessedInput); + } + + + +private: + static ByteArray generateRandomByteArray(size_t len) { + boost::uniform_int<> dist(0, 255); + boost::variate_generator<boost::mt19937&, boost::uniform_int<> > randomByte(randomGen, dist); + ByteArray result(len); + for (size_t i=0; i < len; ++i ) { + result[i] = randomByte(); + } + return result; + } + + // Server responses + void serverRespondHelloOK() { + connection->onDataRead(createSafeByteArrayRef("\x05\00", 2)); + } + + void serverRespondHelloAuthFail() { + connection->onDataRead(createSafeByteArrayRef("\x05\xFF", 2)); + } + + void serverRespondRequestOK() { + boost::shared_ptr<SafeByteArray> dataToSend = createSafeByteArrayRef("\x05\x00\x00\x03", 4); + append(*dataToSend, createSafeByteArray(destination.size())); + append(*dataToSend, createSafeByteArray(destination)); + append(*dataToSend, createSafeByteArray("\x00", 1)); + connection->onDataRead(dataToSend); + } + + void serverRespondRequestFail() { + boost::shared_ptr<SafeByteArray> correctData = createSafeByteArrayRef("\x05\x00\x00\x03", 4); + append(*correctData, createSafeByteArray(destination.size())); + append(*correctData, createSafeByteArray(destination)); + append(*correctData, createSafeByteArray("\x00", 1)); + + boost::shared_ptr<SafeByteArray> dataToSend; + //ByteArray failingData = Hexify::unhexify("8417947d1d305c72c11520ea7d2c6e787396705e72c312c6ccc3f66613d7cae1b91b7ab48e8b59a17d559c15fb51"); + //append(dataToSend, failingData); + //SWIFT_LOG(debug) << "hexed: " << Hexify::hexify(failingData) << std::endl; + do { + ByteArray rndArray = generateRandomByteArray(correctData->size()); + dataToSend = createSafeByteArrayRef(rndArray.data(), rndArray.size()); + } while (*dataToSend == *correctData); + connection->onDataRead(dataToSend); + } + +private: + struct TestHelper { + TestHelper() : sessionReadyCalled(false), sessionReadyError(false) {} + ByteArray unprocessedInput; + bool sessionReadyCalled; + bool sessionReadyError; + + void handleConnectionDataWritten(const SafeByteArray& data) { + append(unprocessedInput, data); + //SWIFT_LOG(debug) << "unprocessedInput (" << unprocessedInput.size() << "): " << Hexify::hexify(unprocessedInput) << std::endl; + } + + void handleSessionReady(bool error) { + sessionReadyCalled = true; + sessionReadyError = error; + } + }; + + +private: + struct MockeryConnection : public Connection, public EventOwner, public boost::enable_shared_from_this<MockeryConnection> { + public: + MockeryConnection(const std::vector<HostAddressPort>& failingPorts, bool isResponsive, EventLoop* eventLoop) : eventLoop(eventLoop), failingPorts(failingPorts), isResponsive(isResponsive), disconnectCalled(false) {} + + void listen() { assert(false); } + void connect(const HostAddressPort& address) { + hostAddressPort = address; + if (isResponsive) { + bool fail = std::find(failingPorts.begin(), failingPorts.end(), address) != failingPorts.end(); + eventLoop->postEvent(boost::bind(boost::ref(onConnectFinished), fail)); + } + } + + HostAddressPort getLocalAddress() const { return HostAddressPort(); } + void disconnect() { + disconnectCalled = true; + } + + void write(const SafeByteArray& data) { + eventLoop->postEvent(boost::ref(onDataWritten), shared_from_this()); + onDataSent(data); + } + + boost::signal<void (const SafeByteArray&)> onDataSent; + + EventLoop* eventLoop; + boost::optional<HostAddressPort> hostAddressPort; + std::vector<HostAddressPort> failingPorts; + bool isResponsive; + bool disconnectCalled; + }; + +private: + DummyEventLoop* eventLoop; + DummyTimerFactory* timerFactory; + boost::shared_ptr<MockeryConnection> connection; + const std::vector<HostAddressPort> failingPorts; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(SOCKS5BytestreamClientSessionTest); diff --git a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp index c6d246d..4fe72c0 100644 --- a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp +++ b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp @@ -4,18 +4,19 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/bind.hpp> -#include "Swiften/FileTransfer/SOCKS5BytestreamServerSession.h" -#include "Swiften/FileTransfer/ByteArrayReadBytestream.h" -#include "Swiften/FileTransfer/SOCKS5BytestreamRegistry.h" -#include "Swiften/Network/DummyConnection.h" -#include "Swiften/EventLoop/DummyEventLoop.h" -#include "Swiften/Base/StartStopper.h" +#include <Swiften/Base/Concat.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamServerSession.h> +#include <Swiften/FileTransfer/ByteArrayReadBytestream.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> +#include <Swiften/Network/DummyConnection.h> +#include <Swiften/EventLoop/DummyEventLoop.h> +#include <Swiften/Base/StartStopper.h> using namespace Swift; @@ -33,122 +34,127 @@ class SOCKS5BytestreamServerSessionTest : public CppUnit::TestFixture { void setUp() { receivedDataChunks = 0; eventLoop = new DummyEventLoop(); + bytestreams = new SOCKS5BytestreamRegistry(); connection = boost::shared_ptr<DummyConnection>(new DummyConnection(eventLoop)); connection->onDataSent.connect(boost::bind(&SOCKS5BytestreamServerSessionTest::handleDataWritten, this, _1)); - stream1 = boost::shared_ptr<ByteArrayReadBytestream>(new ByteArrayReadBytestream(ByteArray("abcdefg"))); + stream1 = boost::shared_ptr<ByteArrayReadBytestream>(new ByteArrayReadBytestream(createByteArray("abcdefg"))); } void tearDown() { connection.reset(); + delete bytestreams; delete eventLoop; } void testAuthenticate() { - std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); - receive(ByteArray("\x05\x02\x01\x02")); + receive(createSafeByteArray("\x05\x02\x01\x02")); - CPPUNIT_ASSERT_EQUAL(ByteArray("\x05\x00", 2), receivedData); + CPPUNIT_ASSERT(createByteArray("\x05\x00", 2) == receivedData); } void testAuthenticate_Chunked() { - std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); - receive(ByteArray("\x05\x02\x01")); + receive(createSafeByteArray("\x05\x02\x01")); - CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedData.getSize())); - receive(ByteArray("\x01")); - CPPUNIT_ASSERT_EQUAL(ByteArray("\x05\x00", 2), receivedData); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedData.size())); + receive(createSafeByteArray("\x01")); + CPPUNIT_ASSERT(createByteArray("\x05\x00", 2) == receivedData); } void testRequest() { - std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); - bytestreams.addBytestream("abcdef", stream1); + bytestreams->addReadBytestream("abcdef", stream1); authenticate(); - ByteArray hostname("abcdef"); - receive(ByteArray("\x05\x01\x00\x03", 4) + hostname.getSize() + hostname + ByteArray("\x00\x00", 2)); - CPPUNIT_ASSERT_EQUAL(ByteArray("\x05\x00\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13), ByteArray(receivedData.getData(), 13)); + ByteArray hostname(createByteArray("abcdef")); + receive(concat(createSafeByteArray("\x05\x01\x00\x03", 4), createSafeByteArray(hostname.size()), createSafeByteArray(hostname), createSafeByteArray("\x00\x00", 2))); + CPPUNIT_ASSERT(createByteArray("\x05\x00\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13) == createByteArray(&receivedData[0], 13)); } void testRequest_UnknownBytestream() { - std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); authenticate(); - ByteArray hostname("abcdef"); - receive(ByteArray("\x05\x01\x00\x03", 4) + hostname.getSize() + hostname + ByteArray("\x00\x00", 2)); - CPPUNIT_ASSERT_EQUAL(ByteArray("\x05\x04\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13), receivedData); + ByteArray hostname(createByteArray("abcdef")); + receive(concat(createSafeByteArray("\x05\x01\x00\x03", 4), createSafeByteArray(hostname.size()), createSafeByteArray(hostname), createSafeByteArray("\x00\x00", 2))); + CPPUNIT_ASSERT(createByteArray("\x05\x04\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13) == receivedData); } void testReceiveData() { - std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); - bytestreams.addBytestream("abcdef", stream1); + bytestreams->addReadBytestream("abcdef", stream1); authenticate(); request("abcdef"); eventLoop->processEvents(); + testling->startTransfer(); skipHeader("abcdef"); + eventLoop->processEvents(); - CPPUNIT_ASSERT_EQUAL(ByteArray("abcdefg"), receivedData); + CPPUNIT_ASSERT(createByteArray("abcdefg") == receivedData); CPPUNIT_ASSERT_EQUAL(2, receivedDataChunks); } void testReceiveData_Chunked() { - std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); testling->setChunkSize(3); StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); - bytestreams.addBytestream("abcdef", stream1); + bytestreams->addReadBytestream("abcdef", stream1); authenticate(); request("abcdef"); eventLoop->processEvents(); - + testling->startTransfer(); + eventLoop->processEvents(); skipHeader("abcdef"); - CPPUNIT_ASSERT_EQUAL(ByteArray("abcdefg"), receivedData); + CPPUNIT_ASSERT(createByteArray("abcdefg") == receivedData); CPPUNIT_ASSERT_EQUAL(4, receivedDataChunks); } private: - void receive(const ByteArray& data) { + void receive(const SafeByteArray& data) { connection->receive(data); eventLoop->processEvents(); } void authenticate() { - receive(ByteArray("\x05\x02\x01\x02")); + receive(createSafeByteArray("\x05\x02\x01\x02")); receivedData.clear(); receivedDataChunks = 0; } void request(const std::string& hostname) { - receive(ByteArray("\x05\x01\x00\x03", 4) + hostname.size() + hostname + ByteArray("\x00\x00", 2)); + receive(concat(createSafeByteArray("\x05\x01\x00\x03", 4), createSafeByteArray(hostname.size()), createSafeByteArray(hostname), createSafeByteArray("\x00\x00", 2))); } void skipHeader(const std::string& hostname) { int headerSize = 7 + hostname.size(); - receivedData = ByteArray(receivedData.getData() + headerSize, receivedData.getSize() - headerSize); + receivedData = createByteArray(&receivedData[headerSize], receivedData.size() - headerSize); } - void handleDataWritten(const ByteArray& data) { - receivedData += data; + void handleDataWritten(const SafeByteArray& data) { + receivedData.insert(receivedData.end(), data.begin(), data.end()); receivedDataChunks++; } private: SOCKS5BytestreamServerSession* createSession() { - SOCKS5BytestreamServerSession* session = new SOCKS5BytestreamServerSession(connection, &bytestreams); + SOCKS5BytestreamServerSession* session = new SOCKS5BytestreamServerSession(connection, bytestreams); return session; } private: DummyEventLoop* eventLoop; - SOCKS5BytestreamRegistry bytestreams; + SOCKS5BytestreamRegistry* bytestreams; boost::shared_ptr<DummyConnection> connection; - ByteArray receivedData; + std::vector<unsigned char> receivedData; int receivedDataChunks; boost::shared_ptr<ByteArrayReadBytestream> stream1; }; diff --git a/Swiften/FileTransfer/WriteBytestream.cpp b/Swiften/FileTransfer/WriteBytestream.cpp index f1a5afc..8d10193 100644 --- a/Swiften/FileTransfer/WriteBytestream.cpp +++ b/Swiften/FileTransfer/WriteBytestream.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/FileTransfer/WriteBytestream.h" +#include <Swiften/FileTransfer/WriteBytestream.h> namespace Swift { diff --git a/Swiften/FileTransfer/WriteBytestream.h b/Swiften/FileTransfer/WriteBytestream.h index 1dc791c..fb6f2f1 100644 --- a/Swiften/FileTransfer/WriteBytestream.h +++ b/Swiften/FileTransfer/WriteBytestream.h @@ -7,8 +7,9 @@ #pragma once #include <boost/shared_ptr.hpp> +#include <vector> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/boost_bsignals.h> namespace Swift { class WriteBytestream { @@ -17,6 +18,8 @@ namespace Swift { virtual ~WriteBytestream(); - virtual void write(const ByteArray&) = 0; + virtual void write(const std::vector<unsigned char>&) = 0; + + boost::signal<void (const std::vector<unsigned char>&)> onWrite; }; } diff --git a/Swiften/History/HistoryManager.cpp b/Swiften/History/HistoryManager.cpp index 7017899..7eb66ab 100644 --- a/Swiften/History/HistoryManager.cpp +++ b/Swiften/History/HistoryManager.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/History/HistoryManager.h" +#include <Swiften/History/HistoryManager.h> namespace Swift { diff --git a/Swiften/History/SQLiteHistoryManager.cpp b/Swiften/History/SQLiteHistoryManager.cpp index 9d5a000..3b65f62 100644 --- a/Swiften/History/SQLiteHistoryManager.cpp +++ b/Swiften/History/SQLiteHistoryManager.cpp @@ -7,8 +7,8 @@ #include <iostream> #include <boost/lexical_cast.hpp> -#include "sqlite3.h" -#include "Swiften/History/SQLiteHistoryManager.h" +#include <sqlite3.h> +#include <Swiften/History/SQLiteHistoryManager.h> namespace { diff --git a/Swiften/History/SQLiteHistoryManager.h b/Swiften/History/SQLiteHistoryManager.h index a2b89f4..ffd9492 100644 --- a/Swiften/History/SQLiteHistoryManager.h +++ b/Swiften/History/SQLiteHistoryManager.h @@ -8,7 +8,7 @@ #include <boost/optional.hpp> -#include "Swiften/History/HistoryManager.h" +#include <Swiften/History/HistoryManager.h> struct sqlite3; diff --git a/Swiften/History/UnitTest/SQLiteHistoryManagerTest.cpp b/Swiften/History/UnitTest/SQLiteHistoryManagerTest.cpp index 0092e0f..4123008 100644 --- a/Swiften/History/UnitTest/SQLiteHistoryManagerTest.cpp +++ b/Swiften/History/UnitTest/SQLiteHistoryManagerTest.cpp @@ -8,7 +8,7 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/date_time/posix_time/posix_time.hpp> -#include "Swiften/History/SQLiteHistoryManager.h" +#include <Swiften/History/SQLiteHistoryManager.h> using namespace Swift; @@ -34,7 +34,7 @@ class SQLiteHistoryManagerTest : public CppUnit::TestFixture { } void testAddMessage() { - std::auto_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); HistoryMessage testMessage("Test", JID("foo@bar.com"), JID("fum@baz.org"), boost::posix_time::time_from_string("1980-01-21 22:03")); testling->addMessage(testMessage); @@ -44,7 +44,7 @@ class SQLiteHistoryManagerTest : public CppUnit::TestFixture { } void testAddMessage_TwoMessages() { - std::auto_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); HistoryMessage testMessage1("Test1", JID("foo@bar.com"), JID("fum@baz.org"), boost::posix_time::time_from_string("1980-01-21 22:03")); testling->addMessage(testMessage1); HistoryMessage testMessage2("Test2", JID("fum@baz.org"), JID("foo@bar.com"), boost::posix_time::time_from_string("1975-03-09 22:04")); @@ -57,7 +57,7 @@ class SQLiteHistoryManagerTest : public CppUnit::TestFixture { } void testGetIDForJID_SameJID() { - std::auto_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); int id1 = testling->getIDForJID(JID("foo@bar.com")); int id2 = testling->getIDForJID(JID("foo@bar.com")); @@ -65,7 +65,7 @@ class SQLiteHistoryManagerTest : public CppUnit::TestFixture { } void testGetIDForJID_DifferentJIDs() { - std::auto_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); int id1 = testling->getIDForJID(JID("foo@bar.com")); int id2 = testling->getIDForJID(JID("foo@baz.com")); @@ -73,7 +73,7 @@ class SQLiteHistoryManagerTest : public CppUnit::TestFixture { } void getJIDFromID() { - std::auto_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); int id = testling->addJID(JID("foo@bar.com")); boost::optional<JID> result(testling->getJIDFromID(id)); @@ -82,7 +82,7 @@ class SQLiteHistoryManagerTest : public CppUnit::TestFixture { } void getJIDFromID_UnexistingID() { - std::auto_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); boost::optional<JID> result(testling->getJIDFromID(1)); @@ -90,7 +90,7 @@ class SQLiteHistoryManagerTest : public CppUnit::TestFixture { } void getIDFromJID() { - std::auto_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); int id = testling->addJID(JID("foo@bar.com")); boost::optional<int> result(testling->getIDFromJID(JID("foo@bar.com"))); @@ -99,7 +99,7 @@ class SQLiteHistoryManagerTest : public CppUnit::TestFixture { } void getIDFromJID_UnexistingJID() { - std::auto_ptr<SQLiteHistoryManager> testling(createHistoryManager()); + boost::shared_ptr<SQLiteHistoryManager> testling(createHistoryManager()); boost::optional<int> result(testling->getIDFromJID(JID("foo@bar.com"))); diff --git a/Swiften/IDN/IDNA.cpp b/Swiften/IDN/IDNA.cpp index 6b6c7a4..16b4183 100644 --- a/Swiften/IDN/IDNA.cpp +++ b/Swiften/IDN/IDNA.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/IDN/IDNA.h" +#include <Swiften/IDN/IDNA.h> #include <stringprep.h> #include <vector> diff --git a/Swiften/IDN/StringPrep.cpp b/Swiften/IDN/StringPrep.cpp index d54fb0b..db09523 100644 --- a/Swiften/IDN/StringPrep.cpp +++ b/Swiften/IDN/StringPrep.cpp @@ -4,36 +4,58 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/IDN/StringPrep.h" +#include <Swiften/IDN/StringPrep.h> #include <stringprep.h> #include <vector> #include <cassert> +#include <Swiften/Base/SafeAllocator.h> -namespace Swift { +using namespace Swift; + + namespace { + static const int MAX_STRINGPREP_SIZE = 1024; -static const int MAX_STRINGPREP_SIZE = 1024; + const Stringprep_profile* getLibIDNProfile(StringPrep::Profile profile) { + switch(profile) { + case StringPrep::NamePrep: return stringprep_nameprep; break; + case StringPrep::XMPPNodePrep: return stringprep_xmpp_nodeprep; break; + case StringPrep::XMPPResourcePrep: return stringprep_xmpp_resourceprep; break; + case StringPrep::SASLPrep: return stringprep_saslprep; break; + } + assert(false); + return 0; + } -const Stringprep_profile* getLibIDNProfile(StringPrep::Profile profile) { - switch(profile) { - case StringPrep::NamePrep: return stringprep_nameprep; break; - case StringPrep::XMPPNodePrep: return stringprep_xmpp_nodeprep; break; - case StringPrep::XMPPResourcePrep: return stringprep_xmpp_resourceprep; break; - case StringPrep::SASLPrep: return stringprep_saslprep; break; + template<typename StringType, typename ContainerType> + ContainerType getStringPrepared(const StringType& s, StringPrep::Profile profile) { + ContainerType input(s.begin(), s.end()); + input.resize(MAX_STRINGPREP_SIZE); + if (stringprep(&input[0], MAX_STRINGPREP_SIZE, static_cast<Stringprep_profile_flags>(0), getLibIDNProfile(profile)) == 0) { + return input; + } + else { + return ContainerType(); + } } - assert(false); - return 0; } +namespace Swift { + std::string StringPrep::getPrepared(const std::string& s, Profile profile) { - std::vector<char> input(s.begin(), s.end()); - input.resize(MAX_STRINGPREP_SIZE); - if (stringprep(&input[0], MAX_STRINGPREP_SIZE, static_cast<Stringprep_profile_flags>(0), getLibIDNProfile(profile)) == 0) { - return std::string(&input[0]); + std::vector<char> preparedData = getStringPrepared< std::string, std::vector<char> >(s, profile); + if (preparedData.empty()) { + throw std::exception(); } - else { + return std::string(vecptr(preparedData)); +} + +SafeByteArray StringPrep::getPrepared(const SafeByteArray& s, Profile profile) { + std::vector<char, SafeAllocator<char> > preparedData = getStringPrepared<SafeByteArray, std::vector<char, SafeAllocator<char> > >(s, profile); + if (preparedData.empty()) { throw std::exception(); } + return createSafeByteArray(reinterpret_cast<const char*>(vecptr(preparedData))); } } diff --git a/Swiften/IDN/StringPrep.h b/Swiften/IDN/StringPrep.h index f40553b..dc8fadc 100644 --- a/Swiften/IDN/StringPrep.h +++ b/Swiften/IDN/StringPrep.h @@ -7,6 +7,7 @@ #pragma once #include <string> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class StringPrep { @@ -19,5 +20,6 @@ namespace Swift { }; static std::string getPrepared(const std::string& s, Profile profile); + static SafeByteArray getPrepared(const SafeByteArray& s, Profile profile); }; } diff --git a/Swiften/JID/JID.cpp b/Swiften/JID/JID.cpp index f121120..66d6ff6 100644 --- a/Swiften/JID/JID.cpp +++ b/Swiften/JID/JID.cpp @@ -7,17 +7,24 @@ #define SWIFTEN_CACHE_JID_PREP #include <vector> +#include <list> #include <iostream> #include <string> #ifdef SWIFTEN_CACHE_JID_PREP #include <boost/unordered_map.hpp> #endif +#include <boost/assign/list_of.hpp> +#include <boost/algorithm/string/find_format.hpp> +#include <boost/algorithm/string/finder.hpp> +#include <sstream> #include <stringprep.h> #include <Swiften/Base/String.h> -#include "Swiften/JID/JID.h" -#include "Swiften/IDN/StringPrep.h" +#include <Swiften/JID/JID.h> +#include <Swiften/IDN/StringPrep.h> + +using namespace Swift; #ifdef SWIFTEN_CACHE_JID_PREP typedef boost::unordered_map<std::string, std::string> PrepCache; @@ -27,7 +34,81 @@ static PrepCache domainPrepCache; static PrepCache resourcePrepCache; #endif -namespace Swift { +static const std::list<char> escapedChars = boost::assign::list_of(' ')('"')('&')('\'')('/')('<')('>')('@')(':'); + +static std::string getEscaped(char c) { + return makeString() << '\\' << std::hex << static_cast<int>(c); +} + +static bool getEscapeSequenceValue(const std::string& sequence, unsigned char& value) { + std::stringstream s; + unsigned int v; + s << std::hex << sequence; + s >> v; + value = static_cast<unsigned char>(v); + return (!s.fail() && !s.bad() && (value == 0x5C || std::find(escapedChars.begin(), escapedChars.end(), value) != escapedChars.end())); +} + +// Disabling this code for now, since GCC4.5+boost1.42 (on ubuntu) seems to +// result in a bug. Replacing it with naive code. +#if 0 +struct UnescapedCharacterFinder { + template<typename Iterator> boost::iterator_range<Iterator> operator()(Iterator begin, Iterator end) { + for (; begin != end; ++begin) { + if (std::find(escapedChars.begin(), escapedChars.end(), *begin) != escapedChars.end()) { + return boost::iterator_range<Iterator>(begin, begin + 1); + } + else if (*begin == '\\') { + // Check if we have an escaped dissalowed character sequence + Iterator innerBegin = begin + 1; + if (innerBegin != end && innerBegin + 1 != end) { + Iterator innerEnd = innerBegin + 2; + unsigned char value; + if (getEscapeSequenceValue(std::string(innerBegin, innerEnd), value)) { + return boost::iterator_range<Iterator>(begin, begin + 1); + } + } + } + } + return boost::iterator_range<Iterator>(end, end); + } +}; + +struct UnescapedCharacterFormatter { + template<typename FindResult> std::string operator()(const FindResult& match) const { + std::ostringstream s; + s << '\\' << std::hex << static_cast<int>(*match.begin()); + return s.str(); + } +}; + +struct EscapedCharacterFinder { + template<typename Iterator> boost::iterator_range<Iterator> operator()(Iterator begin, Iterator end) { + for (; begin != end; ++begin) { + if (*begin == '\\') { + Iterator innerEnd = begin + 1; + for (size_t i = 0; i < 2 && innerEnd != end; ++i, ++innerEnd) { + } + unsigned char value; + if (getEscapeSequenceValue(std::string(begin + 1, innerEnd), value)) { + return boost::iterator_range<Iterator>(begin, innerEnd); + } + } + } + return boost::iterator_range<Iterator>(end, end); + } +}; + +struct EscapedCharacterFormatter { + template<typename FindResult> std::string operator()(const FindResult& match) const { + unsigned char value; + if (getEscapeSequenceValue(std::string(match.begin() + 1, match.end()), value)) { + return std::string(reinterpret_cast<const char*>(&value), 1); + } + return boost::copy_range<std::string>(match); + } +}; +#endif JID::JID(const char* jid) : valid_(true) { initializeFromString(std::string(jid)); @@ -137,5 +218,48 @@ int JID::compare(const Swift::JID& o, CompareType compareType) const { return 0; } -} // namespace Swift - +std::string JID::getEscapedNode(const std::string& node) { + std::string result; + for (std::string::const_iterator i = node.begin(); i != node.end(); ++i) { + if (std::find(escapedChars.begin(), escapedChars.end(), *i) != escapedChars.end()) { + result += getEscaped(*i); + continue; + } + else if (*i == '\\') { + // Check if we have an escaped dissalowed character sequence + std::string::const_iterator innerBegin = i + 1; + if (innerBegin != node.end() && innerBegin + 1 != node.end()) { + std::string::const_iterator innerEnd = innerBegin + 2; + unsigned char value; + if (getEscapeSequenceValue(std::string(innerBegin, innerEnd), value)) { + result += getEscaped(*i); + continue; + } + } + } + result += *i; + } + return result; + //return boost::find_format_all_copy(node, UnescapedCharacterFinder(), UnescapedCharacterFormatter()); +} + +std::string JID::getUnescapedNode() const { + std::string result; + for (std::string::const_iterator j = node_.begin(); j != node_.end();) { + if (*j == '\\') { + std::string::const_iterator innerEnd = j + 1; + for (size_t i = 0; i < 2 && innerEnd != node_.end(); ++i, ++innerEnd) { + } + unsigned char value; + if (getEscapeSequenceValue(std::string(j + 1, innerEnd), value)) { + result += std::string(reinterpret_cast<const char*>(&value), 1); + j = innerEnd; + continue; + } + } + result += *j; + ++j; + } + return result; + //return boost::find_format_all_copy(node_, EscapedCharacterFinder(), EscapedCharacterFormatter()); +} diff --git a/Swiften/JID/JID.h b/Swiften/JID/JID.h index 1a7dbe3..a4461ba 100644 --- a/Swiften/JID/JID.h +++ b/Swiften/JID/JID.h @@ -7,37 +7,120 @@ #pragma once #include <string> -#include <ostream> +//#include <iosfwd> +#include <iostream> namespace Swift { + /** + * This represents the JID used in XMPP + * (RFC6120 - http://tools.ietf.org/html/rfc6120 ). + * For a description of format, see the RFC or page 14 of + * XMPP: The Definitive Guide (Saint-Andre et al.) + * + * Particularly - a Bare JID is a JID without a resource part. + * + * A JID can be invalid (when isValid() returns false). No member methods are + * guaranteed to work correctly if they do. + */ class JID { public: enum CompareType { WithResource, WithoutResource }; - JID(const std::string& = std::string()); + /** + * Create a JID from its String representation. + * + * e.g. + * wonderland.lit + * wonderland.lit/rabbithole + * alice@wonderland.lit + * alice@wonderland.lit/TeaParty + * + * @param jid String representation. Invalid JID if empty or invalid. + */ + JID(const std::string& jid = std::string()); + + /** + * See std::string constructor. + */ JID(const char*); + + /** + * Create a bare JID from the node and domain parts. + * + * JID("node@domain") == JID("node", "domain") + * unless you pass in empty values. + * + * @param node JID node part. + * @param domain JID domain part. + */ JID(const std::string& node, const std::string& domain); + /** + * Create a bare JID from the node, domain and resource parts. + * + * JID("node@domain/resource") == JID("node", "domain", "resource") + * unless you pass in empty values. + * + * @param node JID node part. + * @param domain JID domain part. + * @param resource JID resource part. + */ JID(const std::string& node, const std::string& domain, const std::string& resource); + /** + * @return Is a correctly-formatted JID. + */ bool isValid() const { return valid_; } + /** + * e.g. JID("node@domain").getNode() == "node" + * @return could be empty. + */ const std::string& getNode() const { return node_; } + + /** + * e.g. JID("node@domain").getDomain() == "domain" + */ const std::string& getDomain() const { return domain_; } + + /** + * e.g. JID("node@domain/resource").getResource() == "resource" + * @return could be empty. + */ const std::string& getResource() const { return resource_; } + + /** + * Is a bare JID, i.e. has no resource part. + */ bool isBare() const { return !hasResource_; } + /** + * Returns the given node, escaped according to XEP-0106. + * The resulting node is a valid node for a JID, whereas the input value can contain characters + * that are not allowed. + */ + static std::string getEscapedNode(const std::string& node); + + /** + * Returns the node of the current JID, unescaped according to XEP-0106. + */ + std::string getUnescapedNode() const; + + /** + * Get the JID without a resource. + * @return Invalid if the original is invalid. + */ JID toBare() const { JID result(*this); result.hasResource_ = false; diff --git a/Swiften/JID/UnitTest/JIDTest.cpp b/Swiften/JID/UnitTest/JIDTest.cpp index e083918..81d24ea 100644 --- a/Swiften/JID/UnitTest/JIDTest.cpp +++ b/Swiften/JID/UnitTest/JIDTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/JID/JID.h" +#include <Swiften/JID/JID.h> using namespace Swift; @@ -53,6 +53,11 @@ class JIDTest : public CppUnit::TestFixture CPPUNIT_TEST(testSmallerThan_Larger); CPPUNIT_TEST(testHasResource); CPPUNIT_TEST(testHasResource_NoResource); + CPPUNIT_TEST(testGetEscapedNode); + CPPUNIT_TEST(testGetEscapedNode_XEP106Examples); + CPPUNIT_TEST(testGetEscapedNode_BackslashAtEnd); + CPPUNIT_TEST(testGetUnescapedNode); + CPPUNIT_TEST(testGetUnescapedNode_XEP106Examples); CPPUNIT_TEST_SUITE_END(); public: @@ -325,6 +330,61 @@ class JIDTest : public CppUnit::TestFixture CPPUNIT_ASSERT(testling.isBare()); } + + void testGetEscapedNode() { + std::string escaped = JID::getEscapedNode("alice@wonderland.lit"); + CPPUNIT_ASSERT_EQUAL(std::string("alice\\40wonderland.lit"), escaped); + + escaped = JID::getEscapedNode("\\& \" ' / <\\\\> @ :\\3a\\40"); + CPPUNIT_ASSERT_EQUAL(std::string("\\\\26\\20\\22\\20\\27\\20\\2f\\20\\3c\\\\\\3e\\20\\40\\20\\3a\\5c3a\\5c40"), escaped); + } + + void testGetEscapedNode_XEP106Examples() { + CPPUNIT_ASSERT_EQUAL(std::string("\\2plus\\2is\\4"), JID::getEscapedNode("\\2plus\\2is\\4")); + CPPUNIT_ASSERT_EQUAL(std::string("foo\\bar"), JID::getEscapedNode("foo\\bar")); + CPPUNIT_ASSERT_EQUAL(std::string("foob\\41r"), JID::getEscapedNode("foob\\41r")); + CPPUNIT_ASSERT_EQUAL(JID::getEscapedNode("space cadet"), std::string("space\\20cadet")); + CPPUNIT_ASSERT_EQUAL(JID::getEscapedNode("call me \"ishmael\""), std::string("call\\20me\\20\\22ishmael\\22")); + CPPUNIT_ASSERT_EQUAL(JID::getEscapedNode("at&t guy"), std::string("at\\26t\\20guy")); + CPPUNIT_ASSERT_EQUAL(JID::getEscapedNode("d'artagnan"), std::string("d\\27artagnan")); + CPPUNIT_ASSERT_EQUAL(JID::getEscapedNode("/.fanboy"), std::string("\\2f.fanboy")); + CPPUNIT_ASSERT_EQUAL(JID::getEscapedNode("::foo::"), std::string("\\3a\\3afoo\\3a\\3a")); + CPPUNIT_ASSERT_EQUAL(JID::getEscapedNode("<foo>"), std::string("\\3cfoo\\3e")); + CPPUNIT_ASSERT_EQUAL(JID::getEscapedNode("user@host"), std::string("user\\40host")); + CPPUNIT_ASSERT_EQUAL(JID::getEscapedNode("c:\\net"), std::string("c\\3a\\net")); + CPPUNIT_ASSERT_EQUAL(JID::getEscapedNode("c:\\\\net"), std::string("c\\3a\\\\net")); + CPPUNIT_ASSERT_EQUAL(JID::getEscapedNode("c:\\cool stuff"), std::string("c\\3a\\cool\\20stuff")); + CPPUNIT_ASSERT_EQUAL(JID::getEscapedNode("c:\\5commas"), std::string("c\\3a\\5c5commas")); + } + + void testGetEscapedNode_BackslashAtEnd() { + CPPUNIT_ASSERT_EQUAL(std::string("foo\\"), JID::getEscapedNode("foo\\")); + } + + void testGetUnescapedNode() { + std::string input = "\\& \" ' / <\\\\> @ : \\5c\\40"; + JID testling(JID::getEscapedNode(input) + "@y"); + CPPUNIT_ASSERT(testling.isValid()); + CPPUNIT_ASSERT_EQUAL(input, testling.getUnescapedNode()); + } + + void testGetUnescapedNode_XEP106Examples() { + CPPUNIT_ASSERT_EQUAL(std::string("\\2plus\\2is\\4"), JID("\\2plus\\2is\\4@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("foo\\bar"), JID("foo\\bar@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("foob\\41r"), JID("foob\\41r@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("space cadet"), JID("space\\20cadet@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("call me \"ishmael\""), JID("call\\20me\\20\\22ishmael\\22@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("at&t guy"), JID("at\\26t\\20guy@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("d'artagnan"), JID("d\\27artagnan@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("/.fanboy"), JID("\\2f.fanboy@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("::foo::"), JID("\\3a\\3afoo\\3a\\3a@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("<foo>"), JID("\\3cfoo\\3e@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("user@host"), JID("user\\40host@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("c:\\net"), JID("c\\3a\\net@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("c:\\\\net"), JID("c\\3a\\\\net@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("c:\\cool stuff"), JID("c\\3a\\cool\\20stuff@example.com").getUnescapedNode()); + CPPUNIT_ASSERT_EQUAL(std::string("c:\\5commas"), JID("c\\3a\\5c5commas@example.com").getUnescapedNode()); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(JIDTest); diff --git a/Swiften/Jingle/FakeJingleSession.cpp b/Swiften/Jingle/FakeJingleSession.cpp new file mode 100644 index 0000000..82ec631 --- /dev/null +++ b/Swiften/Jingle/FakeJingleSession.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Jingle/FakeJingleSession.h> + +#include <boost/smart_ptr/make_shared.hpp> + +namespace Swift { + +FakeJingleSession::FakeJingleSession(const JID& initiator, const std::string& id) : JingleSession(initiator, id) { + +} + +FakeJingleSession::~FakeJingleSession() { +} + +void FakeJingleSession::sendInitiate(const JingleContentID& id, JingleDescription::ref desc, JingleTransportPayload::ref payload) { + calledCommands.push_back(InitiateCall(id, desc, payload)); +} + +void FakeJingleSession::sendTerminate(JinglePayload::Reason::Type reason) { + calledCommands.push_back(TerminateCall(reason)); +} + +void FakeJingleSession::sendInfo(boost::shared_ptr<Payload> payload) { + calledCommands.push_back(InfoCall(payload)); +} + +void FakeJingleSession::sendAccept(const JingleContentID& id, JingleDescription::ref desc, JingleTransportPayload::ref payload) { + calledCommands.push_back(AcceptCall(id, desc, payload)); +} + +void FakeJingleSession::sendTransportInfo(const JingleContentID& id, JingleTransportPayload::ref payload) { + calledCommands.push_back(InfoTransportCall(id, payload)); +} + +void FakeJingleSession::sendTransportAccept(const JingleContentID& id, JingleTransportPayload::ref payload) { + calledCommands.push_back(AcceptTransportCall(id, payload)); +} + +void FakeJingleSession::sendTransportReject(const JingleContentID& id, JingleTransportPayload::ref payload) { + calledCommands.push_back(RejectTransportCall(id, payload)); +} + +void FakeJingleSession::sendTransportReplace(const JingleContentID& id, JingleTransportPayload::ref payload) { + calledCommands.push_back(ReplaceTransportCall(id, payload)); +} + +} diff --git a/Swiften/Jingle/FakeJingleSession.h b/Swiften/Jingle/FakeJingleSession.h new file mode 100644 index 0000000..fd3d7b7 --- /dev/null +++ b/Swiften/Jingle/FakeJingleSession.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> +#include <string> +#include <vector> +#include <boost/variant.hpp> + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/JinglePayload.h> +#include <Swiften/Jingle/JingleSession.h> +#include <Swiften/Jingle/JingleContentID.h> + +namespace Swift { + class JingleContentID; + + class FakeJingleSession : public JingleSession { + public: + struct InitiateCall { + InitiateCall(JingleContentID contentId, JingleDescription::ref desc, JingleTransportPayload::ref payL) : id(contentId), description(desc), payload(payL) {} + JingleContentID id; + JingleDescription::ref description; + JingleTransportPayload::ref payload; + }; + + struct TerminateCall { + TerminateCall(JinglePayload::Reason::Type r) : reason(r) {} + JinglePayload::Reason::Type reason; + }; + + struct InfoCall { + InfoCall(boost::shared_ptr<Payload> info) : payload(info) {} + boost::shared_ptr<Payload> payload; + }; + + struct AcceptCall { + AcceptCall(JingleContentID contentId, JingleDescription::ref desc, JingleTransportPayload::ref payL) : id(contentId), description(desc), payload(payL) {} + JingleContentID id; + JingleDescription::ref description; + JingleTransportPayload::ref payload; + }; + + struct InfoTransportCall { + InfoTransportCall(JingleContentID contentId, JingleTransportPayload::ref payL) : id(contentId), payload(payL) {} + JingleContentID id; + JingleTransportPayload::ref payload; + }; + + struct AcceptTransportCall { + AcceptTransportCall(JingleContentID contentId, JingleTransportPayload::ref payL) : id(contentId), payload(payL) {} + JingleContentID id; + JingleTransportPayload::ref payload; + }; + + struct RejectTransportCall { + RejectTransportCall(JingleContentID contentId, JingleTransportPayload::ref payL) : id(contentId), payload(payL) {} + JingleContentID id; + JingleTransportPayload::ref payload; + }; + + struct ReplaceTransportCall { + ReplaceTransportCall(JingleContentID contentId, JingleTransportPayload::ref payL) : id(contentId), payload(payL) {} + JingleContentID id; + JingleTransportPayload::ref payload; + }; + + typedef boost::variant<InitiateCall, TerminateCall, AcceptCall, InfoCall, InfoTransportCall, AcceptTransportCall, RejectTransportCall, ReplaceTransportCall> Command; + + public: + typedef boost::shared_ptr<FakeJingleSession> ref; + + FakeJingleSession(const JID& initiator, const std::string& id); + virtual ~FakeJingleSession(); + + virtual void sendInitiate(const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref); + virtual void sendTerminate(JinglePayload::Reason::Type reason); + virtual void sendInfo(boost::shared_ptr<Payload>); + virtual void sendAccept(const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref = JingleTransportPayload::ref()); + virtual void sendTransportInfo(const JingleContentID&, JingleTransportPayload::ref); + virtual void sendTransportAccept(const JingleContentID&, JingleTransportPayload::ref); + virtual void sendTransportReject(const JingleContentID&, JingleTransportPayload::ref); + virtual void sendTransportReplace(const JingleContentID&, JingleTransportPayload::ref); + + public: + std::vector<Command> calledCommands; + }; +} diff --git a/Swiften/Jingle/IncomingJingleSession.cpp b/Swiften/Jingle/IncomingJingleSession.cpp deleted file mode 100644 index b18d9d3..0000000 --- a/Swiften/Jingle/IncomingJingleSession.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include <Swiften/Jingle/IncomingJingleSession.h> - -namespace Swift { - -IncomingJingleSession::IncomingJingleSession(const std::string& id, const std::vector<JingleContent::ref>& contents) : JingleSession(id, contents) { - -} - -} diff --git a/Swiften/Jingle/IncomingJingleSession.h b/Swiften/Jingle/IncomingJingleSession.h deleted file mode 100644 index 64816f6..0000000 --- a/Swiften/Jingle/IncomingJingleSession.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2011 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/Jingle/JingleSession.h> - -namespace Swift { - class IncomingJingleSession : public JingleSession { - public: - IncomingJingleSession(const std::string& id, const std::vector<JingleContent::ref>& contents); - - typedef boost::shared_ptr<IncomingJingleSession> ref; - }; -} diff --git a/Swiften/Jingle/IncomingJingleSessionHandler.h b/Swiften/Jingle/IncomingJingleSessionHandler.h index 5bf9237..d23570d 100644 --- a/Swiften/Jingle/IncomingJingleSessionHandler.h +++ b/Swiften/Jingle/IncomingJingleSessionHandler.h @@ -6,13 +6,13 @@ #pragma once -#include <Swiften/Jingle/IncomingJingleSession.h> +#include <Swiften/Jingle/JingleSession.h> namespace Swift { class IncomingJingleSessionHandler { public: virtual ~IncomingJingleSessionHandler(); - virtual bool handleIncomingJingleSession(IncomingJingleSession::ref) = 0; + virtual bool handleIncomingJingleSession(JingleSession::ref, const std::vector<JingleContentPayload::ref>& contents, const JID& recipient) = 0; }; } diff --git a/Swiften/Jingle/Jingle.h b/Swiften/Jingle/Jingle.h new file mode 100644 index 0000000..ba4dfe3 --- /dev/null +++ b/Swiften/Jingle/Jingle.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> + +#include <Swiften/Elements/JingleContentPayload.h> + +namespace Swift { + namespace Jingle { + template<typename T> + JingleContentPayload::ref getContentWithDescription(const std::vector<JingleContentPayload::ref>& contents) { + for (size_t i = 0; i < contents.size(); ++i) { + if (contents[i]->getDescription<T>()) { + return contents[i]; + } + } + return JingleContentPayload::ref(); + } + } +} diff --git a/Swiften/Jingle/JingleContentID.h b/Swiften/Jingle/JingleContentID.h new file mode 100644 index 0000000..fc0cc8f --- /dev/null +++ b/Swiften/Jingle/JingleContentID.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <string> + +#include <Swiften/Elements/JingleContentPayload.h> + +namespace Swift { + class JingleContentID { + public: + JingleContentID(const std::string& name, JingleContentPayload::Creator creator) : name(name), creator(creator) { + } + + const std::string getName() const { + return this->name; + } + + JingleContentPayload::Creator getCreator() const { + return this->creator; + } + + private: + std::string name; + JingleContentPayload::Creator creator; + }; +} diff --git a/Swiften/Jingle/JingleResponder.cpp b/Swiften/Jingle/JingleResponder.cpp index 2397e63..4c82f51 100644 --- a/Swiften/Jingle/JingleResponder.cpp +++ b/Swiften/Jingle/JingleResponder.cpp @@ -9,14 +9,19 @@ #include <boost/smart_ptr/make_shared.hpp> #include <Swiften/Jingle/JingleSessionManager.h> -#include <Swiften/Jingle/IncomingJingleSession.h> +#include <Swiften/Jingle/JingleSessionImpl.h> + +#include <Swiften/Base/Log.h> namespace Swift { -JingleResponder::JingleResponder(JingleSessionManager* sessionManager, IQRouter* router) : SetResponder<JinglePayload>(router), sessionManager(sessionManager) { +JingleResponder::JingleResponder(JingleSessionManager* sessionManager, IQRouter* router) : SetResponder<JinglePayload>(router), sessionManager(sessionManager), router(router) { +} + +JingleResponder::~JingleResponder() { } -bool JingleResponder::handleSetRequest(const JID& from, const JID&, const std::string& id, boost::shared_ptr<JinglePayload> payload) { +bool JingleResponder::handleSetRequest(const JID& from, const JID& to, const std::string& id, boost::shared_ptr<JinglePayload> payload) { if (payload->getAction() == JinglePayload::SessionInitiate) { if (sessionManager->getSession(from, payload->getSessionID())) { // TODO: Add tie-break error @@ -24,17 +29,29 @@ bool JingleResponder::handleSetRequest(const JID& from, const JID&, const std::s } else { sendResponse(from, id, boost::shared_ptr<JinglePayload>()); - IncomingJingleSession::ref session = boost::make_shared<IncomingJingleSession>(id, payload->getContents()); - sessionManager->handleIncomingSession(from, session); + if (!payload->getInitiator().isBare()) { + JingleSessionImpl::ref session = boost::make_shared<JingleSessionImpl>(payload->getInitiator(), from, payload->getSessionID(), router); + sessionManager->handleIncomingSession(from, to, session, payload->getContents()); + } else { + SWIFT_LOG(debug) << "Unable to create Jingle session due to initiator not being a full JID." << std::endl; + } } } else { - JingleSession::ref session = sessionManager->getSession(from, payload->getSessionID()); + JingleSessionImpl::ref session; + if (payload->getInitiator().isValid()) { + SWIFT_LOG(debug) << "Lookup session by initiator." << std::endl; + session = sessionManager->getSession(payload->getInitiator(), payload->getSessionID()); + } else { + SWIFT_LOG(debug) << "Lookup session by from attribute." << std::endl; + session = sessionManager->getSession(from, payload->getSessionID()); + } if (session) { session->handleIncomingAction(payload); sendResponse(from, id, boost::shared_ptr<JinglePayload>()); } else { + std::cerr << "WARN: Didn't find jingle session!" << std::endl; // TODO: Add jingle-specific error sendError(from, id, ErrorPayload::ItemNotFound, ErrorPayload::Cancel); } diff --git a/Swiften/Jingle/JingleResponder.h b/Swiften/Jingle/JingleResponder.h index 6e1965c..6f4d688 100644 --- a/Swiften/Jingle/JingleResponder.h +++ b/Swiften/Jingle/JingleResponder.h @@ -16,11 +16,12 @@ namespace Swift { class JingleResponder : public SetResponder<JinglePayload> { public: JingleResponder(JingleSessionManager* sessionManager, IQRouter* router); - + virtual ~JingleResponder(); private: virtual bool handleSetRequest(const JID& from, const JID& to, const std::string& id, boost::shared_ptr<JinglePayload> payload); private: JingleSessionManager* sessionManager; + IQRouter* router; }; } diff --git a/Swiften/Jingle/JingleSession.cpp b/Swiften/Jingle/JingleSession.cpp index d255abd..eb649f3 100644 --- a/Swiften/Jingle/JingleSession.cpp +++ b/Swiften/Jingle/JingleSession.cpp @@ -10,21 +10,13 @@ namespace Swift { -JingleSession::JingleSession(const std::string& id, const std::vector<JingleContent::ref>& contents) : id(id), contents(contents) { - +JingleSession::JingleSession(const JID& initiator, const std::string& id) : initiator(initiator), id(id) { + // initiator must always be a full JID; session lookup based on it wouldn't work otherwise + // this is checked on an upper level so that the assert never fails + assert(!initiator.isBare()); } JingleSession::~JingleSession() { } -void JingleSession::handleIncomingAction(JinglePayload::ref) { -} - -void JingleSession::terminate(JinglePayload::Reason::Type reason) { - JinglePayload::ref payload = boost::make_shared<JinglePayload>(JinglePayload::SessionTerminate, id); - payload->setReason(JinglePayload::Reason(reason)); - //onAction(payload) -} - - } diff --git a/Swiften/Jingle/JingleSession.h b/Swiften/Jingle/JingleSession.h index fe8aa01..150ad79 100644 --- a/Swiften/Jingle/JingleSession.h +++ b/Swiften/Jingle/JingleSession.h @@ -7,47 +7,51 @@ #pragma once #include <boost/shared_ptr.hpp> +#include <boost/optional.hpp> -#include <Swiften/Base/boost_bsignals.h> #include <string> + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/JID/JID.h> #include <Swiften/Elements/JinglePayload.h> -#include <Swiften/Elements/JingleContent.h> -#include <Swiften/Base/foreach.h> namespace Swift { + class JingleContentID; + class JingleSession { - friend class JingleResponder; public: typedef boost::shared_ptr<JingleSession> ref; - JingleSession(const std::string& id, const std::vector<JingleContent::ref>& contents); + JingleSession(const JID& initiator, const std::string& id); virtual ~JingleSession(); - std::string getID() const { - return id; + const JID& getInitiator() const { + return initiator; } - template<typename T> - JingleContent::ref getContentWithDescription() const { - foreach (JingleContent::ref content, contents) { - if (content->getDescription<T>()) { - return content; - } - } - return JingleContent::ref(); - } - - const std::vector<JingleContent::ref>& getContents() const { - return contents; + const std::string& getID() const { + return id; } + virtual void sendInitiate(const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref) = 0; + virtual void sendTerminate(JinglePayload::Reason::Type reason) = 0; + virtual void sendInfo(boost::shared_ptr<Payload>) = 0; + virtual void sendAccept(const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref = JingleTransportPayload::ref()) = 0; + virtual void sendTransportInfo(const JingleContentID&, JingleTransportPayload::ref) = 0; + virtual void sendTransportAccept(const JingleContentID&, JingleTransportPayload::ref) = 0; + virtual void sendTransportReject(const JingleContentID&, JingleTransportPayload::ref) = 0; + virtual void sendTransportReplace(const JingleContentID&, JingleTransportPayload::ref) = 0; - void terminate(JinglePayload::Reason::Type reason); - - private: - void handleIncomingAction(JinglePayload::ref); + public: + boost::signal<void (const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref)> onSessionAcceptReceived; + boost::signal<void (JinglePayload::ref)> onSessionInfoReceived; + boost::signal<void (boost::optional<JinglePayload::Reason>)> onSessionTerminateReceived; + boost::signal<void (const JingleContentID&, JingleTransportPayload::ref)> onTransportAcceptReceived; + boost::signal<void (const JingleContentID&, JingleTransportPayload::ref)> onTransportInfoReceived; + boost::signal<void (const JingleContentID&, JingleTransportPayload::ref)> onTransportRejectReceived; + boost::signal<void (const JingleContentID&, JingleTransportPayload::ref)> onTransportReplaceReceived; private: + JID initiator; std::string id; - std::vector<JingleContent::ref> contents; }; } diff --git a/Swiften/Jingle/JingleSessionImpl.cpp b/Swiften/Jingle/JingleSessionImpl.cpp new file mode 100644 index 0000000..98c5196 --- /dev/null +++ b/Swiften/Jingle/JingleSessionImpl.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Jingle/JingleSessionImpl.h> + +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Parser/PayloadParsers/JingleParser.h> +#include <Swiften/Jingle/JingleContentID.h> +#include <Swiften/Elements/JingleContentPayload.h> +#include <Swiften/Queries/Request.h> +#include <Swiften/Queries/GenericRequest.h> + +#include <Swiften/Base/Log.h> + +#include "Swiften/Serializer/PayloadSerializers/JinglePayloadSerializer.h" +#include "Swiften/FileTransfer/JingleTransport.h" + +namespace Swift { + +JingleSessionImpl::JingleSessionImpl(const JID& initiator, const JID& peerJID, const std::string& id, IQRouter* router) : JingleSession(initiator, id), iqRouter(router), peerJID(peerJID) { + SWIFT_LOG(debug) << "initiator: " << initiator << ", peerJID: " << peerJID << std::endl; +} + +void JingleSessionImpl::handleIncomingAction(JinglePayload::ref action) { + if (action->getAction() == JinglePayload::SessionTerminate) { + onSessionTerminateReceived(action->getReason()); + return; + } + if (action->getAction() == JinglePayload::SessionInfo) { + onSessionInfoReceived(action); + return; + } + + JingleContentPayload::ref content = action->getPayload<JingleContentPayload>(); + if (!content) { + SWIFT_LOG(debug) << "no content payload!" << std::endl; + return; + } + JingleContentID contentID(content->getName(), content->getCreator()); + JingleDescription::ref description = content->getDescriptions().empty() ? JingleDescription::ref() : content->getDescriptions()[0]; + JingleTransportPayload::ref transport = content->getTransports().empty() ? JingleTransportPayload::ref() : content->getTransports()[0]; + switch(action->getAction()) { + case JinglePayload::SessionAccept: + onSessionAcceptReceived(contentID, description, transport); + return; + case JinglePayload::TransportAccept: + onTransportAcceptReceived(contentID, transport); + return; + case JinglePayload::TransportInfo: + onTransportInfoReceived(contentID, transport); + return; + case JinglePayload::TransportReject: + onTransportRejectReceived(contentID, transport); + return; + case JinglePayload::TransportReplace: + onTransportReplaceReceived(contentID, transport); + return; + // following unused Jingle actions + case JinglePayload::ContentAccept: + case JinglePayload::ContentAdd: + case JinglePayload::ContentModify: + case JinglePayload::ContentReject: + case JinglePayload::ContentRemove: + case JinglePayload::DescriptionInfo: + case JinglePayload::SecurityInfo: + + // handled elsewhere + case JinglePayload::SessionInitiate: + case JinglePayload::SessionInfo: + case JinglePayload::SessionTerminate: + + case JinglePayload::UnknownAction: + return; + } + std::cerr << "Unhandled Jingle action!!! ACTION: " << action->getAction() << std::endl; +} + +void JingleSessionImpl::sendInitiate(const JingleContentID& id, JingleDescription::ref description, JingleTransportPayload::ref transport) { + JinglePayload::ref payload = boost::make_shared<JinglePayload>(JinglePayload::SessionInitiate, getID()); + payload->setInitiator(getInitiator()); + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(id.getCreator()); + content->setName(id.getName()); + content->addDescription(description); + content->addTransport(transport); + payload->addPayload(content); + + sendSetRequest(payload); +} + +void JingleSessionImpl::sendTerminate(JinglePayload::Reason::Type reason) { + JinglePayload::ref payload = boost::make_shared<JinglePayload>(JinglePayload::SessionTerminate, getID()); + payload->setReason(JinglePayload::Reason(reason)); + payload->setInitiator(getInitiator()); + sendSetRequest(payload); +} + +void JingleSessionImpl::sendInfo(boost::shared_ptr<Payload> info) { + JinglePayload::ref payload = boost::make_shared<JinglePayload>(JinglePayload::SessionInfo, getID()); + payload->addPayload(info); + + sendSetRequest(payload); +} + +void JingleSessionImpl::sendAccept(const JingleContentID& id, JingleDescription::ref description, JingleTransportPayload::ref transPayload) { + JinglePayload::ref payload = createPayload(); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(id.getCreator()); + content->setName(id.getName()); + content->addTransport(transPayload); + content->addDescription(description); + payload->setAction(JinglePayload::SessionAccept); + payload->addPayload(content); + + // put into IQ:set and send it away + sendSetRequest(payload); +} + + +void JingleSessionImpl::sendTransportAccept(const JingleContentID& id, JingleTransportPayload::ref transPayload) { + JinglePayload::ref payload = createPayload(); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(id.getCreator()); + content->setName(id.getName()); + content->addTransport(transPayload); + payload->setAction(JinglePayload::TransportAccept); + payload->addPayload(content); + + // put into IQ:set and send it away + sendSetRequest(payload); +} + +void JingleSessionImpl::sendTransportInfo(const JingleContentID& id, JingleTransportPayload::ref transPayload) { + JinglePayload::ref payload = createPayload(); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(id.getCreator()); + content->setName(id.getName()); + content->addTransport(transPayload); + payload->setAction(JinglePayload::TransportInfo); + payload->addPayload(content); + + sendSetRequest(payload); +} + +void JingleSessionImpl::sendTransportReject(const JingleContentID& /* id */, JingleTransportPayload::ref /* transPayload */) { + SWIFT_LOG(debug) << "NOT IMPLEMENTED YET!!!!" << std::endl; +} + +void JingleSessionImpl::sendTransportReplace(const JingleContentID& id, JingleTransportPayload::ref transPayload) { + JinglePayload::ref payload = createPayload(); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(id.getCreator()); + content->setName(id.getName()); + content->addTransport(transPayload); + payload->setAction(JinglePayload::TransportReplace); + payload->addContent(content); + + sendSetRequest(payload); +} + + +void JingleSessionImpl::sendSetRequest(JinglePayload::ref payload) { + boost::shared_ptr<GenericRequest<JinglePayload> > request = boost::make_shared<GenericRequest<JinglePayload> >(IQ::Set, peerJID, payload, iqRouter); + request->send(); +} + + +JinglePayload::ref JingleSessionImpl::createPayload() const { + JinglePayload::ref payload = boost::make_shared<JinglePayload>(); + payload->setSessionID(getID()); + payload->setInitiator(getInitiator()); + return payload; +} + + + +} diff --git a/Swiften/Jingle/JingleSessionImpl.h b/Swiften/Jingle/JingleSessionImpl.h new file mode 100644 index 0000000..3c1559a --- /dev/null +++ b/Swiften/Jingle/JingleSessionImpl.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 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/Jingle/JingleSession.h> + +namespace Swift { + class IQRouter; + + class JingleSessionImpl : public JingleSession { + friend class JingleResponder; + public: + typedef boost::shared_ptr<JingleSessionImpl> ref; + + JingleSessionImpl(const JID& initiator, const JID&, const std::string& id, IQRouter* router); + + virtual void sendInitiate(const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref); + virtual void sendTerminate(JinglePayload::Reason::Type reason); + virtual void sendInfo(boost::shared_ptr<Payload>); + virtual void sendAccept(const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref); + virtual void sendTransportInfo(const JingleContentID&, JingleTransportPayload::ref); + virtual void sendTransportAccept(const JingleContentID&, JingleTransportPayload::ref); + virtual void sendTransportReject(const JingleContentID&, JingleTransportPayload::ref); + virtual void sendTransportReplace(const JingleContentID&, JingleTransportPayload::ref); + + private: + void handleIncomingAction(JinglePayload::ref); + + void sendSetRequest(JinglePayload::ref payload); + JinglePayload::ref createPayload() const; + + private: + IQRouter *iqRouter; + JID peerJID; + }; +} diff --git a/Swiften/Jingle/JingleSessionManager.cpp b/Swiften/Jingle/JingleSessionManager.cpp index e60449b..2e15fcd 100644 --- a/Swiften/Jingle/JingleSessionManager.cpp +++ b/Swiften/Jingle/JingleSessionManager.cpp @@ -7,20 +7,24 @@ #include <Swiften/Jingle/JingleSessionManager.h> #include <Swiften/Jingle/JingleResponder.h> #include <Swiften/Jingle/IncomingJingleSessionHandler.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/Algorithm.h> namespace Swift { JingleSessionManager::JingleSessionManager(IQRouter* router) : router(router) { responder = new JingleResponder(this, router); + responder->start(); } JingleSessionManager::~JingleSessionManager() { + responder->stop(); delete responder; } -JingleSession::ref JingleSessionManager::getSession(const JID& jid, const std::string& id) const { - SessionMap::const_iterator i = incomingSessions.find(JIDSession(jid, id)); - return i != incomingSessions.end() ? i->second : JingleSession::ref(); +JingleSessionImpl::ref JingleSessionManager::getSession(const JID& jid, const std::string& id) const { + SessionMap::const_iterator i = sessions.find(JIDSession(jid, id)); + return i != sessions.end() ? i->second : JingleSessionImpl::ref(); } void JingleSessionManager::addIncomingSessionHandler(IncomingJingleSessionHandler* handler) { @@ -28,13 +32,18 @@ void JingleSessionManager::addIncomingSessionHandler(IncomingJingleSessionHandle } void JingleSessionManager::removeIncomingSessionHandler(IncomingJingleSessionHandler* handler) { - incomingSessionHandlers.erase(std::remove(incomingSessionHandlers.begin(), incomingSessionHandlers.end(), handler), incomingSessionHandlers.end()); + erase(incomingSessionHandlers, handler); } -void JingleSessionManager::handleIncomingSession(const JID& from, IncomingJingleSession::ref session) { - incomingSessions.insert(std::make_pair(JIDSession(from, session->getID()), session)); +void JingleSessionManager::registerOutgoingSession(const JID& initiator, JingleSessionImpl::ref session) { + sessions.insert(std::make_pair(JIDSession(initiator, session->getID()), session)); + SWIFT_LOG(debug) << "Added session " << session->getID() << " for initiator " << initiator.toString() << std::endl; +} + +void JingleSessionManager::handleIncomingSession(const JID& initiator, const JID& recipient, JingleSessionImpl::ref session, const std::vector<JingleContentPayload::ref>& contents) { + sessions.insert(std::make_pair(JIDSession(initiator, session->getID()), session)); foreach (IncomingJingleSessionHandler* handler, incomingSessionHandlers) { - if (handler->handleIncomingJingleSession(session)) { + if (handler->handleIncomingJingleSession(session, contents, recipient)) { return; } } diff --git a/Swiften/Jingle/JingleSessionManager.h b/Swiften/Jingle/JingleSessionManager.h index 3e99656..b4f2846 100644 --- a/Swiften/Jingle/JingleSessionManager.h +++ b/Swiften/Jingle/JingleSessionManager.h @@ -10,7 +10,7 @@ #include <map> #include <Swiften/Base/boost_bsignals.h> -#include <Swiften/Jingle/IncomingJingleSession.h> +#include <Swiften/Jingle/JingleSessionImpl.h> namespace Swift { class IQRouter; @@ -23,27 +23,28 @@ namespace Swift { JingleSessionManager(IQRouter* router); ~JingleSessionManager(); - JingleSession::ref getSession(const JID& jid, const std::string& id) const; + JingleSessionImpl::ref getSession(const JID& jid, const std::string& id) const; void addIncomingSessionHandler(IncomingJingleSessionHandler* handler); void removeIncomingSessionHandler(IncomingJingleSessionHandler* handler); + void registerOutgoingSession(const JID& initiator, JingleSessionImpl::ref); protected: - void handleIncomingSession(const JID& from, IncomingJingleSession::ref); + void handleIncomingSession(const JID& initiator, const JID& recipient, JingleSessionImpl::ref, const std::vector<JingleContentPayload::ref>& contents); private: IQRouter* router; JingleResponder* responder; std::vector<IncomingJingleSessionHandler*> incomingSessionHandlers; struct JIDSession { - JIDSession(const JID& jid, const std::string& session) : jid(jid), session(session) {} + JIDSession(const JID& initiator, const std::string& session) : initiator(initiator), session(session) {} bool operator<(const JIDSession& o) const { - return jid == o.jid ? session < o.session : jid < o.jid; + return initiator == o.initiator ? session < o.session : initiator < o.initiator; } - JID jid; + JID initiator; std::string session; }; - typedef std::map<JIDSession, JingleSession::ref> SessionMap; - SessionMap incomingSessions; + typedef std::map<JIDSession, JingleSessionImpl::ref> SessionMap; + SessionMap sessions; }; } diff --git a/Swiften/Jingle/SConscript b/Swiften/Jingle/SConscript index a8890b7..5dcf293 100644 --- a/Swiften/Jingle/SConscript +++ b/Swiften/Jingle/SConscript @@ -1,11 +1,12 @@ Import("swiften_env") sources = [ - "IncomingJingleSession.cpp", + "JingleSession.cpp", + "JingleSessionImpl.cpp", "IncomingJingleSessionHandler.cpp", "JingleSessionManager.cpp", "JingleResponder.cpp", - "JingleSession.cpp", + "FakeJingleSession.cpp", ] swiften_env.Append(SWIFTEN_OBJECTS = swiften_env.SwiftenObject(sources)) diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiBrowseQuery.cpp b/Swiften/LinkLocal/DNSSD/Avahi/AvahiBrowseQuery.cpp new file mode 100644 index 0000000..e31bf87 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiBrowseQuery.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiBrowseQuery.h> + +#include <boost/bind.hpp> +#include <iostream> + +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h> + +namespace Swift { + +void AvahiBrowseQuery::startBrowsing() { + std::cout << "Start browsing" << std::endl; + assert(!browser); + avahi_threaded_poll_lock(querier->getThreadedPoll()); + browser = avahi_service_browser_new(querier->getClient(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_presence._tcp", NULL, static_cast<AvahiLookupFlags>(0), &handleServiceDiscoveredStatic, this); + if (!browser) { + std::cout << "Error" << std::endl; + eventLoop->postEvent(boost::bind(boost::ref(onError)), shared_from_this()); + } + avahi_threaded_poll_unlock(querier->getThreadedPoll()); +} + +void AvahiBrowseQuery::stopBrowsing() { + std::cout << "Stop browsing" << std::endl; + avahi_threaded_poll_lock(querier->getThreadedPoll()); + avahi_service_browser_free(browser); + browser = NULL; + avahi_threaded_poll_unlock(querier->getThreadedPoll()); +} + +void AvahiBrowseQuery::handleServiceDiscovered(AvahiServiceBrowser *, AvahiIfIndex interfaceIndex, AvahiProtocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags) { + switch (event) { + case AVAHI_BROWSER_FAILURE: + std::cout << "Service browse error" << std::endl; + eventLoop->postEvent(boost::bind(boost::ref(onError)), shared_from_this()); + break; + case AVAHI_BROWSER_NEW: { + DNSSDServiceID service(name, domain, type, interfaceIndex); + std::cout << "Service discovered " << name << " " << domain << " " << type << " " << interfaceIndex << std::endl; + eventLoop->postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this()); + break; + } + case AVAHI_BROWSER_REMOVE: { + std::cout << "Service went away " << name << " " << domain << " " << type << " " << interfaceIndex << std::endl; + DNSSDServiceID service(name, domain, type, interfaceIndex); + eventLoop->postEvent(boost::bind(boost::ref(onServiceRemoved), service), shared_from_this()); + break; + } + case AVAHI_BROWSER_ALL_FOR_NOW: + case AVAHI_BROWSER_CACHE_EXHAUSTED: + break; + } +} + +} diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Avahi/AvahiBrowseQuery.h index 163a5f6..38e796d 100644 --- a/Swiften/LinkLocal/DNSSD/Avahi/AvahiBrowseQuery.h +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiBrowseQuery.h @@ -6,11 +6,11 @@ #pragma once -#include <boost/bind.hpp> +#include <avahi-client/lookup.h> -#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h" -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h> +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { class AvahiQuerier; @@ -20,54 +20,15 @@ namespace Swift { AvahiBrowseQuery(boost::shared_ptr<AvahiQuerier> q, EventLoop* eventLoop) : AvahiQuery(q, eventLoop), browser(NULL) { } - void startBrowsing() { - std::cout << "Start browsing" << std::endl; - assert(!browser); - avahi_threaded_poll_lock(querier->getThreadedPoll()); - browser = avahi_service_browser_new(querier->getClient(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_presence._tcp", NULL, static_cast<AvahiLookupFlags>(0), &handleServiceDiscoveredStatic, this); - if (!browser) { - std::cout << "Error" << std::endl; - eventLoop->postEvent(boost::bind(boost::ref(onError)), shared_from_this()); - } - avahi_threaded_poll_unlock(querier->getThreadedPoll()); - } - - void stopBrowsing() { - std::cout << "Stop browsing" << std::endl; - avahi_threaded_poll_lock(querier->getThreadedPoll()); - avahi_service_browser_free(browser); - browser = NULL; - avahi_threaded_poll_unlock(querier->getThreadedPoll()); - } + void startBrowsing(); + void stopBrowsing(); private: static void handleServiceDiscoveredStatic(AvahiServiceBrowser *b, AvahiIfIndex interfaceIndex, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void* context) { static_cast<AvahiBrowseQuery*>(context)->handleServiceDiscovered(b, interfaceIndex, protocol, event, name, type, domain, flags); } - void handleServiceDiscovered(AvahiServiceBrowser *, AvahiIfIndex interfaceIndex, AvahiProtocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags) { - switch (event) { - case AVAHI_BROWSER_FAILURE: - std::cout << "Service browse error" << std::endl; - eventLoop->postEvent(boost::bind(boost::ref(onError)), shared_from_this()); - break; - case AVAHI_BROWSER_NEW: { - DNSSDServiceID service(name, domain, type, interfaceIndex); - std::cout << "Service discovered " << name << " " << domain << " " << type << " " << interfaceIndex << std::endl; - eventLoop->postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this()); - break; - } - case AVAHI_BROWSER_REMOVE: { - std::cout << "Service went away " << name << " " << domain << " " << type << " " << interfaceIndex << std::endl; - DNSSDServiceID service(name, domain, type, interfaceIndex); - eventLoop->postEvent(boost::bind(boost::ref(onServiceRemoved), service), shared_from_this()); - break; - } - case AVAHI_BROWSER_ALL_FOR_NOW: - case AVAHI_BROWSER_CACHE_EXHAUSTED: - break; - } - } + void handleServiceDiscovered(AvahiServiceBrowser *, AvahiIfIndex interfaceIndex, AvahiProtocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags); private: AvahiServiceBrowser* browser; diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.cpp b/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.cpp index dd189d9..e9f5564 100644 --- a/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.cpp +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h" +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h> #include <iostream> -#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiBrowseQuery.h" -#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveServiceQuery.h" -#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveHostnameQuery.h" -#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.h" +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiBrowseQuery.h> +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveServiceQuery.h> +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveHostnameQuery.h> +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.h> namespace Swift { diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h b/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h index bfb017e..6ddd23d 100644 --- a/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h @@ -15,10 +15,10 @@ #include <avahi-common/malloc.h> #include <avahi-common/error.h> -#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" +#include <Swiften/LinkLocal/DNSSD/DNSSDQuerier.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { - class ByteArray; class EventLoop; class AvahiQuerier : diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.cpp b/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.cpp index 1b40dfd..3b0e8da 100644 --- a/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.cpp +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h" -#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h" +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h> +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h> namespace Swift { diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h b/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h index f5df032..047e1cd 100644 --- a/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h @@ -9,7 +9,7 @@ #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> -#include "Swiften/EventLoop/EventOwner.h" +#include <Swiften/EventLoop/EventOwner.h> namespace Swift { class AvahiQuerier; diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.cpp b/Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.cpp new file mode 100644 index 0000000..8a7ed3b --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.h> + +#include <iostream> +#include <boost/bind.hpp> + +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h> + +namespace Swift { + +void AvahiRegisterQuery::registerService() { + std::cout << "Registering service " << name << ":" << port << std::endl; + avahi_threaded_poll_lock(querier->getThreadedPoll()); + if (!group) { + std::cout << "Creating entry group" << std::endl; + group = avahi_entry_group_new(querier->getClient(), handleEntryGroupChange, this); + if (!group) { + std::cout << "Error ceating entry group" << std::endl; + eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this()); + } + } + + doRegisterService(); + avahi_threaded_poll_unlock(querier->getThreadedPoll()); +} + +void AvahiRegisterQuery::unregisterService() { + if (group) { + avahi_entry_group_free(group); + group = NULL; + } +} + +void AvahiRegisterQuery::updateServiceInfo(const ByteArray& txtRecord) { + this->txtRecord = txtRecord; + avahi_threaded_poll_lock(querier->getThreadedPoll()); + assert(group); + avahi_entry_group_reset(group); + doRegisterService(); + avahi_threaded_poll_unlock(querier->getThreadedPoll()); +} + +void AvahiRegisterQuery::doRegisterService() { + AvahiStringList* txtList; + avahi_string_list_parse(vecptr(txtRecord), txtRecord.size(), &txtList); + + int result = avahi_entry_group_add_service_strlst(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, static_cast<AvahiPublishFlags>(0), name.c_str(), "_presence._tcp", NULL, NULL, port, txtList); + if (result < 0) { + std::cout << "Error registering service: " << avahi_strerror(result) << std::endl; + eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this()); + } + result = avahi_entry_group_commit(group); + if (result < 0) { + std::cout << "Error registering service: " << avahi_strerror(result) << std::endl; + } +} + +void AvahiRegisterQuery::handleEntryGroupChange(AvahiEntryGroup* g, AvahiEntryGroupState state) { + std::cout << "ENtry group callback: " << state << std::endl; + switch (state) { + case AVAHI_ENTRY_GROUP_ESTABLISHED : + // Domain is a hack! + eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>(DNSSDServiceID(name, "local", "_presence._tcp", 0))), shared_from_this()); + std::cout << "Entry group established" << std::endl; + break; + case AVAHI_ENTRY_GROUP_COLLISION : { + std::cout << "Entry group collision" << std::endl; + /*char *n; + n = avahi_alternative_service_name(name); + avahi_free(name); + name = n;*/ + break; + } + + case AVAHI_ENTRY_GROUP_FAILURE : + std::cout << "Entry group failure " << avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))) << std::endl; + break; + + case AVAHI_ENTRY_GROUP_UNCOMMITED: + case AVAHI_ENTRY_GROUP_REGISTERING: + ; + + /* + DNSServiceErrorType result = DNSServiceRegister( + &sdRef, 0, 0, name.c_str(), "_presence._tcp", NULL, NULL, port, + txtRecord.getSize(), txtRecord.getData(), + &AvahiRegisterQuery::handleServiceRegisteredStatic, this); + if (result != kDNSServiceErr_NoError) { + sdRef = NULL; + }*/ + //eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this()); + } +} + + +} diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.h index 07966af..b47ed12 100644 --- a/Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.h +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.h @@ -8,10 +8,10 @@ #include <avahi-client/publish.h> -#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" -#include "Swiften/Base/ByteArray.h" -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { class AvahiQuerier; @@ -21,94 +21,18 @@ namespace Swift { AvahiRegisterQuery(const std::string& name, int port, const ByteArray& txtRecord, boost::shared_ptr<AvahiQuerier> querier, EventLoop* eventLoop) : AvahiQuery(querier, eventLoop), name(name), port(port), txtRecord(txtRecord), group(0) { } - void registerService() { - std::cout << "Registering service " << name << ":" << port << std::endl; - avahi_threaded_poll_lock(querier->getThreadedPoll()); - if (!group) { - std::cout << "Creating entry group" << std::endl; - group = avahi_entry_group_new(querier->getClient(), handleEntryGroupChange, this); - if (!group) { - std::cout << "Error ceating entry group" << std::endl; - eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this()); - } - } - - doRegisterService(); - avahi_threaded_poll_unlock(querier->getThreadedPoll()); - } - - void unregisterService() { - if (group) { - avahi_entry_group_free(group); - group = NULL; - } - } - - void updateServiceInfo(const ByteArray& txtRecord) { - this->txtRecord = txtRecord; - avahi_threaded_poll_lock(querier->getThreadedPoll()); - assert(group); - avahi_entry_group_reset(group); - doRegisterService(); - avahi_threaded_poll_unlock(querier->getThreadedPoll()); - } + void registerService(); + void unregisterService(); + void updateServiceInfo(const ByteArray& txtRecord); private: - void doRegisterService() { - AvahiStringList* txtList; - avahi_string_list_parse(txtRecord.getData(), txtRecord.getSize(), &txtList); - - int result = avahi_entry_group_add_service_strlst(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, static_cast<AvahiPublishFlags>(0), name.c_str(), "_presence._tcp", NULL, NULL, port, txtList); - if (result < 0) { - std::cout << "Error registering service: " << avahi_strerror(result) << std::endl; - eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this()); - } - result = avahi_entry_group_commit(group); - if (result < 0) { - std::cout << "Error registering service: " << avahi_strerror(result) << std::endl; - } - } + void doRegisterService(); static void handleEntryGroupChange(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) { static_cast<AvahiRegisterQuery*>(userdata)->handleEntryGroupChange(g, state); } - void handleEntryGroupChange(AvahiEntryGroup* g, AvahiEntryGroupState state) { - std::cout << "ENtry group callback: " << state << std::endl; - switch (state) { - case AVAHI_ENTRY_GROUP_ESTABLISHED : - // Domain is a hack! - eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>(DNSSDServiceID(name, "local", "_presence._tcp", 0))), shared_from_this()); - std::cout << "Entry group established" << std::endl; - break; - case AVAHI_ENTRY_GROUP_COLLISION : { - std::cout << "Entry group collision" << std::endl; - /*char *n; - n = avahi_alternative_service_name(name); - avahi_free(name); - name = n;*/ - break; - } - - case AVAHI_ENTRY_GROUP_FAILURE : - std::cout << "Entry group failure " << avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))) << std::endl; - break; - - case AVAHI_ENTRY_GROUP_UNCOMMITED: - case AVAHI_ENTRY_GROUP_REGISTERING: - ; - - /* - DNSServiceErrorType result = DNSServiceRegister( - &sdRef, 0, 0, name.c_str(), "_presence._tcp", NULL, NULL, port, - txtRecord.getSize(), txtRecord.getData(), - &AvahiRegisterQuery::handleServiceRegisteredStatic, this); - if (result != kDNSServiceErr_NoError) { - sdRef = NULL; - }*/ - //eventLoop->postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this()); - } - } + void handleEntryGroupChange(AvahiEntryGroup* g, AvahiEntryGroupState state); /* static void handleServiceRegisteredStatic(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) { diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveHostnameQuery.cpp b/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveHostnameQuery.cpp new file mode 100644 index 0000000..d9a1c5c --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveHostnameQuery.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveHostnameQuery.h> + +#include <iostream> +#include <boost/bind.hpp> + +namespace Swift { + +AvahiResolveHostnameQuery::AvahiResolveHostnameQuery(const std::string& hostname, int, boost::shared_ptr<AvahiQuerier> querier, EventLoop* eventLoop) : AvahiQuery(querier, eventLoop), hostname(hostname) { + std::cout << "Resolving hostname " << hostname << std::endl; +} + +void AvahiResolveHostnameQuery::run() { + eventLoop->postEvent(boost::bind(boost::ref(onHostnameResolved), boost::optional<HostAddress>(HostAddress(hostname))), shared_from_this()); +} + +} diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveHostnameQuery.h index 00712f1..5ee6346 100644 --- a/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveHostnameQuery.h +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveHostnameQuery.h @@ -7,10 +7,10 @@ #pragma once #include <string> -#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h" -#include "Swiften/EventLoop/EventLoop.h" -#include "Swiften/Network/HostAddress.h" +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/Network/HostAddress.h> #include <netinet/in.h> @@ -19,13 +19,9 @@ namespace Swift { class AvahiResolveHostnameQuery : public DNSSDResolveHostnameQuery, public AvahiQuery { public: - AvahiResolveHostnameQuery(const std::string& hostname, int, boost::shared_ptr<AvahiQuerier> querier, EventLoop* eventLoop) : AvahiQuery(querier, eventLoop), hostname(hostname) { - std::cout << "Resolving hostname " << hostname << std::endl; - } + AvahiResolveHostnameQuery(const std::string& hostname, int, boost::shared_ptr<AvahiQuerier> querier, EventLoop* eventLoop); - void run() { - eventLoop->postEvent(boost::bind(boost::ref(onHostnameResolved), boost::optional<HostAddress>(HostAddress(hostname))), shared_from_this()); - } + void run(); void finish() { } diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveServiceQuery.cpp b/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveServiceQuery.cpp new file mode 100644 index 0000000..ebd2329 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveServiceQuery.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveServiceQuery.h> + +#include <boost/bind.hpp> +#include <iostream> + +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h> + +namespace Swift { + +void AvahiResolveServiceQuery::start() { + std::cout << "Start resolving " << service.getName() << " " << service.getType() << " " << service.getDomain() << std::endl; + avahi_threaded_poll_lock(querier->getThreadedPoll()); + assert(!resolver); + resolver = avahi_service_resolver_new(querier->getClient(), service.getNetworkInterfaceID(), AVAHI_PROTO_UNSPEC, service.getName().c_str(), service.getType().c_str(), service.getDomain().c_str(), AVAHI_PROTO_UNSPEC, static_cast<AvahiLookupFlags>(0), handleServiceResolvedStatic, this); + if (!resolver) { + std::cout << "Error starting resolver" << std::endl; + eventLoop->postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); + } + avahi_threaded_poll_unlock(querier->getThreadedPoll()); +} + +void AvahiResolveServiceQuery::stop() { + std::cout << "Stop resolving" << std::endl; + avahi_threaded_poll_lock(querier->getThreadedPoll()); + avahi_service_resolver_free(resolver); + resolver = NULL; + avahi_threaded_poll_unlock(querier->getThreadedPoll()); +} + +void AvahiResolveServiceQuery::handleServiceResolved(AvahiServiceResolver* resolver, AvahiIfIndex, AvahiProtocol, AvahiResolverEvent event, const char *name, const char * type, const char* domain, const char * /*host_name*/, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags) { + std::cout << "Resolve finished" << std::endl; + switch(event) { + case AVAHI_RESOLVER_FAILURE: + std::cout << "Resolve error " << avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(resolver))) << std::endl; + eventLoop->postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); + break; + case AVAHI_RESOLVER_FOUND: { + std::cout << "Success" << std::endl; + char a[AVAHI_ADDRESS_STR_MAX]; + avahi_address_snprint(a, sizeof(a), address); + + ByteArray txtRecord; + txtRecord.resize(1024); + avahi_string_list_serialize(txt, vecptr(txtRecord), txtRecord.size()); + + // FIXME: Probably not accurate + std::string fullname = std::string(name) + "." + std::string(type) + "." + std::string(domain) + "."; + std::cout << "Result: " << fullname << "->" << std::string(a) << ":" << port << std::endl; + eventLoop->postEvent( + boost::bind( + boost::ref(onServiceResolved), + Result(fullname, std::string(a), port, txtRecord)), + shared_from_this()); + break; + } + } +} + +} diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveServiceQuery.h index e9c4db1..a39d732 100644 --- a/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveServiceQuery.h +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveServiceQuery.h @@ -6,11 +6,13 @@ #pragma once -#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" -#include "Swiften/Base/ByteArray.h" -#include "Swiften/EventLoop/EventLoop.h" +#include <avahi-client/lookup.h> + +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h> +#include <Swiften/LinkLocal/LinkLocalServiceInfo.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { class AvahiQuerier; @@ -20,59 +22,15 @@ namespace Swift { AvahiResolveServiceQuery(const DNSSDServiceID& service, boost::shared_ptr<AvahiQuerier> querier, EventLoop* eventLoop) : AvahiQuery(querier, eventLoop), service(service), resolver(NULL) { } - void start() { - std::cout << "Start resolving " << service.getName() << " " << service.getType() << " " << service.getDomain() << std::endl; - avahi_threaded_poll_lock(querier->getThreadedPoll()); - assert(!resolver); - resolver = avahi_service_resolver_new(querier->getClient(), service.getNetworkInterfaceID(), AVAHI_PROTO_UNSPEC, service.getName().c_str(), service.getType().c_str(), service.getDomain().c_str(), AVAHI_PROTO_UNSPEC, static_cast<AvahiLookupFlags>(0), handleServiceResolvedStatic, this); - if (!resolver) { - std::cout << "Error starting resolver" << std::endl; - eventLoop->postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); - } - avahi_threaded_poll_unlock(querier->getThreadedPoll()); - } - - void stop() { - std::cout << "Stop resolving" << std::endl; - avahi_threaded_poll_lock(querier->getThreadedPoll()); - avahi_service_resolver_free(resolver); - resolver = NULL; - avahi_threaded_poll_unlock(querier->getThreadedPoll()); - } + void start(); + void stop(); private: static void handleServiceResolvedStatic(AvahiServiceResolver* resolver, AvahiIfIndex interfaceIndex, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void* context) { static_cast<AvahiResolveServiceQuery*>(context)->handleServiceResolved(resolver, interfaceIndex, protocol, event, name, type, domain, host_name, address, port, txt, flags); } - void handleServiceResolved(AvahiServiceResolver* resolver, AvahiIfIndex, AvahiProtocol, AvahiResolverEvent event, const char *name, const char * type, const char* domain, const char * /*host_name*/, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags) { - std::cout << "Resolve finished" << std::endl; - switch(event) { - case AVAHI_RESOLVER_FAILURE: - std::cout << "Resolve error " << avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(resolver))) << std::endl; - eventLoop->postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); - break; - case AVAHI_RESOLVER_FOUND: { - std::cout << "Success" << std::endl; - char a[AVAHI_ADDRESS_STR_MAX]; - avahi_address_snprint(a, sizeof(a), address); - - ByteArray txtRecord; - txtRecord.resize(1024); - avahi_string_list_serialize(txt, txtRecord.getData(), txtRecord.getSize()); - - // FIXME: Probably not accurate - std::string fullname = std::string(name) + "." + std::string(type) + "." + std::string(domain) + "."; - std::cout << "Result: " << fullname << "->" << std::string(a) << ":" << port << std::endl; - eventLoop->postEvent( - boost::bind( - boost::ref(onServiceResolved), - Result(fullname, std::string(a), port, txtRecord)), - shared_from_this()); - break; - } - } - } + void handleServiceResolved(AvahiServiceResolver* resolver, AvahiIfIndex, AvahiProtocol, AvahiResolverEvent event, const char *name, const char * type, const char* domain, const char * /*host_name*/, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags); private: DNSSDServiceID service; diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h index 52c47d7..6e79290 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h @@ -6,9 +6,9 @@ #pragma once -#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h" -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h> +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { class BonjourQuerier; diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp index 2d346d9..530e066 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp @@ -4,17 +4,18 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h" +#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h> #include <unistd.h> #include <sys/socket.h> #include <fcntl.h> -#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h" -#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h" -#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h" -#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h" -#include "Swiften/Base/foreach.h" +#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h> +#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h> +#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h> +#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/Algorithm.h> namespace Swift { @@ -22,6 +23,7 @@ BonjourQuerier::BonjourQuerier(EventLoop* eventLoop) : eventLoop(eventLoop), sto int fds[2]; int result = pipe(fds); assert(result == 0); + (void) result; interruptSelectReadSocket = fds[0]; fcntl(interruptSelectReadSocket, F_SETFL, fcntl(interruptSelectReadSocket, F_GETFL)|O_NONBLOCK); interruptSelectWriteSocket = fds[1]; @@ -59,8 +61,7 @@ void BonjourQuerier::addRunningQuery(boost::shared_ptr<BonjourQuery> query) { void BonjourQuerier::removeRunningQuery(boost::shared_ptr<BonjourQuery> query) { { boost::lock_guard<boost::mutex> lock(runningQueriesMutex); - runningQueries.erase(std::remove( - runningQueries.begin(), runningQueries.end(), query), runningQueries.end()); + erase(runningQueries, query); } } diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h index edd3056..57fde49 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h @@ -9,15 +9,14 @@ #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> #include <list> -#include <boost/thread.hpp> +#include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> -#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" -#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" +#include <Swiften/LinkLocal/DNSSD/DNSSDQuerier.h> +#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { - class ByteArray; - class BonjourQuerier : public DNSSDQuerier, public boost::enable_shared_from_this<BonjourQuerier> { diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.cpp b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.cpp index d7ff5d5..9ff4b9f 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.cpp +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" -#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h" +#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h> +#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h> namespace Swift { diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h index e3cd9a5..d91c57c 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h @@ -11,7 +11,7 @@ #include <boost/enable_shared_from_this.hpp> #include <boost/thread/mutex.hpp> -#include "Swiften/EventLoop/EventOwner.h" +#include <Swiften/EventLoop/EventOwner.h> namespace Swift { class BonjourQuerier; diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h index 7eb7ae1..fd0e9d0 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h @@ -6,10 +6,10 @@ #pragma once -#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" -#include "Swiften/Base/ByteArray.h" -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { class BonjourQuerier; @@ -19,7 +19,7 @@ namespace Swift { BonjourRegisterQuery(const std::string& name, int port, const ByteArray& txtRecord, boost::shared_ptr<BonjourQuerier> querier, EventLoop* eventLoop) : BonjourQuery(querier, eventLoop) { DNSServiceErrorType result = DNSServiceRegister( &sdRef, 0, 0, name.c_str(), "_presence._tcp", NULL, NULL, port, - txtRecord.getSize(), txtRecord.getData(), + txtRecord.size(), vecptr(txtRecord), &BonjourRegisterQuery::handleServiceRegisteredStatic, this); if (result != kDNSServiceErr_NoError) { sdRef = NULL; @@ -41,7 +41,7 @@ namespace Swift { void updateServiceInfo(const ByteArray& txtRecord) { boost::lock_guard<boost::mutex> lock(sdRefMutex); - DNSServiceUpdateRecord(sdRef, NULL, NULL, txtRecord.getSize(), txtRecord.getData(), 0); + DNSServiceUpdateRecord(sdRef, NULL, NULL, txtRecord.size(), vecptr(txtRecord), 0); } private: diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h index b08b0b7..9fdd3d5 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h @@ -9,10 +9,10 @@ #pragma GCC diagnostic ignored "-Wold-style-cast" #include <string> -#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h" -#include "Swiften/EventLoop/EventLoop.h" -#include "Swiften/Network/HostAddress.h" +#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/Network/HostAddress.h> #include <netinet/in.h> diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h index 0501b56..1fb050c 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h @@ -6,11 +6,11 @@ #pragma once -#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" -#include "Swiften/Base/ByteArray.h" -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h> +#include <Swiften/LinkLocal/LinkLocalServiceInfo.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { class BonjourQuerier; @@ -56,7 +56,7 @@ namespace Swift { boost::bind( boost::ref(onServiceResolved), Result(std::string(fullName), std::string(host), port, - ByteArray(reinterpret_cast<const char*>(txtRecord), txtLen))), + createByteArray(reinterpret_cast<const char*>(txtRecord), txtLen))), shared_from_this()); } } diff --git a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.cpp b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.cpp index 4e00692..10edb0c 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.cpp +++ b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h" +#include <Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h> namespace Swift { diff --git a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h index 5871866..c2b3be7 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h @@ -6,9 +6,9 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> -#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" +#include <Swiften/LinkLocal/DNSSD/DNSSDServiceID.h> namespace Swift { class DNSSDBrowseQuery { diff --git a/Swiften/LinkLocal/DNSSD/DNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.cpp index 3bc0cf6..0f32aa6 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDQuerier.cpp +++ b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" +#include <Swiften/LinkLocal/DNSSD/DNSSDQuerier.h> namespace Swift { diff --git a/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h index cd55fb7..e6d548b 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h @@ -8,9 +8,9 @@ #include <boost/shared_ptr.hpp> +#include <Swiften/Base/ByteArray.h> + namespace Swift { - - class ByteArray; class DNSSDServiceID; class DNSSDBrowseQuery; class DNSSDRegisterQuery; diff --git a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.cpp b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.cpp index 2f931ed..9a807a4 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.cpp +++ b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" +#include <Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h> namespace Swift { diff --git a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h index ceff862..e794a90 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h @@ -6,14 +6,13 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/optional.hpp> -#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" +#include <Swiften/LinkLocal/DNSSD/DNSSDServiceID.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { - class ByteArray; - class DNSSDRegisterQuery { public: virtual ~DNSSDRegisterQuery(); diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.cpp b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.cpp index 0c072bb..dd34e3d 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.cpp +++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h" +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h> namespace Swift { diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h index cfaf28f..ee8ffb9 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h @@ -6,10 +6,10 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/optional.hpp> -#include "Swiften/Network/HostAddress.h" +#include <Swiften/Network/HostAddress.h> namespace Swift { class DNSSDResolveHostnameQuery { diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.cpp b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.cpp index a2f18a6..feb1712 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.cpp +++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h> namespace Swift { diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h index ad73663..c8d78aa 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h @@ -6,11 +6,11 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/optional.hpp> -#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" -#include "Swiften/Base/ByteArray.h" +#include <Swiften/LinkLocal/DNSSD/DNSSDServiceID.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { class DNSSDResolveServiceQuery { diff --git a/Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp index 76bd2b7..2f2784c 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp +++ b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" +#include <Swiften/LinkLocal/DNSSD/DNSSDServiceID.h> namespace Swift { diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h index 462e471..b2a6d61 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h" +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h> namespace Swift { class FakeDNSSDQuerier; diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp index d7d0228..1ddeffa 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp @@ -4,15 +4,18 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h" +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h> #include <boost/bind.hpp> +#include <iostream> -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h" -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h" -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h" -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h" -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/Algorithm.h> +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h> +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h> +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h> +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h> +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { @@ -72,8 +75,7 @@ void FakeDNSSDQuerier::addRunningQuery(boost::shared_ptr<FakeDNSSDQuery> query) } void FakeDNSSDQuerier::removeRunningQuery(boost::shared_ptr<FakeDNSSDQuery> query) { - runningQueries.erase(std::remove( - runningQueries.begin(), runningQueries.end(), query), runningQueries.end()); + erase(runningQueries, query); } void FakeDNSSDQuerier::addService(const DNSSDServiceID& id) { diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h index b2871c9..f5166ee 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h @@ -11,15 +11,14 @@ #include <list> #include <set> -#include "Swiften/Base/foreach.h" #include <string> -#include "Swiften/EventLoop/EventOwner.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" -#include "Swiften/Network/HostAddress.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/EventLoop/EventOwner.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDQuerier.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h> +#include <Swiften/Network/HostAddress.h> namespace Swift { - class ByteArray; class FakeDNSSDQuery; class FakeDNSSDBrowseQuery; class EventLoop; @@ -63,8 +62,8 @@ namespace Swift { template<typename T> std::vector< boost::shared_ptr<T> > getAllQueriesEverRun() const { std::vector< boost::shared_ptr<T> > result; - foreach(const boost::shared_ptr<FakeDNSSDQuery>& query, allQueriesEverRun) { - if (boost::shared_ptr<T> resultQuery = boost::dynamic_pointer_cast<T>(query)) { + for (QueryList::const_iterator i = allQueriesEverRun.begin(); i != allQueriesEverRun.end(); ++i) { + if (boost::shared_ptr<T> resultQuery = boost::dynamic_pointer_cast<T>(*i)) { result.push_back(resultQuery); } } @@ -75,8 +74,8 @@ namespace Swift { template<typename T> std::vector< boost::shared_ptr<T> > getQueries() const { std::vector< boost::shared_ptr<T> > result; - foreach(const boost::shared_ptr<FakeDNSSDQuery>& query, runningQueries) { - if (boost::shared_ptr<T> resultQuery = boost::dynamic_pointer_cast<T>(query)) { + for (QueryList::const_iterator i = runningQueries.begin(); i != runningQueries.end(); ++i) { + if (boost::shared_ptr<T> resultQuery = boost::dynamic_pointer_cast<T>(*i)) { result.push_back(resultQuery); } } @@ -86,8 +85,9 @@ namespace Swift { private: std::string domain; EventLoop* eventLoop; - std::list< boost::shared_ptr<FakeDNSSDQuery> > runningQueries; - std::list< boost::shared_ptr<FakeDNSSDQuery> > allQueriesEverRun; + typedef std::list< boost::shared_ptr<FakeDNSSDQuery> > QueryList; + QueryList runningQueries; + QueryList allQueriesEverRun; std::set<DNSSDServiceID> services; typedef std::map<DNSSDServiceID,DNSSDResolveServiceQuery::Result> ServiceInfoMap; ServiceInfoMap serviceInfo; diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.cpp b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.cpp index a27f61c..99f55fa 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.cpp +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h" -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h" +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h> +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h> namespace Swift { diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h index 479c41f..b6d5c98 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h @@ -9,7 +9,7 @@ #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> -#include "Swiften/EventLoop/EventOwner.h" +#include <Swiften/EventLoop/EventOwner.h> namespace Swift { class FakeDNSSDQuerier; diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h index a6ae17a..c568f5b 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h @@ -6,9 +6,9 @@ #pragma once -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" -#include "Swiften/Base/ByteArray.h" +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h> +#include <Swiften/Base/ByteArray.h> #include <string> namespace Swift { diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h index cbaa6e6..aa427cc 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h @@ -7,9 +7,9 @@ #pragma once #include <string> -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h" -#include "Swiften/Network/HostAddress.h" +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h> +#include <Swiften/Network/HostAddress.h> namespace Swift { class FakeDNSSDQuerier; diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h index 3d4a3b9..5c69843 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h @@ -6,9 +6,9 @@ #pragma once -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h> +#include <Swiften/LinkLocal/LinkLocalServiceInfo.h> namespace Swift { class FakeDNSSDQuerier; diff --git a/Swiften/LinkLocal/DNSSD/PlatformDNSSDQuerierFactory.cpp b/Swiften/LinkLocal/DNSSD/PlatformDNSSDQuerierFactory.cpp index 7a42129..cc12573 100644 --- a/Swiften/LinkLocal/DNSSD/PlatformDNSSDQuerierFactory.cpp +++ b/Swiften/LinkLocal/DNSSD/PlatformDNSSDQuerierFactory.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/DNSSD/PlatformDNSSDQuerierFactory.h" +#include <Swiften/LinkLocal/DNSSD/PlatformDNSSDQuerierFactory.h> #if defined(HAVE_BONJOUR) -#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h" +#include <Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h> #elif defined(HAVE_AVAHI) -#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h" +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h> #endif diff --git a/Swiften/LinkLocal/IncomingLinkLocalSession.cpp b/Swiften/LinkLocal/IncomingLinkLocalSession.cpp index 3af6d4c..c4dea64 100644 --- a/Swiften/LinkLocal/IncomingLinkLocalSession.cpp +++ b/Swiften/LinkLocal/IncomingLinkLocalSession.cpp @@ -4,17 +4,17 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/IncomingLinkLocalSession.h" +#include <Swiften/LinkLocal/IncomingLinkLocalSession.h> #include <boost/bind.hpp> -#include "Swiften/Elements/ProtocolHeader.h" -#include "Swiften/Network/Connection.h" -#include "Swiften/StreamStack/StreamStack.h" -#include "Swiften/StreamStack/ConnectionLayer.h" -#include "Swiften/StreamStack/XMPPLayer.h" -#include "Swiften/Elements/StreamFeatures.h" -#include "Swiften/Elements/IQ.h" +#include <Swiften/Elements/ProtocolHeader.h> +#include <Swiften/Network/Connection.h> +#include <Swiften/StreamStack/StreamStack.h> +#include <Swiften/StreamStack/ConnectionLayer.h> +#include <Swiften/StreamStack/XMPPLayer.h> +#include <Swiften/Elements/StreamFeatures.h> +#include <Swiften/Elements/IQ.h> namespace Swift { diff --git a/Swiften/LinkLocal/IncomingLinkLocalSession.h b/Swiften/LinkLocal/IncomingLinkLocalSession.h index a586a2e..68e21a5 100644 --- a/Swiften/LinkLocal/IncomingLinkLocalSession.h +++ b/Swiften/LinkLocal/IncomingLinkLocalSession.h @@ -7,11 +7,11 @@ #pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> -#include "Swiften/Session/Session.h" -#include "Swiften/JID/JID.h" -#include "Swiften/Network/Connection.h" +#include <Swiften/Session/Session.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Network/Connection.h> namespace Swift { class ProtocolHeader; diff --git a/Swiften/LinkLocal/LinkLocalConnector.cpp b/Swiften/LinkLocal/LinkLocalConnector.cpp index 42366e8..af96e65 100644 --- a/Swiften/LinkLocal/LinkLocalConnector.cpp +++ b/Swiften/LinkLocal/LinkLocalConnector.cpp @@ -4,16 +4,16 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/LinkLocalConnector.h" +#include <Swiften/LinkLocal/LinkLocalConnector.h> #include <boost/bind.hpp> -#include "Swiften/Network/Connection.h" -#include "Swiften/Network/ConnectionFactory.h" -#include "Swiften/Network/HostAddress.h" -#include "Swiften/Network/HostAddressPort.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h" +#include <Swiften/Network/Connection.h> +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/HostAddress.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDQuerier.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h> namespace Swift { diff --git a/Swiften/LinkLocal/LinkLocalConnector.h b/Swiften/LinkLocal/LinkLocalConnector.h index 0fbb7ec..0acdc51 100644 --- a/Swiften/LinkLocal/LinkLocalConnector.h +++ b/Swiften/LinkLocal/LinkLocalConnector.h @@ -7,12 +7,12 @@ #pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/enable_shared_from_this.hpp> #include <vector> -#include "Swiften/Network/Connection.h" -#include "Swiften/LinkLocal/LinkLocalService.h" +#include <Swiften/Network/Connection.h> +#include <Swiften/LinkLocal/LinkLocalService.h> namespace Swift { class ConnectionFactory; diff --git a/Swiften/LinkLocal/LinkLocalService.cpp b/Swiften/LinkLocal/LinkLocalService.cpp index c8d707d..7c6538c 100644 --- a/Swiften/LinkLocal/LinkLocalService.cpp +++ b/Swiften/LinkLocal/LinkLocalService.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/LinkLocalService.h" +#include <Swiften/LinkLocal/LinkLocalService.h> namespace Swift { diff --git a/Swiften/LinkLocal/LinkLocalService.h b/Swiften/LinkLocal/LinkLocalService.h index 2e74338..2b7f7b2 100644 --- a/Swiften/LinkLocal/LinkLocalService.h +++ b/Swiften/LinkLocal/LinkLocalService.h @@ -7,10 +7,10 @@ #pragma once #include <string> -#include "Swiften/JID/JID.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include <Swiften/JID/JID.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDServiceID.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h> +#include <Swiften/LinkLocal/LinkLocalServiceInfo.h> namespace Swift { class LinkLocalService { diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index 8393ade..4b68a33 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -7,9 +7,9 @@ #include <boost/bind.hpp> #include <iostream> -#include "Swiften/LinkLocal/LinkLocalServiceBrowser.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h" -#include "Swiften/Network/HostAddress.h" +#include <Swiften/LinkLocal/LinkLocalServiceBrowser.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h> +#include <Swiften/Network/HostAddress.h> namespace Swift { diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.h b/Swiften/LinkLocal/LinkLocalServiceBrowser.h index 56b4aa4..57ed969 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.h +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.h @@ -6,19 +6,19 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> #include <boost/optional.hpp> #include <map> #include <vector> #include <string> -#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" -#include "Swiften/LinkLocal/LinkLocalService.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include <Swiften/LinkLocal/DNSSD/DNSSDQuerier.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDServiceID.h> +#include <Swiften/LinkLocal/LinkLocalService.h> +#include <Swiften/LinkLocal/LinkLocalServiceInfo.h> namespace Swift { class LinkLocalServiceBrowser { diff --git a/Swiften/LinkLocal/LinkLocalServiceInfo.cpp b/Swiften/LinkLocal/LinkLocalServiceInfo.cpp index bec2e97..516d303 100644 --- a/Swiften/LinkLocal/LinkLocalServiceInfo.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceInfo.cpp @@ -4,40 +4,43 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include <Swiften/LinkLocal/LinkLocalServiceInfo.h> #include <boost/lexical_cast.hpp> +#include <Swiften/Base/Algorithm.h> +#include <Swiften/Base/Concat.h> + namespace Swift { ByteArray LinkLocalServiceInfo::toTXTRecord() const { ByteArray result(getEncoded("txtvers=1")); if (!firstName.empty()) { - result += getEncoded("1st=" + firstName); + append(result, getEncoded("1st=" + firstName)); } if (!lastName.empty()) { - result += getEncoded("last=" + lastName); + append(result, getEncoded("last=" + lastName)); } if (!email.empty()) { - result += getEncoded("email=" + email); + append(result, getEncoded("email=" + email)); } if (jid.isValid()) { - result += getEncoded("jid=" + jid.toString()); + append(result, getEncoded("jid=" + jid.toString())); } if (!message.empty()) { - result += getEncoded("msg=" + message); + append(result, getEncoded("msg=" + message)); } if (!nick.empty()) { - result += getEncoded("nick=" + nick); + append(result, getEncoded("nick=" + nick)); } if (port) { - result += getEncoded("port.p2pj=" + std::string(boost::lexical_cast<std::string>(*port))); + append(result, getEncoded("port.p2pj=" + std::string(boost::lexical_cast<std::string>(*port)))); } switch (status) { - case Available: result += getEncoded("status=avail"); break; - case Away: result += getEncoded("status=away"); break; - case DND: result += getEncoded("status=dnd"); break; + case Available: append(result, getEncoded("status=avail")); break; + case Away: append(result, getEncoded("status=away")); break; + case DND: append(result, getEncoded("status=dnd")); break; } return result; @@ -47,13 +50,14 @@ ByteArray LinkLocalServiceInfo::getEncoded(const std::string& s) { ByteArray sizeByte; sizeByte.resize(1); sizeByte[0] = s.size(); - return sizeByte + ByteArray(s); + return concat(sizeByte, createByteArray(s)); } LinkLocalServiceInfo LinkLocalServiceInfo::createFromTXTRecord(const ByteArray& record) { LinkLocalServiceInfo info; size_t i = 0; - while (i < record.getSize()) { + size_t recordCount = record.size(); + while (i < recordCount) { std::pair<std::string,std::string> entry = readEntry(record, &i); if (entry.first.empty()) { break; @@ -99,7 +103,7 @@ std::pair<std::string,std::string> LinkLocalServiceInfo::readEntry(const ByteArr size_t entryEnd = i + 1 + record[i]; ++i; bool inKey = true; - while (i < entryEnd && i < record.getSize()) { + while (i < entryEnd && i < record.size()) { if (inKey) { if (record[i] == '=') { inKey = false; diff --git a/Swiften/LinkLocal/LinkLocalServiceInfo.h b/Swiften/LinkLocal/LinkLocalServiceInfo.h index a166c64..79a8cb8 100644 --- a/Swiften/LinkLocal/LinkLocalServiceInfo.h +++ b/Swiften/LinkLocal/LinkLocalServiceInfo.h @@ -8,9 +8,9 @@ #include <boost/optional.hpp> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> #include <string> -#include "Swiften/JID/JID.h" +#include <Swiften/JID/JID.h> namespace Swift { diff --git a/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp b/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp index 65542d2..9d712f8 100644 --- a/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp +++ b/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp @@ -4,14 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/LinkLocal/OutgoingLinkLocalSession.h" +#include <Swiften/LinkLocal/OutgoingLinkLocalSession.h> #include <boost/bind.hpp> -#include "Swiften/StreamStack/XMPPLayer.h" -#include "Swiften/Elements/ProtocolHeader.h" -#include "Swiften/Elements/StreamFeatures.h" -#include "Swiften/Elements/IQ.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/StreamStack/XMPPLayer.h> +#include <Swiften/Elements/ProtocolHeader.h> +#include <Swiften/Elements/StreamFeatures.h> +#include <Swiften/Elements/IQ.h> namespace Swift { diff --git a/Swiften/LinkLocal/OutgoingLinkLocalSession.h b/Swiften/LinkLocal/OutgoingLinkLocalSession.h index 34ea411..430c446 100644 --- a/Swiften/LinkLocal/OutgoingLinkLocalSession.h +++ b/Swiften/LinkLocal/OutgoingLinkLocalSession.h @@ -7,12 +7,12 @@ #pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/enable_shared_from_this.hpp> #include <vector> -#include "Swiften/Session/Session.h" -#include "Swiften/JID/JID.h" +#include <Swiften/Session/Session.h> +#include <Swiften/JID/JID.h> namespace Swift { class ConnectionFactory; diff --git a/Swiften/LinkLocal/SConscript b/Swiften/LinkLocal/SConscript index 6edf993..29ea692 100644 --- a/Swiften/LinkLocal/SConscript +++ b/Swiften/LinkLocal/SConscript @@ -31,7 +31,11 @@ elif myenv.get("HAVE_AVAHI", 0) : myenv.Append(CPPDEFINES = ["HAVE_AVAHI"]) sources += [ "DNSSD/Avahi/AvahiQuerier.cpp", - "DNSSD/Avahi/AvahiQuery.cpp" + "DNSSD/Avahi/AvahiQuery.cpp", + "DNSSD/Avahi/AvahiResolveHostnameQuery.cpp", + "DNSSD/Avahi/AvahiResolveServiceQuery.cpp", + "DNSSD/Avahi/AvahiRegisterQuery.cpp", + "DNSSD/Avahi/AvahiBrowseQuery.cpp", ] objects = myenv.SwiftenObject(sources) diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp index 98deed1..474c772 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp @@ -7,13 +7,15 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/LinkLocal/LinkLocalConnector.h" -#include "Swiften/LinkLocal/LinkLocalService.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h" -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h" -#include "Swiften/EventLoop/DummyEventLoop.h" -#include "Swiften/Network/FakeConnection.h" +#include <boost/bind.hpp> + +#include <Swiften/LinkLocal/LinkLocalConnector.h> +#include <Swiften/LinkLocal/LinkLocalService.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDServiceID.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h> +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h> +#include <Swiften/EventLoop/DummyEventLoop.h> +#include <Swiften/Network/FakeConnection.h> using namespace Swift; diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp index 9c4c288..c0fd248 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp @@ -9,13 +9,13 @@ #include <boost/bind.hpp> #include <map> -#include "Swiften/LinkLocal/LinkLocalServiceBrowser.h" -#include "Swiften/LinkLocal/LinkLocalService.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h" -#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h" -#include "Swiften/EventLoop/DummyEventLoop.h" +#include <Swiften/LinkLocal/LinkLocalServiceBrowser.h> +#include <Swiften/LinkLocal/LinkLocalService.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDServiceID.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h> +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h> +#include <Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h> +#include <Swiften/EventLoop/DummyEventLoop.h> using namespace Swift; diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp index 3943e31..314b46a 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp @@ -4,12 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include <Swiften/LinkLocal/LinkLocalServiceInfo.h> using namespace Swift; @@ -28,11 +29,11 @@ class LinkLocalServiceInfoTest : public CppUnit::TestFixture { info.setLastName("Tron\xc3\xe7on"); info.setStatus(LinkLocalServiceInfo::Away); - CPPUNIT_ASSERT_EQUAL(ByteArray("\x09txtvers=1\x09" + std::string("1st=Remko\x0dlast=Tron\xc3\xe7on\x0bstatus=away")), info.toTXTRecord()); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x09txtvers=1\x09" + std::string("1st=Remko\x0dlast=Tron\xc3\xe7on\x0bstatus=away")), info.toTXTRecord()); } void testCreateFromTXTRecord() { - LinkLocalServiceInfo info = LinkLocalServiceInfo::createFromTXTRecord(ByteArray("\x09txtvers=1\x09" + std::string("1st=Remko\x0dlast=Tron\xc3\xe7on\x0bstatus=away"))); + LinkLocalServiceInfo info = LinkLocalServiceInfo::createFromTXTRecord(createByteArray("\x09txtvers=1\x09" + std::string("1st=Remko\x0dlast=Tron\xc3\xe7on\x0bstatus=away"))); CPPUNIT_ASSERT_EQUAL(std::string("Remko"), info.getFirstName()); CPPUNIT_ASSERT_EQUAL(std::string("Tron\xc3\xe7on"), info.getLastName()); @@ -40,7 +41,7 @@ class LinkLocalServiceInfoTest : public CppUnit::TestFixture { } void testCreateFromTXTRecord_InvalidSize() { - LinkLocalServiceInfo info = LinkLocalServiceInfo::createFromTXTRecord(ByteArray("\x10last=a")); + LinkLocalServiceInfo info = LinkLocalServiceInfo::createFromTXTRecord(createByteArray("\x10last=a")); CPPUNIT_ASSERT_EQUAL(std::string("a"), info.getLastName()); } diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp index 4835bde..2e3e1bb 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/LinkLocal/LinkLocalService.h" +#include <Swiften/LinkLocal/LinkLocalService.h> using namespace Swift; diff --git a/Swiften/MUC/MUC.cpp b/Swiften/MUC/MUC.cpp index 68a5a86..6fe8f19 100644 --- a/Swiften/MUC/MUC.cpp +++ b/Swiften/MUC/MUC.cpp @@ -4,21 +4,25 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/MUC/MUC.h" +#include <Swiften/MUC/MUC.h> #include <boost/bind.hpp> #include <boost/shared_ptr.hpp> #include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/Presence/DirectedPresenceSender.h" -#include "Swiften/Client/StanzaChannel.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Elements/Form.h" -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/MUCUserPayload.h" -#include "Swiften/Elements/MUCPayload.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/Queries/GenericRequest.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Presence/DirectedPresenceSender.h> +#include <Swiften/Client/StanzaChannel.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Elements/Form.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/IQ.h> +#include <Swiften/Elements/MUCUserPayload.h> +#include <Swiften/Elements/MUCAdminPayload.h> +#include <Swiften/Elements/MUCPayload.h> +#include <Swiften/Elements/MUCDestroyPayload.h> +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/Queries/GenericRequest.h> namespace Swift { @@ -93,7 +97,7 @@ void MUC::handleIncomingPresence(Presence::ref presence) { MUCUserPayload::ref mucPayload; foreach (MUCUserPayload::ref payload, presence->getPayloads<MUCUserPayload>()) { - if (payload->getItems().size() > 0 || payload->getStatusCodes().size() > 0) { + if (!payload->getItems().empty() || !payload->getStatusCodes().empty()) { mucPayload = payload; } } @@ -120,8 +124,8 @@ void MUC::handleIncomingPresence(Presence::ref presence) { MUCOccupant::Affiliation affiliation(MUCOccupant::NoAffiliation); boost::optional<JID> realJID; if (mucPayload && mucPayload->getItems().size() > 0) { - role = mucPayload->getItems()[0].role; - affiliation = mucPayload->getItems()[0].affiliation; + role = mucPayload->getItems()[0].role ? mucPayload->getItems()[0].role.get() : MUCOccupant::NoRole; + affiliation = mucPayload->getItems()[0].affiliation ? mucPayload->getItems()[0].affiliation.get() : MUCOccupant::NoAffiliation; realJID = mucPayload->getItems()[0].realJID; } @@ -196,7 +200,6 @@ void MUC::handleIncomingPresence(Presence::ref presence) { } } } - } void MUC::handleCreationConfigResponse(MUCOwnerPayload::ref /*unused*/, ErrorPayload::ref error) { @@ -216,7 +219,72 @@ MUCOccupant MUC::getOccupant(const std::string& nick) { return occupants.find(nick)->second; } -//FIXME: Recognise Topic changes +void MUC::kickUser(const JID& jid) { + MUCAdminPayload::ref mucPayload = boost::make_shared<MUCAdminPayload>(); + MUCItem item; + item.role = MUCOccupant::NoRole; + item.nick = jid.getResource(); + mucPayload->addItem(item); + GenericRequest<MUCAdminPayload>* request = new GenericRequest<MUCAdminPayload>(IQ::Set, getJID(), mucPayload, iqRouter_); + request->onResponse.connect(boost::bind(&MUC::handleKickResponse, this, _1, _2, jid)); + request->send(); +} + +void MUC::handleKickResponse(MUCAdminPayload::ref /*unused*/, ErrorPayload::ref error, const JID& jid) { + if (error) { + onKickFailed(error, jid); + } +} + +void MUC::changeSubject(const std::string& subject) { + Message::ref message = boost::make_shared<Message>(); + message->setSubject(subject); + message->setType(Message::Groupchat); + message->setTo(ownMUCJID.toBare()); + stanzaChannel->sendMessage(message); +} + +void MUC::requestConfigurationForm() { + MUCOwnerPayload::ref mucPayload(new MUCOwnerPayload()); + GenericRequest<MUCOwnerPayload>* request = new GenericRequest<MUCOwnerPayload>(IQ::Get, getJID(), mucPayload, iqRouter_); + request->onResponse.connect(boost::bind(&MUC::handleConfigurationFormReceived, this, _1, _2)); + request->send(); +} + +void MUC::handleConfigurationFormReceived(MUCOwnerPayload::ref payload, ErrorPayload::ref error) { + Form::ref form; + if (payload) { + form = payload->getForm(); + } + if (error || !form) { + onConfigurationFailed(error); + } else { + onConfigurationFormReceived(form); + } +} + +void MUC::handleConfigurationResultReceived(MUCOwnerPayload::ref /*payload*/, ErrorPayload::ref error) { + if (error) { + onConfigurationFailed(error); + } +} + +void MUC::configureRoom(Form::ref form) { + MUCOwnerPayload::ref mucPayload(new MUCOwnerPayload()); + mucPayload->setPayload(form); + GenericRequest<MUCOwnerPayload>* request = new GenericRequest<MUCOwnerPayload>(IQ::Set, getJID(), mucPayload, iqRouter_); + request->onResponse.connect(boost::bind(&MUC::handleConfigurationResultReceived, this, _1, _2)); + request->send(); +} + +void MUC::destroyRoom() { + MUCOwnerPayload::ref mucPayload = boost::make_shared<MUCOwnerPayload>(); + MUCDestroyPayload::ref mucDestroyPayload = boost::make_shared<MUCDestroyPayload>(); + mucPayload->setPayload(mucDestroyPayload); + GenericRequest<MUCOwnerPayload>* request = new GenericRequest<MUCOwnerPayload>(IQ::Set, getJID(), mucPayload, iqRouter_); + request->onResponse.connect(boost::bind(&MUC::handleConfigurationResultReceived, this, _1, _2)); + request->send(); +} //TODO: Invites(direct/mediated) diff --git a/Swiften/MUC/MUC.h b/Swiften/MUC/MUC.h index 278ef95..b99c4b4 100644 --- a/Swiften/MUC/MUC.h +++ b/Swiften/MUC/MUC.h @@ -6,16 +6,18 @@ #pragma once -#include "Swiften/JID/JID.h" +#include <Swiften/JID/JID.h> #include <string> -#include "Swiften/Elements/Message.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/MUCOccupant.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/Elements/MUCOwnerPayload.h" +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Elements/MUCOccupant.h> +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/Elements/MUCOwnerPayload.h> +#include <Swiften/Elements/MUCAdminPayload.h> +#include <Swiften/Elements/Form.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/signals/connection.hpp> #include <map> @@ -54,14 +56,22 @@ namespace Swift { /** Get occupant information*/ MUCOccupant getOccupant(const std::string& nick); bool hasOccupant(const std::string& nick); + void kickUser(const JID& jid); + void changeSubject(const std::string& subject); + void requestConfigurationForm(); + void configureRoom(Form::ref); + void destroyRoom(); public: boost::signal<void (const std::string& /*nick*/)> onJoinComplete; boost::signal<void (ErrorPayload::ref)> onJoinFailed; + boost::signal<void (ErrorPayload::ref, const JID&)> onKickFailed; + boost::signal<void (ErrorPayload::ref)> onConfigurationFailed; boost::signal<void (Presence::ref)> onOccupantPresenceChange; boost::signal<void (const std::string&, const MUCOccupant& /*now*/, const MUCOccupant::Role& /*old*/)> onOccupantRoleChanged; boost::signal<void (const std::string&, const MUCOccupant::Affiliation& /*new*/, const MUCOccupant::Affiliation& /*old*/)> onOccupantAffiliationChanged; boost::signal<void (const MUCOccupant&)> onOccupantJoined; boost::signal<void (const MUCOccupant&, LeavingType, const std::string& /*reason*/)> onOccupantLeft; + boost::signal<void (Form::ref)> onConfigurationFormReceived; /* boost::signal<void (const MUCInfo&)> onInfoResult; */ /* boost::signal<void (const blah&)> onItemsResult; */ @@ -79,6 +89,9 @@ namespace Swift { void handleIncomingPresence(Presence::ref presence); void internalJoin(const std::string& nick); void handleCreationConfigResponse(MUCOwnerPayload::ref, ErrorPayload::ref); + void handleKickResponse(MUCAdminPayload::ref, ErrorPayload::ref, const JID&); + void handleConfigurationFormReceived(MUCOwnerPayload::ref, ErrorPayload::ref); + void handleConfigurationResultReceived(MUCOwnerPayload::ref, ErrorPayload::ref); private: JID ownMUCJID; diff --git a/Swiften/MUC/MUCBookmark.h b/Swiften/MUC/MUCBookmark.h index 10e1b78..3f612c4 100644 --- a/Swiften/MUC/MUCBookmark.h +++ b/Swiften/MUC/MUCBookmark.h @@ -9,8 +9,8 @@ #include <boost/optional.hpp> #include <string> -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/Storage.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/Storage.h> namespace Swift { class MUCBookmark { diff --git a/Swiften/MUC/MUCBookmarkManager.cpp b/Swiften/MUC/MUCBookmarkManager.cpp index d0855cd..643a8c4 100644 --- a/Swiften/MUC/MUCBookmarkManager.cpp +++ b/Swiften/MUC/MUCBookmarkManager.cpp @@ -9,9 +9,10 @@ #include <boost/bind.hpp> #include <iostream> -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Queries/Requests/GetPrivateStorageRequest.h" -#include "Swiften/Queries/Requests/SetPrivateStorageRequest.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Queries/Requests/GetPrivateStorageRequest.h> +#include <Swiften/Queries/Requests/SetPrivateStorageRequest.h> namespace Swift { @@ -85,7 +86,7 @@ void MUCBookmarkManager::addBookmark(const MUCBookmark& bookmark) { void MUCBookmarkManager::removeBookmark(const MUCBookmark& bookmark) { if (!ready_) return; std::vector<MUCBookmark>::iterator it; - for (it = bookmarks_.begin(); it != bookmarks_.end(); it++) { + for (it = bookmarks_.begin(); it != bookmarks_.end(); ++it) { if ((*it) == bookmark) { bookmarks_.erase(it); onBookmarkRemoved(bookmark); diff --git a/Swiften/MUC/MUCBookmarkManager.h b/Swiften/MUC/MUCBookmarkManager.h index 39699df..ccea46c 100644 --- a/Swiften/MUC/MUCBookmarkManager.h +++ b/Swiften/MUC/MUCBookmarkManager.h @@ -9,12 +9,12 @@ #include <vector> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/optional.hpp> -#include "Swiften/MUC/MUCBookmark.h" -#include "Swiften/Elements/Storage.h" -#include "Swiften/Elements/ErrorPayload.h" +#include <Swiften/MUC/MUCBookmark.h> +#include <Swiften/Elements/Storage.h> +#include <Swiften/Elements/ErrorPayload.h> namespace Swift { class IQRouter; diff --git a/Swiften/MUC/MUCManager.cpp b/Swiften/MUC/MUCManager.cpp index 8950029..6e9b820 100644 --- a/Swiften/MUC/MUCManager.cpp +++ b/Swiften/MUC/MUCManager.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/MUC/MUCManager.h" +#include <Swiften/MUC/MUCManager.h> namespace Swift { diff --git a/Swiften/MUC/MUCManager.h b/Swiften/MUC/MUCManager.h index 0efdf9a..36ae61e 100644 --- a/Swiften/MUC/MUCManager.h +++ b/Swiften/MUC/MUCManager.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/MUC/MUC.h" +#include <Swiften/MUC/MUC.h> namespace Swift { class IQRouter; diff --git a/Swiften/MUC/MUCRegistry.cpp b/Swiften/MUC/MUCRegistry.cpp index e433165..f4d061e 100644 --- a/Swiften/MUC/MUCRegistry.cpp +++ b/Swiften/MUC/MUCRegistry.cpp @@ -4,9 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/MUC/MUCRegistry.h" +#include <Swiften/MUC/MUCRegistry.h> -#include <algorithm> +#include <Swiften/Base/Algorithm.h> namespace Swift { @@ -22,7 +22,7 @@ void MUCRegistry::addMUC(const JID& j) { } void MUCRegistry::removeMUC(const JID& j) { - mucs.erase(std::remove(mucs.begin(), mucs.end(), j), mucs.end()); + erase(mucs, j); } diff --git a/Swiften/MUC/MUCRegistry.h b/Swiften/MUC/MUCRegistry.h index 6356931..0ed2d2e 100644 --- a/Swiften/MUC/MUCRegistry.h +++ b/Swiften/MUC/MUCRegistry.h @@ -8,7 +8,7 @@ #include <vector> -#include "Swiften/JID/JID.h" +#include <Swiften/JID/JID.h> namespace Swift { class JID; diff --git a/Swiften/MUC/UnitTest/MUCTest.cpp b/Swiften/MUC/UnitTest/MUCTest.cpp index 117760c..427e938 100644 --- a/Swiften/MUC/UnitTest/MUCTest.cpp +++ b/Swiften/MUC/UnitTest/MUCTest.cpp @@ -15,6 +15,11 @@ #include <Swiften/Presence/StanzaChannelPresenceSender.h> #include <Swiften/Presence/DirectedPresenceSender.h> #include <Swiften/Queries/IQRouter.h> +#include <Swiften/Elements/MUCUserPayload.h> +#include <Swiften/Elements/MUCOwnerPayload.h> +#include <Swiften/Elements/VCard.h> +#include <Swiften/Elements/CapsInfo.h> + using namespace Swift; @@ -23,6 +28,8 @@ class MUCTest : public CppUnit::TestFixture { CPPUNIT_TEST(testJoin); CPPUNIT_TEST(testJoin_ChangePresenceDuringJoinDoesNotSendPresenceBeforeJoinSuccess); CPPUNIT_TEST(testJoin_ChangePresenceDuringJoinResendsPresenceAfterJoinSuccess); + CPPUNIT_TEST(testCreateInstant); + CPPUNIT_TEST(testReplicateBug); /*CPPUNIT_TEST(testJoin_Success); CPPUNIT_TEST(testJoin_Fail);*/ CPPUNIT_TEST_SUITE_END(); @@ -76,6 +83,64 @@ class MUCTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(std::string("Test"), p->getStatus()); } + void testCreateInstant() { + MUC::ref testling = createMUC(JID("rabbithole@wonderland.lit")); + testling->joinAs("Alice"); + Presence::ref serverRespondsLocked = boost::make_shared<Presence>(); + serverRespondsLocked->setFrom(JID("rabbithole@wonderland.lit/Alice")); + MUCUserPayload::ref mucPayload(new MUCUserPayload()); + MUCItem myItem; + myItem.affiliation = MUCOccupant::Owner; + myItem.role = MUCOccupant::Moderator; + mucPayload->addItem(myItem); + mucPayload->addStatusCode(MUCUserPayload::StatusCode(110)); + mucPayload->addStatusCode(MUCUserPayload::StatusCode(201)); + serverRespondsLocked->addPayload(mucPayload); + channel->onPresenceReceived(serverRespondsLocked); + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(channel->sentStanzas.size())); + IQ::ref iq = channel->getStanzaAtIndex<IQ>(1); + CPPUNIT_ASSERT(iq); + CPPUNIT_ASSERT(iq->getPayload<MUCOwnerPayload>()); + CPPUNIT_ASSERT(iq->getPayload<MUCOwnerPayload>()->getForm()); + CPPUNIT_ASSERT_EQUAL(Form::SubmitType, iq->getPayload<MUCOwnerPayload>()->getForm()->getType()); + } + + void testReplicateBug() { + Presence::ref initialPresence = boost::make_shared<Presence>(); + initialPresence->setStatus(""); + VCard::ref vcard = boost::make_shared<VCard>(); + vcard->setPhoto(createByteArray("15c30080ae98ec48be94bf0e191d43edd06e500a")); + initialPresence->addPayload(vcard); + CapsInfo::ref caps = boost::make_shared<CapsInfo>(); + caps->setNode("http://swift.im"); + caps->setVersion("p2UP0DrcVgKM6jJqYN/B92DKK0o="); + initialPresence->addPayload(caps); + channel->sendPresence(initialPresence); + + MUC::ref testling = createMUC(JID("test@rooms.swift.im")); + testling->joinAs("Test"); + Presence::ref serverRespondsLocked = boost::make_shared<Presence>(); + serverRespondsLocked->setFrom(JID("test@rooms.swift.im/Test")); + serverRespondsLocked->setTo(JID("test@swift.im/6913d576d55f0b67")); + serverRespondsLocked->addPayload(vcard); + serverRespondsLocked->addPayload(caps); + serverRespondsLocked->setStatus(""); + MUCUserPayload::ref mucPayload(new MUCUserPayload()); + MUCItem myItem; + myItem.affiliation = MUCOccupant::Owner; + myItem.role = MUCOccupant::Moderator; + mucPayload->addItem(myItem); + mucPayload->addStatusCode(MUCUserPayload::StatusCode(201)); + serverRespondsLocked->addPayload(mucPayload); + channel->onPresenceReceived(serverRespondsLocked); + CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(channel->sentStanzas.size())); + IQ::ref iq = channel->getStanzaAtIndex<IQ>(2); + CPPUNIT_ASSERT(iq); + CPPUNIT_ASSERT(iq->getPayload<MUCOwnerPayload>()); + CPPUNIT_ASSERT(iq->getPayload<MUCOwnerPayload>()->getForm()); + CPPUNIT_ASSERT_EQUAL(Form::SubmitType, iq->getPayload<MUCOwnerPayload>()->getForm()->getType()); + } + /*void testJoin_Success() { MUC::ref testling = createMUC(JID("foo@bar.com")); testling->onJoinFinished.connect(boost::bind(&MUCTest::handleJoinFinished, this, _1, _2)); diff --git a/Swiften/Network/BoostConnection.cpp b/Swiften/Network/BoostConnection.cpp index f7ff8c4..043743e 100644 --- a/Swiften/Network/BoostConnection.cpp +++ b/Swiften/Network/BoostConnection.cpp @@ -4,18 +4,24 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/BoostConnection.h" +#include <Swiften/Network/BoostConnection.h> #include <iostream> +#include <string> +#include <algorithm> #include <boost/bind.hpp> #include <boost/thread.hpp> +#include <boost/asio/placeholders.hpp> +#include <boost/asio/write.hpp> +#include <boost/smart_ptr/make_shared.hpp> #include <Swiften/Base/Log.h> -#include "Swiften/EventLoop/EventLoop.h" -#include <string> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Network/HostAddressPort.h" -#include "Swiften/Base/sleep.h" +#include <Swiften/Base/Algorithm.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Base/sleep.h> +#include <Swiften/Base/SafeAllocator.h> namespace Swift { @@ -26,8 +32,8 @@ static const size_t BUFFER_SIZE = 4096; // A reference-counted non-modifiable buffer class. class SharedBuffer { public: - SharedBuffer(const ByteArray& data) : - data_(new std::vector<char>(data.begin(), data.end())), + SharedBuffer(const SafeByteArray& data) : + data_(new std::vector<char, SafeAllocator<char> >(data.begin(), data.end())), buffer_(boost::asio::buffer(*data_)) { } @@ -38,14 +44,14 @@ class SharedBuffer { const boost::asio::const_buffer* end() const { return &buffer_ + 1; } private: - boost::shared_ptr< std::vector<char> > data_; + boost::shared_ptr< std::vector<char, SafeAllocator<char> > > data_; boost::asio::const_buffer buffer_; }; // ----------------------------------------------------------------------------- BoostConnection::BoostConnection(boost::shared_ptr<boost::asio::io_service> ioService, EventLoop* eventLoop) : - eventLoop(eventLoop), ioService(ioService), socket_(*ioService), readBuffer_(BUFFER_SIZE), writing_(false) { + eventLoop(eventLoop), ioService(ioService), socket_(*ioService), writing_(false) { } BoostConnection::~BoostConnection() { @@ -75,18 +81,18 @@ void BoostConnection::disconnect() { socket_.close(); } -void BoostConnection::write(const ByteArray& data) { +void BoostConnection::write(const SafeByteArray& data) { boost::lock_guard<boost::mutex> lock(writeMutex_); if (!writing_) { writing_ = true; doWrite(data); } else { - writeQueue_ += data; + append(writeQueue_, data); } } -void BoostConnection::doWrite(const ByteArray& data) { +void BoostConnection::doWrite(const SafeByteArray& data) { boost::asio::async_write(socket_, SharedBuffer(data), boost::bind(&BoostConnection::handleDataWritten, shared_from_this(), boost::asio::placeholders::error)); } @@ -103,15 +109,17 @@ void BoostConnection::handleConnectFinished(const boost::system::error_code& err } void BoostConnection::doRead() { + readBuffer_ = boost::make_shared<SafeByteArray>(BUFFER_SIZE); socket_.async_read_some( - boost::asio::buffer(readBuffer_), + boost::asio::buffer(*readBuffer_), boost::bind(&BoostConnection::handleSocketRead, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void BoostConnection::handleSocketRead(const boost::system::error_code& error, size_t bytesTransferred) { SWIFT_LOG(debug) << "Socket read " << error << std::endl; if (!error) { - eventLoop->postEvent(boost::bind(boost::ref(onDataRead), ByteArray(&readBuffer_[0], bytesTransferred)), shared_from_this()); + readBuffer_->resize(bytesTransferred); + eventLoop->postEvent(boost::bind(boost::ref(onDataRead), readBuffer_), shared_from_this()); doRead(); } else if (/*error == boost::asio::error::eof ||*/ error == boost::asio::error::operation_aborted) { @@ -135,7 +143,7 @@ void BoostConnection::handleDataWritten(const boost::system::error_code& error) } { boost::lock_guard<boost::mutex> lock(writeMutex_); - if (writeQueue_.isEmpty()) { + if (writeQueue_.empty()) { writing_ = false; } else { diff --git a/Swiften/Network/BoostConnection.h b/Swiften/Network/BoostConnection.h index 506eedf..7d5ec60 100644 --- a/Swiften/Network/BoostConnection.h +++ b/Swiften/Network/BoostConnection.h @@ -6,12 +6,14 @@ #pragma once -#include <boost/asio.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/ip/tcp.hpp> #include <boost/enable_shared_from_this.hpp> #include <boost/thread/mutex.hpp> -#include "Swiften/Network/Connection.h" -#include "Swiften/EventLoop/EventOwner.h" +#include <Swiften/Network/Connection.h> +#include <Swiften/EventLoop/EventOwner.h> +#include <Swiften/Base/SafeByteArray.h> namespace boost { class thread; @@ -36,7 +38,7 @@ namespace Swift { virtual void listen(); virtual void connect(const HostAddressPort& address); virtual void disconnect(); - virtual void write(const ByteArray& data); + virtual void write(const SafeByteArray& data); boost::asio::ip::tcp::socket& getSocket() { return socket_; @@ -51,15 +53,15 @@ namespace Swift { void handleSocketRead(const boost::system::error_code& error, size_t bytesTransferred); void handleDataWritten(const boost::system::error_code& error); void doRead(); - void doWrite(const ByteArray& data); + void doWrite(const SafeByteArray& data); private: EventLoop* eventLoop; boost::shared_ptr<boost::asio::io_service> ioService; boost::asio::ip::tcp::socket socket_; - std::vector<char> readBuffer_; + boost::shared_ptr<SafeByteArray> readBuffer_; boost::mutex writeMutex_; bool writing_; - ByteArray writeQueue_; + SafeByteArray writeQueue_; }; } diff --git a/Swiften/Network/BoostConnectionFactory.cpp b/Swiften/Network/BoostConnectionFactory.cpp index 743bb61..d5f9fad 100644 --- a/Swiften/Network/BoostConnectionFactory.cpp +++ b/Swiften/Network/BoostConnectionFactory.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/BoostConnectionFactory.h" -#include "Swiften/Network/BoostConnection.h" +#include <Swiften/Network/BoostConnectionFactory.h> +#include <Swiften/Network/BoostConnection.h> namespace Swift { diff --git a/Swiften/Network/BoostConnectionFactory.h b/Swiften/Network/BoostConnectionFactory.h index ea9d656..c0a105b 100644 --- a/Swiften/Network/BoostConnectionFactory.h +++ b/Swiften/Network/BoostConnectionFactory.h @@ -6,10 +6,10 @@ #pragma once -#include <boost/asio.hpp> +#include <boost/asio/io_service.hpp> -#include "Swiften/Network/ConnectionFactory.h" -#include "Swiften/Network/BoostConnection.h" +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/BoostConnection.h> namespace Swift { class BoostConnection; diff --git a/Swiften/Network/BoostConnectionServer.cpp b/Swiften/Network/BoostConnectionServer.cpp index 27a1008..eccffc6 100644 --- a/Swiften/Network/BoostConnectionServer.cpp +++ b/Swiften/Network/BoostConnectionServer.cpp @@ -4,12 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/BoostConnectionServer.h" +#include <Swiften/Network/BoostConnectionServer.h> #include <boost/bind.hpp> #include <boost/system/system_error.hpp> +#include <boost/asio/placeholders.hpp> -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { diff --git a/Swiften/Network/BoostConnectionServer.h b/Swiften/Network/BoostConnectionServer.h index aba9e3e..56dc8bd 100644 --- a/Swiften/Network/BoostConnectionServer.h +++ b/Swiften/Network/BoostConnectionServer.h @@ -7,13 +7,14 @@ #pragma once #include <boost/shared_ptr.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/ip/tcp.hpp> #include <boost/enable_shared_from_this.hpp> -#include <boost/asio.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> -#include "Swiften/Network/BoostConnection.h" -#include "Swiften/Network/ConnectionServer.h" -#include "Swiften/EventLoop/EventOwner.h" +#include <Swiften/Network/BoostConnection.h> +#include <Swiften/Network/ConnectionServer.h> +#include <Swiften/EventLoop/EventOwner.h> namespace Swift { class BoostConnectionServer : public ConnectionServer, public EventOwner, public boost::enable_shared_from_this<BoostConnectionServer> { diff --git a/Swiften/Network/BoostIOServiceThread.cpp b/Swiften/Network/BoostIOServiceThread.cpp index 031e7b5..c98a653 100644 --- a/Swiften/Network/BoostIOServiceThread.cpp +++ b/Swiften/Network/BoostIOServiceThread.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/BoostIOServiceThread.h" +#include <Swiften/Network/BoostIOServiceThread.h> #include <boost/smart_ptr/make_shared.hpp> diff --git a/Swiften/Network/BoostIOServiceThread.h b/Swiften/Network/BoostIOServiceThread.h index 1f72049..00fb397 100644 --- a/Swiften/Network/BoostIOServiceThread.h +++ b/Swiften/Network/BoostIOServiceThread.h @@ -6,8 +6,8 @@ #pragma once -#include <boost/asio.hpp> -#include <boost/thread.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/thread/thread.hpp> #include <boost/shared_ptr.hpp> namespace Swift { @@ -16,7 +16,7 @@ namespace Swift { BoostIOServiceThread(); ~BoostIOServiceThread(); - boost::shared_ptr<boost::asio::io_service> getIOService() { + boost::shared_ptr<boost::asio::io_service> getIOService() const { return ioService_; } diff --git a/Swiften/Network/BoostNetworkFactories.cpp b/Swiften/Network/BoostNetworkFactories.cpp index 1d9479a..315290c 100644 --- a/Swiften/Network/BoostNetworkFactories.cpp +++ b/Swiften/Network/BoostNetworkFactories.cpp @@ -4,11 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/BoostNetworkFactories.h" -#include "Swiften/Network/BoostTimerFactory.h" -#include "Swiften/Network/BoostConnectionFactory.h" +#include <Swiften/Network/BoostNetworkFactories.h> +#include <Swiften/Network/BoostTimerFactory.h> +#include <Swiften/Network/BoostConnectionFactory.h> #include <Swiften/Network/PlatformDomainNameResolver.h> #include <Swiften/Network/BoostConnectionServerFactory.h> +#include <Swiften/Network/PlatformNATTraversalWorker.h> +#include <Swiften/Network/NullNATTraverser.h> namespace Swift { @@ -17,9 +19,15 @@ BoostNetworkFactories::BoostNetworkFactories(EventLoop* eventLoop) { connectionFactory = new BoostConnectionFactory(ioServiceThread.getIOService(), eventLoop); domainNameResolver = new PlatformDomainNameResolver(eventLoop); connectionServerFactory = new BoostConnectionServerFactory(ioServiceThread.getIOService(), eventLoop); +#ifdef SWIFT_EXPERIMENTAL_FT + natTraverser = new PlatformNATTraversalWorker(eventLoop); +#else + natTraverser = new NullNATTraverser(eventLoop); +#endif } BoostNetworkFactories::~BoostNetworkFactories() { + delete natTraverser; delete connectionServerFactory; delete domainNameResolver; delete connectionFactory; diff --git a/Swiften/Network/BoostNetworkFactories.h b/Swiften/Network/BoostNetworkFactories.h index e4d3128..bc7a963 100644 --- a/Swiften/Network/BoostNetworkFactories.h +++ b/Swiften/Network/BoostNetworkFactories.h @@ -6,11 +6,12 @@ #pragma once -#include "Swiften/Network/NetworkFactories.h" -#include "Swiften/Network/BoostIOServiceThread.h" +#include <Swiften/Network/NetworkFactories.h> +#include <Swiften/Network/BoostIOServiceThread.h> namespace Swift { class EventLoop; + class NATTraverser; class BoostNetworkFactories : public NetworkFactories { public: @@ -37,11 +38,16 @@ namespace Swift { return connectionServerFactory; } + NATTraverser* getNATTraverser() const { + return natTraverser; + } + private: BoostIOServiceThread ioServiceThread; TimerFactory* timerFactory; ConnectionFactory* connectionFactory; DomainNameResolver* domainNameResolver; ConnectionServerFactory* connectionServerFactory; + NATTraverser* natTraverser; }; } diff --git a/Swiften/Network/BoostTimer.cpp b/Swiften/Network/BoostTimer.cpp index 12d06c1..bf042d6 100644 --- a/Swiften/Network/BoostTimer.cpp +++ b/Swiften/Network/BoostTimer.cpp @@ -4,12 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/BoostTimer.h" +#include <Swiften/Network/BoostTimer.h> #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/asio.hpp> +#include <boost/bind.hpp> -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { diff --git a/Swiften/Network/BoostTimer.h b/Swiften/Network/BoostTimer.h index 1139dcf..bfe631b 100644 --- a/Swiften/Network/BoostTimer.h +++ b/Swiften/Network/BoostTimer.h @@ -6,12 +6,12 @@ #pragma once -#include <boost/asio.hpp> -#include <boost/thread.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/deadline_timer.hpp> #include <boost/enable_shared_from_this.hpp> -#include "Swiften/EventLoop/EventOwner.h" -#include "Swiften/Network/Timer.h" +#include <Swiften/EventLoop/EventOwner.h> +#include <Swiften/Network/Timer.h> namespace Swift { class EventLoop; diff --git a/Swiften/Network/BoostTimerFactory.cpp b/Swiften/Network/BoostTimerFactory.cpp index b8e628f..c0bdb56 100644 --- a/Swiften/Network/BoostTimerFactory.cpp +++ b/Swiften/Network/BoostTimerFactory.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/BoostTimerFactory.h" -#include "Swiften/Network/BoostTimer.h" +#include <Swiften/Network/BoostTimerFactory.h> +#include <Swiften/Network/BoostTimer.h> namespace Swift { diff --git a/Swiften/Network/BoostTimerFactory.h b/Swiften/Network/BoostTimerFactory.h index c0e9ef7..6093db0 100644 --- a/Swiften/Network/BoostTimerFactory.h +++ b/Swiften/Network/BoostTimerFactory.h @@ -6,10 +6,10 @@ #pragma once -#include <boost/asio.hpp> +#include <boost/asio/io_service.hpp> -#include "Swiften/Network/TimerFactory.h" -#include "Swiften/Network/BoostTimer.h" +#include <Swiften/Network/TimerFactory.h> +#include <Swiften/Network/BoostTimer.h> namespace Swift { class BoostTimer; diff --git a/Swiften/Network/CAresDomainNameResolver.cpp b/Swiften/Network/CAresDomainNameResolver.cpp index dd49139..da0f49e 100644 --- a/Swiften/Network/CAresDomainNameResolver.cpp +++ b/Swiften/Network/CAresDomainNameResolver.cpp @@ -7,8 +7,8 @@ // TODO: Check the second param of postEvent. We sometimes omit it. Same // goes for the PlatformDomainNameResolver. -#include "Swiften/Network/CAresDomainNameResolver.h" -#include "Swiften/Base/Platform.h" +#include <Swiften/Network/CAresDomainNameResolver.h> +#include <Swiften/Base/Platform.h> #ifndef SWIFTEN_PLATFORM_WINDOWS #include <netdb.h> @@ -16,11 +16,11 @@ #endif #include <algorithm> -#include "Swiften/Network/DomainNameServiceQuery.h" -#include "Swiften/Network/DomainNameAddressQuery.h" -#include "Swiften/Base/ByteArray.h" -#include "Swiften/EventLoop/EventLoop.h" -#include "Swiften/Base/foreach.h" +#include <Swiften/Network/DomainNameServiceQuery.h> +#include <Swiften/Network/DomainNameAddressQuery.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/Base/foreach.h> namespace Swift { diff --git a/Swiften/Network/CAresDomainNameResolver.h b/Swiften/Network/CAresDomainNameResolver.h index a630b61..d0ff82c 100644 --- a/Swiften/Network/CAresDomainNameResolver.h +++ b/Swiften/Network/CAresDomainNameResolver.h @@ -7,11 +7,11 @@ #pragma once #include <ares.h> -#include <boost/thread.hpp> +#include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <list> -#include "Swiften/Network/DomainNameResolver.h" +#include <Swiften/Network/DomainNameResolver.h> namespace Swift { class CAresQuery; diff --git a/Swiften/Network/ChainedConnector.cpp b/Swiften/Network/ChainedConnector.cpp new file mode 100644 index 0000000..1a38e53 --- /dev/null +++ b/Swiften/Network/ChainedConnector.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Network/ChainedConnector.h> + +#include <boost/bind.hpp> +#include <typeinfo> + +#include <Swiften/Base/Log.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Network/Connector.h> +#include <Swiften/Network/ConnectionFactory.h> + +using namespace Swift; + +ChainedConnector::ChainedConnector( + const std::string& hostname, + DomainNameResolver* resolver, + const std::vector<ConnectionFactory*>& connectionFactories, + TimerFactory* timerFactory) : + hostname(hostname), + resolver(resolver), + connectionFactories(connectionFactories), + timerFactory(timerFactory), + timeoutMilliseconds(0) { +} + +void ChainedConnector::setTimeoutMilliseconds(int milliseconds) { + timeoutMilliseconds = milliseconds; +} + +void ChainedConnector::start() { + SWIFT_LOG(debug) << "Starting queued connector for " << hostname << std::endl; + + connectionFactoryQueue = std::deque<ConnectionFactory*>(connectionFactories.begin(), connectionFactories.end()); + tryNextConnectionFactory(); +} + +void ChainedConnector::stop() { + if (currentConnector) { + currentConnector->onConnectFinished.disconnect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1)); + currentConnector->stop(); + currentConnector.reset(); + } + finish(boost::shared_ptr<Connection>()); +} + +void ChainedConnector::tryNextConnectionFactory() { + assert(!currentConnector); + if (connectionFactoryQueue.empty()) { + SWIFT_LOG(debug) << "No more connection factories" << std::endl; + finish(boost::shared_ptr<Connection>()); + } + else { + ConnectionFactory* connectionFactory = connectionFactoryQueue.front(); + SWIFT_LOG(debug) << "Trying next connection factory: " << typeid(*connectionFactory).name() << std::endl; + connectionFactoryQueue.pop_front(); + currentConnector = Connector::create(hostname, resolver, connectionFactory, timerFactory); + currentConnector->setTimeoutMilliseconds(timeoutMilliseconds); + currentConnector->onConnectFinished.connect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1)); + currentConnector->start(); + } +} + +void ChainedConnector::handleConnectorFinished(boost::shared_ptr<Connection> connection) { + SWIFT_LOG(debug) << "Connector finished" << std::endl; + currentConnector->onConnectFinished.disconnect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1)); + currentConnector.reset(); + if (connection) { + finish(connection); + } + else { + tryNextConnectionFactory(); + } +} + +void ChainedConnector::finish(boost::shared_ptr<Connection> connection) { + onConnectFinished(connection); +} diff --git a/Swiften/Network/ChainedConnector.h b/Swiften/Network/ChainedConnector.h new file mode 100644 index 0000000..15b17f3 --- /dev/null +++ b/Swiften/Network/ChainedConnector.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <string> +#include <vector> +#include <deque> +#include <boost/shared_ptr.hpp> + +#include <Swiften/Base/boost_bsignals.h> + +namespace Swift { + class Connection; + class Connector; + class ConnectionFactory; + class TimerFactory; + class DomainNameResolver; + + class ChainedConnector { + public: + ChainedConnector(const std::string& hostname, DomainNameResolver*, const std::vector<ConnectionFactory*>&, TimerFactory*); + + void setTimeoutMilliseconds(int milliseconds); + void start(); + void stop(); + + boost::signal<void (boost::shared_ptr<Connection>)> onConnectFinished; + + private: + void finish(boost::shared_ptr<Connection> connection); + void tryNextConnectionFactory(); + void handleConnectorFinished(boost::shared_ptr<Connection>); + + private: + std::string hostname; + DomainNameResolver* resolver; + std::vector<ConnectionFactory*> connectionFactories; + TimerFactory* timerFactory; + int timeoutMilliseconds; + std::deque<ConnectionFactory*> connectionFactoryQueue; + boost::shared_ptr<Connector> currentConnector; + }; +}; diff --git a/Swiften/Network/Connection.cpp b/Swiften/Network/Connection.cpp new file mode 100644 index 0000000..9bb29e1 --- /dev/null +++ b/Swiften/Network/Connection.cpp @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Network/Connection.h> + +using namespace Swift; + +Connection::Connection() { +} + +Connection::~Connection() { +} diff --git a/Swiften/Network/Connection.h b/Swiften/Network/Connection.h index 529dd82..6ad2999 100644 --- a/Swiften/Network/Connection.h +++ b/Swiften/Network/Connection.h @@ -7,13 +7,13 @@ #pragma once #include <boost/shared_ptr.hpp> +#include <Swiften/Base/boost_bsignals.h> -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/Base/ByteArray.h" -#include <string> -#include "Swiften/Network/HostAddressPort.h" +#include <Swiften/Base/SafeByteArray.h> namespace Swift { + class HostAddressPort; + class Connection { public: typedef boost::shared_ptr<Connection> ref; @@ -23,20 +23,20 @@ namespace Swift { WriteError }; - Connection() {} - virtual ~Connection() {} + Connection(); + virtual ~Connection(); virtual void listen() = 0; virtual void connect(const HostAddressPort& address) = 0; virtual void disconnect() = 0; - virtual void write(const ByteArray& data) = 0; + virtual void write(const SafeByteArray& data) = 0; virtual HostAddressPort getLocalAddress() const = 0; public: boost::signal<void (bool /* error */)> onConnectFinished; boost::signal<void (const boost::optional<Error>&)> onDisconnected; - boost::signal<void (const ByteArray&)> onDataRead; + boost::signal<void (boost::shared_ptr<SafeByteArray>)> onDataRead; boost::signal<void ()> onDataWritten; }; } diff --git a/Swiften/Network/ConnectionFactory.cpp b/Swiften/Network/ConnectionFactory.cpp index dc322a4..2e38b21 100644 --- a/Swiften/Network/ConnectionFactory.cpp +++ b/Swiften/Network/ConnectionFactory.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/ConnectionFactory.h" +#include <Swiften/Network/ConnectionFactory.h> namespace Swift { diff --git a/Swiften/Network/ConnectionServer.cpp b/Swiften/Network/ConnectionServer.cpp index 9631efc..78312e7 100644 --- a/Swiften/Network/ConnectionServer.cpp +++ b/Swiften/Network/ConnectionServer.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/ConnectionServer.h" +#include <Swiften/Network/ConnectionServer.h> namespace Swift { diff --git a/Swiften/Network/ConnectionServer.h b/Swiften/Network/ConnectionServer.h index b90f73d..00703a4 100644 --- a/Swiften/Network/ConnectionServer.h +++ b/Swiften/Network/ConnectionServer.h @@ -7,10 +7,10 @@ #pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> -#include "Swiften/Network/Connection.h" -#include "Swiften/Network/HostAddressPort.h" +#include <Swiften/Network/Connection.h> +#include <Swiften/Network/HostAddressPort.h> namespace Swift { class ConnectionServer { diff --git a/Swiften/Network/Connector.cpp b/Swiften/Network/Connector.cpp index 868bd50..8f35aba 100644 --- a/Swiften/Network/Connector.cpp +++ b/Swiften/Network/Connector.cpp @@ -4,15 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/Connector.h" +#include <Swiften/Network/Connector.h> #include <boost/bind.hpp> #include <iostream> -#include "Swiften/Network/ConnectionFactory.h" -#include "Swiften/Network/DomainNameResolver.h" -#include "Swiften/Network/DomainNameAddressQuery.h" -#include "Swiften/Network/TimerFactory.h" +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/DomainNameResolver.h> +#include <Swiften/Network/DomainNameAddressQuery.h> +#include <Swiften/Network/TimerFactory.h> #include <Swiften/Base/Log.h> namespace Swift { diff --git a/Swiften/Network/Connector.h b/Swiften/Network/Connector.h index b3e7d83..8336299 100644 --- a/Swiften/Network/Connector.h +++ b/Swiften/Network/Connector.h @@ -7,15 +7,15 @@ #pragma once #include <deque> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Network/DomainNameServiceQuery.h" -#include "Swiften/Network/Connection.h" -#include "Swiften/Network/Timer.h" -#include "Swiften/Network/HostAddressPort.h" +#include <Swiften/Network/DomainNameServiceQuery.h> +#include <Swiften/Network/Connection.h> +#include <Swiften/Network/Timer.h> +#include <Swiften/Network/HostAddressPort.h> #include <string> -#include "Swiften/Network/DomainNameResolveError.h" +#include <Swiften/Network/DomainNameResolveError.h> namespace Swift { class DomainNameAddressQuery; @@ -28,7 +28,7 @@ namespace Swift { typedef boost::shared_ptr<Connector> ref; static Connector::ref create(const std::string& hostname, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) { - return Connector::ref(new Connector(hostname, resolver, connectionFactory, timerFactory)); + return ref(new Connector(hostname, resolver, connectionFactory, timerFactory)); } void setTimeoutMilliseconds(int milliseconds); diff --git a/Swiften/Network/DomainNameAddressQuery.cpp b/Swiften/Network/DomainNameAddressQuery.cpp index fd36964..856f301 100644 --- a/Swiften/Network/DomainNameAddressQuery.cpp +++ b/Swiften/Network/DomainNameAddressQuery.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/DomainNameAddressQuery.h" +#include <Swiften/Network/DomainNameAddressQuery.h> namespace Swift { diff --git a/Swiften/Network/DomainNameAddressQuery.h b/Swiften/Network/DomainNameAddressQuery.h index 5bac350..c8ed981 100644 --- a/Swiften/Network/DomainNameAddressQuery.h +++ b/Swiften/Network/DomainNameAddressQuery.h @@ -6,12 +6,12 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/optional.hpp> #include <boost/shared_ptr.hpp> -#include "Swiften/Network/DomainNameResolveError.h" -#include "Swiften/Network/HostAddress.h" +#include <Swiften/Network/DomainNameResolveError.h> +#include <Swiften/Network/HostAddress.h> namespace Swift { class DomainNameAddressQuery { diff --git a/Swiften/Network/DomainNameResolveError.h b/Swiften/Network/DomainNameResolveError.h index 632ba77..aa4441d 100644 --- a/Swiften/Network/DomainNameResolveError.h +++ b/Swiften/Network/DomainNameResolveError.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Base/Error.h" +#include <Swiften/Base/Error.h> namespace Swift { class DomainNameResolveError : public Error { diff --git a/Swiften/Network/DomainNameResolver.cpp b/Swiften/Network/DomainNameResolver.cpp index 96c5165..56a9d72 100644 --- a/Swiften/Network/DomainNameResolver.cpp +++ b/Swiften/Network/DomainNameResolver.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/DomainNameResolver.h" +#include <Swiften/Network/DomainNameResolver.h> namespace Swift { diff --git a/Swiften/Network/DomainNameServiceQuery.cpp b/Swiften/Network/DomainNameServiceQuery.cpp index 423330c..5713b63 100644 --- a/Swiften/Network/DomainNameServiceQuery.cpp +++ b/Swiften/Network/DomainNameServiceQuery.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/DomainNameServiceQuery.h" +#include <Swiften/Network/DomainNameServiceQuery.h> namespace Swift { diff --git a/Swiften/Network/DomainNameServiceQuery.h b/Swiften/Network/DomainNameServiceQuery.h index 63d5841..0bd1569 100644 --- a/Swiften/Network/DomainNameServiceQuery.h +++ b/Swiften/Network/DomainNameServiceQuery.h @@ -6,13 +6,13 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/optional.hpp> #include <vector> #include <boost/shared_ptr.hpp> #include <string> -#include "Swiften/Network/DomainNameResolveError.h" +#include <Swiften/Network/DomainNameResolveError.h> namespace Swift { class DomainNameServiceQuery { diff --git a/Swiften/Network/DummyConnection.cpp b/Swiften/Network/DummyConnection.cpp new file mode 100644 index 0000000..09bd06d --- /dev/null +++ b/Swiften/Network/DummyConnection.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Network/DummyConnection.h> + +#include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> +#include <cassert> + +namespace Swift { + +DummyConnection::DummyConnection(EventLoop* eventLoop) : eventLoop(eventLoop) { +} + +void DummyConnection::receive(const SafeByteArray& data) { + eventLoop->postEvent(boost::bind(boost::ref(onDataRead), boost::make_shared<SafeByteArray>(data)), shared_from_this()); +} + +void DummyConnection::listen() { + assert(false); +} + +void DummyConnection::connect(const HostAddressPort&) { + assert(false); +} + + +} diff --git a/Swiften/Network/DummyConnection.h b/Swiften/Network/DummyConnection.h index 6b426b1..5191e30 100644 --- a/Swiften/Network/DummyConnection.h +++ b/Swiften/Network/DummyConnection.h @@ -6,45 +6,37 @@ #pragma once -#include <cassert> -#include <boost/bind.hpp> #include <boost/enable_shared_from_this.hpp> -#include "Swiften/Network/Connection.h" -#include "Swiften/EventLoop/EventLoop.h" -#include "Swiften/EventLoop/EventOwner.h" +#include <Swiften/Network/Connection.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/EventLoop/EventOwner.h> namespace Swift { class DummyConnection : public Connection, public EventOwner, public boost::enable_shared_from_this<DummyConnection> { public: - DummyConnection(EventLoop* eventLoop) : eventLoop(eventLoop) {} + DummyConnection(EventLoop* eventLoop); - void listen() { - assert(false); - } - - void connect(const HostAddressPort&) { - assert(false); - } + void listen(); + void connect(const HostAddressPort&); void disconnect() { //assert(false); } - void write(const ByteArray& data) { + void write(const SafeByteArray& data) { eventLoop->postEvent(boost::ref(onDataWritten), shared_from_this()); onDataSent(data); } - void receive(const ByteArray& data) { - eventLoop->postEvent(boost::bind(boost::ref(onDataRead), ByteArray(data)), shared_from_this()); - } + void receive(const SafeByteArray& data); HostAddressPort getLocalAddress() const { return localAddress; } - boost::signal<void (const ByteArray&)> onDataSent; + boost::signal<void (const SafeByteArray&)> onDataSent; EventLoop* eventLoop; HostAddressPort localAddress; diff --git a/Swiften/Network/DummyConnectionFactory.h b/Swiften/Network/DummyConnectionFactory.h new file mode 100644 index 0000000..e8a294e --- /dev/null +++ b/Swiften/Network/DummyConnectionFactory.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/DummyConnection.h> + +namespace Swift { + +class EventLoop; + +class DummyConnectionFactory : public ConnectionFactory { +public: + DummyConnectionFactory(EventLoop *eventLoop) : eventLoop(eventLoop) {} + virtual ~DummyConnectionFactory() {} + virtual boost::shared_ptr<Connection> createConnection() { + return boost::make_shared<DummyConnection>(eventLoop); + } +private: + EventLoop* eventLoop; +}; + +} diff --git a/Swiften/Network/DummyTimerFactory.cpp b/Swiften/Network/DummyTimerFactory.cpp index 105b103..16428b7 100644 --- a/Swiften/Network/DummyTimerFactory.cpp +++ b/Swiften/Network/DummyTimerFactory.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/DummyTimerFactory.h" +#include <Swiften/Network/DummyTimerFactory.h> #include <algorithm> -#include "Swiften/Base/foreach.h" -#include "Swiften/Network/Timer.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Network/Timer.h> namespace Swift { diff --git a/Swiften/Network/DummyTimerFactory.h b/Swiften/Network/DummyTimerFactory.h index 408b647..0c49f3d 100644 --- a/Swiften/Network/DummyTimerFactory.h +++ b/Swiften/Network/DummyTimerFactory.h @@ -8,7 +8,7 @@ #include <list> -#include "Swiften/Network/TimerFactory.h" +#include <Swiften/Network/TimerFactory.h> namespace Swift { class DummyTimerFactory : public TimerFactory { diff --git a/Swiften/Network/EnvironmentProxyProvider.cpp b/Swiften/Network/EnvironmentProxyProvider.cpp new file mode 100644 index 0000000..7701da1 --- /dev/null +++ b/Swiften/Network/EnvironmentProxyProvider.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <iostream> + +#include <Swiften/Base/Log.h> +#include <Swiften/Network/EnvironmentProxyProvider.h> + +namespace Swift { + +EnvironmentProxyProvider::EnvironmentProxyProvider() { + socksProxy = getFromEnv("all_proxy", "socks"); + httpProxy = getFromEnv("http_proxy", "http"); + SWIFT_LOG(debug) << "Environment: SOCKS5 => " << socksProxy.toString() << "; HTTP Connect => " << httpProxy.toString() << std::endl; +} + +HostAddressPort EnvironmentProxyProvider::getHTTPConnectProxy() const { + return httpProxy; +} + +HostAddressPort EnvironmentProxyProvider::getSOCKS5Proxy() const { + return socksProxy; +} + +HostAddressPort EnvironmentProxyProvider::getFromEnv(const char* envVarName, std::string proxyProtocol) { + char* envVar = NULL; + std::string address; + int port = 0; + + envVar = getenv(envVarName); + + proxyProtocol += "://"; + address = envVar != NULL ? envVar : "0.0.0.0"; + if(envVar != NULL && address.compare(0, proxyProtocol.length(), proxyProtocol) == 0) { + address = address.substr(proxyProtocol.length(), address.length()); + port = atoi(address.substr(address.find(':') + 1, address.length()).c_str()); + address = address.substr(0, address.find(':')); + } + + return HostAddressPort(HostAddress(address), port); +} + +} diff --git a/Swiften/Network/EnvironmentProxyProvider.h b/Swiften/Network/EnvironmentProxyProvider.h new file mode 100644 index 0000000..224d301 --- /dev/null +++ b/Swiften/Network/EnvironmentProxyProvider.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Network/ProxyProvider.h> + +namespace Swift { + class EnvironmentProxyProvider : public ProxyProvider { + public: + EnvironmentProxyProvider(); + virtual HostAddressPort getHTTPConnectProxy() const; + virtual HostAddressPort getSOCKS5Proxy() const; + private: + HostAddressPort getFromEnv(const char* envVarName, std::string proxyProtocol); + HostAddressPort socksProxy; + HostAddressPort httpProxy; + }; +} + + diff --git a/Swiften/Network/FakeConnection.cpp b/Swiften/Network/FakeConnection.cpp new file mode 100644 index 0000000..be5555c --- /dev/null +++ b/Swiften/Network/FakeConnection.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Network/FakeConnection.h> + +#include <boost/bind.hpp> + +namespace Swift { + +FakeConnection::FakeConnection(EventLoop* eventLoop) : eventLoop(eventLoop), state(Initial), delayConnect(false) { +} + +FakeConnection::~FakeConnection() { +} + +void FakeConnection::listen() { + assert(false); +} + +void FakeConnection::setError(const Error& e) { + error = boost::optional<Error>(e); + state = DisconnectedWithError; + if (connectedTo) { + eventLoop->postEvent( + boost::bind(boost::ref(onDisconnected), error), + shared_from_this()); + } +} + +void FakeConnection::connect(const HostAddressPort& address) { + if (delayConnect) { + state = Connecting; + } + else { + if (!error) { + connectedTo = address; + state = Connected; + } + else { + state = DisconnectedWithError; + } + eventLoop->postEvent( + boost::bind(boost::ref(onConnectFinished), error), + shared_from_this()); + } +} + +void FakeConnection::disconnect() { + if (!error) { + state = Disconnected; + } + else { + state = DisconnectedWithError; + } + connectedTo.reset(); + eventLoop->postEvent( + boost::bind(boost::ref(onDisconnected), error), + shared_from_this()); +} + +} diff --git a/Swiften/Network/FakeConnection.h b/Swiften/Network/FakeConnection.h index 4e2e960..99cb584 100644 --- a/Swiften/Network/FakeConnection.h +++ b/Swiften/Network/FakeConnection.h @@ -7,14 +7,13 @@ #pragma once #include <boost/optional.hpp> -#include <boost/bind.hpp> #include <boost/enable_shared_from_this.hpp> #include <vector> -#include "Swiften/Network/Connection.h" -#include "Swiften/Network/HostAddressPort.h" -#include "Swiften/EventLoop/EventOwner.h" -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/Network/Connection.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/EventLoop/EventOwner.h> +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { class FakeConnection : @@ -30,58 +29,19 @@ namespace Swift { DisconnectedWithError }; - FakeConnection(EventLoop* eventLoop) : eventLoop(eventLoop), state(Initial), delayConnect(false) {} - - virtual void listen() { - assert(false); - } + FakeConnection(EventLoop* eventLoop); + ~FakeConnection(); + virtual void listen(); virtual HostAddressPort getLocalAddress() const { return HostAddressPort(); } - void setError(const Error& e) { - error = boost::optional<Error>(e); - state = DisconnectedWithError; - if (connectedTo) { - eventLoop->postEvent( - boost::bind(boost::ref(onDisconnected), error), - shared_from_this()); - } - } - - virtual void connect(const HostAddressPort& address) { - if (delayConnect) { - state = Connecting; - } - else { - if (!error) { - connectedTo = address; - state = Connected; - } - else { - state = DisconnectedWithError; - } - eventLoop->postEvent( - boost::bind(boost::ref(onConnectFinished), error), - shared_from_this()); - } - } - - virtual void disconnect() { - if (!error) { - state = Disconnected; - } - else { - state = DisconnectedWithError; - } - connectedTo.reset(); - eventLoop->postEvent( - boost::bind(boost::ref(onDisconnected), error), - shared_from_this()); - } + void setError(const Error& e); + virtual void connect(const HostAddressPort& address); + virtual void disconnect(); - virtual void write(const ByteArray& data) { + virtual void write(const SafeByteArray& data) { dataWritten.push_back(data); } @@ -91,7 +51,7 @@ namespace Swift { EventLoop* eventLoop; boost::optional<HostAddressPort> connectedTo; - std::vector<ByteArray> dataWritten; + std::vector<SafeByteArray> dataWritten; boost::optional<Error> error; State state; bool delayConnect; diff --git a/Swiften/Network/GConfProxyProvider.cpp b/Swiften/Network/GConfProxyProvider.cpp new file mode 100644 index 0000000..8d97c68 --- /dev/null +++ b/Swiften/Network/GConfProxyProvider.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <iostream> + +#include <gconf/gconf-client.h> + +#include <Swiften/Base/Log.h> +#include <Swiften/Network/GConfProxyProvider.h> + +namespace Swift { + +GConfProxyProvider::GConfProxyProvider() { + // Ensure static GLib initialization methods are called + static bool glibInitialized = false; + if (!glibInitialized) { + g_type_init(); + glibInitialized = true; + } + + socksProxy = getFromGConf("/system/proxy/socks_host", "/system/proxy/socks_port"); + httpProxy = getFromGConf("/system/http_proxy/host", "/system/http_proxy/port"); + SWIFT_LOG(debug) << "GConf: SOCKS5 => " << socksProxy.toString() << "; HTTP Connect => " << httpProxy.toString() << std::endl; +} + +HostAddressPort GConfProxyProvider::getHTTPConnectProxy() const { + return httpProxy; +} + +HostAddressPort GConfProxyProvider::getSOCKS5Proxy() const { + return socksProxy; +} + +HostAddressPort GConfProxyProvider::getFromGConf(const char* gcHost, const char* gcPort) { + std::string address; + int port = 0; + gchar* str; + + GConfClient* client = gconf_client_get_default(); + + str = gconf_client_get_string(client, gcHost, NULL); + port = static_cast<int> (gconf_client_get_int(client, gcPort, NULL)); + + if(str) { + address = static_cast<char*> (str); + g_free(str); + } + + g_object_unref(client); + return HostAddressPort(HostAddress(address), port); +} + +} diff --git a/Swiften/Network/GConfProxyProvider.h b/Swiften/Network/GConfProxyProvider.h new file mode 100644 index 0000000..31f38a9 --- /dev/null +++ b/Swiften/Network/GConfProxyProvider.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Network/ProxyProvider.h> + +namespace Swift { + class GConfProxyProvider : public ProxyProvider { + public: + GConfProxyProvider(); + virtual HostAddressPort getHTTPConnectProxy() const; + virtual HostAddressPort getSOCKS5Proxy() const; + private: + HostAddressPort getFromGConf(const char* gcHost, const char* gcPort); + HostAddressPort socksProxy; + HostAddressPort httpProxy; + }; +} + + diff --git a/Swiften/Network/HTTPConnectProxiedConnection.cpp b/Swiften/Network/HTTPConnectProxiedConnection.cpp new file mode 100644 index 0000000..e05a933 --- /dev/null +++ b/Swiften/Network/HTTPConnectProxiedConnection.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Network/HTTPConnectProxiedConnection.h> + +#include <iostream> +#include <boost/bind.hpp> +#include <boost/thread.hpp> +#include <boost/lexical_cast.hpp> + +#include <Swiften/Base/Log.h> +#include <Swiften/Base/String.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Network/ConnectionFactory.h> + +using namespace Swift; + +HTTPConnectProxiedConnection::HTTPConnectProxiedConnection(ConnectionFactory* connectionFactory, HostAddressPort proxy) : connectionFactory_(connectionFactory), proxy_(proxy), server_(HostAddressPort(HostAddress("0.0.0.0"), 0)) { + connected_ = false; +} + +HTTPConnectProxiedConnection::~HTTPConnectProxiedConnection() { + if (connection_) { + connection_->onDataRead.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleDataRead, shared_from_this(), _1)); + connection_->onDisconnected.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleDisconnected, shared_from_this(), _1)); + } + + if (connected_) { + std::cerr << "Warning: Connection was still established." << std::endl; + } +} + +void HTTPConnectProxiedConnection::connect(const HostAddressPort& server) { + server_ = server; + connection_ = connectionFactory_->createConnection(); + connection_->onConnectFinished.connect(boost::bind(&HTTPConnectProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1)); + connection_->onDataRead.connect(boost::bind(&HTTPConnectProxiedConnection::handleDataRead, shared_from_this(), _1)); + connection_->onDisconnected.connect(boost::bind(&HTTPConnectProxiedConnection::handleDisconnected, shared_from_this(), _1)); + connection_->connect(proxy_); +} + +void HTTPConnectProxiedConnection::listen() { + assert(false); + connection_->listen(); +} + +void HTTPConnectProxiedConnection::disconnect() { + connected_ = false; + connection_->disconnect(); +} + +void HTTPConnectProxiedConnection::handleDisconnected(const boost::optional<Error>& error) { + onDisconnected(error); +} + +void HTTPConnectProxiedConnection::write(const SafeByteArray& data) { + connection_->write(data); +} + +void HTTPConnectProxiedConnection::handleConnectionConnectFinished(bool error) { + connection_->onConnectFinished.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1)); + if (!error) { + std::stringstream connect; + connect << "CONNECT " << server_.getAddress().toString() << ":" << server_.getPort() << " HTTP/1.1\r\n\r\n"; + connection_->write(createSafeByteArray(connect.str())); + } + else { + onConnectFinished(true); + } +} + +void HTTPConnectProxiedConnection::handleDataRead(boost::shared_ptr<SafeByteArray> data) { + if (!connected_) { + SWIFT_LOG(debug) << byteArrayToString(ByteArray(data->begin(), data->end())) << std::endl; + std::vector<std::string> tmp = String::split(byteArrayToString(ByteArray(data->begin(), data->end())), ' '); + if(tmp.size() > 1) { + int status = boost::lexical_cast<int> (tmp[1].c_str()); + SWIFT_LOG(debug) << "Proxy Status: " << status << std::endl; + if (status / 100 == 2) { // all 2XX states are OK + connected_ = true; + onConnectFinished(false); + return; + } + SWIFT_LOG(debug) << "HTTP Proxy returned an error: " << byteArrayToString(ByteArray(data->begin(), data->end())) << std::endl; + } + disconnect(); + onConnectFinished(true); + } + else { + onDataRead(data); + } +} + +HostAddressPort HTTPConnectProxiedConnection::getLocalAddress() const { + return connection_->getLocalAddress(); +} diff --git a/Swiften/Network/HTTPConnectProxiedConnection.h b/Swiften/Network/HTTPConnectProxiedConnection.h new file mode 100644 index 0000000..d3f5b7a --- /dev/null +++ b/Swiften/Network/HTTPConnectProxiedConnection.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/enable_shared_from_this.hpp> + +#include <Swiften/Network/Connection.h> +#include <Swiften/Network/HostAddressPort.h> + +namespace boost { + class thread; + namespace system { + class error_code; + } +} + +namespace Swift { + class ConnectionFactory; + + class HTTPConnectProxiedConnection : public Connection, public boost::enable_shared_from_this<HTTPConnectProxiedConnection> { + public: + typedef boost::shared_ptr<HTTPConnectProxiedConnection> ref; + + ~HTTPConnectProxiedConnection(); + + static ref create(ConnectionFactory* connectionFactory, HostAddressPort proxy) { + return ref(new HTTPConnectProxiedConnection(connectionFactory, proxy)); + } + + virtual void listen(); + virtual void connect(const HostAddressPort& address); + virtual void disconnect(); + virtual void write(const SafeByteArray& data); + + virtual HostAddressPort getLocalAddress() const; + private: + HTTPConnectProxiedConnection(ConnectionFactory* connectionFactory, HostAddressPort proxy); + + void handleConnectionConnectFinished(bool error); + void handleDataRead(boost::shared_ptr<SafeByteArray> data); + void handleDisconnected(const boost::optional<Error>& error); + + private: + bool connected_; + ConnectionFactory* connectionFactory_; + HostAddressPort proxy_; + HostAddressPort server_; + boost::shared_ptr<Connection> connection_; + }; +} diff --git a/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp b/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp new file mode 100644 index 0000000..ab7f18e --- /dev/null +++ b/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Network/HTTPConnectProxiedConnectionFactory.h> + +#include <Swiften/Network/HTTPConnectProxiedConnection.h> + +namespace Swift { + +HTTPConnectProxiedConnectionFactory::HTTPConnectProxiedConnectionFactory(ConnectionFactory* connectionFactory, const HostAddressPort& proxy) : connectionFactory_(connectionFactory), proxy_(proxy) { +} + +boost::shared_ptr<Connection> HTTPConnectProxiedConnectionFactory::createConnection() { + return HTTPConnectProxiedConnection::create(connectionFactory_, proxy_); +} + +} diff --git a/Swiften/Network/HTTPConnectProxiedConnectionFactory.h b/Swiften/Network/HTTPConnectProxiedConnectionFactory.h new file mode 100644 index 0000000..b475586 --- /dev/null +++ b/Swiften/Network/HTTPConnectProxiedConnectionFactory.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/HostAddressPort.h> + +namespace Swift { + class HTTPConnectProxiedConnectionFactory : public ConnectionFactory { + public: + HTTPConnectProxiedConnectionFactory(ConnectionFactory* connectionFactory, const HostAddressPort& proxy); + + virtual boost::shared_ptr<Connection> createConnection(); + + private: + ConnectionFactory* connectionFactory_; + HostAddressPort proxy_; + }; +} diff --git a/Swiften/Network/HostAddress.cpp b/Swiften/Network/HostAddress.cpp index 2ca1414..7ba2a7f 100644 --- a/Swiften/Network/HostAddress.cpp +++ b/Swiften/Network/HostAddress.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/HostAddress.h" +#include <Swiften/Network/HostAddress.h> #include <boost/numeric/conversion/cast.hpp> #include <boost/lexical_cast.hpp> @@ -12,7 +12,7 @@ #include <stdexcept> #include <boost/array.hpp> -#include "Swiften/Base/foreach.h" +#include <Swiften/Base/foreach.h> #include <string> namespace Swift { @@ -24,7 +24,7 @@ HostAddress::HostAddress(const std::string& address) { try { address_ = boost::asio::ip::address::from_string(address); } - catch (const std::exception& t) { + catch (const std::exception&) { } } diff --git a/Swiften/Network/HostAddress.h b/Swiften/Network/HostAddress.h index 4b05c32..0b3bdda 100644 --- a/Swiften/Network/HostAddress.h +++ b/Swiften/Network/HostAddress.h @@ -3,16 +3,12 @@ * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ - #pragma once #include <string> -#include <vector> -#include <boost/asio.hpp> +#include <boost/asio/ip/address.hpp> namespace Swift { - - class HostAddress { public: HostAddress(); diff --git a/Swiften/Network/HostAddressPort.cpp b/Swiften/Network/HostAddressPort.cpp new file mode 100644 index 0000000..e2e6012 --- /dev/null +++ b/Swiften/Network/HostAddressPort.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Network/HostAddressPort.h> + +#include <boost/lexical_cast.hpp> + +using namespace Swift; + +HostAddressPort::HostAddressPort(const HostAddress& address, int port) : address_(address), port_(port) { +} + +HostAddressPort::HostAddressPort(const boost::asio::ip::tcp::endpoint& endpoint) { + address_ = HostAddress(endpoint.address()); + port_ = endpoint.port(); +} + +std::string HostAddressPort::toString() const { + return getAddress().toString() + ":" + boost::lexical_cast<std::string>(getPort()); +} diff --git a/Swiften/Network/HostAddressPort.h b/Swiften/Network/HostAddressPort.h index 6883380..e3c0413 100644 --- a/Swiften/Network/HostAddressPort.h +++ b/Swiften/Network/HostAddressPort.h @@ -6,21 +6,15 @@ #pragma once -#include <boost/asio.hpp> +#include <boost/asio/ip/tcp.hpp> -#include "Swiften/Network/HostAddress.h" +#include <Swiften/Network/HostAddress.h> namespace Swift { class HostAddressPort { public: - HostAddressPort(const HostAddress& address = HostAddress(), int port = -1) : address_(address), port_(port) { - } - - HostAddressPort(const boost::asio::ip::tcp::endpoint& endpoint) { - address_ = HostAddress(endpoint.address()); - port_ = endpoint.port(); - } - + HostAddressPort(const HostAddress& address = HostAddress(), int port = -1); + HostAddressPort(const boost::asio::ip::tcp::endpoint& endpoint); const HostAddress& getAddress() const { return address_; @@ -37,6 +31,8 @@ namespace Swift { bool isValid() const { return address_.isValid() && port_ > 0; } + + std::string toString() const; private: HostAddress address_; diff --git a/Swiften/Network/MacOSXProxyProvider.cpp b/Swiften/Network/MacOSXProxyProvider.cpp new file mode 100644 index 0000000..eaadd28 --- /dev/null +++ b/Swiften/Network/MacOSXProxyProvider.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Base/Platform.h> +#include <Swiften/Network/MacOSXProxyProvider.h> + +#include <stdio.h> +#include <stdlib.h> +#include <iostream> +#include <utility> + +#ifndef SWIFTEN_PLATFORM_IPHONE +#include <SystemConfiguration/SystemConfiguration.h> +#endif + +using namespace Swift; + +#ifndef SWIFTEN_PLATFORM_IPHONE +static HostAddressPort getFromDictionary(CFDictionaryRef dict, CFStringRef enabledKey, CFStringRef hostKey, CFStringRef portKey) { + CFNumberRef numberValue = NULL; + HostAddressPort ret = HostAddressPort(HostAddress(), 0); + + if(CFDictionaryGetValueIfPresent(dict, reinterpret_cast<const void*> (enabledKey), reinterpret_cast<const void**> (&numberValue)) == true) { + const int i = 0; + CFNumberRef zero = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i); + CFComparisonResult result = CFNumberCompare(numberValue, zero, NULL); + CFRelease(numberValue); + + if(result != kCFCompareEqualTo) { + int port = 0; + std::string host = ""; + + try { + CFNumberRef numberValue = reinterpret_cast<CFNumberRef> (CFDictionaryGetValue(dict, portKey)); + if(numberValue != NULL) { + CFNumberGetValue(numberValue, kCFNumberIntType, &port); + CFRelease(numberValue); + } + + CFStringRef stringValue = reinterpret_cast<CFStringRef> (CFDictionaryGetValue(dict, hostKey)); + if(stringValue != NULL) { + std::vector<char> buffer; + // length must be +1 for the ending zero; and the Docu of CFStringGetCString tells it like + // if the string is toby the length must be at least 5. + CFIndex length = CFStringGetLength(stringValue) + 1; + buffer.resize(length); + if(CFStringGetCString(stringValue, &buffer[0], length, kCFStringEncodingMacRoman)) { + for(std::vector<char>::iterator iter = buffer.begin(); iter != buffer.end(); ++iter) { + host += *iter; + } + } + CFRelease(stringValue); + } + } + catch(...) { + std::cerr << "Exception caught ... " << std::endl; + } + + if(host != "" && port != 0) { + ret = HostAddressPort(HostAddress(host), port); + } + } + } + return ret; +} +#endif +namespace Swift { + +MacOSXProxyProvider::MacOSXProxyProvider() { +} + +HostAddressPort MacOSXProxyProvider::getHTTPConnectProxy() const { + HostAddressPort result; +#ifndef SWIFTEN_PLATFORM_IPHONE + CFDictionaryRef proxies = SCDynamicStoreCopyProxies(NULL); + if(proxies != NULL) { + result = getFromDictionary(proxies, kSCPropNetProxiesHTTPEnable, kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort); + } +#endif + return result; +} + +HostAddressPort MacOSXProxyProvider::getSOCKS5Proxy() const { + HostAddressPort result; +#ifndef SWIFTEN_PLATFORM_IPHONE + CFDictionaryRef proxies = SCDynamicStoreCopyProxies(NULL); + if(proxies != NULL) { + result = getFromDictionary(proxies, kSCPropNetProxiesSOCKSEnable, kSCPropNetProxiesSOCKSProxy, kSCPropNetProxiesSOCKSPort); + } +#endif + return result; +} + +} diff --git a/Swiften/Network/MacOSXProxyProvider.h b/Swiften/Network/MacOSXProxyProvider.h new file mode 100644 index 0000000..6666d30 --- /dev/null +++ b/Swiften/Network/MacOSXProxyProvider.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once +#include <Swiften/Network/ProxyProvider.h> +#include <CoreFoundation/CoreFoundation.h> + +namespace Swift { + class MacOSXProxyProvider : public ProxyProvider { + public: + MacOSXProxyProvider(); + virtual HostAddressPort getHTTPConnectProxy() const; + virtual HostAddressPort getSOCKS5Proxy() const; + }; +} diff --git a/Swiften/Network/MiniUPnPInterface.cpp b/Swiften/Network/MiniUPnPInterface.cpp new file mode 100644 index 0000000..f6e3b5d --- /dev/null +++ b/Swiften/Network/MiniUPnPInterface.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Network/MiniUPnPInterface.h> + +#include <upnpcommands.h> +#include <upnperrors.h> +#include <boost/lexical_cast.hpp> + +#include <Swiften/Base/Log.h> + +namespace Swift { + +MiniUPnPInterface::MiniUPnPInterface() : isValid(false) { + int error = 0; + deviceList = upnpDiscover(1500 /* timeout in ms */, 0, 0, 0, 0 /* do IPv6? */, &error); + if (!deviceList) { + return; + } + + char lanAddress[64]; + if (!UPNP_GetValidIGD(deviceList, &urls, &data, lanAddress, sizeof(lanAddress))) { + return; + } + localAddress = std::string(lanAddress); + isValid = true; +} + +MiniUPnPInterface::~MiniUPnPInterface() { + if (isValid) { + FreeUPNPUrls(&urls); + } + freeUPNPDevlist(deviceList); +} + +boost::optional<HostAddress> MiniUPnPInterface::getPublicIP() { + if (!isValid) { + return boost::optional<HostAddress>(); + } + char externalIPAddress[40]; + int ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress); + if (ret != UPNPCOMMAND_SUCCESS) { + return boost::optional<HostAddress>(); + } + else { + return HostAddress(std::string(externalIPAddress)); + } +} + +boost::optional<NATPortMapping> MiniUPnPInterface::addPortForward(int actualLocalPort, int actualPublicPort) { + if (!isValid) { + return boost::optional<NATPortMapping>(); + } + + NATPortMapping mapping(actualLocalPort, actualPublicPort, NATPortMapping::TCP); + + std::string publicPort = boost::lexical_cast<std::string>(mapping.publicPort); + std::string localPort = boost::lexical_cast<std::string>(mapping.localPort); + std::string leaseSeconds = boost::lexical_cast<std::string>(mapping.leaseInSeconds); + + int ret = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, publicPort.c_str(), localPort.c_str(), localAddress.c_str(), 0, mapping.protocol == NATPortMapping::TCP ? "TCP" : "UDP", 0, leaseSeconds.c_str()); + if (ret == UPNPCOMMAND_SUCCESS) { + return mapping; + } + else { + return boost::optional<NATPortMapping>(); + } +} + +bool MiniUPnPInterface::removePortForward(const NATPortMapping& mapping) { + if (!isValid) { + return false; + } + + std::string publicPort = boost::lexical_cast<std::string>(mapping.publicPort); + std::string localPort = boost::lexical_cast<std::string>(mapping.localPort); + std::string leaseSeconds = boost::lexical_cast<std::string>(mapping.leaseInSeconds); + + int ret = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, publicPort.c_str(), mapping.protocol == NATPortMapping::TCP ? "TCP" : "UDP", 0); + return ret == UPNPCOMMAND_SUCCESS; +} + +} diff --git a/Swiften/Network/MiniUPnPInterface.h b/Swiften/Network/MiniUPnPInterface.h new file mode 100644 index 0000000..ae9be66 --- /dev/null +++ b/Swiften/Network/MiniUPnPInterface.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/optional.hpp> +#include <miniupnpc.h> + +#include <Swiften/Network/NATPortMapping.h> +#include <Swiften/Network/NATTraversalInterface.h> + +namespace Swift { + class MiniUPnPInterface : public NATTraversalInterface { + public: + MiniUPnPInterface(); + ~MiniUPnPInterface(); + + virtual bool isAvailable() { + return isValid; + } + + boost::optional<HostAddress> getPublicIP(); + boost::optional<NATPortMapping> addPortForward(int localPort, int publicPort); + bool removePortForward(const NATPortMapping&); + + private: + bool isValid; + std::string localAddress; + UPNPDev* deviceList; + UPNPUrls urls; + IGDdatas data; + }; +} diff --git a/Swiften/Network/NATPMPInterface.cpp b/Swiften/Network/NATPMPInterface.cpp new file mode 100644 index 0000000..298240a --- /dev/null +++ b/Swiften/Network/NATPMPInterface.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Network/NATPMPInterface.h> + +#include <Swiften/Base/Log.h> + +#pragma GCC diagnostic ignored "-Wold-style-cast" + +namespace Swift { + +NATPMPInterface::NATPMPInterface() { + initnatpmp(&natpmp, 0, 0); +} + +NATPMPInterface::~NATPMPInterface() { + closenatpmp(&natpmp); +} + +bool NATPMPInterface::isAvailable() { + return getPublicIP(); +} + +boost::optional<HostAddress> NATPMPInterface::getPublicIP() { + if (sendpublicaddressrequest(&natpmp) < 0) { + SWIFT_LOG(debug) << "Failed to send NAT-PMP public address request!" << std::endl; + return boost::optional<HostAddress>(); + } + + int r = 0; + natpmpresp_t response; + do { + fd_set fds; + struct timeval timeout; + FD_ZERO(&fds); + FD_SET(natpmp.s, &fds); + getnatpmprequesttimeout(&natpmp, &timeout); + select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + r = readnatpmpresponseorretry(&natpmp, &response); + } while (r == NATPMP_TRYAGAIN); + + if (r == 0) { + return boost::optional<HostAddress>(HostAddress(reinterpret_cast<const unsigned char*>(&(response.pnu.publicaddress.addr)), 4)); + } + else { + SWIFT_LOG(debug) << "Inavlid NAT-PMP response." << std::endl; + return boost::optional<HostAddress>(); + } +} + +boost::optional<NATPortMapping> NATPMPInterface::addPortForward(int localPort, int publicPort) { + NATPortMapping mapping(localPort, publicPort, NATPortMapping::TCP); + if (sendnewportmappingrequest(&natpmp, mapping.protocol == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, mapping.leaseInSeconds, mapping.publicPort, mapping.localPort) < 0) { + SWIFT_LOG(debug) << "Failed to send NAT-PMP port forwarding request!" << std::endl; + return boost::optional<NATPortMapping>(); + } + + int r = 0; + natpmpresp_t response; + do { + fd_set fds; + struct timeval timeout; + FD_ZERO(&fds); + FD_SET(natpmp.s, &fds); + getnatpmprequesttimeout(&natpmp, &timeout); + select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + r = readnatpmpresponseorretry(&natpmp, &response); + } while(r == NATPMP_TRYAGAIN); + + if (r == 0) { + mapping.localPort = response.pnu.newportmapping.privateport; + mapping.publicPort = response.pnu.newportmapping.mappedpublicport; + mapping.leaseInSeconds = response.pnu.newportmapping.lifetime; + return mapping; + } + else { + SWIFT_LOG(debug) << "Invalid NAT-PMP response." << std::endl; + return boost::optional<NATPortMapping>(); + } +} + +bool NATPMPInterface::removePortForward(const NATPortMapping& mapping) { + if (sendnewportmappingrequest(&natpmp, mapping.protocol == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, 0, 0, mapping.localPort) < 0) { + SWIFT_LOG(debug) << "Failed to send NAT-PMP remove forwarding request!" << std::endl; + return false; + } + + int r = 0; + natpmpresp_t response; + do { + fd_set fds; + struct timeval timeout; + FD_ZERO(&fds); + FD_SET(natpmp.s, &fds); + getnatpmprequesttimeout(&natpmp, &timeout); + select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + r = readnatpmpresponseorretry(&natpmp, &response); + } while(r == NATPMP_TRYAGAIN); + + if (r == 0) { + return true; + } + else { + SWIFT_LOG(debug) << "Invalid NAT-PMP response." << std::endl; + return false; + } +} + + +} diff --git a/Swiften/Network/NATPMPInterface.h b/Swiften/Network/NATPMPInterface.h new file mode 100644 index 0000000..6e7fb73 --- /dev/null +++ b/Swiften/Network/NATPMPInterface.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/optional.hpp> +#include <Swiften/Network/NATPortMapping.h> +#include <Swiften/Network/NATTraversalInterface.h> + +// This has to be included after the previous headers, because of WIN32 macro +// being defined somewhere. +#include <natpmp.h> + +namespace Swift { + class NATPMPInterface : public NATTraversalInterface { + public: + NATPMPInterface(); + ~NATPMPInterface(); + + virtual bool isAvailable(); + + virtual boost::optional<HostAddress> getPublicIP(); + virtual boost::optional<NATPortMapping> addPortForward(int localPort, int publicPort); + virtual bool removePortForward(const NATPortMapping&); + + private: + natpmp_t natpmp; + }; +} diff --git a/Swiften/Network/NATPortMapping.h b/Swiften/Network/NATPortMapping.h new file mode 100644 index 0000000..82f62bb --- /dev/null +++ b/Swiften/Network/NATPortMapping.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Network/HostAddress.h> + +namespace Swift { + struct NATPortMapping { + enum Protocol { + TCP, + UDP, + }; + + NATPortMapping(int localPort, int publicPort, Protocol protocol = TCP, int leaseInSeconds = 60 * 60 * 24) : publicPort(publicPort), localPort(localPort), protocol(protocol), leaseInSeconds(leaseInSeconds) { + + } + + int publicPort; + int localPort; + Protocol protocol; + int leaseInSeconds; + }; +} diff --git a/Swiften/Network/NATTraversalForwardPortRequest.cpp b/Swiften/Network/NATTraversalForwardPortRequest.cpp new file mode 100644 index 0000000..c364b8f --- /dev/null +++ b/Swiften/Network/NATTraversalForwardPortRequest.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Network/NATTraversalForwardPortRequest.h> + +namespace Swift { + +NATTraversalForwardPortRequest::~NATTraversalForwardPortRequest() { +} + +} diff --git a/Swiften/Network/NATTraversalForwardPortRequest.h b/Swiften/Network/NATTraversalForwardPortRequest.h new file mode 100644 index 0000000..1bbc9ca --- /dev/null +++ b/Swiften/Network/NATTraversalForwardPortRequest.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Base/boost_bsignals.h> + +#include <Swiften/Network/NATPortMapping.h> + +namespace Swift { + class NATTraversalForwardPortRequest { + public: + virtual ~NATTraversalForwardPortRequest(); + + virtual void run() = 0; + + boost::signal<void (boost::optional<NATPortMapping>)> onResult; + }; +} diff --git a/Swiften/Network/NATTraversalGetPublicIPRequest.cpp b/Swiften/Network/NATTraversalGetPublicIPRequest.cpp new file mode 100644 index 0000000..d8219d5 --- /dev/null +++ b/Swiften/Network/NATTraversalGetPublicIPRequest.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Network/NATTraversalGetPublicIPRequest.h> + +namespace Swift { + +NATTraversalGetPublicIPRequest::~NATTraversalGetPublicIPRequest() { +} + +} diff --git a/Swiften/Network/NATTraversalGetPublicIPRequest.h b/Swiften/Network/NATTraversalGetPublicIPRequest.h new file mode 100644 index 0000000..db1f005 --- /dev/null +++ b/Swiften/Network/NATTraversalGetPublicIPRequest.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Network/HostAddress.h> + +namespace Swift { + class NATTraversalGetPublicIPRequest { + public: + virtual ~NATTraversalGetPublicIPRequest(); + + virtual void run() = 0; + + boost::signal<void (boost::optional<HostAddress>)> onResult; + }; +} diff --git a/Swiften/Network/NATTraversalInterface.cpp b/Swiften/Network/NATTraversalInterface.cpp new file mode 100644 index 0000000..f8a0cc2 --- /dev/null +++ b/Swiften/Network/NATTraversalInterface.cpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Network/NATTraversalInterface.h> + +#include <Swiften/Base/Log.h> + + +namespace Swift { + +NATTraversalInterface::~NATTraversalInterface() { +} + +} diff --git a/Swiften/Network/NATTraversalInterface.h b/Swiften/Network/NATTraversalInterface.h new file mode 100644 index 0000000..c84deba --- /dev/null +++ b/Swiften/Network/NATTraversalInterface.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/optional.hpp> + +#include <Swiften/Network/NATPortMapping.h> + +namespace Swift { + class NATTraversalInterface { + public: + virtual ~NATTraversalInterface(); + + virtual bool isAvailable() = 0; + + virtual boost::optional<HostAddress> getPublicIP() = 0; + virtual boost::optional<NATPortMapping> addPortForward(int localPort, int publicPort) = 0; + virtual bool removePortForward(const NATPortMapping&) = 0; + }; +} diff --git a/Swiften/Network/NATTraversalRemovePortForwardingRequest.cpp b/Swiften/Network/NATTraversalRemovePortForwardingRequest.cpp new file mode 100644 index 0000000..04ec715 --- /dev/null +++ b/Swiften/Network/NATTraversalRemovePortForwardingRequest.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Network/NATTraversalRemovePortForwardingRequest.h> + +namespace Swift { + +NATTraversalRemovePortForwardingRequest::~NATTraversalRemovePortForwardingRequest() { +} + +} diff --git a/Swiften/Network/NATTraversalRemovePortForwardingRequest.h b/Swiften/Network/NATTraversalRemovePortForwardingRequest.h new file mode 100644 index 0000000..cf349b1 --- /dev/null +++ b/Swiften/Network/NATTraversalRemovePortForwardingRequest.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Network/HostAddress.h> + +namespace Swift { + class NATTraversalRemovePortForwardingRequest { + public: + struct PortMapping { + enum Protocol { + TCP, + UDP, + }; + + unsigned int publicPort; + unsigned int localPort; + Protocol protocol; + unsigned long leaseInSeconds; + }; + + public: + virtual ~NATTraversalRemovePortForwardingRequest(); + + virtual void run() = 0; + + boost::signal<void (boost::optional<bool> /* failure */)> onResult; + }; +} diff --git a/Swiften/Network/NATTraverser.cpp b/Swiften/Network/NATTraverser.cpp new file mode 100644 index 0000000..8c628ee --- /dev/null +++ b/Swiften/Network/NATTraverser.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Network/NATTraverser.h> + +namespace Swift { + +NATTraverser::~NATTraverser() { +} + +} diff --git a/Swiften/Network/NATTraverser.h b/Swiften/Network/NATTraverser.h new file mode 100644 index 0000000..e48ce26 --- /dev/null +++ b/Swiften/Network/NATTraverser.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 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> + +namespace Swift { + class NATTraversalGetPublicIPRequest; + class NATTraversalForwardPortRequest; + class NATTraversalRemovePortForwardingRequest; + + class NATTraverser { + public: + virtual ~NATTraverser(); + + virtual boost::shared_ptr<NATTraversalGetPublicIPRequest> createGetPublicIPRequest() = 0; + virtual boost::shared_ptr<NATTraversalForwardPortRequest> createForwardPortRequest(int localPort, int publicPort) = 0; + virtual boost::shared_ptr<NATTraversalRemovePortForwardingRequest> createRemovePortForwardingRequest(int localPort, int publicPort) = 0; + }; +} diff --git a/Swiften/Network/NetworkEnvironment.cpp b/Swiften/Network/NetworkEnvironment.cpp new file mode 100644 index 0000000..52ceb01 --- /dev/null +++ b/Swiften/Network/NetworkEnvironment.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Network/NetworkEnvironment.h> + +#include <Swiften/Network/NetworkInterface.h> +#include <Swiften/Network/HostAddress.h> +#include <Swiften/Base/foreach.h> + +namespace Swift { + +NetworkEnvironment::~NetworkEnvironment() { +} + +HostAddress NetworkEnvironment::getLocalAddress() const { + std::vector<NetworkInterface> networkInterfaces = getNetworkInterfaces(); + foreach (const NetworkInterface& iface, networkInterfaces) { + if (!iface.isLoopback()) { + foreach (const HostAddress& address, iface.getAddresses()) { + if (address.getRawAddress().is_v4()) { + return address; + } + } + } + } + return HostAddress(); +} + +} diff --git a/Swiften/Network/NetworkEnvironment.h b/Swiften/Network/NetworkEnvironment.h new file mode 100644 index 0000000..fbff0cb --- /dev/null +++ b/Swiften/Network/NetworkEnvironment.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <vector> + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Network/NetworkInterface.h> + +namespace Swift { + class NetworkEnvironment { + public: + virtual ~NetworkEnvironment(); + + virtual std::vector<NetworkInterface> getNetworkInterfaces() const = 0; + + HostAddress getLocalAddress() const; + }; +} diff --git a/Swiften/Network/NetworkFactories.cpp b/Swiften/Network/NetworkFactories.cpp index 361cb90..7046fd3 100644 --- a/Swiften/Network/NetworkFactories.cpp +++ b/Swiften/Network/NetworkFactories.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/NetworkFactories.h" +#include <Swiften/Network/NetworkFactories.h> namespace Swift { diff --git a/Swiften/Network/NetworkFactories.h b/Swiften/Network/NetworkFactories.h index d0d2299..05ddfe3 100644 --- a/Swiften/Network/NetworkFactories.h +++ b/Swiften/Network/NetworkFactories.h @@ -11,6 +11,7 @@ namespace Swift { class ConnectionFactory; class DomainNameResolver; class ConnectionServerFactory; + class NATTraverser; /** * An interface collecting network factories. @@ -23,5 +24,6 @@ namespace Swift { virtual ConnectionFactory* getConnectionFactory() const = 0; virtual DomainNameResolver* getDomainNameResolver() const = 0; virtual ConnectionServerFactory* getConnectionServerFactory() const = 0; + virtual NATTraverser* getNATTraverser() const = 0; }; } diff --git a/Swiften/Network/NetworkInterface.h b/Swiften/Network/NetworkInterface.h new file mode 100644 index 0000000..1d302cb --- /dev/null +++ b/Swiften/Network/NetworkInterface.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <vector> + +#include <Swiften/Network/HostAddress.h> + +namespace Swift { + class NetworkInterface { + public: + NetworkInterface(const std::string& name, bool loopback) : name(name), loopback(loopback) { + } + + void addAddress(const HostAddress& address) { + addresses.push_back(address); + } + + const std::vector<HostAddress>& getAddresses() const { + return addresses; + } + + const std::string& getName() const { + return name; + } + + bool isLoopback() const { + return loopback; + } + + private: + std::string name; + bool loopback; + std::vector<HostAddress> addresses; + }; +} diff --git a/Swiften/Network/NullNATTraversalInterface.h b/Swiften/Network/NullNATTraversalInterface.h new file mode 100644 index 0000000..72a4a08 --- /dev/null +++ b/Swiften/Network/NullNATTraversalInterface.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/optional.hpp> + +#include <Swiften/Network/NATTraversalInterface.h> + +namespace Swift { + class NullNATTraversalInterface : public NATTraversalInterface { + public: + virtual bool isAvailable() { + return true; + } + + virtual boost::optional<HostAddress> getPublicIP() { + return boost::optional<HostAddress>(); + } + + virtual boost::optional<NATPortMapping> addPortForward(int, int) { + return boost::optional<NATPortMapping>(); + } + + virtual bool removePortForward(const NATPortMapping&) { + return false; + } + }; +} diff --git a/Swiften/Network/NullNATTraverser.cpp b/Swiften/Network/NullNATTraverser.cpp new file mode 100644 index 0000000..8cb35cd --- /dev/null +++ b/Swiften/Network/NullNATTraverser.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Network/NullNATTraverser.h> + +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/bind.hpp> + +#include <Swiften/Network/NATTraversalGetPublicIPRequest.h> +#include <Swiften/Network/NATTraversalForwardPortRequest.h> +#include <Swiften/Network/NATTraversalRemovePortForwardingRequest.h> +#include <Swiften/EventLoop/EventLoop.h> + +namespace Swift { + +class NullNATTraversalGetPublicIPRequest : public NATTraversalGetPublicIPRequest { + public: + NullNATTraversalGetPublicIPRequest(EventLoop* eventLoop) : eventLoop(eventLoop) { + } + + virtual void run() { + eventLoop->postEvent(boost::bind(boost::ref(onResult), boost::optional<HostAddress>())); + } + + private: + EventLoop* eventLoop; +}; + +class NullNATTraversalForwardPortRequest : public NATTraversalForwardPortRequest { + public: + NullNATTraversalForwardPortRequest(EventLoop* eventLoop) : eventLoop(eventLoop) { + } + + virtual void run() { + eventLoop->postEvent(boost::bind(boost::ref(onResult), boost::optional<NATPortMapping>())); + } + + private: + EventLoop* eventLoop; +}; + +class NullNATTraversalRemovePortForwardingRequest : public NATTraversalRemovePortForwardingRequest { + public: + NullNATTraversalRemovePortForwardingRequest(EventLoop* eventLoop) : eventLoop(eventLoop) { + } + + virtual void run() { + eventLoop->postEvent(boost::bind(boost::ref(onResult), boost::optional<bool>(true))); + } + + private: + EventLoop* eventLoop; +}; + +NullNATTraverser::NullNATTraverser(EventLoop* eventLoop) : eventLoop(eventLoop) { +} + +boost::shared_ptr<NATTraversalGetPublicIPRequest> NullNATTraverser::createGetPublicIPRequest() { + return boost::make_shared<NullNATTraversalGetPublicIPRequest>(eventLoop); +} + +boost::shared_ptr<NATTraversalForwardPortRequest> NullNATTraverser::createForwardPortRequest(int, int) { + return boost::make_shared<NullNATTraversalForwardPortRequest>(eventLoop); +} + +boost::shared_ptr<NATTraversalRemovePortForwardingRequest> NullNATTraverser::createRemovePortForwardingRequest(int, int) { + return boost::make_shared<NullNATTraversalRemovePortForwardingRequest>(eventLoop); +} + +} diff --git a/Swiften/Network/NullNATTraverser.h b/Swiften/Network/NullNATTraverser.h new file mode 100644 index 0000000..5775a9b --- /dev/null +++ b/Swiften/Network/NullNATTraverser.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Network/NATTraverser.h> + +namespace Swift { + class EventLoop; + + class NullNATTraverser : public NATTraverser { + public: + NullNATTraverser(EventLoop* eventLoop); + + boost::shared_ptr<NATTraversalGetPublicIPRequest> createGetPublicIPRequest(); + boost::shared_ptr<NATTraversalForwardPortRequest> createForwardPortRequest(int localPort, int publicPort); + boost::shared_ptr<NATTraversalRemovePortForwardingRequest> createRemovePortForwardingRequest(int localPort, int publicPort); + + private: + EventLoop* eventLoop; + }; +} diff --git a/Swiften/Network/NullProxyProvider.cpp b/Swiften/Network/NullProxyProvider.cpp new file mode 100644 index 0000000..3b9d94d --- /dev/null +++ b/Swiften/Network/NullProxyProvider.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Network/NullProxyProvider.h> + +using namespace Swift; + +NullProxyProvider::NullProxyProvider() { +} + +HostAddressPort NullProxyProvider::getHTTPConnectProxy() const { + return HostAddressPort(); +} + +HostAddressPort NullProxyProvider::getSOCKS5Proxy() const { + return HostAddressPort(); +} diff --git a/Swiften/Network/NullProxyProvider.h b/Swiften/Network/NullProxyProvider.h new file mode 100644 index 0000000..544bea2 --- /dev/null +++ b/Swiften/Network/NullProxyProvider.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Network/ProxyProvider.h> + +namespace Swift { + class NullProxyProvider : public ProxyProvider { + public: + NullProxyProvider(); + + virtual HostAddressPort getHTTPConnectProxy() const; + virtual HostAddressPort getSOCKS5Proxy() const; + }; +} diff --git a/Swiften/Network/PlatformDomainNameAddressQuery.cpp b/Swiften/Network/PlatformDomainNameAddressQuery.cpp index 1832255..ec7e663 100644 --- a/Swiften/Network/PlatformDomainNameAddressQuery.cpp +++ b/Swiften/Network/PlatformDomainNameAddressQuery.cpp @@ -6,6 +6,8 @@ #include <Swiften/Network/PlatformDomainNameAddressQuery.h> +#include <boost/asio/ip/tcp.hpp> + #include <Swiften/Network/PlatformDomainNameResolver.h> #include <Swiften/EventLoop/EventLoop.h> diff --git a/Swiften/Network/PlatformDomainNameAddressQuery.h b/Swiften/Network/PlatformDomainNameAddressQuery.h index c2854ac..e1dc05f 100644 --- a/Swiften/Network/PlatformDomainNameAddressQuery.h +++ b/Swiften/Network/PlatformDomainNameAddressQuery.h @@ -6,7 +6,7 @@ #pragma once -#include <boost/asio.hpp> +#include <boost/asio/io_service.hpp> #include <boost/enable_shared_from_this.hpp> #include <Swiften/Network/DomainNameAddressQuery.h> diff --git a/Swiften/Network/PlatformDomainNameResolver.cpp b/Swiften/Network/PlatformDomainNameResolver.cpp index f2c1e36..63f7404 100644 --- a/Swiften/Network/PlatformDomainNameResolver.cpp +++ b/Swiften/Network/PlatformDomainNameResolver.cpp @@ -4,10 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/PlatformDomainNameResolver.h" +#include <Swiften/Network/PlatformDomainNameResolver.h> // Putting this early on, because some system types conflict with thread -#include "Swiften/Network/PlatformDomainNameServiceQuery.h" +#include <Swiften/Network/PlatformDomainNameServiceQuery.h> #include <string> #include <vector> @@ -16,11 +16,11 @@ #include <algorithm> #include <string> -#include "Swiften/IDN/IDNA.h" -#include "Swiften/Network/HostAddress.h" -#include "Swiften/EventLoop/EventLoop.h" -#include "Swiften/Network/HostAddressPort.h" -#include "Swiften/Network/DomainNameAddressQuery.h" +#include <Swiften/IDN/IDNA.h> +#include <Swiften/Network/HostAddress.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Network/DomainNameAddressQuery.h> #include <Swiften/Network/PlatformDomainNameAddressQuery.h> using namespace Swift; diff --git a/Swiften/Network/PlatformDomainNameResolver.h b/Swiften/Network/PlatformDomainNameResolver.h index e681331..295ecc5 100644 --- a/Swiften/Network/PlatformDomainNameResolver.h +++ b/Swiften/Network/PlatformDomainNameResolver.h @@ -7,7 +7,7 @@ #pragma once #include <deque> -#include <boost/thread.hpp> +#include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/condition_variable.hpp> diff --git a/Swiften/Network/PlatformDomainNameServiceQuery.cpp b/Swiften/Network/PlatformDomainNameServiceQuery.cpp index 7d8074d..5d076ac 100644 --- a/Swiften/Network/PlatformDomainNameServiceQuery.cpp +++ b/Swiften/Network/PlatformDomainNameServiceQuery.cpp @@ -6,11 +6,11 @@ #include <boost/asio.hpp> -#include "Swiften/Network/PlatformDomainNameServiceQuery.h" +#include <Swiften/Network/PlatformDomainNameServiceQuery.h> #pragma GCC diagnostic ignored "-Wold-style-cast" -#include "Swiften/Base/Platform.h" +#include <Swiften/Base/Platform.h> #include <stdlib.h> #ifdef SWIFTEN_PLATFORM_WINDOWS #undef UNICODE @@ -26,9 +26,9 @@ #endif #include <boost/bind.hpp> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/EventLoop/EventLoop.h" -#include "Swiften/Base/foreach.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/Base/foreach.h> #include <Swiften/Base/Log.h> #include <Swiften/Network/PlatformDomainNameResolver.h> @@ -81,7 +81,7 @@ void PlatformDomainNameServiceQuery::runBlocking() { ByteArray response; response.resize(NS_PACKETSZ); - int responseLength = res_query(const_cast<char*>(service.c_str()), ns_c_in, ns_t_srv, reinterpret_cast<u_char*>(response.getData()), response.getSize()); + int responseLength = res_query(const_cast<char*>(service.c_str()), ns_c_in, ns_t_srv, reinterpret_cast<u_char*>(vecptr(response)), response.size()); if (responseLength == -1) { SWIFT_LOG(debug) << "Error" << std::endl; emitError(); @@ -89,8 +89,8 @@ void PlatformDomainNameServiceQuery::runBlocking() { } // Parse header - HEADER* header = reinterpret_cast<HEADER*>(response.getData()); - unsigned char* messageStart = reinterpret_cast<unsigned char*>(response.getData()); + HEADER* header = reinterpret_cast<HEADER*>(vecptr(response)); + unsigned char* messageStart = vecptr(response); unsigned char* messageEnd = messageStart + responseLength; unsigned char* currentEntry = messageStart + NS_HFIXEDSZ; @@ -146,12 +146,12 @@ void PlatformDomainNameServiceQuery::runBlocking() { } ByteArray entry; entry.resize(NS_MAXDNAME); - entryLength = dn_expand(messageStart, messageEnd, currentEntry, reinterpret_cast<char*>(entry.getData()), entry.getSize()); + entryLength = dn_expand(messageStart, messageEnd, currentEntry, reinterpret_cast<char*>(vecptr(entry)), entry.size()); if (entryLength < 0) { emitError(); return; } - record.hostname = std::string(reinterpret_cast<const char*>(entry.getData())); + record.hostname = std::string(reinterpret_cast<const char*>(vecptr(entry))); records.push_back(record); currentEntry += entryLength; answersCount--; diff --git a/Swiften/Network/PlatformDomainNameServiceQuery.h b/Swiften/Network/PlatformDomainNameServiceQuery.h index 52f8bc1..3372517 100644 --- a/Swiften/Network/PlatformDomainNameServiceQuery.h +++ b/Swiften/Network/PlatformDomainNameServiceQuery.h @@ -8,8 +8,8 @@ #include <boost/enable_shared_from_this.hpp> -#include "Swiften/Network/DomainNameServiceQuery.h" -#include "Swiften/EventLoop/EventOwner.h" +#include <Swiften/Network/DomainNameServiceQuery.h> +#include <Swiften/EventLoop/EventOwner.h> #include <string> #include <Swiften/Network/PlatformDomainNameQuery.h> diff --git a/Swiften/Network/PlatformNATTraversalWorker.cpp b/Swiften/Network/PlatformNATTraversalWorker.cpp new file mode 100644 index 0000000..c962b3b --- /dev/null +++ b/Swiften/Network/PlatformNATTraversalWorker.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "PlatformNATTraversalWorker.h" + +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/enable_shared_from_this.hpp> + +#include <Swiften/Base/Log.h> +#include <Swiften/Network/NATTraversalGetPublicIPRequest.h> +#include <Swiften/Network/NATTraversalForwardPortRequest.h> +#include <Swiften/Network/NATTraversalRemovePortForwardingRequest.h> +#include <Swiften/Network/NATPMPInterface.h> +#include <Swiften/Network/MiniUPnPInterface.h> + +namespace Swift { + +class PlatformNATTraversalRequest : public boost::enable_shared_from_this<PlatformNATTraversalRequest> { + public: + typedef boost::shared_ptr<PlatformNATTraversalRequest> ref; + + public: + PlatformNATTraversalRequest(PlatformNATTraversalWorker* worker) : worker(worker) { + } + + virtual ~PlatformNATTraversalRequest() { + } + + virtual void doRun() { + worker->addRequestToQueue(shared_from_this()); + } + + NATTraversalInterface* getNATTraversalInterface() const { + return worker->getNATTraversalInterface(); + } + + + virtual void runBlocking() = 0; + + private: + PlatformNATTraversalWorker* worker; +}; + +class PlatformNATTraversalGetPublicIPRequest : public NATTraversalGetPublicIPRequest, public PlatformNATTraversalRequest { + public: + PlatformNATTraversalGetPublicIPRequest(PlatformNATTraversalWorker* worker) : PlatformNATTraversalRequest(worker) { + } + + virtual void run() { + doRun(); + } + + virtual void runBlocking() { + onResult(getNATTraversalInterface()->getPublicIP()); + } +}; + +class PlatformNATTraversalForwardPortRequest : public NATTraversalForwardPortRequest, public PlatformNATTraversalRequest { + public: + PlatformNATTraversalForwardPortRequest(PlatformNATTraversalWorker* worker, unsigned int localIP, unsigned int publicIP) : PlatformNATTraversalRequest(worker), localIP(localIP), publicIP(publicIP) { + } + + virtual void run() { + doRun(); + } + + virtual void runBlocking() { + onResult(getNATTraversalInterface()->addPortForward(localIP, publicIP)); + } + + private: + unsigned int localIP; + unsigned int publicIP; +}; + +class PlatformNATTraversalRemovePortForwardingRequest : public NATTraversalRemovePortForwardingRequest, public PlatformNATTraversalRequest { + public: + PlatformNATTraversalRemovePortForwardingRequest(PlatformNATTraversalWorker* worker, const NATPortMapping& mapping) : PlatformNATTraversalRequest(worker), mapping(mapping) { + } + + virtual void run() { + doRun(); + } + + virtual void runBlocking() { + onResult(getNATTraversalInterface()->removePortForward(mapping)); + } + + private: + NATPortMapping mapping; +}; + +PlatformNATTraversalWorker::PlatformNATTraversalWorker(EventLoop* eventLoop) : eventLoop(eventLoop), stopRequested(false), natPMPSupported(boost::logic::indeterminate), natPMPInterface(NULL), miniUPnPSupported(boost::logic::indeterminate), miniUPnPInterface(NULL) { + nullNATTraversalInterface = new NullNATTraversalInterface(); + thread = new boost::thread(boost::bind(&PlatformNATTraversalWorker::run, this)); +} + +PlatformNATTraversalWorker::~PlatformNATTraversalWorker() { + stopRequested = true; + addRequestToQueue(boost::shared_ptr<PlatformNATTraversalRequest>()); + thread->join(); + delete thread; + delete natPMPInterface; + delete miniUPnPInterface; + delete nullNATTraversalInterface; +} + +NATTraversalInterface* PlatformNATTraversalWorker::getNATTraversalInterface() const { + if (boost::logic::indeterminate(miniUPnPSupported)) { + miniUPnPInterface = new MiniUPnPInterface(); + miniUPnPSupported = miniUPnPInterface->isAvailable(); + } + if (miniUPnPSupported) { + return miniUPnPInterface; + } + + + if (boost::logic::indeterminate(natPMPSupported)) { + natPMPInterface = new NATPMPInterface(); + natPMPSupported = natPMPInterface->isAvailable(); + } + if (natPMPSupported) { + return natPMPInterface; + } + + return nullNATTraversalInterface; +} + +boost::shared_ptr<NATTraversalGetPublicIPRequest> PlatformNATTraversalWorker::createGetPublicIPRequest() { + return boost::make_shared<PlatformNATTraversalGetPublicIPRequest>(this); +} + +boost::shared_ptr<NATTraversalForwardPortRequest> PlatformNATTraversalWorker::createForwardPortRequest(int localPort, int publicPort) { + return boost::make_shared<PlatformNATTraversalForwardPortRequest>(this, localPort, publicPort); +} + +boost::shared_ptr<NATTraversalRemovePortForwardingRequest> PlatformNATTraversalWorker::createRemovePortForwardingRequest(int localPort, int publicPort) { + NATPortMapping mapping(localPort, publicPort, NATPortMapping::TCP); // FIXME + return boost::make_shared<PlatformNATTraversalRemovePortForwardingRequest>(this, mapping); +} + +void PlatformNATTraversalWorker::run() { + while (!stopRequested) { + PlatformNATTraversalRequest::ref request; + { + boost::unique_lock<boost::mutex> lock(queueMutex); + while (queue.empty()) { + queueNonEmpty.wait(lock); + } + request = queue.front(); + queue.pop_front(); + } + // Check whether we don't have a non-null request (used to stop the + // worker) + if (request) { + request->runBlocking(); + } + } +} + +void PlatformNATTraversalWorker::addRequestToQueue(PlatformNATTraversalRequest::ref request) { + { + boost::lock_guard<boost::mutex> lock(queueMutex); + queue.push_back(request); + } + queueNonEmpty.notify_one(); +} + +} diff --git a/Swiften/Network/PlatformNATTraversalWorker.h b/Swiften/Network/PlatformNATTraversalWorker.h new file mode 100644 index 0000000..94d3339 --- /dev/null +++ b/Swiften/Network/PlatformNATTraversalWorker.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <deque> +#include <boost/optional.hpp> +#include <boost/thread/thread.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/condition_variable.hpp> +#include <boost/logic/tribool.hpp> + +#include <Swiften/Network/NATTraverser.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Network/NullNATTraversalInterface.h> + +namespace Swift { + class EventLoop; + class NATTraversalGetPublicIPRequest; + class NATTraversalForwardPortRequest; + class NATTraversalRemovePortForwardingRequest; + class PlatformNATTraversalRequest; + class NATPMPInterface; + class MiniUPnPInterface; + class NATTraversalInterface; + class NATPortMapping; + + class PlatformNATTraversalWorker : public NATTraverser { + friend class PlatformNATTraversalRequest; + + public: + PlatformNATTraversalWorker(EventLoop* eventLoop); + ~PlatformNATTraversalWorker(); + + boost::shared_ptr<NATTraversalGetPublicIPRequest> createGetPublicIPRequest(); + boost::shared_ptr<NATTraversalForwardPortRequest> createForwardPortRequest(int localPort, int publicPort); + boost::shared_ptr<NATTraversalRemovePortForwardingRequest> createRemovePortForwardingRequest(int localPort, int publicPort); + + private: + NATTraversalInterface* getNATTraversalInterface() const; + void addRequestToQueue(boost::shared_ptr<PlatformNATTraversalRequest>); + void run(); + + private: + EventLoop* eventLoop; + bool stopRequested; + boost::thread* thread; + std::deque<boost::shared_ptr<PlatformNATTraversalRequest> > queue; + boost::mutex queueMutex; + boost::condition_variable queueNonEmpty; + + NullNATTraversalInterface* nullNATTraversalInterface; + mutable boost::logic::tribool natPMPSupported; + mutable NATPMPInterface* natPMPInterface; + mutable boost::logic::tribool miniUPnPSupported; + mutable MiniUPnPInterface* miniUPnPInterface; + }; +} diff --git a/Swiften/Network/PlatformNetworkEnvironment.h b/Swiften/Network/PlatformNetworkEnvironment.h new file mode 100644 index 0000000..c6b945e --- /dev/null +++ b/Swiften/Network/PlatformNetworkEnvironment.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Base/Platform.h> + +#if defined(SWIFTEN_PLATFORM_MACOSX) +#include <Swiften/Network/UnixNetworkEnvironment.h> +namespace Swift { + typedef UnixNetworkEnvironment PlatformNetworkEnvironment; +} +#elif defined(SWIFTEN_PLATFORM_WIN32) +#include <Swiften/Network/WindowsNetworkEnvironment.h> +namespace Swift { + typedef WindowsNetworkEnvironment PlatformNetworkEnvironment; +} +#else +#include <Swiften/Network/UnixNetworkEnvironment.h> +namespace Swift { + typedef UnixNetworkEnvironment PlatformNetworkEnvironment; +} +#endif diff --git a/Swiften/Network/PlatformProxyProvider.h b/Swiften/Network/PlatformProxyProvider.h new file mode 100644 index 0000000..1a0a1c6 --- /dev/null +++ b/Swiften/Network/PlatformProxyProvider.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Base/Platform.h> + +#if defined(SWIFTEN_PLATFORM_MACOSX) +#include <Swiften/Network/MacOSXProxyProvider.h> +namespace Swift { + typedef MacOSXProxyProvider PlatformProxyProvider; +} +#elif defined(SWIFTEN_PLATFORM_WIN32) +#include <Swiften/Network/WindowsProxyProvider.h> +namespace Swift { + typedef WindowsProxyProvider PlatformProxyProvider; +} +#else +#include <Swiften/Network/UnixProxyProvider.h> +namespace Swift { + typedef UnixProxyProvider PlatformProxyProvider; +} +#endif diff --git a/Swiften/Network/ProxyProvider.cpp b/Swiften/Network/ProxyProvider.cpp new file mode 100644 index 0000000..fe235b1 --- /dev/null +++ b/Swiften/Network/ProxyProvider.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "ProxyProvider.h" + +namespace Swift { + +ProxyProvider::ProxyProvider() +{ +} + +ProxyProvider::~ProxyProvider() +{ +} + +} diff --git a/Swiften/Network/ProxyProvider.h b/Swiften/Network/ProxyProvider.h new file mode 100644 index 0000000..0b63d51 --- /dev/null +++ b/Swiften/Network/ProxyProvider.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once +#include <map> + +#include <Swiften/Base/Log.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Base/String.h> + +namespace Swift { + class ProxyProvider { + public: + ProxyProvider(); + virtual ~ProxyProvider(); + virtual HostAddressPort getHTTPConnectProxy() const = 0; + virtual HostAddressPort getSOCKS5Proxy() const = 0; + }; +} + diff --git a/Swiften/Network/SConscript b/Swiften/Network/SConscript index d5cc185..49df18f 100644 --- a/Swiften/Network/SConscript +++ b/Swiften/Network/SConscript @@ -6,6 +6,10 @@ if myenv.get("HAVE_CARES", False) : myenv.MergeFlags(myenv.get("CARES_FLAGS", {})) sourceList = [ + "HTTPConnectProxiedConnection.cpp", + "HTTPConnectProxiedConnectionFactory.cpp", + "SOCKS5ProxiedConnection.cpp", + "SOCKS5ProxiedConnectionFactory.cpp", "BoostConnection.cpp", "BoostConnectionFactory.cpp", "BoostConnectionServer.cpp", @@ -14,7 +18,11 @@ sourceList = [ "ConnectionFactory.cpp", "ConnectionServer.cpp", "ConnectionServerFactory.cpp", + "DummyConnection.cpp", + "FakeConnection.cpp", + "ChainedConnector.cpp", "Connector.cpp", + "Connection.cpp", "TimerFactory.cpp", "DummyTimerFactory.cpp", "BoostTimerFactory.cpp", @@ -26,13 +34,59 @@ sourceList = [ "PlatformDomainNameAddressQuery.cpp", "StaticDomainNameResolver.cpp", "HostAddress.cpp", + "HostAddressPort.cpp", "NetworkFactories.cpp", "BoostNetworkFactories.cpp", + "NetworkEnvironment.cpp", "Timer.cpp", - "BoostTimer.cpp"] + "BoostTimer.cpp", + "ProxyProvider.cpp", + "NullProxyProvider.cpp", + "NATTraverser.cpp", + "NullNATTraverser.cpp", + "NATTraversalGetPublicIPRequest.cpp", + "NATTraversalForwardPortRequest.cpp", + "NATTraversalRemovePortForwardingRequest.cpp", + "NATTraversalInterface.cpp", + ] + if myenv.get("HAVE_CARES", False) : sourceList.append("CAresDomainNameResolver.cpp") +if myenv["PLATFORM"] == "darwin" : + myenv.Append(FRAMEWORKS = ["CoreServices", "SystemConfiguration"]) + sourceList += [ "MacOSXProxyProvider.cpp" ] + sourceList += [ "UnixNetworkEnvironment.cpp" ] +elif myenv["PLATFORM"] == "win32" : + sourceList += [ "WindowsProxyProvider.cpp" ] + sourceList += [ "WindowsNetworkEnvironment.cpp" ] +else : + sourceList += [ "UnixNetworkEnvironment.cpp" ] + sourceList += [ "UnixProxyProvider.cpp" ] + sourceList += [ "EnvironmentProxyProvider.cpp" ] + if myenv.get("HAVE_GCONF", 0) : + myenv.Append(CPPDEFINES = "HAVE_GCONF") + myenv.MergeFlags(myenv["GCONF_FLAGS"]) + sourceList += [ "GConfProxyProvider.cpp" ] objects = myenv.SwiftenObject(sourceList) + +if myenv["experimental"] : + # LibNATPMP classes + natpmp_env = myenv.Clone() + natpmp_env.Append(CPPDEFINES = natpmp_env["LIBNATPMP_FLAGS"].get("INTERNAL_CPPDEFINES", [])) + objects += natpmp_env.SwiftenObject([ + "NATPMPInterface.cpp", + ]) + + # LibMINIUPnP classes + upnp_env = myenv.Clone() + upnp_env.Append(CPPDEFINES = upnp_env["LIBMINIUPNPC_FLAGS"].get("INTERNAL_CPPDEFINES", [])) + objects += upnp_env.SwiftenObject([ + "MiniUPnPInterface.cpp", + ]) + objects += myenv.SwiftenObject([ + "PlatformNATTraversalWorker.cpp", + ]) + swiften_env.Append(SWIFTEN_OBJECTS = [objects]) diff --git a/Swiften/Network/SOCKS5ProxiedConnection.cpp b/Swiften/Network/SOCKS5ProxiedConnection.cpp new file mode 100644 index 0000000..163e23a --- /dev/null +++ b/Swiften/Network/SOCKS5ProxiedConnection.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Network/SOCKS5ProxiedConnection.h> + +#include <iostream> +#include <boost/bind.hpp> +#include <boost/thread.hpp> + +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Base/Log.h> +#include <Swiften/Base/String.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Network/HostAddressPort.h> + +using namespace Swift; + +SOCKS5ProxiedConnection::SOCKS5ProxiedConnection(ConnectionFactory* connectionFactory, const HostAddressPort& proxy) : connectionFactory_(connectionFactory), proxy_(proxy), server_(HostAddressPort(HostAddress("0.0.0.0"), 0)) { + connected_ = false; +} + +SOCKS5ProxiedConnection::~SOCKS5ProxiedConnection() { + if (connection_) { + connection_->onDataRead.disconnect(boost::bind(&SOCKS5ProxiedConnection::handleDataRead, shared_from_this(), _1)); + connection_->onDisconnected.disconnect(boost::bind(&SOCKS5ProxiedConnection::handleDisconnected, shared_from_this(), _1)); + } + + if (connected_) { + std::cerr << "Warning: Connection was still established." << std::endl; + } +} + +void SOCKS5ProxiedConnection::connect(const HostAddressPort& server) { + server_ = server; + connection_ = connectionFactory_->createConnection(); + connection_->onConnectFinished.connect(boost::bind(&SOCKS5ProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1)); + connection_->onDataRead.connect(boost::bind(&SOCKS5ProxiedConnection::handleDataRead, shared_from_this(), _1)); + connection_->onDisconnected.connect(boost::bind(&SOCKS5ProxiedConnection::handleDisconnected, shared_from_this(), _1)); + SWIFT_LOG(debug) << "Trying to connect via proxy " << proxy_.getAddress().toString() << ":" << proxy_.getPort() << std::endl; + SWIFT_LOG(debug) << "to server " << server.getAddress().toString() << ":" << server.getPort() << std::endl; + connection_->connect(proxy_); +} + +void SOCKS5ProxiedConnection::listen() { + assert(false); + connection_->listen(); +} + +void SOCKS5ProxiedConnection::disconnect() { + connected_ = false; + if (connection_) { + connection_->disconnect(); + } +} + +void SOCKS5ProxiedConnection::handleDisconnected(const boost::optional<Error>& error) { + onDisconnected(error); +} + +void SOCKS5ProxiedConnection::write(const SafeByteArray& data) { + if (connection_) { + connection_->write(data); + } +} + +void SOCKS5ProxiedConnection::handleConnectionConnectFinished(bool error) { + connection_->onConnectFinished.disconnect(boost::bind(&SOCKS5ProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1)); + if (!error) { + SWIFT_LOG(debug) << "Connection to proxy established, now connect to the server via it." << std::endl; + + proxyState_ = ProxyAuthenticating; + SafeByteArray socksConnect; + socksConnect.push_back(0x05); // VER = SOCKS5 = 0x05 + socksConnect.push_back(0x01); // Number of authentication methods after this byte. + socksConnect.push_back(0x00); // 0x00 == no authentication + // buffer.push_back(0x01); // 0x01 == GSSAPI + // buffer.push_back(0x02); // 0x02 == Username/Password + // rest see RFC 1928 (http://tools.ietf.org/html/rfc1928) + connection_->write(socksConnect); + } + else { + onConnectFinished(true); + } +} + +void SOCKS5ProxiedConnection::handleDataRead(boost::shared_ptr<SafeByteArray> data) { + SafeByteArray socksConnect; + boost::asio::ip::address rawAddress = server_.getAddress().getRawAddress(); + assert(rawAddress.is_v4() || rawAddress.is_v6()); + if (!connected_) { + if (proxyState_ == ProxyAuthenticating) { + SWIFT_LOG(debug) << "ProxyAuthenticating response received, reply with the connect BYTEs" << std::endl; + unsigned char choosenMethod = static_cast<unsigned char> ((*data)[1]); + if ((*data)[0] == 0x05 && choosenMethod != 0xFF) { + switch(choosenMethod) { // use the correct Method + case 0x00: + try { + proxyState_ = ProxyConnecting; + socksConnect.push_back(0x05); // VER = SOCKS5 = 0x05 + socksConnect.push_back(0x01); // Construct a TCP connection. (CMD) + socksConnect.push_back(0x00); // reserved. + socksConnect.push_back(rawAddress.is_v4() ? 0x01 : 0x04); // IPv4 == 0x01, Hostname == 0x02, IPv6 == 0x04. (ATYP) + size_t size = rawAddress.is_v4() ? rawAddress.to_v4().to_bytes().size() : rawAddress.to_v6().to_bytes().size(); + for (size_t s = 0; s < size; s++) { + unsigned char uc; + if(rawAddress.is_v4()) { + uc = rawAddress.to_v4().to_bytes()[s]; // the address. + } + else { + uc = rawAddress.to_v6().to_bytes()[s]; // the address. + } + socksConnect.push_back(static_cast<char>(uc)); + + } + socksConnect.push_back(static_cast<unsigned char> ((server_.getPort() >> 8) & 0xFF)); // highbyte of the port. + socksConnect.push_back(static_cast<unsigned char> (server_.getPort() & 0xFF)); // lowbyte of the port. + connection_->write(socksConnect); + return; + } + catch(...) { + std::cerr << "exception caught" << std::endl; + } + connection_->write(socksConnect); + break; + default: + onConnectFinished(true); + break; + } + return; + } + } + else if (proxyState_ == ProxyConnecting) { + SWIFT_LOG(debug) << "Connect response received, check if successfully." << std::endl; + SWIFT_LOG(debug) << "Errorbyte: 0x" << std::hex << static_cast<int> ((*data)[1]) << std::dec << std::endl; + /* + + data.at(1) can be one of the following: + 0x00 succeeded + 0x01 general SOCKS server failure + 0x02 connection not allowed by ruleset + 0x03 Network unreachable + 0x04 Host unreachable + 0x05 Connection refused + 0x06 TTL expired + 0x07 Command not supported (CMD) + 0x08 Address type not supported (ATYP) + 0x09 bis 0xFF unassigned + */ + if ((*data)[0] == 0x05 && (*data)[1] == 0x0) { + SWIFT_LOG(debug) << "Successfully connected the server via the proxy." << std::endl; + connected_ = true; + onConnectFinished(false); + return; + } + else { + std::cerr << "SOCKS Proxy returned an error: " << std::hex << (*data)[1] << std::endl; + } + return; + } + } + else { + onDataRead(data); + return; + } + disconnect(); + onConnectFinished(true); +} + +HostAddressPort SOCKS5ProxiedConnection::getLocalAddress() const { + return connection_->getLocalAddress(); +} diff --git a/Swiften/Network/SOCKS5ProxiedConnection.h b/Swiften/Network/SOCKS5ProxiedConnection.h new file mode 100644 index 0000000..592ce7d --- /dev/null +++ b/Swiften/Network/SOCKS5ProxiedConnection.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/enable_shared_from_this.hpp> + +#include <Swiften/Network/Connection.h> +#include <Swiften/Network/HostAddressPort.h> + +namespace boost { + class thread; + namespace system { + class error_code; + } +} + +namespace Swift { + class ConnectionFactory; + + class SOCKS5ProxiedConnection : public Connection, public boost::enable_shared_from_this<SOCKS5ProxiedConnection> { + public: + typedef boost::shared_ptr<SOCKS5ProxiedConnection> ref; + + ~SOCKS5ProxiedConnection(); + + static ref create(ConnectionFactory* connectionFactory, const HostAddressPort& proxy) { + return ref(new SOCKS5ProxiedConnection(connectionFactory, proxy)); + } + + virtual void listen(); + virtual void connect(const HostAddressPort& address); + virtual void disconnect(); + virtual void write(const SafeByteArray& data); + + virtual HostAddressPort getLocalAddress() const; + + private: + SOCKS5ProxiedConnection(ConnectionFactory* connectionFactory, const HostAddressPort& proxy); + + void handleConnectionConnectFinished(bool error); + void handleDataRead(boost::shared_ptr<SafeByteArray> data); + void handleDisconnected(const boost::optional<Error>& error); + + private: + enum { + ProxyAuthenticating = 0, + ProxyConnecting, + } proxyState_; + bool connected_; + ConnectionFactory* connectionFactory_; + HostAddressPort proxy_; + HostAddressPort server_; + boost::shared_ptr<Connection> connection_; + }; +} diff --git a/Swiften/Network/SOCKS5ProxiedConnectionFactory.cpp b/Swiften/Network/SOCKS5ProxiedConnectionFactory.cpp new file mode 100644 index 0000000..272ade9 --- /dev/null +++ b/Swiften/Network/SOCKS5ProxiedConnectionFactory.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Network/SOCKS5ProxiedConnectionFactory.h> + +#include <Swiften/Network/SOCKS5ProxiedConnection.h> + +namespace Swift { + +SOCKS5ProxiedConnectionFactory::SOCKS5ProxiedConnectionFactory(ConnectionFactory* connectionFactory, const HostAddressPort& proxy) : connectionFactory_(connectionFactory), proxy_(proxy) { +} + +boost::shared_ptr<Connection> SOCKS5ProxiedConnectionFactory::createConnection() { + return SOCKS5ProxiedConnection::create(connectionFactory_, proxy_); +} + +} diff --git a/Swiften/Network/SOCKS5ProxiedConnectionFactory.h b/Swiften/Network/SOCKS5ProxiedConnectionFactory.h new file mode 100644 index 0000000..f36d42a --- /dev/null +++ b/Swiften/Network/SOCKS5ProxiedConnectionFactory.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/HostAddressPort.h> + +namespace Swift { + class SOCKS5ProxiedConnectionFactory : public ConnectionFactory { + public: + SOCKS5ProxiedConnectionFactory(ConnectionFactory* connectionFactory, const HostAddressPort& proxy); + + virtual boost::shared_ptr<Connection> createConnection(); + + private: + ConnectionFactory* connectionFactory_; + HostAddressPort proxy_; + }; +} diff --git a/Swiften/Network/StaticDomainNameResolver.cpp b/Swiften/Network/StaticDomainNameResolver.cpp index a338272..76ab411 100644 --- a/Swiften/Network/StaticDomainNameResolver.cpp +++ b/Swiften/Network/StaticDomainNameResolver.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/StaticDomainNameResolver.h" +#include <Swiften/Network/StaticDomainNameResolver.h> #include <boost/bind.hpp> #include <boost/lexical_cast.hpp> -#include "Swiften/Network/DomainNameResolveError.h" +#include <Swiften/Network/DomainNameResolveError.h> #include <string> using namespace Swift; diff --git a/Swiften/Network/StaticDomainNameResolver.h b/Swiften/Network/StaticDomainNameResolver.h index 2ef1295..a72db7c 100644 --- a/Swiften/Network/StaticDomainNameResolver.h +++ b/Swiften/Network/StaticDomainNameResolver.h @@ -9,12 +9,12 @@ #include <vector> #include <map> -#include "Swiften/Network/HostAddress.h" -#include "Swiften/Network/HostAddressPort.h" -#include "Swiften/Network/DomainNameResolver.h" -#include "Swiften/Network/DomainNameServiceQuery.h" -#include "Swiften/Network/DomainNameAddressQuery.h" -#include "Swiften/EventLoop/EventLoop.h" +#include <Swiften/Network/HostAddress.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Network/DomainNameResolver.h> +#include <Swiften/Network/DomainNameServiceQuery.h> +#include <Swiften/Network/DomainNameAddressQuery.h> +#include <Swiften/EventLoop/EventLoop.h> namespace Swift { diff --git a/Swiften/Network/Timer.cpp b/Swiften/Network/Timer.cpp index daa4490..3efbd3b 100644 --- a/Swiften/Network/Timer.cpp +++ b/Swiften/Network/Timer.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/Timer.h" +#include <Swiften/Network/Timer.h> namespace Swift { diff --git a/Swiften/Network/Timer.h b/Swiften/Network/Timer.h index d44a00d..b7578f2 100644 --- a/Swiften/Network/Timer.h +++ b/Swiften/Network/Timer.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> namespace Swift { /** diff --git a/Swiften/Network/TimerFactory.cpp b/Swiften/Network/TimerFactory.cpp index 502f669..3fb807c 100644 --- a/Swiften/Network/TimerFactory.cpp +++ b/Swiften/Network/TimerFactory.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Network/TimerFactory.h" +#include <Swiften/Network/TimerFactory.h> namespace Swift { diff --git a/Swiften/Network/TimerFactory.h b/Swiften/Network/TimerFactory.h index 44c87b6..99903c3 100644 --- a/Swiften/Network/TimerFactory.h +++ b/Swiften/Network/TimerFactory.h @@ -8,7 +8,7 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Network/Timer.h" +#include <Swiften/Network/Timer.h> namespace Swift { class TimerFactory { diff --git a/Swiften/Network/UnitTest/ChainedConnectorTest.cpp b/Swiften/Network/UnitTest/ChainedConnectorTest.cpp new file mode 100644 index 0000000..c7d23da --- /dev/null +++ b/Swiften/Network/UnitTest/ChainedConnectorTest.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Network/ChainedConnector.h> +#include <Swiften/Network/Connection.h> +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Network/StaticDomainNameResolver.h> +#include <Swiften/Network/DummyTimerFactory.h> +#include <Swiften/EventLoop/DummyEventLoop.h> + +using namespace Swift; + +class ChainedConnectorTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(ChainedConnectorTest); + CPPUNIT_TEST(testConnect_FirstConnectorSucceeds); + CPPUNIT_TEST(testConnect_SecondConnectorSucceeds); + CPPUNIT_TEST(testConnect_NoConnectorSucceeds); + CPPUNIT_TEST(testStop); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + host = HostAddressPort(HostAddress("1.1.1.1"), 1234); + eventLoop = new DummyEventLoop(); + resolver = new StaticDomainNameResolver(eventLoop); + resolver->addXMPPClientService("foo.com", host); + connectionFactory1 = new MockConnectionFactory(eventLoop, 1); + connectionFactory2 = new MockConnectionFactory(eventLoop, 2); + timerFactory = new DummyTimerFactory(); + } + + void tearDown() { + delete timerFactory; + delete connectionFactory2; + delete connectionFactory1; + delete resolver; + delete eventLoop; + } + + void testConnect_FirstConnectorSucceeds() { + boost::shared_ptr<ChainedConnector> testling(createConnector()); + connectionFactory1->connects = true; + connectionFactory2->connects = false; + + testling->start(); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); + CPPUNIT_ASSERT(connections[0]); + CPPUNIT_ASSERT_EQUAL(1, boost::dynamic_pointer_cast<MockConnection>(connections[0])->id); + } + + void testConnect_SecondConnectorSucceeds() { + boost::shared_ptr<ChainedConnector> testling(createConnector()); + connectionFactory1->connects = false; + connectionFactory2->connects = true; + + testling->start(); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); + CPPUNIT_ASSERT(connections[0]); + CPPUNIT_ASSERT_EQUAL(2, boost::dynamic_pointer_cast<MockConnection>(connections[0])->id); + } + + void testConnect_NoConnectorSucceeds() { + boost::shared_ptr<ChainedConnector> testling(createConnector()); + connectionFactory1->connects = false; + connectionFactory2->connects = false; + + testling->start(); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); + CPPUNIT_ASSERT(!connections[0]); + } + + void testStop() { + boost::shared_ptr<ChainedConnector> testling(createConnector()); + connectionFactory1->connects = true; + connectionFactory2->connects = false; + + testling->start(); + testling->stop(); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); + CPPUNIT_ASSERT(!connections[0]); + } + + private: + boost::shared_ptr<ChainedConnector> createConnector() { + std::vector<ConnectionFactory*> factories; + factories.push_back(connectionFactory1); + factories.push_back(connectionFactory2); + boost::shared_ptr<ChainedConnector> connector = boost::make_shared<ChainedConnector>("foo.com", resolver, factories, timerFactory); + connector->onConnectFinished.connect(boost::bind(&ChainedConnectorTest::handleConnectorFinished, this, _1)); + return connector; + } + + void handleConnectorFinished(boost::shared_ptr<Connection> connection) { + boost::shared_ptr<MockConnection> c(boost::dynamic_pointer_cast<MockConnection>(connection)); + if (connection) { + assert(c); + } + connections.push_back(c); + } + + struct MockConnection : public Connection { + public: + MockConnection(bool connects, int id, EventLoop* eventLoop) : connects(connects), id(id), eventLoop(eventLoop) { + } + + void listen() { assert(false); } + void connect(const HostAddressPort&) { + eventLoop->postEvent(boost::bind(boost::ref(onConnectFinished), !connects)); + } + + HostAddressPort getLocalAddress() const { return HostAddressPort(); } + void disconnect() { assert(false); } + void write(const SafeByteArray&) { assert(false); } + + bool connects; + int id; + EventLoop* eventLoop; + }; + + struct MockConnectionFactory : public ConnectionFactory { + MockConnectionFactory(EventLoop* eventLoop, int id) : eventLoop(eventLoop), connects(true), id(id) { + } + + boost::shared_ptr<Connection> createConnection() { + return boost::make_shared<MockConnection>(connects, id, eventLoop); + } + + EventLoop* eventLoop; + bool connects; + int id; + }; + + private: + HostAddressPort host; + DummyEventLoop* eventLoop; + StaticDomainNameResolver* resolver; + MockConnectionFactory* connectionFactory1; + MockConnectionFactory* connectionFactory2; + DummyTimerFactory* timerFactory; + std::vector< boost::shared_ptr<MockConnection> > connections; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(ChainedConnectorTest); diff --git a/Swiften/Network/UnitTest/ConnectorTest.cpp b/Swiften/Network/UnitTest/ConnectorTest.cpp index c8aa9a9..6488e67 100644 --- a/Swiften/Network/UnitTest/ConnectorTest.cpp +++ b/Swiften/Network/UnitTest/ConnectorTest.cpp @@ -10,13 +10,13 @@ #include <boost/optional.hpp> #include <boost/bind.hpp> -#include "Swiften/Network/Connector.h" -#include "Swiften/Network/Connection.h" -#include "Swiften/Network/ConnectionFactory.h" -#include "Swiften/Network/HostAddressPort.h" -#include "Swiften/Network/StaticDomainNameResolver.h" -#include "Swiften/Network/DummyTimerFactory.h" -#include "Swiften/EventLoop/DummyEventLoop.h" +#include <Swiften/Network/Connector.h> +#include <Swiften/Network/Connection.h> +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Network/StaticDomainNameResolver.h> +#include <Swiften/Network/DummyTimerFactory.h> +#include <Swiften/EventLoop/DummyEventLoop.h> using namespace Swift; @@ -269,7 +269,7 @@ class ConnectorTest : public CppUnit::TestFixture { HostAddressPort getLocalAddress() const { return HostAddressPort(); } void disconnect() { assert(false); } - void write(const ByteArray&) { assert(false); } + void write(const SafeByteArray&) { assert(false); } EventLoop* eventLoop; boost::optional<HostAddressPort> hostAddressPort; diff --git a/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp new file mode 100644 index 0000000..133773f --- /dev/null +++ b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ +#include <QA/Checker/IO.h> + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <boost/optional.hpp> +#include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/shared_ptr.hpp> + +#include <Swiften/Base/Algorithm.h> +#include <Swiften/Network/Connection.h> +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/HTTPConnectProxiedConnection.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/EventLoop/DummyEventLoop.h> + +using namespace Swift; + +class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(HTTPConnectProxiedConnectionTest); + CPPUNIT_TEST(testConnect_CreatesConnectionToProxy); + CPPUNIT_TEST(testConnect_SendsConnectRequest); + CPPUNIT_TEST(testConnect_ReceiveConnectResponse); + CPPUNIT_TEST(testConnect_ReceiveMalformedConnectResponse); + CPPUNIT_TEST(testConnect_ReceiveErrorConnectResponse); + CPPUNIT_TEST(testConnect_ReceiveDataAfterConnect); + CPPUNIT_TEST(testWrite_AfterConnect); + CPPUNIT_TEST(testDisconnect_AfterConnectRequest); + CPPUNIT_TEST(testDisconnect_AfterConnect); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + proxyHost = HostAddressPort(HostAddress("1.1.1.1"), 1234); + host = HostAddressPort(HostAddress("2.2.2.2"), 2345); + eventLoop = new DummyEventLoop(); + connectionFactory = new MockConnectionFactory(eventLoop); + connectFinished = false; + disconnected = false; + } + + void tearDown() { + delete connectionFactory; + delete eventLoop; + } + + void testConnect_CreatesConnectionToProxy() { + HTTPConnectProxiedConnection::ref testling(createTestling()); + + testling->connect(host); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connectionFactory->connections.size())); + CPPUNIT_ASSERT(connectionFactory->connections[0]->hostAddressPort); + CPPUNIT_ASSERT(proxyHost == *connectionFactory->connections[0]->hostAddressPort); + CPPUNIT_ASSERT(!connectFinished); + } + + void testConnect_SendsConnectRequest() { + HTTPConnectProxiedConnection::ref testling(createTestling()); + + testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(createByteArray("CONNECT 2.2.2.2:2345 HTTP/1.1\r\n\r\n"), connectionFactory->connections[0]->dataWritten); + } + + void testConnect_ReceiveConnectResponse() { + HTTPConnectProxiedConnection::ref testling(createTestling()); + testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); + eventLoop->processEvents(); + + connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n")); + eventLoop->processEvents(); + + CPPUNIT_ASSERT(connectFinished); + CPPUNIT_ASSERT(!connectFinishedWithError); + CPPUNIT_ASSERT(dataRead.empty()); + } + + void testConnect_ReceiveMalformedConnectResponse() { + HTTPConnectProxiedConnection::ref testling(createTestling()); + testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); + eventLoop->processEvents(); + + connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("FLOOP")); + eventLoop->processEvents(); + + CPPUNIT_ASSERT(connectFinished); + CPPUNIT_ASSERT(connectFinishedWithError); + CPPUNIT_ASSERT(connectionFactory->connections[0]->disconnected); + } + + void testConnect_ReceiveErrorConnectResponse() { + HTTPConnectProxiedConnection::ref testling(createTestling()); + testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); + eventLoop->processEvents(); + + connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 401 Unauthorized\r\n\r\n")); + eventLoop->processEvents(); + + CPPUNIT_ASSERT(connectFinished); + CPPUNIT_ASSERT(connectFinishedWithError); + CPPUNIT_ASSERT(connectionFactory->connections[0]->disconnected); + } + + void testConnect_ReceiveDataAfterConnect() { + HTTPConnectProxiedConnection::ref testling(createTestling()); + testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); + eventLoop->processEvents(); + connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n")); + eventLoop->processEvents(); + + connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("abcdef")); + + CPPUNIT_ASSERT_EQUAL(createByteArray("abcdef"), dataRead); + } + + void testWrite_AfterConnect() { + HTTPConnectProxiedConnection::ref testling(createTestling()); + testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); + eventLoop->processEvents(); + connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n")); + eventLoop->processEvents(); + connectionFactory->connections[0]->dataWritten.clear(); + + testling->write(createSafeByteArray("abcdef")); + + CPPUNIT_ASSERT_EQUAL(createByteArray("abcdef"), connectionFactory->connections[0]->dataWritten); + } + + void testDisconnect_AfterConnectRequest() { + HTTPConnectProxiedConnection::ref testling(createTestling()); + testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); + eventLoop->processEvents(); + + testling->disconnect(); + + CPPUNIT_ASSERT(connectionFactory->connections[0]->disconnected); + CPPUNIT_ASSERT(disconnected); + CPPUNIT_ASSERT(!disconnectedError); + } + + void testDisconnect_AfterConnect() { + HTTPConnectProxiedConnection::ref testling(createTestling()); + testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); + eventLoop->processEvents(); + connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n")); + eventLoop->processEvents(); + + testling->disconnect(); + + CPPUNIT_ASSERT(connectionFactory->connections[0]->disconnected); + CPPUNIT_ASSERT(disconnected); + CPPUNIT_ASSERT(!disconnectedError); + } + + private: + HTTPConnectProxiedConnection::ref createTestling() { + boost::shared_ptr<HTTPConnectProxiedConnection> c = HTTPConnectProxiedConnection::create(connectionFactory, proxyHost); + c->onConnectFinished.connect(boost::bind(&HTTPConnectProxiedConnectionTest::handleConnectFinished, this, _1)); + c->onDisconnected.connect(boost::bind(&HTTPConnectProxiedConnectionTest::handleDisconnected, this, _1)); + c->onDataRead.connect(boost::bind(&HTTPConnectProxiedConnectionTest::handleDataRead, this, _1)); + return c; + } + + void handleConnectFinished(bool error) { + connectFinished = true; + connectFinishedWithError = error; + } + + void handleDisconnected(const boost::optional<Connection::Error>& e) { + disconnected = true; + disconnectedError = e; + } + + void handleDataRead(boost::shared_ptr<SafeByteArray> d) { + append(dataRead, *d); + } + + struct MockConnection : public Connection { + public: + MockConnection(const std::vector<HostAddressPort>& failingPorts, EventLoop* eventLoop) : eventLoop(eventLoop), failingPorts(failingPorts), disconnected(false) { + } + + void listen() { assert(false); } + + void connect(const HostAddressPort& address) { + hostAddressPort = address; + bool fail = std::find(failingPorts.begin(), failingPorts.end(), address) != failingPorts.end(); + eventLoop->postEvent(boost::bind(boost::ref(onConnectFinished), fail)); + } + + HostAddressPort getLocalAddress() const { return HostAddressPort(); } + + void disconnect() { + disconnected = true; + onDisconnected(boost::optional<Connection::Error>()); + } + + void write(const SafeByteArray& d) { + append(dataWritten, d); + } + + EventLoop* eventLoop; + boost::optional<HostAddressPort> hostAddressPort; + std::vector<HostAddressPort> failingPorts; + ByteArray dataWritten; + bool disconnected; + }; + + struct MockConnectionFactory : public ConnectionFactory { + MockConnectionFactory(EventLoop* eventLoop) : eventLoop(eventLoop) { + } + + boost::shared_ptr<Connection> createConnection() { + boost::shared_ptr<MockConnection> connection = boost::make_shared<MockConnection>(failingPorts, eventLoop); + connections.push_back(connection); + return connection; + } + + EventLoop* eventLoop; + std::vector< boost::shared_ptr<MockConnection> > connections; + std::vector<HostAddressPort> failingPorts; + }; + + private: + HostAddressPort proxyHost; + HostAddressPort host; + DummyEventLoop* eventLoop; + MockConnectionFactory* connectionFactory; + std::vector< boost::shared_ptr<MockConnection> > connections; + bool connectFinished; + bool connectFinishedWithError; + bool disconnected; + boost::optional<Connection::Error> disconnectedError; + ByteArray dataRead; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(HTTPConnectProxiedConnectionTest); diff --git a/Swiften/Network/UnitTest/HostAddressTest.cpp b/Swiften/Network/UnitTest/HostAddressTest.cpp index 7fb33ca..b2511a8 100644 --- a/Swiften/Network/UnitTest/HostAddressTest.cpp +++ b/Swiften/Network/UnitTest/HostAddressTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Network/HostAddress.h" +#include <Swiften/Network/HostAddress.h> #include <string> using namespace Swift; diff --git a/Swiften/Network/UnixNetworkEnvironment.cpp b/Swiften/Network/UnixNetworkEnvironment.cpp new file mode 100644 index 0000000..52c5cbe --- /dev/null +++ b/Swiften/Network/UnixNetworkEnvironment.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Network/UnixNetworkEnvironment.h> + +#include <string> +#include <vector> +#include <map> +#include <boost/optional.hpp> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <net/if.h> +#include <ifaddrs.h> + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Network/HostAddress.h> +#include <Swiften/Network/NetworkInterface.h> + +namespace Swift { + +std::vector<NetworkInterface> UnixNetworkEnvironment::getNetworkInterfaces() const { + std::map<std::string, NetworkInterface> interfaces; + + ifaddrs* addrs = 0; + int ret = getifaddrs(&addrs); + if (ret != 0) { + return std::vector<NetworkInterface>(); + } + + for (ifaddrs* a = addrs; a != 0; a = a->ifa_next) { + std::string name(a->ifa_name); + boost::optional<HostAddress> address; + if (a->ifa_addr->sa_family == PF_INET) { + sockaddr_in* sa = reinterpret_cast<sockaddr_in*>(a->ifa_addr); + address = HostAddress(reinterpret_cast<const unsigned char*>(&(sa->sin_addr)), 4); + } + else if (a->ifa_addr->sa_family == PF_INET6) { + sockaddr_in6* sa = reinterpret_cast<sockaddr_in6*>(a->ifa_addr); + address = HostAddress(reinterpret_cast<const unsigned char*>(&(sa->sin6_addr)), 16); + } + if (address) { + std::map<std::string, NetworkInterface>::iterator i = interfaces.insert(std::make_pair(name, NetworkInterface(name, a->ifa_flags & IFF_LOOPBACK))).first; + i->second.addAddress(*address); + } + } + + freeifaddrs(addrs); + + std::vector<NetworkInterface> result; + for (std::map<std::string,NetworkInterface>::const_iterator i = interfaces.begin(); i != interfaces.end(); ++i) { + result.push_back(i->second); + } + return result; +} + +} diff --git a/Swiften/Network/UnixNetworkEnvironment.h b/Swiften/Network/UnixNetworkEnvironment.h new file mode 100644 index 0000000..8b51cae --- /dev/null +++ b/Swiften/Network/UnixNetworkEnvironment.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <vector> + +#include <Swiften/Base/boost_bsignals.h> + +#include <Swiften/Network/NetworkEnvironment.h> +#include <Swiften/Network/NetworkInterface.h> + +namespace Swift { + +class UnixNetworkEnvironment : public NetworkEnvironment { + public: + std::vector<NetworkInterface> getNetworkInterfaces() const; +}; + +} diff --git a/Swiften/Network/UnixProxyProvider.cpp b/Swiften/Network/UnixProxyProvider.cpp new file mode 100644 index 0000000..4ca9311 --- /dev/null +++ b/Swiften/Network/UnixProxyProvider.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <iostream> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Network/UnixProxyProvider.h> +#if defined(HAVE_GCONF) +# include "Swiften/Network/GConfProxyProvider.h" +#endif + +namespace Swift { + +UnixProxyProvider::UnixProxyProvider() : + gconfProxyProvider(0), + environmentProxyProvider() +{ +#if defined(HAVE_GCONF) + gconfProxyProvider = new GConfProxyProvider(); +#endif +} + +UnixProxyProvider::~UnixProxyProvider() { +#if defined(HAVE_GCONF) + delete gconfProxyProvider; +#endif +} + +HostAddressPort UnixProxyProvider::getSOCKS5Proxy() const { + HostAddressPort proxy; +#if defined(HAVE_GCONF) + proxy = gconfProxyProvider->getSOCKS5Proxy(); + if(proxy.isValid()) { + return proxy; + } +#endif + proxy = environmentProxyProvider.getSOCKS5Proxy(); + if(proxy.isValid()) { + return proxy; + } + return HostAddressPort(HostAddress(), 0); +} + +HostAddressPort UnixProxyProvider::getHTTPConnectProxy() const { + HostAddressPort proxy; +#if defined(HAVE_GCONF) + proxy = gconfProxyProvider->getHTTPConnectProxy(); + if(proxy.isValid()) { + return proxy; + } +#endif + proxy = environmentProxyProvider.getHTTPConnectProxy(); + if(proxy.isValid()) { + return proxy; + } + return HostAddressPort(HostAddress(), 0); +} + + +} diff --git a/Swiften/Network/UnixProxyProvider.h b/Swiften/Network/UnixProxyProvider.h new file mode 100644 index 0000000..37a4d05 --- /dev/null +++ b/Swiften/Network/UnixProxyProvider.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Network/EnvironmentProxyProvider.h> + +namespace Swift { + class GConfProxyProvider; + + class UnixProxyProvider : public ProxyProvider { + public: + UnixProxyProvider(); + ~UnixProxyProvider(); + + virtual HostAddressPort getHTTPConnectProxy() const; + virtual HostAddressPort getSOCKS5Proxy() const; + + private: + GConfProxyProvider* gconfProxyProvider; + EnvironmentProxyProvider environmentProxyProvider; + }; +} diff --git a/Swiften/Network/WindowsNetworkEnvironment.cpp b/Swiften/Network/WindowsNetworkEnvironment.cpp new file mode 100644 index 0000000..20f559d --- /dev/null +++ b/Swiften/Network/WindowsNetworkEnvironment.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Network/WindowsNetworkEnvironment.h> + +#include <string> +#include <vector> +#include <map> +#include <boost/optional.hpp> +#include <Swiften/Network/HostAddress.h> +#include <Swiften/Network/NetworkInterface.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/ByteArray.h> + +#include <winsock2.h> +#include <iphlpapi.h> + +namespace Swift { + +std::vector<NetworkInterface> WindowsNetworkEnvironment::getNetworkInterfaces() const { + std::vector<NetworkInterface> result; + + ByteArray adapters; + ULONG bufferSize = 0; + ULONG ret; + ULONG flags = GAA_FLAG_INCLUDE_ALL_INTERFACES | GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER; + while ((ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, reinterpret_cast<IP_ADAPTER_ADDRESSES*>(vecptr(adapters)), &bufferSize)) == ERROR_BUFFER_OVERFLOW) { + adapters.resize(bufferSize); + }; + if (ret != ERROR_SUCCESS) { + return result; + } + + std::map<std::string,NetworkInterface> interfaces; + for (IP_ADAPTER_ADDRESSES* adapter = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(vecptr(adapters)); adapter; adapter = adapter->Next) { + std::string name(adapter->AdapterName); + if (adapter->OperStatus != IfOperStatusUp) { + continue; + } + for (IP_ADAPTER_UNICAST_ADDRESS* address = adapter->FirstUnicastAddress; address; address = address->Next) { + boost::optional<HostAddress> hostAddress; + if (address->Address.lpSockaddr->sa_family == PF_INET) { + sockaddr_in* sa = reinterpret_cast<sockaddr_in*>(address->Address.lpSockaddr); + hostAddress = HostAddress(reinterpret_cast<const unsigned char*>(&(sa->sin_addr)), 4); + } + else if (address->Address.lpSockaddr->sa_family == PF_INET6) { + sockaddr_in6* sa = reinterpret_cast<sockaddr_in6*>(address->Address.lpSockaddr); + hostAddress = HostAddress(reinterpret_cast<const unsigned char*>(&(sa->sin6_addr)), 16); + } + if (hostAddress) { + std::map<std::string, NetworkInterface>::iterator i = interfaces.insert(std::make_pair(name, NetworkInterface(name, false))).first; + i->second.addAddress(*hostAddress); + } + } + } + + for (std::map<std::string,NetworkInterface>::const_iterator i = interfaces.begin(); i != interfaces.end(); ++i) { + result.push_back(i->second); + } + return result; +} + +} diff --git a/Swiften/Network/WindowsNetworkEnvironment.h b/Swiften/Network/WindowsNetworkEnvironment.h new file mode 100644 index 0000000..f43b951 --- /dev/null +++ b/Swiften/Network/WindowsNetworkEnvironment.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <vector> +#include <Swiften/Base/boost_bsignals.h> + +#include <Swiften/Network/NetworkEnvironment.h> + +namespace Swift { + class WindowsNetworkEnvironment : public NetworkEnvironment { + public: + std::vector<NetworkInterface> getNetworkInterfaces() const; + }; +} diff --git a/Swiften/Network/WindowsProxyProvider.cpp b/Swiften/Network/WindowsProxyProvider.cpp new file mode 100644 index 0000000..3ae43e0 --- /dev/null +++ b/Swiften/Network/WindowsProxyProvider.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <iostream> +#include <boost/lexical_cast.hpp> + +#include <Swiften/Base/log.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Network/WindowsProxyProvider.h> +#include <Swiften/Base/ByteArray.h> + +#include <windows.h> + +namespace Swift { + +WindowsProxyProvider::WindowsProxyProvider() +: ProxyProvider() +{ + HKEY hKey = (HKEY)INVALID_HANDLE_VALUE; + long result; + + result = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 0, KEY_READ, &hKey); + if (result == ERROR_SUCCESS && hKey != INVALID_HANDLE_VALUE && proxyEnabled(hKey)) { + DWORD dataType = REG_SZ; + DWORD dataSize = 0; + ByteArray dataBuffer; + + result = RegQueryValueEx(hKey, "ProxyServer", NULL, &dataType, NULL, &dataSize); + if(result != ERROR_SUCCESS) { + return; + } + dataBuffer.resize(dataSize); + result = RegQueryValueEx(hKey, "ProxyServer", NULL, &dataType, reinterpret_cast<BYTE*>(vecptr(dataBuffer)), &dataSize); + if(result == ERROR_SUCCESS) { + std::vector<std::string> proxies = String::split(byteArrayToString(dataBuffer), ';'); + std::pair<std::string, std::string> protocolAndProxy; + foreach(std::string proxy, proxies) { + if(proxy.find('=') != std::string::npos) { + protocolAndProxy = String::getSplittedAtFirst(proxy, '='); + SWIFT_LOG(debug) << "Found proxy: " << protocolAndProxy.first << " => " << protocolAndProxy.second << std::endl; + if(protocolAndProxy.first.compare("socks") == 0) { + socksProxy = getAsHostAddressPort(protocolAndProxy.second); + } + else if (protocolAndProxy.first.compare("http") == 0) { + httpProxy = getAsHostAddressPort(protocolAndProxy.second); + } + } + } + } + } +} + +HostAddressPort WindowsProxyProvider::getHTTPConnectProxy() const { + return httpProxy; +} + +HostAddressPort WindowsProxyProvider::getSOCKS5Proxy() const { + return socksProxy; +} + +HostAddressPort WindowsProxyProvider::getAsHostAddressPort(std::string proxy) { + HostAddressPort ret(HostAddress(), 0); + + try { + std::pair<std::string, std::string> tmp; + int port = 0; + tmp = String::getSplittedAtFirst(proxy, ':'); + // .c_str() is needed as tmp.second can include a \0 char which will end in an exception of the lexical cast. + // with .c_str() the \0 will not be part of the string which is to be casted + port = boost::lexical_cast<int> (tmp.second.c_str()); + ret = HostAddressPort(HostAddress(tmp.first), port); + } + catch(...) { + std::cerr << "Exception occured while parsing windows proxy \"getHostAddressPort\"." << std::endl; + } + + return ret; +} + + +bool WindowsProxyProvider::proxyEnabled(HKEY hKey) const { + bool ret = false; + long result; + DWORD dataType = REG_DWORD; + DWORD dataSize = 0; + DWORD data = 0; + ByteArray dataBuffer; + + if(hKey == INVALID_HANDLE_VALUE) + return ret; + + result = RegQueryValueEx(hKey, "ProxyEnable", NULL, &dataType, NULL, &dataSize); + if(result != ERROR_SUCCESS) + return ret; + + dataBuffer.resize(dataSize); + result = RegQueryValueEx(hKey, "ProxyEnable", NULL, &dataType, reinterpret_cast<BYTE*>(vecptr(dataBuffer)), &dataSize); + if(result != ERROR_SUCCESS) + return ret; + + for(size_t t = 0; t < dataBuffer.size(); t++) { + data += static_cast<int> (dataBuffer[t]) * pow(256, static_cast<double>(t)); + } + return (data == 1); +} + +} diff --git a/Swiften/Network/WindowsProxyProvider.h b/Swiften/Network/WindowsProxyProvider.h new file mode 100644 index 0000000..c2d1f51 --- /dev/null +++ b/Swiften/Network/WindowsProxyProvider.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once +#include <Swiften/Network/ProxyProvider.h> + +namespace Swift { + class WindowsProxyProvider : public ProxyProvider { + public: + WindowsProxyProvider(); + virtual HostAddressPort getHTTPConnectProxy() const; + virtual HostAddressPort getSOCKS5Proxy() const; + private: + HostAddressPort getAsHostAddressPort(std::string proxy); + bool proxyEnabled(HKEY hKey) const; + HostAddressPort socksProxy; + HostAddressPort httpProxy; + }; +} diff --git a/Swiften/Parser/Attribute.h b/Swiften/Parser/Attribute.h new file mode 100644 index 0000000..f1f9a83 --- /dev/null +++ b/Swiften/Parser/Attribute.h @@ -0,0 +1,33 @@ +/* + * 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 <string> + +namespace Swift { + class Attribute { + public: + Attribute(const std::string& name, const std::string& ns) : name(name), ns(ns) { + } + + const std::string& getName() const { + return name; + } + + const std::string& getNamespace() const { + return ns; + } + + bool operator==(const Attribute& o) const { + return o.name == name && o.ns == ns; + } + + private: + std::string name; + std::string ns; + }; +} diff --git a/Swiften/Parser/AttributeMap.cpp b/Swiften/Parser/AttributeMap.cpp new file mode 100644 index 0000000..1aeaf99 --- /dev/null +++ b/Swiften/Parser/AttributeMap.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Parser/AttributeMap.h> + +#include <algorithm> +#include <boost/optional.hpp> + +using namespace Swift; + +namespace { + struct AttributeIs { + AttributeIs(const Attribute& attribute) : attribute(attribute) { + } + + bool operator()(const AttributeMap::Entry& o) const { + return o.getAttribute() == attribute; + } + + Attribute attribute; + }; +} + +AttributeMap::AttributeMap() { +} + +std::string AttributeMap::getAttribute(const std::string& attribute, const std::string& ns) const { + AttributeValueMap::const_iterator i = std::find_if(attributes.begin(), attributes.end(), AttributeIs(Attribute(attribute, ns))); + if (i == attributes.end()) { + return ""; + } + else { + return i->getValue(); + } +} + +bool AttributeMap::getBoolAttribute(const std::string& attribute, bool defaultValue) const { + AttributeValueMap::const_iterator i = std::find_if(attributes.begin(), attributes.end(), AttributeIs(Attribute(attribute, ""))); + if (i == attributes.end()) { + return defaultValue; + } + else { + return i->getValue() == "true" || i->getValue() == "1"; + } +} + +boost::optional<std::string> AttributeMap::getAttributeValue(const std::string& attribute) const { + AttributeValueMap::const_iterator i = std::find_if(attributes.begin(), attributes.end(), AttributeIs(Attribute(attribute, ""))); + if (i == attributes.end()) { + return boost::optional<std::string>(); + } + else { + return i->getValue(); + } +} + +void AttributeMap::addAttribute(const std::string& name, const std::string& ns, const std::string& value) { + attributes.push_back(Entry(Attribute(name, ns), value)); +} diff --git a/Swiften/Parser/AttributeMap.h b/Swiften/Parser/AttributeMap.h index c8b287b..31df606 100644 --- a/Swiften/Parser/AttributeMap.h +++ b/Swiften/Parser/AttributeMap.h @@ -4,38 +4,50 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef ATTRIBUTEMAP_H -#define ATTRIBUTEMAP_H +#pragma once +#include <vector> +#include <string> #include <map> +#include <boost/optional/optional_fwd.hpp> -#include <string> +#include <Swiften/Parser/Attribute.h> namespace Swift { - class AttributeMap : public std::map<std::string,std::string> { + class AttributeMap { public: - AttributeMap() {} - - std::string getAttribute(const std::string& attribute) const { - AttributeMap::const_iterator i = find(attribute); - if (i == end()) { - return ""; - } - else { - return i->second; - } - } + class Entry { + public: + Entry(const Attribute& attribute, const std::string& value) : attribute(attribute), value(value) { + } + + const Attribute& getAttribute() const { + return attribute; + } + + const std::string& getValue() const { + return value; + } + + private: + Attribute attribute; + std::string value; + }; - bool getBoolAttribute(const std::string& attribute, bool defaultValue = false) const { - AttributeMap::const_iterator i = find(attribute); - if (i == end()) { - return defaultValue; - } - else { - return i->second == "true" || i->second == "1"; - } + AttributeMap(); + + std::string getAttribute(const std::string& attribute, const std::string& ns = "") const; + bool getBoolAttribute(const std::string& attribute, bool defaultValue = false) const; + boost::optional<std::string> getAttributeValue(const std::string&) const; + + void addAttribute(const std::string& name, const std::string& ns, const std::string& value); + + const std::vector<Entry>& getEntries() const { + return attributes; } + + private: + typedef std::vector<Entry> AttributeValueMap; + AttributeValueMap attributes; }; } - -#endif diff --git a/Swiften/Parser/AuthChallengeParser.cpp b/Swiften/Parser/AuthChallengeParser.cpp index 1e5e0c4..7cb665a 100644 --- a/Swiften/Parser/AuthChallengeParser.cpp +++ b/Swiften/Parser/AuthChallengeParser.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/AuthChallengeParser.h" -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/Parser/AuthChallengeParser.h> +#include <Swiften/StringCodecs/Base64.h> namespace Swift { diff --git a/Swiften/Parser/AuthChallengeParser.h b/Swiften/Parser/AuthChallengeParser.h index 39f7c57..31b6d89 100644 --- a/Swiften/Parser/AuthChallengeParser.h +++ b/Swiften/Parser/AuthChallengeParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/AuthChallenge.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/AuthChallenge.h> #include <string> namespace Swift { diff --git a/Swiften/Parser/AuthFailureParser.h b/Swiften/Parser/AuthFailureParser.h index af54794..1a71ea4 100644 --- a/Swiften/Parser/AuthFailureParser.h +++ b/Swiften/Parser/AuthFailureParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_AuthFailureParser_H -#define SWIFTEN_AuthFailureParser_H +#pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/AuthFailure.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/AuthFailure.h> namespace Swift { class AuthFailureParser : public GenericElementParser<AuthFailure> { @@ -16,5 +15,3 @@ namespace Swift { AuthFailureParser() : GenericElementParser<AuthFailure>() {} }; } - -#endif diff --git a/Swiften/Parser/AuthRequestParser.cpp b/Swiften/Parser/AuthRequestParser.cpp index 38af047..04d9e4f 100644 --- a/Swiften/Parser/AuthRequestParser.cpp +++ b/Swiften/Parser/AuthRequestParser.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/AuthRequestParser.h" -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/Parser/AuthRequestParser.h> +#include <Swiften/StringCodecs/Base64.h> namespace Swift { @@ -22,7 +22,7 @@ void AuthRequestParser::handleStartElement(const std::string&, const std::string void AuthRequestParser::handleEndElement(const std::string&, const std::string&) { --depth_; if (depth_ == 0) { - getElementGeneric()->setMessage(Base64::decode(text_)); + getElementGeneric()->setMessage(createSafeByteArray(Base64::decode(text_))); } } diff --git a/Swiften/Parser/AuthRequestParser.h b/Swiften/Parser/AuthRequestParser.h index 5cc3694..1562df7 100644 --- a/Swiften/Parser/AuthRequestParser.h +++ b/Swiften/Parser/AuthRequestParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_AuthRequestParser_H -#define SWIFTEN_AuthRequestParser_H +#pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/AuthRequest.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/AuthRequest.h> #include <string> namespace Swift { @@ -25,5 +24,3 @@ namespace Swift { int depth_; }; } - -#endif diff --git a/Swiften/Parser/AuthResponseParser.cpp b/Swiften/Parser/AuthResponseParser.cpp index 0db6a2a..7f9a530 100644 --- a/Swiften/Parser/AuthResponseParser.cpp +++ b/Swiften/Parser/AuthResponseParser.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/AuthResponseParser.h" -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/Parser/AuthResponseParser.h> +#include <Swiften/StringCodecs/Base64.h> namespace Swift { @@ -19,7 +19,7 @@ void AuthResponseParser::handleStartElement(const std::string&, const std::strin void AuthResponseParser::handleEndElement(const std::string&, const std::string&) { --depth; if (depth == 0) { - getElementGeneric()->setValue(Base64::decode(text)); + getElementGeneric()->setValue(createSafeByteArray(Base64::decode(text))); } } diff --git a/Swiften/Parser/AuthResponseParser.h b/Swiften/Parser/AuthResponseParser.h index aee2f9c..3dc2282 100644 --- a/Swiften/Parser/AuthResponseParser.h +++ b/Swiften/Parser/AuthResponseParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/AuthResponse.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/AuthResponse.h> #include <string> namespace Swift { diff --git a/Swiften/Parser/AuthSuccessParser.cpp b/Swiften/Parser/AuthSuccessParser.cpp index 0dee6ad..50246a4 100644 --- a/Swiften/Parser/AuthSuccessParser.cpp +++ b/Swiften/Parser/AuthSuccessParser.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/AuthSuccessParser.h" -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/Parser/AuthSuccessParser.h> +#include <Swiften/StringCodecs/Base64.h> namespace Swift { diff --git a/Swiften/Parser/AuthSuccessParser.h b/Swiften/Parser/AuthSuccessParser.h index 30c89d2..b726b95 100644 --- a/Swiften/Parser/AuthSuccessParser.h +++ b/Swiften/Parser/AuthSuccessParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/AuthSuccess.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/AuthSuccess.h> #include <string> namespace Swift { diff --git a/Swiften/Parser/BOSHBodyExtractor.cpp b/Swiften/Parser/BOSHBodyExtractor.cpp new file mode 100644 index 0000000..d8759a3 --- /dev/null +++ b/Swiften/Parser/BOSHBodyExtractor.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Parser/BOSHBodyExtractor.h> + +#include <boost/shared_ptr.hpp> + +#include <Swiften/Parser/XMLParserClient.h> +#include <Swiften/Parser/XMLParser.h> +#include <Swiften/Parser/XMLParserFactory.h> + +namespace Swift { + +class BOSHBodyParserClient : public XMLParserClient { + public: + BOSHBodyParserClient(BOSHBodyExtractor* bodyExtractor) : bodyExtractor(bodyExtractor) { + } + + virtual void handleStartElement(const std::string&, const std::string&, const AttributeMap& attributes) { + bodyExtractor->body->attributes = attributes; + } + + virtual void handleEndElement(const std::string&, const std::string&) { + } + + virtual void handleCharacterData(const std::string&) { + } + + private: + BOSHBodyExtractor* bodyExtractor; +}; + +inline bool isWhitespace(char c) { + return c == ' ' || c == '\n' || c == '\t' || c == '\r'; +} + +BOSHBodyExtractor::BOSHBodyExtractor(XMLParserFactory* parserFactory, const ByteArray& data) { + // Look for the opening body element + ByteArray::const_iterator i = data.begin(); + while (i < data.end() && isWhitespace(*i)) { + ++i; + } + if (std::distance(i, data.end()) < 6 || *i != '<' || *(i+1) != 'b' || *(i+2) != 'o' || *(i+3) != 'd' || *(i+4) != 'y' || !(isWhitespace(*(i+5)) || *(i+5) == '>' || *(i+5) == '/')) { + return; + } + i += 5; + + // Parse until end of element + bool inSingleQuote = false; + bool inDoubleQuote = false; + bool endStartTagSeen = false; + bool endElementSeen = false; + for (; i != data.end(); ++i) { + char c = static_cast<char>(*i); + if (inSingleQuote) { + if (c == '\'') { + inSingleQuote = false; + } + } + else if (inDoubleQuote) { + if (c == '"') { + inDoubleQuote = false; + } + } + else if (c == '\'') { + inSingleQuote = true; + } + else if (c == '"') { + inDoubleQuote = true; + } + else if (c == '/') { + if (i + 1 == data.end() || *(i+1) != '>') { + return; + } + else { + endElementSeen = true; + endStartTagSeen = true; + i += 2; + break; + } + } + else if (c == '>') { + endStartTagSeen = true; + i += 1; + break; + } + } + + if (!endStartTagSeen) { + return; + } + + // Look for the end of the element + ByteArray::const_reverse_iterator j = data.rbegin(); + if (!endElementSeen) { + while (isWhitespace(*j) && j < data.rend()) { + ++j; + } + + if (j == data.rend() || *j != '>') { + return; + } + ++j; + + while (j < data.rend() && isWhitespace(*j)) { + ++j; + } + + if (std::distance(j, data.rend()) < 6 || *(j+5) != '<' || *(j+4) != '/' || *(j+3) != 'b' || *(j+2) != 'o' || *(j+1) != 'd' || *j != 'y') { + return; + } + j += 6; + } + + body = BOSHBody(); + if (!endElementSeen) { + body->content = std::string(reinterpret_cast<const char*>(vecptr(data) + std::distance(data.begin(), i)), std::distance(i, j.base())); + } + + // Parse the body element + BOSHBodyParserClient parserClient(this); + boost::shared_ptr<XMLParser> parser(parserFactory->createXMLParser(&parserClient)); + if (!parser->parse(std::string(reinterpret_cast<const char*>(vecptr(data)), std::distance(data.begin(), i)))) { + body = boost::optional<BOSHBody>(); + return; + } +} + +} diff --git a/Swiften/Parser/BOSHBodyExtractor.h b/Swiften/Parser/BOSHBodyExtractor.h new file mode 100644 index 0000000..d1266c6 --- /dev/null +++ b/Swiften/Parser/BOSHBodyExtractor.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/optional.hpp> + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Parser/XMLParserClient.h> + +namespace Swift { + struct XMLParserFactory; + + class BOSHBodyExtractor { + friend class BOSHBodyParserClient; + public: + struct BOSHBody { + AttributeMap attributes; + std::string content; + }; + + BOSHBodyExtractor(XMLParserFactory* parserFactory, const ByteArray& data); + + const boost::optional<BOSHBody>& getBody() { + return body; + } + + private: + boost::optional<BOSHBody> body; + }; +} diff --git a/Swiften/Parser/ComponentHandshakeParser.cpp b/Swiften/Parser/ComponentHandshakeParser.cpp index 4117a56..c58caf0 100644 --- a/Swiften/Parser/ComponentHandshakeParser.cpp +++ b/Swiften/Parser/ComponentHandshakeParser.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/ComponentHandshakeParser.h" -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/Parser/ComponentHandshakeParser.h> +#include <Swiften/StringCodecs/Base64.h> namespace Swift { diff --git a/Swiften/Parser/ComponentHandshakeParser.h b/Swiften/Parser/ComponentHandshakeParser.h index 389bb6d..25cee6e 100644 --- a/Swiften/Parser/ComponentHandshakeParser.h +++ b/Swiften/Parser/ComponentHandshakeParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/ComponentHandshake.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/ComponentHandshake.h> #include <string> namespace Swift { diff --git a/Swiften/Parser/CompressFailureParser.h b/Swiften/Parser/CompressFailureParser.h index 7983a04..ed59324 100644 --- a/Swiften/Parser/CompressFailureParser.h +++ b/Swiften/Parser/CompressFailureParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_CompressFailureParser_H -#define SWIFTEN_CompressFailureParser_H +#pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/CompressFailure.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/CompressFailure.h> namespace Swift { class CompressFailureParser : public GenericElementParser<CompressFailure> { @@ -16,5 +15,3 @@ namespace Swift { CompressFailureParser() : GenericElementParser<CompressFailure>() {} }; } - -#endif diff --git a/Swiften/Parser/CompressParser.cpp b/Swiften/Parser/CompressParser.cpp index 5ce5204..d8f773b 100644 --- a/Swiften/Parser/CompressParser.cpp +++ b/Swiften/Parser/CompressParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/CompressParser.h" +#include <Swiften/Parser/CompressParser.h> namespace Swift { diff --git a/Swiften/Parser/CompressParser.h b/Swiften/Parser/CompressParser.h index 54257b6..51244c4 100644 --- a/Swiften/Parser/CompressParser.h +++ b/Swiften/Parser/CompressParser.h @@ -4,12 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_CompressParser_H -#define SWIFTEN_CompressParser_H +#pragma once #include <string> -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/CompressRequest.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/CompressRequest.h> namespace Swift { class CompressParser : public GenericElementParser<CompressRequest> { @@ -27,5 +26,3 @@ namespace Swift { bool inMethod_; }; } - -#endif diff --git a/Swiften/Parser/CompressedParser.h b/Swiften/Parser/CompressedParser.h index af1f063..5ba80eb 100644 --- a/Swiften/Parser/CompressedParser.h +++ b/Swiften/Parser/CompressedParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_COMPRESSEDPARSER_H -#define SWIFTEN_COMPRESSEDPARSER_H +#pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/Compressed.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/Compressed.h> namespace Swift { class CompressedParser : public GenericElementParser<Compressed> { @@ -16,5 +15,3 @@ namespace Swift { CompressedParser() : GenericElementParser<Compressed>() {} }; } - -#endif diff --git a/Swiften/Parser/ElementParser.cpp b/Swiften/Parser/ElementParser.cpp index f669a01..1064f2e 100644 --- a/Swiften/Parser/ElementParser.cpp +++ b/Swiften/Parser/ElementParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/ElementParser.h" +#include <Swiften/Parser/ElementParser.h> namespace Swift { diff --git a/Swiften/Parser/ElementParser.h b/Swiften/Parser/ElementParser.h index 60f2395..a11b505 100644 --- a/Swiften/Parser/ElementParser.h +++ b/Swiften/Parser/ElementParser.h @@ -4,14 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_ElementParser_H -#define SWIFTEN_ElementParser_H +#pragma once #include <boost/shared_ptr.hpp> #include <string> -#include "Swiften/Elements/Element.h" -#include "Swiften/Parser/AttributeMap.h" +#include <Swiften/Elements/Element.h> +#include <Swiften/Parser/AttributeMap.h> namespace Swift { class ElementParser { @@ -25,5 +24,3 @@ namespace Swift { virtual boost::shared_ptr<Element> getElement() const = 0; }; } - -#endif diff --git a/Swiften/Parser/EnableStreamManagementParser.h b/Swiften/Parser/EnableStreamManagementParser.h index bd86420..530efd9 100644 --- a/Swiften/Parser/EnableStreamManagementParser.h +++ b/Swiften/Parser/EnableStreamManagementParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/EnableStreamManagement.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/EnableStreamManagement.h> namespace Swift { class EnableStreamManagementParser : public GenericElementParser<EnableStreamManagement> { diff --git a/Swiften/Parser/ExpatParser.cpp b/Swiften/Parser/ExpatParser.cpp index f091f79..f3b5250 100644 --- a/Swiften/Parser/ExpatParser.cpp +++ b/Swiften/Parser/ExpatParser.cpp @@ -4,13 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/ExpatParser.h" +#include <Swiften/Parser/ExpatParser.h> #include <iostream> #include <string> #include <Swiften/Base/String.h> -#include "Swiften/Parser/XMLParserClient.h" +#include <Swiften/Parser/XMLParserClient.h> namespace Swift { @@ -30,7 +30,7 @@ static void handleStartElement(void* parser, const XML_Char* name, const XML_Cha nsAttributePair.second = nsAttributePair.first; nsAttributePair.first = ""; } - attributeValues[nsAttributePair.second] = std::string(*(currentAttribute+1)); + attributeValues.addAttribute(nsAttributePair.second, nsAttributePair.first, std::string(*(currentAttribute+1))); currentAttribute += 2; } diff --git a/Swiften/Parser/ExpatParser.h b/Swiften/Parser/ExpatParser.h index cd981ef..359f786 100644 --- a/Swiften/Parser/ExpatParser.h +++ b/Swiften/Parser/ExpatParser.h @@ -4,13 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_ExpatParser_H -#define SWIFTEN_ExpatParser_H +#pragma once #include <expat.h> #include <boost/noncopyable.hpp> -#include "Swiften/Parser/XMLParser.h" +#include <Swiften/Parser/XMLParser.h> namespace Swift { class ExpatParser : public XMLParser, public boost::noncopyable { @@ -28,5 +27,3 @@ namespace Swift { XML_Parser parser_; }; } - -#endif diff --git a/Swiften/Parser/GenericPayloadParserFactory.h b/Swiften/Parser/GenericPayloadParserFactory.h index 9b108a0..43042a1 100644 --- a/Swiften/Parser/GenericPayloadParserFactory.h +++ b/Swiften/Parser/GenericPayloadParserFactory.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Parser/PayloadParserFactory.h" +#include <Swiften/Parser/PayloadParserFactory.h> #include <string> namespace Swift { diff --git a/Swiften/Parser/GenericPayloadTreeParser.h b/Swiften/Parser/GenericPayloadTreeParser.h new file mode 100644 index 0000000..df6d022 --- /dev/null +++ b/Swiften/Parser/GenericPayloadTreeParser.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <deque> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Parser/GenericPayloadParser.h> +#include <Swiften/Parser/Tree/ParserElement.h> + +namespace Swift { + /** + * Generic parser offering something a bit like a DOM to work with. + */ + template<typename PAYLOAD_TYPE> + class GenericPayloadTreeParser : public GenericPayloadParser<PAYLOAD_TYPE> { + public: + virtual void handleStartElement(const std::string& element, const std::string& xmlns, const AttributeMap& attributes) { + if (!root_) { + root_ = boost::make_shared<ParserElement>(element, xmlns, attributes); + elementStack_.push_back(root_); + } + else { + ParserElement::ref current = *elementStack_.rbegin(); + elementStack_.push_back(current->addChild(element, xmlns, attributes)); + } + } + + virtual void handleEndElement(const std::string& /*element*/, const std::string&) { + elementStack_.pop_back(); + if (elementStack_.empty()) { + handleTree(root_); + } + } + + virtual void handleCharacterData(const std::string& data) { + ParserElement::ref current = *elementStack_.rbegin(); + current->appendCharacterData(data); + } + + virtual void handleTree(ParserElement::ref root) = 0; + + private: + std::deque<ParserElement::ref> elementStack_; + ParserElement::ref root_; + }; +} diff --git a/Swiften/Parser/IQParser.cpp b/Swiften/Parser/IQParser.cpp index e0883f2..62d775f 100644 --- a/Swiften/Parser/IQParser.cpp +++ b/Swiften/Parser/IQParser.cpp @@ -5,8 +5,9 @@ */ #include <iostream> +#include <boost/optional.hpp> -#include "Swiften/Parser/IQParser.h" +#include <Swiften/Parser/IQParser.h> namespace Swift { @@ -15,22 +16,22 @@ IQParser::IQParser(PayloadParserFactoryCollection* factories) : } void IQParser::handleStanzaAttributes(const AttributeMap& attributes) { - AttributeMap::const_iterator type = attributes.find("type"); - if (type != attributes.end()) { - if (type->second == "set") { + boost::optional<std::string> type = attributes.getAttributeValue("type"); + if (type) { + if (*type == "set") { getStanzaGeneric()->setType(IQ::Set); } - else if (type->second == "get") { + else if (*type == "get") { getStanzaGeneric()->setType(IQ::Get); } - else if (type->second == "result") { + else if (*type == "result") { getStanzaGeneric()->setType(IQ::Result); } - else if (type->second == "error") { + else if (*type == "error") { getStanzaGeneric()->setType(IQ::Error); } else { - std::cerr << "Unknown IQ type: " << type->second << std::endl; + std::cerr << "Unknown IQ type: " << *type << std::endl; getStanzaGeneric()->setType(IQ::Get); } } diff --git a/Swiften/Parser/IQParser.h b/Swiften/Parser/IQParser.h index e104dc4..a7aa967 100644 --- a/Swiften/Parser/IQParser.h +++ b/Swiften/Parser/IQParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_IQParser_H -#define SWIFTEN_IQParser_H +#pragma once -#include "Swiften/Parser/GenericStanzaParser.h" -#include "Swiften/Elements/IQ.h" +#include <Swiften/Parser/GenericStanzaParser.h> +#include <Swiften/Elements/IQ.h> namespace Swift { class IQParser : public GenericStanzaParser<IQ> { @@ -19,5 +18,3 @@ namespace Swift { virtual void handleStanzaAttributes(const AttributeMap&); }; } - -#endif diff --git a/Swiften/Parser/LibXMLParser.cpp b/Swiften/Parser/LibXMLParser.cpp index c94a360..ae87f38 100644 --- a/Swiften/Parser/LibXMLParser.cpp +++ b/Swiften/Parser/LibXMLParser.cpp @@ -4,21 +4,29 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/LibXMLParser.h" +#include <Swiften/Parser/LibXMLParser.h> #include <iostream> #include <cassert> #include <cstring> #include <string> -#include "Swiften/Parser/XMLParserClient.h" +#include <Swiften/Parser/XMLParserClient.h> namespace Swift { -static void handleStartElement(void *parser, const xmlChar* name, const xmlChar*, const xmlChar* xmlns, int, const xmlChar**, int nbAttributes, int, const xmlChar ** attributes) { +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) { + // Just because i don't understand what this means yet :-) + std::cerr << "Unexpected nbDefaulted on XML element" << std::endl; + } for (int i = 0; i < nbAttributes*5; i += 5) { - attributeValues[std::string(reinterpret_cast<const char*>(attributes[i]))] = std::string(reinterpret_cast<const char*>(attributes[i+3]), attributes[i+4]-attributes[i+3]); + std::string attributeNS = ""; + if (attributes[i+2]) { + 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])); } static_cast<XMLParser*>(parser)->getClient()->handleStartElement(reinterpret_cast<const char*>(name), (xmlns ? reinterpret_cast<const char*>(xmlns) : std::string()), attributeValues); } diff --git a/Swiften/Parser/LibXMLParser.h b/Swiften/Parser/LibXMLParser.h index d0dac8b..ba61ad9 100644 --- a/Swiften/Parser/LibXMLParser.h +++ b/Swiften/Parser/LibXMLParser.h @@ -9,7 +9,7 @@ #include <libxml/parser.h> #include <boost/noncopyable.hpp> -#include "Swiften/Parser/XMLParser.h" +#include <Swiften/Parser/XMLParser.h> namespace Swift { class LibXMLParser : public XMLParser, public boost::noncopyable { diff --git a/Swiften/Parser/MessageParser.cpp b/Swiften/Parser/MessageParser.cpp index 5f4d59c..7f5e6d4 100644 --- a/Swiften/Parser/MessageParser.cpp +++ b/Swiften/Parser/MessageParser.cpp @@ -4,9 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include <iostream> +#include <boost/optional.hpp> -#include "Swiften/Parser/MessageParser.h" +#include <Swiften/Parser/MessageParser.h> namespace Swift { @@ -16,18 +16,18 @@ MessageParser::MessageParser(PayloadParserFactoryCollection* factories) : } void MessageParser::handleStanzaAttributes(const AttributeMap& attributes) { - AttributeMap::const_iterator type = attributes.find("type"); - if (type != attributes.end()) { - if (type->second == "chat") { + boost::optional<std::string> type = attributes.getAttributeValue("type"); + if (type) { + if (*type == "chat") { getStanzaGeneric()->setType(Message::Chat); } - else if (type->second == "error") { + else if (*type == "error") { getStanzaGeneric()->setType(Message::Error); } - else if (type->second == "groupchat") { + else if (*type == "groupchat") { getStanzaGeneric()->setType(Message::Groupchat); } - else if (type->second == "headline") { + else if (*type == "headline") { getStanzaGeneric()->setType(Message::Headline); } else { diff --git a/Swiften/Parser/MessageParser.h b/Swiften/Parser/MessageParser.h index 70def0a..a8aaa99 100644 --- a/Swiften/Parser/MessageParser.h +++ b/Swiften/Parser/MessageParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_MESSAGEPARSER_H -#define SWIFTEN_MESSAGEPARSER_H +#pragma once -#include "Swiften/Parser/GenericStanzaParser.h" -#include "Swiften/Elements/Message.h" +#include <Swiften/Parser/GenericStanzaParser.h> +#include <Swiften/Elements/Message.h> namespace Swift { class MessageParser : public GenericStanzaParser<Message> { @@ -19,5 +18,3 @@ namespace Swift { virtual void handleStanzaAttributes(const AttributeMap&); }; } - -#endif diff --git a/Swiften/Parser/PayloadParser.cpp b/Swiften/Parser/PayloadParser.cpp index 42d36e0..3680d63 100644 --- a/Swiften/Parser/PayloadParser.cpp +++ b/Swiften/Parser/PayloadParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParser.h" +#include <Swiften/Parser/PayloadParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParser.h b/Swiften/Parser/PayloadParser.h index 423a2bb..8a9a290 100644 --- a/Swiften/Parser/PayloadParser.h +++ b/Swiften/Parser/PayloadParser.h @@ -7,9 +7,9 @@ #pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Parser/AttributeMap.h" +#include <Swiften/Parser/AttributeMap.h> -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> namespace Swift { @@ -44,6 +44,6 @@ namespace Swift { /** * Retrieve a pointer to the payload. */ - virtual Payload::ref getPayload() const = 0; + virtual boost::shared_ptr<Payload> getPayload() const = 0; }; } diff --git a/Swiften/Parser/PayloadParserFactory.cpp b/Swiften/Parser/PayloadParserFactory.cpp index 29501d6..4dac217 100644 --- a/Swiften/Parser/PayloadParserFactory.cpp +++ b/Swiften/Parser/PayloadParserFactory.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParserFactory.h" +#include <Swiften/Parser/PayloadParserFactory.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParserFactory.h b/Swiften/Parser/PayloadParserFactory.h index 2baa2ad..5619d21 100644 --- a/Swiften/Parser/PayloadParserFactory.h +++ b/Swiften/Parser/PayloadParserFactory.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Parser/AttributeMap.h" +#include <Swiften/Parser/AttributeMap.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParserFactoryCollection.cpp index 0080fbe..e3efc3d 100644 --- a/Swiften/Parser/PayloadParserFactoryCollection.cpp +++ b/Swiften/Parser/PayloadParserFactoryCollection.cpp @@ -7,8 +7,8 @@ #include <boost/bind.hpp> #include <algorithm> -#include "Swiften/Parser/PayloadParserFactoryCollection.h" -#include "Swiften/Parser/PayloadParserFactory.h" +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/PayloadParserFactory.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParserFactoryCollection.h b/Swiften/Parser/PayloadParserFactoryCollection.h index 9afb9b7..6407641 100644 --- a/Swiften/Parser/PayloadParserFactoryCollection.h +++ b/Swiften/Parser/PayloadParserFactoryCollection.h @@ -4,16 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_PAYLOADPARSERFACTORYCOLLECTION_H -#define SWIFTEN_PAYLOADPARSERFACTORYCOLLECTION_H +#pragma once #include <vector> -#include "Swiften/Parser/AttributeMap.h" +#include <Swiften/Parser/AttributeMap.h> namespace Swift { class PayloadParserFactory; - class PayloadParserFactoryCollection { public: @@ -30,5 +28,3 @@ namespace Swift { PayloadParserFactory* defaultFactory_; }; } - -#endif diff --git a/Swiften/Parser/PayloadParsers/BlockParser.h b/Swiften/Parser/PayloadParsers/BlockParser.h new file mode 100644 index 0000000..cd727ad --- /dev/null +++ b/Swiften/Parser/PayloadParsers/BlockParser.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/Nickname.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + template<typename BLOCK_ELEMENT> + class BlockParser : public GenericPayloadParser<BLOCK_ELEMENT> { + public: + BlockParser() : GenericPayloadParser<BLOCK_ELEMENT>() { + } + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) { + if (level == 1 && element == "item") { + JID jid(attributes.getAttribute("jid")); + if (jid.isValid()) { + GenericPayloadParser<BLOCK_ELEMENT>::getPayloadInternal()->addItem(jid); + } + } + ++level; + } + + virtual void handleEndElement(const std::string&, const std::string&) { + --level; + } + + virtual void handleCharacterData(const std::string&) { + } + + private: + int level; + }; +} diff --git a/Swiften/Parser/PayloadParsers/BodyParser.cpp b/Swiften/Parser/PayloadParsers/BodyParser.cpp index d0f4e09..ac8bdd5 100644 --- a/Swiften/Parser/PayloadParsers/BodyParser.cpp +++ b/Swiften/Parser/PayloadParsers/BodyParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/BodyParser.h" +#include <Swiften/Parser/PayloadParsers/BodyParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/BodyParser.h b/Swiften/Parser/PayloadParsers/BodyParser.h index f9e17e0..f571370 100644 --- a/Swiften/Parser/PayloadParsers/BodyParser.h +++ b/Swiften/Parser/PayloadParsers/BodyParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_BodyParser_H -#define SWIFTEN_BodyParser_H +#pragma once -#include "Swiften/Elements/Body.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/Body.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class BodyParser : public GenericPayloadParser<Body> { @@ -24,5 +23,3 @@ namespace Swift { std::string text_; }; } - -#endif diff --git a/Swiften/Parser/PayloadParsers/BytestreamsParser.cpp b/Swiften/Parser/PayloadParsers/BytestreamsParser.cpp index 35db9ec..fddc1c7 100644 --- a/Swiften/Parser/PayloadParsers/BytestreamsParser.cpp +++ b/Swiften/Parser/PayloadParsers/BytestreamsParser.cpp @@ -4,11 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/BytestreamsParser.h" +#include <Swiften/Parser/PayloadParsers/BytestreamsParser.h> #include <boost/lexical_cast.hpp> -#include "Swiften/Base/foreach.h" +#include <Swiften/Base/foreach.h> namespace Swift { @@ -27,7 +27,7 @@ void BytestreamsParser::handleStartElement(const std::string& element, const std try { getPayloadInternal()->addStreamHost(Bytestreams::StreamHost(attributes.getAttribute("host"), JID(attributes.getAttribute("jid")), boost::lexical_cast<int>(attributes.getAttribute("port")))); } - catch (boost::bad_lexical_cast& e) { + catch (boost::bad_lexical_cast&) { } } else if (element == "streamhost-used") { diff --git a/Swiften/Parser/PayloadParsers/BytestreamsParser.h b/Swiften/Parser/PayloadParsers/BytestreamsParser.h index 2d67785..4785913 100644 --- a/Swiften/Parser/PayloadParsers/BytestreamsParser.h +++ b/Swiften/Parser/PayloadParsers/BytestreamsParser.h @@ -8,8 +8,8 @@ #include <boost/optional.hpp> -#include "Swiften/Elements/Bytestreams.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/Bytestreams.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class BytestreamsParser : public GenericPayloadParser<Bytestreams> { diff --git a/Swiften/Parser/PayloadParsers/BytestreamsParserFactory.h b/Swiften/Parser/PayloadParsers/BytestreamsParserFactory.h deleted file mode 100644 index 8defd45..0000000 --- a/Swiften/Parser/PayloadParsers/BytestreamsParserFactory.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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/Parser/GenericPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/BytestreamsParser.h" - -namespace Swift { - class BytestreamsParserFactory : public GenericPayloadParserFactory<BytestreamsParser> { - public: - BytestreamsParserFactory() : GenericPayloadParserFactory<BytestreamsParser>("query", "http://jabber.org/protocol/bytestreams") {} - }; -} diff --git a/Swiften/Parser/PayloadParsers/CapsInfoParser.cpp b/Swiften/Parser/PayloadParsers/CapsInfoParser.cpp index d7d9324..770d98b 100644 --- a/Swiften/Parser/PayloadParsers/CapsInfoParser.cpp +++ b/Swiften/Parser/PayloadParsers/CapsInfoParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/CapsInfoParser.h" +#include <Swiften/Parser/PayloadParsers/CapsInfoParser.h> #include <locale> diff --git a/Swiften/Parser/PayloadParsers/CapsInfoParser.h b/Swiften/Parser/PayloadParsers/CapsInfoParser.h index 590326d..96aa734 100644 --- a/Swiften/Parser/PayloadParsers/CapsInfoParser.h +++ b/Swiften/Parser/PayloadParsers/CapsInfoParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Elements/CapsInfo.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/CapsInfo.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class CapsInfoParser : public GenericPayloadParser<CapsInfo> { diff --git a/Swiften/Parser/PayloadParsers/ChatStateParser.cpp b/Swiften/Parser/PayloadParsers/ChatStateParser.cpp index 3a5ba3b..a85dcf7 100644 --- a/Swiften/Parser/PayloadParsers/ChatStateParser.cpp +++ b/Swiften/Parser/PayloadParsers/ChatStateParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/ChatStateParser.h" +#include <Swiften/Parser/PayloadParsers/ChatStateParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/ChatStateParser.h b/Swiften/Parser/PayloadParsers/ChatStateParser.h index 8d0e7f5..4363d6b 100644 --- a/Swiften/Parser/PayloadParsers/ChatStateParser.h +++ b/Swiften/Parser/PayloadParsers/ChatStateParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Elements/ChatState.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/ChatState.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class ChatStateParser : public GenericPayloadParser<ChatState> { diff --git a/Swiften/Parser/PayloadParsers/ChatStateParserFactory.h b/Swiften/Parser/PayloadParsers/ChatStateParserFactory.h index 3dadda7..80d76c4 100644 --- a/Swiften/Parser/PayloadParsers/ChatStateParserFactory.h +++ b/Swiften/Parser/PayloadParsers/ChatStateParserFactory.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Parser/PayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/ChatStateParser.h" +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/ChatStateParser.h> namespace Swift { class PayloadParserFactoryCollection; diff --git a/Swiften/Parser/PayloadParsers/CommandParser.cpp b/Swiften/Parser/PayloadParsers/CommandParser.cpp index 3ebab39..1af4074 100644 --- a/Swiften/Parser/PayloadParsers/CommandParser.cpp +++ b/Swiften/Parser/PayloadParsers/CommandParser.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/CommandParser.h" +#include <Swiften/Parser/PayloadParsers/CommandParser.h> #include <boost/cast.hpp> -#include "Swiften/Parser/PayloadParsers/FormParserFactory.h" -#include "Swiften/Parser/PayloadParsers/FormParser.h" +#include <Swiften/Parser/PayloadParsers/FormParserFactory.h> +#include <Swiften/Parser/PayloadParsers/FormParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/CommandParser.h b/Swiften/Parser/PayloadParsers/CommandParser.h index 0415ba6..80cffc4 100644 --- a/Swiften/Parser/PayloadParsers/CommandParser.h +++ b/Swiften/Parser/PayloadParsers/CommandParser.h @@ -8,8 +8,8 @@ #include <boost/optional.hpp> -#include "Swiften/Elements/Command.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/Command.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class FormParserFactory; diff --git a/Swiften/Parser/PayloadParsers/CommandParserFactory.h b/Swiften/Parser/PayloadParsers/CommandParserFactory.h deleted file mode 100644 index 9eaaf62..0000000 --- a/Swiften/Parser/PayloadParsers/CommandParserFactory.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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/Parser/PayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/CommandParser.h" - -namespace Swift { - class PayloadParserFactoryCollection; - - class CommandParserFactory : public PayloadParserFactory { - public: - CommandParserFactory() { - } - - virtual bool canParse(const std::string& element, const std::string& ns, const AttributeMap&) const { - return ns == "http://jabber.org/protocol/commands" && element == "command"; - } - - virtual PayloadParser* createPayloadParser() { - return new CommandParser(); - } - - }; -} diff --git a/Swiften/Parser/PayloadParsers/DelayParser.cpp b/Swiften/Parser/PayloadParsers/DelayParser.cpp index 3425b84..e18d09d 100644 --- a/Swiften/Parser/PayloadParsers/DelayParser.cpp +++ b/Swiften/Parser/PayloadParsers/DelayParser.cpp @@ -4,28 +4,18 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/DelayParser.h" +#include <Swiften/Parser/PayloadParsers/DelayParser.h> -#include <locale> - -#include <boost/date_time/time_facet.hpp> +#include <Swiften/Base/DateTime.h> namespace Swift { -DelayParser::DelayParser(const std::locale& locale) : locale(locale), level_(0) { -} - -boost::posix_time::ptime DelayParser::dateFromString(const std::string& string) { - std::istringstream stream(string); - stream.imbue(locale); - boost::posix_time::ptime result(boost::posix_time::not_a_date_time); - stream >> result; - return result; +DelayParser::DelayParser() : level_(0) { } void DelayParser::handleStartElement(const std::string& /*element*/, const std::string& /*ns*/, const AttributeMap& attributes) { if (level_ == 0) { - boost::posix_time::ptime stamp = dateFromString(attributes.getAttribute("stamp")); + boost::posix_time::ptime stamp = stringToDateTime(attributes.getAttribute("stamp")); getPayloadInternal()->setStamp(stamp); if (!attributes.getAttribute("from").empty()) { std::string from = attributes.getAttribute("from"); diff --git a/Swiften/Parser/PayloadParsers/DelayParser.h b/Swiften/Parser/PayloadParsers/DelayParser.h index c2e2bb6..144220a 100644 --- a/Swiften/Parser/PayloadParsers/DelayParser.h +++ b/Swiften/Parser/PayloadParsers/DelayParser.h @@ -6,23 +6,19 @@ #pragma once -#include "Swiften/Elements/Delay.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/Delay.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class DelayParser : public GenericPayloadParser<Delay> { public: - DelayParser(const std::locale& locale); + DelayParser(); virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); virtual void handleEndElement(const std::string& element, const std::string&); virtual void handleCharacterData(const std::string& data); private: - boost::posix_time::ptime dateFromString(const std::string& string); - - private: - std::locale locale; int level_; }; } diff --git a/Swiften/Parser/PayloadParsers/DelayParserFactory.cpp b/Swiften/Parser/PayloadParsers/DelayParserFactory.cpp deleted file mode 100644 index 19d0530..0000000 --- a/Swiften/Parser/PayloadParsers/DelayParserFactory.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2010 Kevin Smith - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include <Swiften/Parser/PayloadParsers/DelayParserFactory.h> - -#include <boost/date_time/time_facet.hpp> - -namespace Swift { - -DelayParserFactory::DelayParserFactory() { - boost::posix_time::time_input_facet* facet = new boost::posix_time::time_input_facet("%Y-%m-%d %H:%M:%S%F%Q"); - locale = std::locale(std::locale::classic(), facet); -} - -} diff --git a/Swiften/Parser/PayloadParsers/DelayParserFactory.h b/Swiften/Parser/PayloadParsers/DelayParserFactory.h deleted file mode 100644 index c150853..0000000 --- a/Swiften/Parser/PayloadParsers/DelayParserFactory.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2010 Kevin Smith - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#pragma once - -#include "Swiften/Parser/PayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/DelayParser.h" - -namespace Swift { - class PayloadParserFactoryCollection; - - class DelayParserFactory : public PayloadParserFactory { - public: - DelayParserFactory(); - - virtual bool canParse(const std::string& /*element*/, const std::string& ns, const AttributeMap&) const { - return ns == "urn:xmpp:delay"; - } - - virtual PayloadParser* createPayloadParser() { - return new DelayParser(locale); - } - - private: - std::locale locale; - }; -} diff --git a/Swiften/Parser/PayloadParsers/DiscoInfoParser.cpp b/Swiften/Parser/PayloadParsers/DiscoInfoParser.cpp index e1fcb20..14ff79d 100644 --- a/Swiften/Parser/PayloadParsers/DiscoInfoParser.cpp +++ b/Swiften/Parser/PayloadParsers/DiscoInfoParser.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/DiscoInfoParser.h" -#include "Swiften/Parser/PayloadParsers/FormParser.h" +#include <Swiften/Parser/PayloadParsers/DiscoInfoParser.h> +#include <Swiften/Parser/PayloadParsers/FormParser.h> namespace Swift { @@ -15,7 +15,7 @@ DiscoInfoParser::DiscoInfoParser() : level_(TopLevel), formParser_(NULL) { void DiscoInfoParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { if (level_ == PayloadLevel) { if (element == "identity") { - getPayloadInternal()->addIdentity(DiscoInfo::Identity(attributes.getAttribute("name"), attributes.getAttribute("category"), attributes.getAttribute("type"), attributes.getAttribute("lang"))); + getPayloadInternal()->addIdentity(DiscoInfo::Identity(attributes.getAttribute("name"), attributes.getAttribute("category"), attributes.getAttribute("type"), attributes.getAttribute("lang", "http://www.w3.org/XML/1998/namespace"))); } else if (element == "feature") { getPayloadInternal()->addFeature(attributes.getAttribute("var")); diff --git a/Swiften/Parser/PayloadParsers/DiscoInfoParser.h b/Swiften/Parser/PayloadParsers/DiscoInfoParser.h index 24a1d6f..df1441c 100644 --- a/Swiften/Parser/PayloadParsers/DiscoInfoParser.h +++ b/Swiften/Parser/PayloadParsers/DiscoInfoParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Elements/DiscoInfo.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/DiscoInfo.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class DiscoInfoParser : public GenericPayloadParser<DiscoInfo> { diff --git a/Swiften/Parser/PayloadParsers/DiscoItemsParser.cpp b/Swiften/Parser/PayloadParsers/DiscoItemsParser.cpp index 7ff375b..d6ac94d 100644 --- a/Swiften/Parser/PayloadParsers/DiscoItemsParser.cpp +++ b/Swiften/Parser/PayloadParsers/DiscoItemsParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/DiscoItemsParser.h" +#include <Swiften/Parser/PayloadParsers/DiscoItemsParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/DiscoItemsParser.h b/Swiften/Parser/PayloadParsers/DiscoItemsParser.h index 0700df6..ae799cb 100644 --- a/Swiften/Parser/PayloadParsers/DiscoItemsParser.h +++ b/Swiften/Parser/PayloadParsers/DiscoItemsParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Elements/DiscoItems.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/DiscoItems.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class DiscoItemsParser : public GenericPayloadParser<DiscoItems> { diff --git a/Swiften/Parser/PayloadParsers/ErrorParser.cpp b/Swiften/Parser/PayloadParsers/ErrorParser.cpp index 4034cb5..8a02317 100644 --- a/Swiften/Parser/PayloadParsers/ErrorParser.cpp +++ b/Swiften/Parser/PayloadParsers/ErrorParser.cpp @@ -4,14 +4,16 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/ErrorParser.h" +#include <Swiften/Parser/PayloadParsers/ErrorParser.h> +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/PayloadParserFactory.h> namespace Swift { -ErrorParser::ErrorParser() : level_(TopLevel) { +ErrorParser::ErrorParser(PayloadParserFactoryCollection* factories) : factories(factories), level_(TopLevel) { } -void ErrorParser::handleStartElement(const std::string&, const std::string&, const AttributeMap& attributes) { +void ErrorParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { if (level_ == TopLevel) { std::string type = attributes.getAttribute("type"); if (type == "continue") { @@ -30,14 +32,9 @@ void ErrorParser::handleStartElement(const std::string&, const std::string&, con getPayloadInternal()->setType(ErrorPayload::Cancel); } } - ++level_; -} - -void ErrorParser::handleEndElement(const std::string& element, const std::string&) { - --level_; - if (level_ == PayloadLevel) { + else if (level_ == PayloadLevel) { if (element == "text") { - getPayloadInternal()->setText(currentText_); + } else if (element == "bad-request") { getPayloadInternal()->setCondition(ErrorPayload::BadRequest); @@ -103,13 +100,46 @@ void ErrorParser::handleEndElement(const std::string& element, const std::string getPayloadInternal()->setCondition(ErrorPayload::UnexpectedRequest); } else { - getPayloadInternal()->setCondition(ErrorPayload::UndefinedCondition); + PayloadParserFactory* payloadParserFactory = factories->getPayloadParserFactory(element, ns, attributes); + if (payloadParserFactory) { + currentPayloadParser.reset(payloadParserFactory->createPayloadParser()); + } else { + getPayloadInternal()->setCondition(ErrorPayload::UndefinedCondition); + } + } + } + if (level_ >= PayloadLevel && currentPayloadParser) { + currentPayloadParser->handleStartElement(element, ns, attributes); + } + ++level_; +} + +void ErrorParser::handleEndElement(const std::string& element, const std::string& ns) { + --level_; + if (currentPayloadParser) { + if (level_ >= PayloadLevel) { + currentPayloadParser->handleEndElement(element, ns); + } + + if (level_ == PayloadLevel) { + getPayloadInternal()->setPayload(currentPayloadParser->getPayload()); + currentPayloadParser.reset(); + } + } + else if (level_ == PayloadLevel) { + if (element == "text") { + getPayloadInternal()->setText(currentText_); } } } void ErrorParser::handleCharacterData(const std::string& data) { - currentText_ += data; + if (level_ > PayloadLevel && currentPayloadParser) { + currentPayloadParser->handleCharacterData(data); + } + else { + currentText_ += data; + } } } diff --git a/Swiften/Parser/PayloadParsers/ErrorParser.h b/Swiften/Parser/PayloadParsers/ErrorParser.h index 4318a8c..b2d05cf 100644 --- a/Swiften/Parser/PayloadParsers/ErrorParser.h +++ b/Swiften/Parser/PayloadParsers/ErrorParser.h @@ -4,16 +4,16 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_ErrorParser_H -#define SWIFTEN_ErrorParser_H +#pragma once -#include "Swiften/Elements/ErrorPayload.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/ErrorPayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { + class PayloadParserFactoryCollection; class ErrorParser : public GenericPayloadParser<ErrorPayload> { public: - ErrorParser(); + ErrorParser(PayloadParserFactoryCollection* factories); virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); virtual void handleEndElement(const std::string& element, const std::string&); @@ -24,9 +24,9 @@ namespace Swift { TopLevel = 0, PayloadLevel = 1 }; + PayloadParserFactoryCollection* factories; int level_; std::string currentText_; + boost::shared_ptr<PayloadParser> currentPayloadParser; }; } - -#endif diff --git a/Swiften/Parser/PayloadParsers/ErrorParserFactory.h b/Swiften/Parser/PayloadParsers/ErrorParserFactory.h new file mode 100644 index 0000000..1463807 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/ErrorParserFactory.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/ErrorParser.h> + +namespace Swift { + class PayloadParserFactoryCollection; + + class ErrorParserFactory : public PayloadParserFactory { + public: + ErrorParserFactory(PayloadParserFactoryCollection* factories) : factories(factories) { + } + + virtual bool canParse(const std::string& element, const std::string& /*ns*/, const AttributeMap&) const { + return element == "error"; + } + + virtual PayloadParser* createPayloadParser() { + return new ErrorParser(factories); + } + + private: + PayloadParserFactoryCollection* factories; + + }; +} diff --git a/Swiften/Parser/PayloadParsers/FormParser.cpp b/Swiften/Parser/PayloadParsers/FormParser.cpp index f8e02a4..3905302 100644 --- a/Swiften/Parser/PayloadParsers/FormParser.cpp +++ b/Swiften/Parser/PayloadParsers/FormParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/FormParser.h" +#include <Swiften/Parser/PayloadParsers/FormParser.h> namespace Swift { @@ -63,12 +63,9 @@ void FormParser::handleStartElement(const std::string& element, const std::strin else if (type == "text-private") { currentFieldParseHelper_ = TextPrivateFormFieldParseHelper::create(); } - else if (type == "text-single") { + else /*if (type == "text-single") || undefined */ { currentFieldParseHelper_ = TextSingleFormFieldParseHelper::create(); } - else { - currentFieldParseHelper_ = UntypedFormFieldParseHelper::create(); - } if (currentFieldParseHelper_) { currentFieldParseHelper_->getField()->setName(attributes.getAttribute("var")); currentFieldParseHelper_->getField()->setLabel(attributes.getAttribute("label")); diff --git a/Swiften/Parser/PayloadParsers/FormParser.h b/Swiften/Parser/PayloadParsers/FormParser.h index 90a3550..eae40a1 100644 --- a/Swiften/Parser/PayloadParsers/FormParser.h +++ b/Swiften/Parser/PayloadParsers/FormParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Elements/Form.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/Form.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class FormParser : public GenericPayloadParser<Form> { @@ -96,7 +96,6 @@ namespace Swift { SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(JIDSingle, JID); SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(JIDMulti, JIDList); SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(ListMulti, StringList); - SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(Untyped, StringList); enum Level { TopLevel = 0, diff --git a/Swiften/Parser/PayloadParsers/FormParserFactory.h b/Swiften/Parser/PayloadParsers/FormParserFactory.h index 7c095a7..9e1794a 100644 --- a/Swiften/Parser/PayloadParsers/FormParserFactory.h +++ b/Swiften/Parser/PayloadParsers/FormParserFactory.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Parser/PayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/FormParser.h" +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/FormParser.h> namespace Swift { class PayloadParserFactoryCollection; diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp index e20c06d..9865a1e 100644 --- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp +++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp @@ -4,77 +4,122 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" -#include "Swiften/Base/foreach.h" -#include "Swiften/Parser/GenericPayloadParser.h" -#include "Swiften/Parser/PayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/ErrorParser.h" -#include "Swiften/Parser/PayloadParsers/BodyParser.h" -#include "Swiften/Parser/PayloadParsers/SubjectParser.h" -#include "Swiften/Parser/PayloadParsers/ChatStateParserFactory.h" -#include "Swiften/Parser/PayloadParsers/PriorityParser.h" -#include "Swiften/Parser/PayloadParsers/ResourceBindParser.h" -#include "Swiften/Parser/PayloadParsers/StartSessionParser.h" -#include "Swiften/Parser/PayloadParsers/StatusParser.h" -#include "Swiften/Parser/PayloadParsers/StatusShowParser.h" -#include "Swiften/Parser/PayloadParsers/RosterParser.h" -#include "Swiften/Parser/PayloadParsers/SoftwareVersionParser.h" -#include "Swiften/Parser/PayloadParsers/StorageParser.h" -#include "Swiften/Parser/PayloadParsers/DiscoInfoParser.h" -#include "Swiften/Parser/PayloadParsers/DiscoItemsParser.h" -#include "Swiften/Parser/PayloadParsers/CapsInfoParser.h" -#include "Swiften/Parser/PayloadParsers/SecurityLabelParserFactory.h" -#include "Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParserFactory.h" -#include "Swiften/Parser/PayloadParsers/FormParserFactory.h" -#include "Swiften/Parser/PayloadParsers/CommandParserFactory.h" -#include "Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/SearchPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/StreamInitiationParserFactory.h" -#include "Swiften/Parser/PayloadParsers/BytestreamsParserFactory.h" -#include "Swiften/Parser/PayloadParsers/IBBParser.h" -#include "Swiften/Parser/PayloadParsers/VCardUpdateParserFactory.h" -#include "Swiften/Parser/PayloadParsers/VCardParserFactory.h" -#include "Swiften/Parser/PayloadParsers/RawXMLPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h" -#include "Swiften/Parser/PayloadParsers/DelayParserFactory.h" -#include "Swiften/Parser/PayloadParsers/MUCUserPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/NicknameParserFactory.h" +#include <Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Elements/BlockPayload.h> +#include <Swiften/Elements/UnblockPayload.h> +#include <Swiften/Elements/BlockListPayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/ErrorParser.h> +#include <Swiften/Parser/PayloadParsers/ErrorParserFactory.h> +#include <Swiften/Parser/PayloadParsers/BodyParser.h> +#include <Swiften/Parser/PayloadParsers/BlockParser.h> +#include <Swiften/Parser/PayloadParsers/SubjectParser.h> +#include <Swiften/Parser/PayloadParsers/ChatStateParserFactory.h> +#include <Swiften/Parser/PayloadParsers/PriorityParser.h> +#include <Swiften/Parser/PayloadParsers/ResourceBindParser.h> +#include <Swiften/Parser/PayloadParsers/StartSessionParser.h> +#include <Swiften/Parser/PayloadParsers/StatusParser.h> +#include <Swiften/Parser/PayloadParsers/StatusShowParser.h> +#include <Swiften/Parser/PayloadParsers/RosterItemExchangeParser.h> +#include <Swiften/Parser/PayloadParsers/RosterParser.h> +#include <Swiften/Parser/PayloadParsers/SoftwareVersionParser.h> +#include <Swiften/Parser/PayloadParsers/StorageParser.h> +#include <Swiften/Parser/PayloadParsers/DiscoInfoParser.h> +#include <Swiften/Parser/PayloadParsers/DiscoItemsParser.h> +#include <Swiften/Parser/PayloadParsers/CapsInfoParser.h> +#include <Swiften/Parser/PayloadParsers/SecurityLabelParserFactory.h> +#include <Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h> +#include <Swiften/Parser/PayloadParsers/FormParserFactory.h> +#include <Swiften/Parser/PayloadParsers/CommandParser.h> +#include <Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParser.h> +#include <Swiften/Parser/PayloadParsers/SearchPayloadParser.h> +#include <Swiften/Parser/PayloadParsers/StreamInitiationParser.h> +#include <Swiften/Parser/PayloadParsers/BytestreamsParser.h> +#include <Swiften/Parser/PayloadParsers/IBBParser.h> +#include <Swiften/Parser/PayloadParsers/VCardUpdateParser.h> +#include <Swiften/Parser/PayloadParsers/VCardParser.h> +#include <Swiften/Parser/PayloadParsers/RawXMLPayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h> +#include <Swiften/Parser/PayloadParsers/DelayParser.h> +#include <Swiften/Parser/PayloadParsers/MUCUserPayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/MUCAdminPayloadParser.h> +#include <Swiften/Parser/PayloadParsers/MUCOwnerPayloadParser.h> +#include <Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.h> +#include <Swiften/Parser/PayloadParsers/MUCOwnerPayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/NicknameParser.h> +#include <Swiften/Parser/PayloadParsers/ReplaceParser.h> +#include <Swiften/Parser/PayloadParsers/LastParser.h> +#include <Swiften/Parser/PayloadParsers/JingleParserFactory.h> +#include <Swiften/Parser/PayloadParsers/JingleReasonParser.h> +#include <Swiften/Parser/PayloadParsers/JingleContentPayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.h> +#include <Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.h> +#include <Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParserFactory.h> +#include <Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h> +#include <Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h> +#include <Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.h> +#include <Swiften/Parser/PayloadParsers/S5BProxyRequestParser.h> +#include <Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.h> +#include <Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.h> using namespace boost; namespace Swift { FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() { - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<IBBParser>("", "http://jabber.org/protocol/ibb"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<StatusShowParser>("show"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<StatusParser>("status"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<BodyParser>("body"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<SubjectParser>("subject"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<PriorityParser>("priority"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<ErrorParser>("error"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<SoftwareVersionParser>("query", "jabber:iq:version"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<StorageParser>("storage", "storage:bookmarks"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<RosterParser>("query", "jabber:iq:roster"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<DiscoInfoParser>("query", "http://jabber.org/protocol/disco#info"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<DiscoItemsParser>("query", "http://jabber.org/protocol/disco#items"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<CapsInfoParser>("c", "http://jabber.org/protocol/caps"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<ResourceBindParser>("bind", "urn:ietf:params:xml:ns:xmpp-bind"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<StartSessionParser>("session", "urn:ietf:params:xml:ns:xmpp-session"))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new SecurityLabelParserFactory())); - factories_.push_back(shared_ptr<PayloadParserFactory>(new SecurityLabelsCatalogParserFactory())); - factories_.push_back(shared_ptr<PayloadParserFactory>(new FormParserFactory())); - factories_.push_back(shared_ptr<PayloadParserFactory>(new CommandParserFactory())); - factories_.push_back(shared_ptr<PayloadParserFactory>(new InBandRegistrationPayloadParserFactory())); - factories_.push_back(shared_ptr<PayloadParserFactory>(new SearchPayloadParserFactory())); - factories_.push_back(shared_ptr<PayloadParserFactory>(new StreamInitiationParserFactory())); - factories_.push_back(shared_ptr<PayloadParserFactory>(new BytestreamsParserFactory())); - factories_.push_back(shared_ptr<PayloadParserFactory>(new VCardUpdateParserFactory())); - factories_.push_back(shared_ptr<PayloadParserFactory>(new VCardParserFactory())); - factories_.push_back(shared_ptr<PayloadParserFactory>(new PrivateStorageParserFactory(this))); - factories_.push_back(shared_ptr<PayloadParserFactory>(new ChatStateParserFactory())); - factories_.push_back(shared_ptr<PayloadParserFactory>(new DelayParserFactory())); - factories_.push_back(shared_ptr<PayloadParserFactory>(new MUCUserPayloadParserFactory())); - factories_.push_back(shared_ptr<PayloadParserFactory>(new NicknameParserFactory())); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<IBBParser> >("", "http://jabber.org/protocol/ibb")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<StatusShowParser> >("show")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<StatusParser> >("status")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<ReplaceParser> >("replace", "http://swift.im/protocol/replace")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<LastParser> >("query", "jabber:iq:last")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<BodyParser> >("body")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<SubjectParser> >("subject")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<PriorityParser> >("priority")); + factories_.push_back(boost::make_shared<ErrorParserFactory>(this)); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<DelayParser> >("delay", "urn:xmpp:delay")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<SoftwareVersionParser> >("query", "jabber:iq:version")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<StorageParser> >("storage", "storage:bookmarks")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<RosterItemExchangeParser> >("x", "http://jabber.org/protocol/rosterx")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<RosterParser> >("query", "jabber:iq:roster")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<DiscoInfoParser> >("query", "http://jabber.org/protocol/disco#info")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<DiscoItemsParser> >("query", "http://jabber.org/protocol/disco#items")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<CapsInfoParser> >("c", "http://jabber.org/protocol/caps")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<ResourceBindParser> >("bind", "urn:ietf:params:xml:ns:xmpp-bind")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<StartSessionParser> >("session", "urn:ietf:params:xml:ns:xmpp-session")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<BlockParser<BlockPayload> > >("block", "urn:xmpp:blocking")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<BlockParser<BlockListPayload> > >("blocklist", "urn:xmpp:blocking")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<BlockParser<UnblockPayload> > >("unblock", "urn:xmpp:blocking")); + factories_.push_back(boost::make_shared<SecurityLabelParserFactory>()); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<SecurityLabelsCatalogParser> >("catalog", "urn:xmpp:sec-label:catalog:2")); + factories_.push_back(boost::make_shared<FormParserFactory>()); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<CommandParser> >("command", "http://jabber.org/protocol/commands")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<InBandRegistrationPayloadParser> >("query", "jabber:iq:register")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<SearchPayloadParser> >("query", "jabber:iq:search")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<StreamInitiationParser> >("si", "http://jabber.org/protocol/si")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<BytestreamsParser> >("query", "http://jabber.org/protocol/bytestreams")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<VCardUpdateParser> >("x", "vcard-temp:x:update")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<VCardParser> >("vCard", "vcard-temp")); + factories_.push_back(boost::make_shared<PrivateStorageParserFactory>(this)); + factories_.push_back(boost::make_shared<ChatStateParserFactory>()); + factories_.push_back(boost::make_shared<MUCUserPayloadParserFactory>(this)); + factories_.push_back(boost::make_shared<MUCOwnerPayloadParserFactory>(this)); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<MUCAdminPayloadParser> >("query", "http://jabber.org/protocol/muc#admin")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<MUCDestroyPayloadParser> >("destroy", "http://jabber.org/protocol/muc#user")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<MUCDestroyPayloadParser> >("destroy", "http://jabber.org/protocol/muc#owner")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<NicknameParser> >("nick", "http://jabber.org/protocol/nick")); + factories_.push_back(boost::make_shared<JingleParserFactory>(this)); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<JingleReasonParser> >("reason", "urn:xmpp:jingle:1")); + factories_.push_back(boost::make_shared<JingleContentPayloadParserFactory>(this)); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<JingleIBBTransportMethodPayloadParser> >("transport", "urn:xmpp:jingle:transports:ibb:1")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<JingleS5BTransportMethodPayloadParser> >("transport", "urn:xmpp:jingle:transports:s5b:1")); + factories_.push_back(boost::make_shared<JingleFileTransferDescriptionParserFactory>(this)); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<StreamInitiationFileInfoParser> >("file", "http://jabber.org/protocol/si/profile/file-transfer")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<JingleFileTransferReceivedParser> >("received", "urn:xmpp:jingle:apps:file-transfer:3")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<JingleFileTransferHashParser> >("checksum")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<S5BProxyRequestParser> >("query", "http://jabber.org/protocol/bytestreams")); + foreach(shared_ptr<PayloadParserFactory> factory, factories_) { addFactory(factory.get()); } diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h index f3883b0..46b692b 100644 --- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h +++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h @@ -9,8 +9,8 @@ #include <boost/shared_ptr.hpp> #include <vector> -#include "Swiften/Parser/PayloadParserFactoryCollection.h" -#include "Swiften/Parser/PayloadParserFactory.h" +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/PayloadParserFactory.h> namespace Swift { class FullPayloadParserFactoryCollection : public PayloadParserFactoryCollection { diff --git a/Swiften/Parser/PayloadParsers/IBBParser.cpp b/Swiften/Parser/PayloadParsers/IBBParser.cpp index f36dc43..20a1ce9 100644 --- a/Swiften/Parser/PayloadParsers/IBBParser.cpp +++ b/Swiften/Parser/PayloadParsers/IBBParser.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/IBBParser.h" +#include <Swiften/Parser/PayloadParsers/IBBParser.h> #include <boost/lexical_cast.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/StringCodecs/Base64.h> namespace Swift { @@ -27,7 +27,7 @@ void IBBParser::handleStartElement(const std::string& element, const std::string try { getPayloadInternal()->setSequenceNumber(boost::lexical_cast<int>(attributes.getAttribute("seq"))); } - catch (boost::bad_lexical_cast& e) { + catch (boost::bad_lexical_cast&) { } } else if (element == "open") { @@ -42,7 +42,7 @@ void IBBParser::handleStartElement(const std::string& element, const std::string try { getPayloadInternal()->setBlockSize(boost::lexical_cast<int>(attributes.getAttribute("block-size"))); } - catch (boost::bad_lexical_cast& e) { + catch (boost::bad_lexical_cast&) { } } else if (element == "close") { @@ -60,7 +60,7 @@ void IBBParser::handleEndElement(const std::string& element, const std::string&) std::vector<char> data; for (size_t i = 0; i < currentText.size(); ++i) { char c = currentText[i]; - if (c >= 48 && c <= 122) { + if ((c >= 48 && c <= 122) || c == 47 || c == 43) { data.push_back(c); } } diff --git a/Swiften/Parser/PayloadParsers/IBBParser.h b/Swiften/Parser/PayloadParsers/IBBParser.h index 132e79d..d899475 100644 --- a/Swiften/Parser/PayloadParsers/IBBParser.h +++ b/Swiften/Parser/PayloadParsers/IBBParser.h @@ -8,8 +8,8 @@ #include <boost/optional.hpp> -#include "Swiften/Elements/IBB.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/IBB.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class IBBParser : public GenericPayloadParser<IBB> { diff --git a/Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParser.cpp b/Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParser.cpp index 56995d8..06759cb 100644 --- a/Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParser.cpp +++ b/Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParser.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParser.h" +#include <Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParser.h> #include <boost/cast.hpp> -#include "Swiften/Parser/PayloadParsers/FormParserFactory.h" -#include "Swiften/Parser/PayloadParsers/FormParser.h" +#include <Swiften/Parser/PayloadParsers/FormParserFactory.h> +#include <Swiften/Parser/PayloadParsers/FormParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParser.h b/Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParser.h index c0209c4..ae8d36c 100644 --- a/Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParser.h +++ b/Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParser.h @@ -8,8 +8,8 @@ #include <boost/optional.hpp> -#include "Swiften/Elements/InBandRegistrationPayload.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/InBandRegistrationPayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class FormParserFactory; diff --git a/Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParserFactory.h b/Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParserFactory.h deleted file mode 100644 index 0417174..0000000 --- a/Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParserFactory.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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/Parser/GenericPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParser.h" - -namespace Swift { - class InBandRegistrationPayloadParserFactory : public GenericPayloadParserFactory<InBandRegistrationPayloadParser> { - public: - InBandRegistrationPayloadParserFactory() : GenericPayloadParserFactory<InBandRegistrationPayloadParser>("query", "jabber:iq:register") {} - }; -} diff --git a/Swiften/Parser/PayloadParsers/JingleContentPayloadParser.cpp b/Swiften/Parser/PayloadParsers/JingleContentPayloadParser.cpp new file mode 100644 index 0000000..1431b9e --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleContentPayloadParser.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "JingleContentPayloadParser.h" +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Elements/JinglePayload.h> + +#include <Swiften/Base/Log.h> + +namespace Swift { + JingleContentPayloadParser::JingleContentPayloadParser(PayloadParserFactoryCollection* factories) : factories(factories), level(0) { + + } + + void JingleContentPayloadParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { + if (level == 0) { + std::string creator = attributes.getAttributeValue("creator").get_value_or(""); + if (creator == "initiator") { + getPayloadInternal()->setCreator(JingleContentPayload::InitiatorCreator); + } else if (creator == "responder") { + getPayloadInternal()->setCreator(JingleContentPayload::ResponderCreator); + } else { + getPayloadInternal()->setCreator(JingleContentPayload::UnknownCreator); + } + + getPayloadInternal()->setName(attributes.getAttributeValue("name").get_value_or("")); + } + + if (level == 1) { + PayloadParserFactory* payloadParserFactory = factories->getPayloadParserFactory(element, ns, attributes); + if (payloadParserFactory) { + currentPayloadParser.reset(payloadParserFactory->createPayloadParser()); + } + } + + if (level >= 1 && currentPayloadParser) { + currentPayloadParser->handleStartElement(element, ns, attributes); + } + + ++level; + } + + void JingleContentPayloadParser::handleEndElement(const std::string& element, const std::string& ns) { + --level; + + if (currentPayloadParser) { + if (level >= 1) { + currentPayloadParser->handleEndElement(element, ns); + } + + if (level == 1) { + boost::shared_ptr<JingleTransportPayload> transport = boost::dynamic_pointer_cast<JingleTransportPayload>(currentPayloadParser->getPayload()); + if (transport) { + getPayloadInternal()->addTransport(transport); + } + + boost::shared_ptr<JingleDescription> description = boost::dynamic_pointer_cast<JingleDescription>(currentPayloadParser->getPayload()); + if (description) { + getPayloadInternal()->addDescription(description); + } + } + } + } + + void JingleContentPayloadParser::handleCharacterData(const std::string& data) { + if (level > 1 && currentPayloadParser) { + currentPayloadParser->handleCharacterData(data); + } + } +} diff --git a/Swiften/Parser/PayloadParsers/JingleContentPayloadParser.h b/Swiften/Parser/PayloadParsers/JingleContentPayloadParser.h new file mode 100644 index 0000000..a871cc4 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleContentPayloadParser.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/JingleContentPayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + +class PayloadParserFactoryCollection; + +class JingleContentPayloadParser : public GenericPayloadParser<JingleContentPayload> { + public: + JingleContentPayloadParser(PayloadParserFactoryCollection* factories); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + + private: + PayloadParserFactoryCollection* factories; + int level; + boost::shared_ptr<PayloadParser> currentPayloadParser; +}; + +} diff --git a/Swiften/Parser/PayloadParsers/JingleContentPayloadParserFactory.h b/Swiften/Parser/PayloadParsers/JingleContentPayloadParserFactory.h new file mode 100644 index 0000000..6d66e74 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleContentPayloadParserFactory.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Parser/GenericPayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/JingleContentPayloadParser.h> + +namespace Swift { + + class PayloadParserFactoryCollection; + + class JingleContentPayloadParserFactory : public PayloadParserFactory { + public: + JingleContentPayloadParserFactory(PayloadParserFactoryCollection* factories) : factories(factories) { + } + + virtual bool canParse(const std::string& element, const std::string& ns, const AttributeMap&) const { + return element == "content" && ns == "urn:xmpp:jingle:1"; + } + + virtual PayloadParser* createPayloadParser() { + return new JingleContentPayloadParser(factories); + } + + private: + PayloadParserFactoryCollection* factories; + + }; +} + + diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.cpp b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.cpp new file mode 100644 index 0000000..b394115 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "JingleFileTransferDescriptionParser.h" + +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Base/Log.h> + +namespace Swift { + +JingleFileTransferDescriptionParser::JingleFileTransferDescriptionParser(PayloadParserFactoryCollection* factories) : factories(factories), level(0), + currentElement(UnknownElement) { + +} + +void JingleFileTransferDescriptionParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { + if (level == 0) { + + } + + if (level == 1) { + if (element == "offer") { + currentElement = OfferElement; + } else if (element == "request") { + currentElement = RequestElement; + } else { + currentElement = UnknownElement; + } + } + + if (level == 2) { + PayloadParserFactory* payloadParserFactory = factories->getPayloadParserFactory(element, ns, attributes); + if (payloadParserFactory) { + currentPayloadParser.reset(payloadParserFactory->createPayloadParser()); + } + } + + if (level >= 2 && currentPayloadParser) { + currentPayloadParser->handleStartElement(element, ns, attributes); + } + + ++level; +} + +void JingleFileTransferDescriptionParser::handleEndElement(const std::string& element, const std::string& ns) { + --level; + if (currentPayloadParser) { + if (level >= 2) { + currentPayloadParser->handleEndElement(element, ns); + } + + if (level == 2) { + boost::shared_ptr<StreamInitiationFileInfo> info = boost::dynamic_pointer_cast<StreamInitiationFileInfo>(currentPayloadParser->getPayload()); + if (info) { + if (currentElement == OfferElement) { + getPayloadInternal()->addOffer(*info); + } else if (currentElement == RequestElement) { + getPayloadInternal()->addRequest(*info); + } + } + } + } +} + +void JingleFileTransferDescriptionParser::handleCharacterData(const std::string& data) { + if (level >= 2 && currentPayloadParser) { + currentPayloadParser->handleCharacterData(data); + } +} + +} diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.h b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.h new file mode 100644 index 0000000..93560c6 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/JingleFileTransferDescription.h> +#include <Swiften/Parser/GenericPayloadParser.h> +#include <Swiften/Parser/PayloadParser.h> + +namespace Swift { + +class PayloadParserFactoryCollection; + +class JingleFileTransferDescriptionParser : public GenericPayloadParser<JingleFileTransferDescription> { + public: + JingleFileTransferDescriptionParser(PayloadParserFactoryCollection* factories); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + + private: + enum CurrentParseElement { + UnknownElement, + RequestElement, + OfferElement, + }; + + PayloadParserFactoryCollection* factories; + int level; + CurrentParseElement currentElement; + boost::shared_ptr<PayloadParser> currentPayloadParser; +}; + +} diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParserFactory.h b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParserFactory.h new file mode 100644 index 0000000..b997c1d --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParserFactory.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Parser/GenericPayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.h> + +namespace Swift { + + class PayloadParserFactoryCollection; + + class JingleFileTransferDescriptionParserFactory : public PayloadParserFactory { + public: + JingleFileTransferDescriptionParserFactory(PayloadParserFactoryCollection* factories) : factories(factories) { + } + + virtual bool canParse(const std::string& element, const std::string& ns, const AttributeMap&) const { + return element == "description" && ns == "urn:xmpp:jingle:apps:file-transfer:3"; + } + + virtual PayloadParser* createPayloadParser() { + return new JingleFileTransferDescriptionParser(factories); + } + + private: + PayloadParserFactoryCollection* factories; + + }; +} + + diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.cpp b/Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.cpp new file mode 100644 index 0000000..87f8317 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "JingleFileTransferHashParser.h" + +#include <boost/shared_ptr.hpp> +#include <boost/algorithm/string.hpp> + +#include <Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h> +#include <Swiften/Parser/GenericPayloadParserFactory.h> +#include <Swiften/Parser/PayloadParserFactory.h> + +namespace Swift { + +JingleFileTransferHashParser::JingleFileTransferHashParser() { +} + +void JingleFileTransferHashParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) { + if (element == "hash") { + algo = attributes.getAttribute("algo"); + } +} + +void JingleFileTransferHashParser::handleEndElement(const std::string& element, const std::string& ) { + if (element == "hash" && !algo.empty() && !hash.empty()) { + getPayloadInternal()->setHash(algo, hash); + algo.clear(); + hash.clear(); + } +} + +void JingleFileTransferHashParser::handleCharacterData(const std::string& data) { + if (!algo.empty()) { + std::string new_data(data); + boost::trim(new_data); + hash += new_data; + } +} + +} diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.h b/Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.h new file mode 100644 index 0000000..35e4a05 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/JingleFileTransferHash.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + +class JingleFileTransferHashParser : public GenericPayloadParser<JingleFileTransferHash> { +public: + JingleFileTransferHashParser(); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + +private: + std::string algo; + std::string hash; +}; + +} diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.cpp b/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.cpp new file mode 100644 index 0000000..20ad73e --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "JingleFileTransferReceivedParser.h" +#include "StreamInitiationFileInfoParser.h" + +#include <boost/shared_ptr.hpp> +#include <Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h> +#include <Swiften/Parser/GenericPayloadParserFactory.h> +#include <Swiften/Parser/PayloadParserFactory.h> + +namespace Swift { + +JingleFileTransferReceivedParser::JingleFileTransferReceivedParser() : level(0) { +} + +void JingleFileTransferReceivedParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { + if (level == 1 && element == "file") { + PayloadParserFactory* payloadParserFactory = new GenericPayloadParserFactory<StreamInitiationFileInfoParser>("file", "http://jabber.org/protocol/si/profile/file-transfer"); + if (payloadParserFactory) { + currentPayloadParser.reset(payloadParserFactory->createPayloadParser()); + } + } + + if (currentPayloadParser && level >= 1) { + currentPayloadParser->handleStartElement(element, ns, attributes); + } + + ++level; +} + +void JingleFileTransferReceivedParser::handleEndElement(const std::string& element, const std::string& ) { + --level; + if (element == "file") { + boost::shared_ptr<StreamInitiationFileInfo> fileInfo = boost::dynamic_pointer_cast<StreamInitiationFileInfo>(currentPayloadParser->getPayload()); + if (fileInfo) { + getPayloadInternal()->setFileInfo(*fileInfo); + } + } +} + +void JingleFileTransferReceivedParser::handleCharacterData(const std::string& ) { + +} + +} diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h b/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h new file mode 100644 index 0000000..824b06d --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/JingleFileTransferReceived.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + +class JingleFileTransferReceivedParser : public GenericPayloadParser<JingleFileTransferReceived> { +public: + JingleFileTransferReceivedParser(); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + +private: + boost::shared_ptr<PayloadParser> currentPayloadParser; + int level; +}; + +}
\ No newline at end of file diff --git a/Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.cpp b/Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.cpp new file mode 100644 index 0000000..a3dfd12 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <boost/lexical_cast.hpp> +#include <boost/optional.hpp> + +#include "JingleIBBTransportMethodPayloadParser.h" + +#include <Swiften/Base/Log.h> + +namespace Swift { + JingleIBBTransportMethodPayloadParser::JingleIBBTransportMethodPayloadParser() : level(0) { + + } + + void JingleIBBTransportMethodPayloadParser::handleStartElement(const std::string&, const std::string&, const AttributeMap& attributes) { + try { + getPayloadInternal()->setBlockSize(boost::lexical_cast<int>(attributes.getAttributeValue("block-size").get_value_or("0"))); + } catch (boost::bad_lexical_cast &) { + getPayloadInternal()->setBlockSize(0); + } + getPayloadInternal()->setSessionID(attributes.getAttributeValue("sid").get_value_or("")); + ++level; + } + + void JingleIBBTransportMethodPayloadParser::handleEndElement(const std::string&, const std::string&) { + --level; + + + } + + void JingleIBBTransportMethodPayloadParser::handleCharacterData(const std::string&) { + + } +} diff --git a/Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.h b/Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.h new file mode 100644 index 0000000..311cc5b --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + +class JingleIBBTransportMethodPayloadParser : public GenericPayloadParser<JingleIBBTransportPayload> { + public: + JingleIBBTransportMethodPayloadParser(); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + + private: + int level; +}; + +} diff --git a/Swiften/Parser/PayloadParsers/JingleParser.cpp b/Swiften/Parser/PayloadParsers/JingleParser.cpp new file mode 100644 index 0000000..dd34458 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleParser.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Parser/PayloadParsers/JingleParser.h> +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Elements/JingleContentPayload.h> +#include <Swiften/Elements/JingleFileTransferReceived.h> +#include <Swiften/Elements/JingleFileTransferHash.h> +#include <Swiften/Base/Log.h> + +#include <boost/intrusive_ptr.hpp> + +namespace Swift { + + JingleParser::JingleParser(PayloadParserFactoryCollection* factories) : factories(factories), level(0) { + + } + + void JingleParser::handleStartElement(const std::string& element, const std::string &ns, const AttributeMap& attributes) { + if (level == 0) { + // <jingle > tag + JinglePayload::ref payload = getPayloadInternal(); + payload->setAction(stringToAction(attributes.getAttributeValue("action").get_value_or(""))); + payload->setInitiator(JID(attributes.getAttributeValue("initiator").get_value_or(""))); + payload->setResponder(JID(attributes.getAttributeValue("responder").get_value_or(""))); + payload->setSessionID(attributes.getAttributeValue("sid").get_value_or("")); + } + + if (level == 1) { + PayloadParserFactory* payloadParserFactory = factories->getPayloadParserFactory(element, ns, attributes); + if (payloadParserFactory) { + currentPayloadParser.reset(payloadParserFactory->createPayloadParser()); + } + } + + if (level >= 1 && currentPayloadParser) { + currentPayloadParser->handleStartElement(element, ns, attributes); + } + + ++level; + } + + void JingleParser::handleEndElement(const std::string& element, const std::string &ns) { + --level; + if (currentPayloadParser) { + if (level >= 1) { + currentPayloadParser->handleEndElement(element, ns); + } + + if (level == 1) { + boost::shared_ptr<JinglePayload::Reason> reason = boost::dynamic_pointer_cast<JinglePayload::Reason>(currentPayloadParser->getPayload()); + if (reason) { + getPayloadInternal()->setReason(*reason); + } + + boost::shared_ptr<JingleContentPayload> payload = boost::dynamic_pointer_cast<JingleContentPayload>(currentPayloadParser->getPayload()); + if (payload) { + getPayloadInternal()->addContent(payload); + } + + boost::shared_ptr<JingleFileTransferReceived> received = boost::dynamic_pointer_cast<JingleFileTransferReceived>(currentPayloadParser->getPayload()); + if (received) { + getPayloadInternal()->addPayload(received); + } + + boost::shared_ptr<JingleFileTransferHash> hash = boost::dynamic_pointer_cast<JingleFileTransferHash>(currentPayloadParser->getPayload()); + if (hash) { + getPayloadInternal()->addPayload(hash); + } + } + } + } + + void JingleParser::handleCharacterData(const std::string& data) { + if (level > 1 && currentPayloadParser) { + currentPayloadParser->handleCharacterData(data); + } + } + + JinglePayload::Action JingleParser::stringToAction(const std::string &str) const { + if (str == "content-accept") { + return JinglePayload::ContentAccept; + } else if (str == "content-add") { + return JinglePayload::ContentAdd; + } else if (str == "content-modify") { + return JinglePayload::ContentModify; + } else if (str == "content-reject") { + return JinglePayload::ContentReject; + } else if (str == "content-remove") { + return JinglePayload::ContentRemove; + } else if (str == "description-info") { + return JinglePayload::DescriptionInfo; + } else if (str == "security-info") { + return JinglePayload::SecurityInfo; + } else if (str == "session-accept") { + return JinglePayload::SessionAccept; + } else if (str == "session-info") { + return JinglePayload::SessionInfo; + } else if (str == "session-initiate") { + return JinglePayload::SessionInitiate; + } else if (str == "session-terminate") { + return JinglePayload::SessionTerminate; + } else if (str == "transport-accept") { + return JinglePayload::TransportAccept; + } else if (str == "transport-info") { + return JinglePayload::TransportInfo; + } else if (str == "transport-reject") { + return JinglePayload::TransportReject; + } else if (str == "transport-replace") { + return JinglePayload::TransportReplace; + } else { + return JinglePayload::UnknownAction; + } + + } +} diff --git a/Swiften/Parser/PayloadParsers/JingleParser.h b/Swiften/Parser/PayloadParsers/JingleParser.h new file mode 100644 index 0000000..ecaca3c --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleParser.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/JinglePayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> +#include <Swiften/Parser/PayloadParserFactoryCollection.h> + +namespace Swift { + +class JingleParser : public GenericPayloadParser<JinglePayload> { + public: + JingleParser(PayloadParserFactoryCollection* factories); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + + private: + JinglePayload::Action stringToAction(const std::string &str) const; + + private: + PayloadParserFactoryCollection* factories; + int level; + boost::shared_ptr<PayloadParser> currentPayloadParser; +}; + +};
\ No newline at end of file diff --git a/Swiften/Parser/PayloadParsers/JingleParserFactory.h b/Swiften/Parser/PayloadParsers/JingleParserFactory.h new file mode 100644 index 0000000..fa25aeb --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleParserFactory.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Parser/GenericPayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/JingleParser.h> + +namespace Swift { + + class PayloadParserFactoryCollection; + + class JingleParserFactory : public PayloadParserFactory { + public: + JingleParserFactory(PayloadParserFactoryCollection* factories) : factories(factories) { + } + + virtual bool canParse(const std::string& element, const std::string& ns, const AttributeMap&) const { + return element == "jingle" && ns == "urn:xmpp:jingle:1"; + } + + virtual PayloadParser* createPayloadParser() { + return new JingleParser(factories); + } + + private: + PayloadParserFactoryCollection* factories; + + }; +} + + diff --git a/Swiften/Parser/PayloadParsers/JingleReasonParser.cpp b/Swiften/Parser/PayloadParsers/JingleReasonParser.cpp new file mode 100644 index 0000000..3df82ae --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleReasonParser.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "JingleReasonParser.h" + +#include <Swiften/Base/Log.h> + +namespace Swift { + JingleReasonParser::JingleReasonParser() : level(0), parseText(false) { + + } + + void JingleReasonParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap&) { + if (level == 1) { + if (element == "text") { + parseText = true; + } else { + // reason type + getPayloadInternal()->type = stringToReasonType(element); + } + } + ++level; + } + + void JingleReasonParser::handleEndElement(const std::string& element, const std::string&) { + --level; + if (element == "text") { + parseText = false; + getPayloadInternal()->text = text; + } + } + + void JingleReasonParser::handleCharacterData(const std::string& data) { + if (parseText) { + text += data; + } + } + + JinglePayload::Reason::Type JingleReasonParser::stringToReasonType(const std::string& type) const { + if (type == "alternative-session") { + return JinglePayload::Reason::AlternativeSession; + } else if (type == "busy") { + return JinglePayload::Reason::Busy; + } else if (type == "cancel") { + return JinglePayload::Reason::Cancel; + } else if (type == "connectivity-error") { + return JinglePayload::Reason::ConnectivityError; + } else if (type == "decline") { + return JinglePayload::Reason::Decline; + } else if (type == "expired") { + return JinglePayload::Reason::Expired; + } else if (type == "failed-application") { + return JinglePayload::Reason::FailedApplication; + } else if (type == "failed-transport") { + return JinglePayload::Reason::FailedTransport; + } else if (type == "general-error") { + return JinglePayload::Reason::GeneralError; + } else if (type == "gone") { + return JinglePayload::Reason::Gone; + } else if (type == "incompatible-parameters") { + return JinglePayload::Reason::IncompatibleParameters; + } else if (type == "media-error") { + return JinglePayload::Reason::MediaError; + } else if (type == "security-error") { + return JinglePayload::Reason::SecurityError; + } else if (type == "success") { + return JinglePayload::Reason::Success; + } else if (type == "timeout") { + return JinglePayload::Reason::Timeout; + } else if (type == "unsupported-applications") { + return JinglePayload::Reason::UnsupportedApplications; + } else if (type == "unsupported-transports") { + return JinglePayload::Reason::UnsupportedTransports; + } else { + return JinglePayload::Reason::UnknownType; + } + } +} diff --git a/Swiften/Parser/PayloadParsers/JingleReasonParser.h b/Swiften/Parser/PayloadParsers/JingleReasonParser.h new file mode 100644 index 0000000..08af31a --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleReasonParser.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/JinglePayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + +class JingleReasonParser : public GenericPayloadParser<JinglePayload::Reason> { + public: + JingleReasonParser(); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + private: + JinglePayload::Reason::Type stringToReasonType(const std::string& type) const; + + private: + int level; + bool parseText; + std::string text; +}; + +} diff --git a/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp b/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp new file mode 100644 index 0000000..14a80e6 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <boost/lexical_cast.hpp> +#include <boost/optional.hpp> + +#include "JingleS5BTransportMethodPayloadParser.h" + +#include <Swiften/Base/Log.h> + +namespace Swift { + JingleS5BTransportMethodPayloadParser::JingleS5BTransportMethodPayloadParser() : level(0) { + + } + + void JingleS5BTransportMethodPayloadParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) { + if (level == 0) { + getPayloadInternal()->setSessionID(attributes.getAttributeValue("sid").get_value_or("")); + std::string mode = attributes.getAttributeValue("mode").get_value_or("tcp"); + if (mode == "tcp") { + getPayloadInternal()->setMode(JingleS5BTransportPayload::TCPMode); + } else if(mode == "udp") { + getPayloadInternal()->setMode(JingleS5BTransportPayload::UDPMode); + } else { + std::cerr << "Unknown S5B mode; falling back to defaul!" << std::endl; + getPayloadInternal()->setMode(JingleS5BTransportPayload::TCPMode); + } + } else if (level == 1) { + if (element == "candidate") { + JingleS5BTransportPayload::Candidate candidate; + candidate.cid = attributes.getAttributeValue("cid").get_value_or(""); + + int port = -1; + try { + port = boost::lexical_cast<int>(attributes.getAttributeValue("port").get_value_or("-1")); + } catch(boost::bad_lexical_cast &) { } + candidate.hostPort = HostAddressPort(HostAddress(attributes.getAttributeValue("host").get_value_or("")), port); + candidate.jid = JID(attributes.getAttributeValue("jid").get_value_or("")); + int priority = -1; + try { + priority = boost::lexical_cast<int>(attributes.getAttributeValue("priority").get_value_or("-1")); + } catch(boost::bad_lexical_cast &) { } + candidate.priority = priority; + candidate.type = stringToType(attributes.getAttributeValue("type").get_value_or("direct")); + + getPayloadInternal()->addCandidate(candidate); + } else if (element == "candidate-used") { + getPayloadInternal()->setCandidateUsed(attributes.getAttributeValue("cid").get_value_or("")); + } else if (element == "candidate-error") { + getPayloadInternal()->setCandidateError(true); + } else if (element == "activated") { + getPayloadInternal()->setActivated(attributes.getAttributeValue("cid").get_value_or("")); + } else if (element == "proxy-error") { + getPayloadInternal()->setProxyError(true); + } + } + + ++level; + } + + void JingleS5BTransportMethodPayloadParser::handleEndElement(const std::string&, const std::string&) { + --level; + + + } + + void JingleS5BTransportMethodPayloadParser::handleCharacterData(const std::string&) { + + } + + JingleS5BTransportPayload::Candidate::Type JingleS5BTransportMethodPayloadParser::stringToType(const std::string &str) const { + if (str == "direct") { + return JingleS5BTransportPayload::Candidate::DirectType; + } else if (str == "assisted") { + return JingleS5BTransportPayload::Candidate::AssistedType; + } else if (str == "tunnel") { + return JingleS5BTransportPayload::Candidate::TunnelType; + } else if (str == "proxy") { + return JingleS5BTransportPayload::Candidate::ProxyType; + } else { + std::cerr << "Unknown candidate type; falling back to default!" << std::endl; + return JingleS5BTransportPayload::Candidate::DirectType; + } + } +} diff --git a/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.h b/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.h new file mode 100644 index 0000000..1987d3f --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + +class JingleS5BTransportMethodPayloadParser : public GenericPayloadParser<JingleS5BTransportPayload> { + public: + JingleS5BTransportMethodPayloadParser(); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + + private: + JingleS5BTransportPayload::Candidate::Type stringToType(const std::string &str) const; + + private: + int level; +}; + +} diff --git a/Swiften/Parser/PayloadParsers/LastParser.cpp b/Swiften/Parser/PayloadParsers/LastParser.cpp new file mode 100644 index 0000000..77ebba8 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/LastParser.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Parser/PayloadParsers/LastParser.h> + +#include <boost/lexical_cast.hpp> + +namespace Swift { + +LastParser::LastParser() : level_(0) { +} + +void LastParser::handleStartElement(const std::string&, const std::string&, const AttributeMap& attributes) { + if (level_ == 0) { + int seconds = 0; + try { + seconds = boost::lexical_cast<int>(attributes.getAttribute("seconds")); + } + catch (boost::bad_lexical_cast&) { + } + getPayloadInternal()->setSeconds(seconds); + } + ++level_; + +} + +void LastParser::handleEndElement(const std::string&, const std::string&) { +} + +void LastParser::handleCharacterData(const std::string&) { +} + +} diff --git a/Swiften/Parser/PayloadParsers/LastParser.h b/Swiften/Parser/PayloadParsers/LastParser.h new file mode 100644 index 0000000..7c5c707 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/LastParser.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/Last.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + class LastParser : public GenericPayloadParser<Last> { + public: + LastParser(); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + + private: + int level_; + }; +} diff --git a/Swiften/Parser/PayloadParsers/MUCAdminPayloadParser.cpp b/Swiften/Parser/PayloadParsers/MUCAdminPayloadParser.cpp new file mode 100644 index 0000000..137ead4 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/MUCAdminPayloadParser.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Parser/PayloadParsers/MUCAdminPayloadParser.h> + +#include <boost/lexical_cast.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Elements/MUCOccupant.h> + +namespace Swift { + +void MUCAdminPayloadParser::handleTree(ParserElement::ref root) { + foreach (ParserElement::ref itemElement, root->getChildren("item", "http://jabber.org/protocol/muc#admin")) { + MUCItem item = MUCItemParser::itemFromTree(itemElement); + getPayloadInternal()->addItem(item); + } +} + +} diff --git a/Swiften/Parser/PayloadParsers/MUCAdminPayloadParser.h b/Swiften/Parser/PayloadParsers/MUCAdminPayloadParser.h new file mode 100644 index 0000000..dfa26da --- /dev/null +++ b/Swiften/Parser/PayloadParsers/MUCAdminPayloadParser.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/optional.hpp> + +#include <Swiften/Elements/MUCAdminPayload.h> +#include <Swiften/Parser/GenericPayloadTreeParser.h> +#include <Swiften/Parser/PayloadParsers/MUCItemParser.h> + +namespace Swift { + class MUCAdminPayloadParser : public GenericPayloadTreeParser<MUCAdminPayload> { + public: + virtual void handleTree(ParserElement::ref root); + }; +} diff --git a/Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.cpp b/Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.cpp new file mode 100644 index 0000000..a8d29d0 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.h> + +#include <Swiften/Base/foreach.h> + +namespace Swift { + +void MUCDestroyPayloadParser::handleTree(ParserElement::ref root) { + std::string ns = root->getNamespace(); + std::string jid = root->getAttributes().getAttribute("jid"); + if (!jid.empty()) { + getPayloadInternal()->setNewVenue(JID(jid)); + } + getPayloadInternal()->setReason(root->getChild("reason", ns)->getText()); +} + +} diff --git a/Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.h b/Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.h new file mode 100644 index 0000000..714651f --- /dev/null +++ b/Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/optional.hpp> + +#include <Swiften/Elements/MUCDestroyPayload.h> +#include <Swiften/Parser/GenericPayloadTreeParser.h> + +namespace Swift { + class MUCDestroyPayloadParser : public GenericPayloadTreeParser<MUCDestroyPayload> { + public: + virtual void handleTree(ParserElement::ref root); + }; +} diff --git a/Swiften/Parser/PayloadParsers/MUCItemParser.cpp b/Swiften/Parser/PayloadParsers/MUCItemParser.cpp new file mode 100644 index 0000000..2eb9997 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/MUCItemParser.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Parser/PayloadParsers/MUCItemParser.h> + +#include <boost/lexical_cast.hpp> + +#include <Swiften/Elements/MUCOccupant.h> + +#include <cassert> +#include <iostream> + +namespace Swift { + +MUCItem MUCItemParser::itemFromTree(ParserElement::ref root) { + MUCItem item; + std::string affiliation = root->getAttributes().getAttribute("affiliation"); + std::string role = root->getAttributes().getAttribute("role"); + std::string nick = root->getAttributes().getAttribute("nick"); + std::string jid = root->getAttributes().getAttribute("jid"); + item.affiliation = parseAffiliation(affiliation); + item.role = parseRole(role); + if (!jid.empty()) { + item.realJID = JID(jid); + } + if (!nick.empty()) { + item.nick = nick; + } + std::string xmlns = root->getNamespace(); + std::string reason = root->getChild("reason", xmlns)->getText(); + std::string actor = root->getChild("actor", xmlns)->getAttributes().getAttribute("jid"); + if (!reason.empty()) { + item.reason = reason; + } + if (!actor.empty()) { + item.actor = JID(actor); + } + + return item; +} + +boost::optional<MUCOccupant::Role> MUCItemParser::parseRole(const std::string& roleString) { + if (roleString == "moderator") { + return MUCOccupant::Moderator; + } + if (roleString == "participant") { + return MUCOccupant::Participant; + } + if (roleString == "visitor") { + return MUCOccupant::Visitor; + } + if (roleString == "none") { + return MUCOccupant::NoRole; + } + return boost::optional<MUCOccupant::Role>(); +} + +boost::optional<MUCOccupant::Affiliation> MUCItemParser::parseAffiliation(const std::string& affiliationString) { + if (affiliationString == "owner") { + return MUCOccupant::Owner; + } + if (affiliationString == "admin") { + return MUCOccupant::Admin; + } + if (affiliationString == "member") { + return MUCOccupant::Member; + } + if (affiliationString == "outcast") { + return MUCOccupant::Outcast; + } + if (affiliationString == "none") { + return MUCOccupant::NoAffiliation; + } + return boost::optional<MUCOccupant::Affiliation>(); +} + +} + + diff --git a/Swiften/Parser/PayloadParsers/MUCItemParser.h b/Swiften/Parser/PayloadParsers/MUCItemParser.h new file mode 100644 index 0000000..a0ea060 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/MUCItemParser.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/MUCItem.h> +#include <Swiften/Parser/GenericPayloadTreeParser.h> + +namespace Swift { + class MUCItemParser { + public: + static MUCItem itemFromTree(ParserElement::ref root); + private: + static boost::optional<MUCOccupant::Role> parseRole(const std::string& itemString); + static boost::optional<MUCOccupant::Affiliation> parseAffiliation(const std::string& statusString); + }; +} diff --git a/Swiften/Parser/PayloadParsers/MUCOwnerPayloadParser.cpp b/Swiften/Parser/PayloadParsers/MUCOwnerPayloadParser.cpp new file mode 100644 index 0000000..d7ae789 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/MUCOwnerPayloadParser.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Parser/PayloadParsers/MUCOwnerPayloadParser.h> +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/PayloadParserFactory.h> + +namespace Swift { + +MUCOwnerPayloadParser::MUCOwnerPayloadParser(PayloadParserFactoryCollection* factories) : factories(factories), level(0) { +} + +void MUCOwnerPayloadParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { + if (level == 1) { + PayloadParserFactory* payloadParserFactory = factories->getPayloadParserFactory(element, ns, attributes); + if (payloadParserFactory) { + currentPayloadParser.reset(payloadParserFactory->createPayloadParser()); + } + } + + if (level >= 1 && currentPayloadParser) { + currentPayloadParser->handleStartElement(element, ns, attributes); + } + ++level; +} + +void MUCOwnerPayloadParser::handleEndElement(const std::string& element, const std::string& ns) { + --level; + if (currentPayloadParser) { + if (level >= 1) { + currentPayloadParser->handleEndElement(element, ns); + } + + if (level == 1) { + getPayloadInternal()->setPayload(currentPayloadParser->getPayload()); + } + } +} + +void MUCOwnerPayloadParser::handleCharacterData(const std::string& data) { + if (level > 1 && currentPayloadParser) { + currentPayloadParser->handleCharacterData(data); + } +} + +} diff --git a/Swiften/Parser/PayloadParsers/MUCOwnerPayloadParser.h b/Swiften/Parser/PayloadParsers/MUCOwnerPayloadParser.h new file mode 100644 index 0000000..2761981 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/MUCOwnerPayloadParser.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/optional.hpp> + +#include <Swiften/Elements/MUCOwnerPayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + class PayloadParserFactoryCollection; + + class MUCOwnerPayloadParser : public GenericPayloadParser<MUCOwnerPayload> { + public: + MUCOwnerPayloadParser(PayloadParserFactoryCollection* factories); + + private: + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + + private: + PayloadParserFactoryCollection* factories; + int level; + boost::shared_ptr<PayloadParser> currentPayloadParser; + }; +} diff --git a/Swiften/Parser/PayloadParsers/MUCOwnerPayloadParserFactory.h b/Swiften/Parser/PayloadParsers/MUCOwnerPayloadParserFactory.h new file mode 100644 index 0000000..918c72c --- /dev/null +++ b/Swiften/Parser/PayloadParsers/MUCOwnerPayloadParserFactory.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/MUCOwnerPayloadParser.h> + +namespace Swift { + class PayloadParserFactoryCollection; + + class MUCOwnerPayloadParserFactory : public PayloadParserFactory { + public: + MUCOwnerPayloadParserFactory(PayloadParserFactoryCollection* factories) : factories(factories) { + } + + virtual bool canParse(const std::string& element, const std::string& ns, const AttributeMap&) const { + return element == "query" && ns == "http://jabber.org/protocol/muc#owner"; + } + + virtual PayloadParser* createPayloadParser() { + return new MUCOwnerPayloadParser(factories); + } + + private: + PayloadParserFactoryCollection* factories; + + }; +} diff --git a/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.cpp b/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.cpp index ec9e200..2da8b35 100644 --- a/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.cpp +++ b/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.cpp @@ -4,91 +4,36 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h" +#include <Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h> #include <boost/lexical_cast.hpp> -#include "Swiften/Elements/MUCOccupant.h" - -#include <cassert> -#include <iostream> +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Elements/MUCOccupant.h> +#include <Swiften/Parser/Tree/TreeReparser.h> namespace Swift { -MUCUserPayloadParser::MUCUserPayloadParser() : level(TopLevel) { -} - -void MUCUserPayloadParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) { - if (level == ItemLevel) { - if (element == "item") { - MUCUserPayload::Item item; - std::string affiliation = attributes.getAttribute("affiliation"); - std::string role = attributes.getAttribute("role"); - std::string nick = attributes.getAttribute("nick"); - std::string jid = attributes.getAttribute("jid"); - item.affiliation = parseAffiliation(affiliation); - item.role = parseRole(role); - if (!jid.empty()) { - item.realJID = JID(jid); - } - if (!nick.empty()) { - item.nick = nick; - } +void MUCUserPayloadParser::handleTree(ParserElement::ref root) { + foreach (ParserElement::ref child, root->getAllChildren()) { + if (child->getName() == "item" && child->getNamespace() == root->getNamespace()) { + MUCItem item = MUCItemParser::itemFromTree(child); getPayloadInternal()->addItem(item); - } else if (element == "status") { + } + else if (child->getName() == "status" && child->getNamespace() == root->getNamespace()) { MUCUserPayload::StatusCode status; try { - status.code = boost::lexical_cast<int>(attributes.getAttribute("code").c_str()); + status.code = boost::lexical_cast<int>(child->getAttributes().getAttribute("code").c_str()); getPayloadInternal()->addStatusCode(status); } catch (boost::bad_lexical_cast&) { } } + else { + getPayloadInternal()->setPayload(TreeReparser::parseTree(child, factories)); + } } - ++level; -} - -MUCOccupant::Role MUCUserPayloadParser::parseRole(const std::string& roleString) const { - if (roleString == "moderator") { - return MUCOccupant::Moderator; - } - if (roleString == "participant") { - return MUCOccupant::Participant; - } - if (roleString == "visitor") { - return MUCOccupant::Visitor; - } - if (roleString == "none") { - return MUCOccupant::NoRole; - } - return MUCOccupant::NoRole; -} - -MUCOccupant::Affiliation MUCUserPayloadParser::parseAffiliation(const std::string& affiliationString) const { - if (affiliationString == "owner") { - return MUCOccupant::Owner; - } - if (affiliationString == "admin") { - return MUCOccupant::Admin; - } - if (affiliationString == "member") { - return MUCOccupant::Member; - } - if (affiliationString == "outcast") { - return MUCOccupant::Outcast; - } - if (affiliationString == "none") { - return MUCOccupant::NoAffiliation; - } - return MUCOccupant::NoAffiliation; -} - - -void MUCUserPayloadParser::handleEndElement(const std::string& /*element*/, const std::string&) { - --level; -} - -void MUCUserPayloadParser::handleCharacterData(const std::string& /*data*/) { - } } diff --git a/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h b/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h index 384f0cd..66e63a8 100644 --- a/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h +++ b/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h @@ -8,24 +8,17 @@ #include <boost/optional.hpp> -#include "Swiften/Elements/MUCUserPayload.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/MUCUserPayload.h> +#include <Swiften/Parser/GenericPayloadTreeParser.h> +#include <Swiften/Parser/PayloadParsers/MUCItemParser.h> namespace Swift { - class MUCUserPayloadParser : public GenericPayloadParser<MUCUserPayload> { + class PayloadParserFactoryCollection; + class MUCUserPayloadParser : public GenericPayloadTreeParser<MUCUserPayload> { public: - MUCUserPayloadParser(); - - virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); - virtual void handleEndElement(const std::string& element, const std::string&); - virtual void handleCharacterData(const std::string& data); - MUCOccupant::Role parseRole(const std::string& itemString) const; - MUCOccupant::Affiliation parseAffiliation(const std::string& statusString) const; + MUCUserPayloadParser(PayloadParserFactoryCollection* collection) : factories(collection) {} + virtual void handleTree(ParserElement::ref root); private: - enum Level { - TopLevel = 0, - ItemLevel = 1 - }; - int level; + PayloadParserFactoryCollection* factories; }; } diff --git a/Swiften/Parser/PayloadParsers/MUCUserPayloadParserFactory.h b/Swiften/Parser/PayloadParsers/MUCUserPayloadParserFactory.h index 3946ece..2c1c915 100644 --- a/Swiften/Parser/PayloadParsers/MUCUserPayloadParserFactory.h +++ b/Swiften/Parser/PayloadParsers/MUCUserPayloadParserFactory.h @@ -6,12 +6,24 @@ #pragma once -#include "Swiften/Parser/GenericPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h" +#include <Swiften/Parser/GenericPayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h> namespace Swift { - class MUCUserPayloadParserFactory : public GenericPayloadParserFactory<MUCUserPayloadParser> { + class MUCUserPayloadParserFactory : public PayloadParserFactory { public: - MUCUserPayloadParserFactory() : GenericPayloadParserFactory<MUCUserPayloadParser>("x", "http://jabber.org/protocol/muc#user") {} + MUCUserPayloadParserFactory(PayloadParserFactoryCollection* factories) : factories(factories) { + } + + virtual bool canParse(const std::string& element, const std::string& ns, const AttributeMap&) const { + return element == "x" && ns == "http://jabber.org/protocol/muc#user"; + } + + virtual PayloadParser* createPayloadParser() { + return new MUCUserPayloadParser(factories); + } + + private: + PayloadParserFactoryCollection* factories; }; } diff --git a/Swiften/Parser/PayloadParsers/NicknameParser.cpp b/Swiften/Parser/PayloadParsers/NicknameParser.cpp index cd7ec27..b647b4d 100644 --- a/Swiften/Parser/PayloadParsers/NicknameParser.cpp +++ b/Swiften/Parser/PayloadParsers/NicknameParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/NicknameParser.h" +#include <Swiften/Parser/PayloadParsers/NicknameParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/NicknameParser.h b/Swiften/Parser/PayloadParsers/NicknameParser.h index 6e723c8..a89f835 100644 --- a/Swiften/Parser/PayloadParsers/NicknameParser.h +++ b/Swiften/Parser/PayloadParsers/NicknameParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Elements/Nickname.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/Nickname.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class NicknameParser : public GenericPayloadParser<Nickname> { diff --git a/Swiften/Parser/PayloadParsers/NicknameParserFactory.h b/Swiften/Parser/PayloadParsers/NicknameParserFactory.h deleted file mode 100644 index ce2ebdd..0000000 --- a/Swiften/Parser/PayloadParsers/NicknameParserFactory.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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/Parser/GenericPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/NicknameParser.h" - -namespace Swift { - class NicknameParserFactory : public GenericPayloadParserFactory<NicknameParser> { - public: - NicknameParserFactory() : GenericPayloadParserFactory<NicknameParser>("nick", "http://jabber.org/protocol/nick") {} - }; -} diff --git a/Swiften/Parser/PayloadParsers/PriorityParser.cpp b/Swiften/Parser/PayloadParsers/PriorityParser.cpp index bcbf67f..b440444 100644 --- a/Swiften/Parser/PayloadParsers/PriorityParser.cpp +++ b/Swiften/Parser/PayloadParsers/PriorityParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/PriorityParser.h" +#include <Swiften/Parser/PayloadParsers/PriorityParser.h> #include <boost/lexical_cast.hpp> @@ -24,7 +24,7 @@ void PriorityParser::handleEndElement(const std::string&, const std::string&) { try { priority = boost::lexical_cast<int>(text_); } - catch (boost::bad_lexical_cast& e) { + catch (boost::bad_lexical_cast&) { } getPayloadInternal()->setPriority(priority); } diff --git a/Swiften/Parser/PayloadParsers/PriorityParser.h b/Swiften/Parser/PayloadParsers/PriorityParser.h index 1b02255..8d6bf86 100644 --- a/Swiften/Parser/PayloadParsers/PriorityParser.h +++ b/Swiften/Parser/PayloadParsers/PriorityParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_PriorityParser_H -#define SWIFTEN_PriorityParser_H +#pragma once -#include "Swiften/Elements/Priority.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/Priority.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class PriorityParser : public GenericPayloadParser<Priority> { @@ -24,5 +23,3 @@ namespace Swift { std::string text_; }; } - -#endif diff --git a/Swiften/Parser/PayloadParsers/PrivateStorageParser.cpp b/Swiften/Parser/PayloadParsers/PrivateStorageParser.cpp index 026da96..bf16394 100644 --- a/Swiften/Parser/PayloadParsers/PrivateStorageParser.cpp +++ b/Swiften/Parser/PayloadParsers/PrivateStorageParser.cpp @@ -4,9 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/PrivateStorageParser.h" -#include "Swiften/Parser/PayloadParserFactoryCollection.h" -#include "Swiften/Parser/PayloadParserFactory.h" +#include <Swiften/Parser/PayloadParsers/PrivateStorageParser.h> +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/PayloadParserFactory.h> namespace Swift { @@ -21,7 +21,7 @@ void PrivateStorageParser::handleStartElement(const std::string& element, const } } - if (level >= 1 && currentPayloadParser.get()) { + if (level >= 1 && currentPayloadParser) { currentPayloadParser->handleStartElement(element, ns, attributes); } ++level; @@ -29,7 +29,7 @@ void PrivateStorageParser::handleStartElement(const std::string& element, const void PrivateStorageParser::handleEndElement(const std::string& element, const std::string& ns) { --level; - if (currentPayloadParser.get()) { + if (currentPayloadParser) { if (level >= 1) { currentPayloadParser->handleEndElement(element, ns); } @@ -41,7 +41,7 @@ void PrivateStorageParser::handleEndElement(const std::string& element, const st } void PrivateStorageParser::handleCharacterData(const std::string& data) { - if (level > 1 && currentPayloadParser.get()) { + if (level > 1 && currentPayloadParser) { currentPayloadParser->handleCharacterData(data); } } diff --git a/Swiften/Parser/PayloadParsers/PrivateStorageParser.h b/Swiften/Parser/PayloadParsers/PrivateStorageParser.h index f5f569a..d350593 100644 --- a/Swiften/Parser/PayloadParsers/PrivateStorageParser.h +++ b/Swiften/Parser/PayloadParsers/PrivateStorageParser.h @@ -8,8 +8,8 @@ #include <boost/optional.hpp> -#include "Swiften/Elements/PrivateStorage.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/PrivateStorage.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class PayloadParserFactoryCollection; @@ -26,6 +26,6 @@ namespace Swift { private: PayloadParserFactoryCollection* factories; int level; - std::auto_ptr<PayloadParser> currentPayloadParser; + boost::shared_ptr<PayloadParser> currentPayloadParser; }; } diff --git a/Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h b/Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h index 9399ace..5b93aef 100644 --- a/Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h +++ b/Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Parser/PayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/PrivateStorageParser.h" +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/PrivateStorageParser.h> namespace Swift { class PayloadParserFactoryCollection; diff --git a/Swiften/Parser/PayloadParsers/RawXMLPayloadParser.cpp b/Swiften/Parser/PayloadParsers/RawXMLPayloadParser.cpp index bc9b843..0837ae8 100644 --- a/Swiften/Parser/PayloadParsers/RawXMLPayloadParser.cpp +++ b/Swiften/Parser/PayloadParsers/RawXMLPayloadParser.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/RawXMLPayloadParser.h" -#include "Swiften/Parser/SerializingParser.h" +#include <Swiften/Parser/PayloadParsers/RawXMLPayloadParser.h> +#include <Swiften/Parser/SerializingParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/RawXMLPayloadParser.h b/Swiften/Parser/PayloadParsers/RawXMLPayloadParser.h index b5c887a..4a027a1 100644 --- a/Swiften/Parser/PayloadParsers/RawXMLPayloadParser.h +++ b/Swiften/Parser/PayloadParsers/RawXMLPayloadParser.h @@ -6,9 +6,9 @@ #pragma once -#include "Swiften/Elements/RawXMLPayload.h" -#include "Swiften/Parser/GenericPayloadParser.h" -#include "Swiften/Parser/SerializingParser.h" +#include <Swiften/Elements/RawXMLPayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> +#include <Swiften/Parser/SerializingParser.h> namespace Swift { class SerializingParser; diff --git a/Swiften/Parser/PayloadParsers/RawXMLPayloadParserFactory.h b/Swiften/Parser/PayloadParsers/RawXMLPayloadParserFactory.h index b180e1e..d777caa 100644 --- a/Swiften/Parser/PayloadParsers/RawXMLPayloadParserFactory.h +++ b/Swiften/Parser/PayloadParsers/RawXMLPayloadParserFactory.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Parser/PayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/RawXMLPayloadParser.h" +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/RawXMLPayloadParser.h> #include <string> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/ReplaceParser.cpp b/Swiften/Parser/PayloadParsers/ReplaceParser.cpp new file mode 100644 index 0000000..fb85fbd --- /dev/null +++ b/Swiften/Parser/PayloadParsers/ReplaceParser.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 Vlad Voicu + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Parser/PayloadParsers/ReplaceParser.h> + +namespace Swift { + + ReplaceParser::ReplaceParser() : level_(0) { + } + + void ReplaceParser::handleStartElement(const std::string&, const std::string&, const AttributeMap& attributes) { + if (level_ == 0) { + std::string id = attributes.getAttribute("id"); + getPayloadInternal()->setID(id); + } + level_++; + } + + void ReplaceParser::handleEndElement(const std::string&, const std::string&) { + --level_; + } + + void ReplaceParser::handleCharacterData(const std::string&) { + } + +} diff --git a/Swiften/Parser/PayloadParsers/ReplaceParser.h b/Swiften/Parser/PayloadParsers/ReplaceParser.h new file mode 100644 index 0000000..4d73459 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/ReplaceParser.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Vlad Voicu + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/Replace.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + class ReplaceParser : public GenericPayloadParser<Replace> { + public: + ReplaceParser(); + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + + private: + int level_; + }; +} diff --git a/Swiften/Parser/PayloadParsers/ResourceBindParser.cpp b/Swiften/Parser/PayloadParsers/ResourceBindParser.cpp index 5c3affb..81378df 100644 --- a/Swiften/Parser/PayloadParsers/ResourceBindParser.cpp +++ b/Swiften/Parser/PayloadParsers/ResourceBindParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/ResourceBindParser.h" +#include <Swiften/Parser/PayloadParsers/ResourceBindParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/ResourceBindParser.h b/Swiften/Parser/PayloadParsers/ResourceBindParser.h index 875b5f4..e604751 100644 --- a/Swiften/Parser/PayloadParsers/ResourceBindParser.h +++ b/Swiften/Parser/PayloadParsers/ResourceBindParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_ResourceBindParser_H -#define SWIFTEN_ResourceBindParser_H +#pragma once -#include "Swiften/Elements/ResourceBind.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/ResourceBind.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class ResourceBindParser : public GenericPayloadParser<ResourceBind> { @@ -26,5 +25,3 @@ namespace Swift { std::string text_; }; } - -#endif diff --git a/Swiften/Parser/PayloadParsers/RosterItemExchangeParser.cpp b/Swiften/Parser/PayloadParsers/RosterItemExchangeParser.cpp new file mode 100644 index 0000000..32be2c7 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/RosterItemExchangeParser.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Parser/PayloadParsers/RosterItemExchangeParser.h> +#include <Swiften/Parser/SerializingParser.h> + +namespace Swift { + +RosterItemExchangeParser::RosterItemExchangeParser() : level_(TopLevel), inItem_(false) { +} + +void RosterItemExchangeParser::handleStartElement(const std::string& element, const std::string& /*ns*/, const AttributeMap& attributes) { + if (level_ == PayloadLevel) { + if (element == "item") { + inItem_ = true; + + currentItem_ = RosterItemExchangePayload::Item(); + + currentItem_.setJID(JID(attributes.getAttribute("jid"))); + currentItem_.setName(attributes.getAttribute("name")); + + std::string action = attributes.getAttribute("action"); + if (action == "add") { + currentItem_.setAction(RosterItemExchangePayload::Item::Add); + } + else if (action == "modify") { + currentItem_.setAction(RosterItemExchangePayload::Item::Modify); + } + else if (action == "delete") { + currentItem_.setAction(RosterItemExchangePayload::Item::Delete); + } + else { + // Add is default action according to XEP + currentItem_.setAction(RosterItemExchangePayload::Item::Add); + } + } + } + else if (level_ == ItemLevel) { + if (element == "group") { + currentText_ = ""; + } + } + ++level_; +} + +void RosterItemExchangeParser::handleEndElement(const std::string& element, const std::string& /*ns*/) { + --level_; + if (level_ == PayloadLevel) { + if (inItem_) { + getPayloadInternal()->addItem(currentItem_); + inItem_ = false; + } + } + else if (level_ == ItemLevel) { + if (element == "group") { + currentItem_.addGroup(currentText_); + } + } +} + +void RosterItemExchangeParser::handleCharacterData(const std::string& data) { + currentText_ += data; +} + +} diff --git a/Swiften/Parser/PayloadParsers/RosterItemExchangeParser.h b/Swiften/Parser/PayloadParsers/RosterItemExchangeParser.h new file mode 100644 index 0000000..5652b94 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/RosterItemExchangeParser.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/RosterItemExchangePayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + class SerializingParser; + + class RosterItemExchangeParser : public GenericPayloadParser<RosterItemExchangePayload> { + public: + RosterItemExchangeParser(); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + + private: + enum Level { + TopLevel = 0, + PayloadLevel = 1, + ItemLevel = 2 + }; + int level_; + bool inItem_; + RosterItemExchangePayload::Item currentItem_; + std::string currentText_; + }; +} diff --git a/Swiften/Parser/PayloadParsers/RosterParser.cpp b/Swiften/Parser/PayloadParsers/RosterParser.cpp index ba19fbf..53c433a 100644 --- a/Swiften/Parser/PayloadParsers/RosterParser.cpp +++ b/Swiften/Parser/PayloadParsers/RosterParser.cpp @@ -4,8 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/RosterParser.h" -#include "Swiften/Parser/SerializingParser.h" +#include <Swiften/Parser/PayloadParsers/RosterParser.h> + +#include <boost/optional.hpp> + +#include <Swiften/Parser/SerializingParser.h> namespace Swift { @@ -13,7 +16,13 @@ RosterParser::RosterParser() : level_(TopLevel), inItem_(false), unknownContentP } void RosterParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { - if (level_ == PayloadLevel) { + if (level_ == TopLevel) { + boost::optional<std::string> ver = attributes.getAttributeValue("ver"); + if (ver) { + getPayloadInternal()->setVersion(*ver); + } + } + else if (level_ == PayloadLevel) { if (element == "item") { inItem_ = true; currentItem_ = RosterItemPayload(); diff --git a/Swiften/Parser/PayloadParsers/RosterParser.h b/Swiften/Parser/PayloadParsers/RosterParser.h index ac72696..c29064f 100644 --- a/Swiften/Parser/PayloadParsers/RosterParser.h +++ b/Swiften/Parser/PayloadParsers/RosterParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_RosterParser_H -#define SWIFTEN_RosterParser_H +#pragma once -#include "Swiften/Elements/RosterPayload.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/RosterPayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class SerializingParser; @@ -34,5 +33,3 @@ namespace Swift { SerializingParser* unknownContentParser_; }; } - -#endif diff --git a/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp b/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp new file mode 100644 index 0000000..6e33f16 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "S5BProxyRequestParser.h" + +#include <boost/lexical_cast.hpp> +#include <boost/optional.hpp> + +namespace Swift { + +S5BProxyRequestParser::S5BProxyRequestParser() : parseActivate(false) { +} + +S5BProxyRequestParser::~S5BProxyRequestParser() { +} + +void S5BProxyRequestParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) { + if (element == "streamhost") { + if (attributes.getAttributeValue("host") && attributes.getAttributeValue("jid") && attributes.getAttributeValue("port")) { + HostAddress address = attributes.getAttributeValue("host").get_value_or(""); + int port = -1; + JID jid = attributes.getAttributeValue("jid").get_value_or(""); + + try { + port = boost::lexical_cast<int>(attributes.getAttributeValue("port").get()); + } catch (boost::bad_lexical_cast &) { + port = -1; + } + if (address.isValid() && port != -1 && jid.isValid()) { + S5BProxyRequest::StreamHost streamHost; + streamHost.addressPort = HostAddressPort(address, port); + streamHost.jid = jid; + getPayloadInternal()->setStreamHost(streamHost); + } + } + } else if (element == "activate") { + parseActivate = true; + } else if (element == "query") { + if (attributes.getAttributeValue("sid")) { + getPayloadInternal()->setSID(attributes.getAttributeValue("sid").get()); + } + } +} + +void S5BProxyRequestParser::handleEndElement(const std::string& element, const std::string&) { + if (element == "activate") { + JID activate = JID(activateJID); + if (activate.isValid()) { + getPayloadInternal()->setActivate(activate); + } + parseActivate = false; + } +} + +void S5BProxyRequestParser::handleCharacterData(const std::string& data) { + if (parseActivate) { + activateJID = activateJID + data; + } +} + +} diff --git a/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.h b/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.h new file mode 100644 index 0000000..0bf1a26 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <string> + +#include <Swiften/Elements/S5BProxyRequest.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + +class S5BProxyRequestParser : public GenericPayloadParser<S5BProxyRequest> { +public: + S5BProxyRequestParser(); + virtual ~S5BProxyRequestParser(); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + +private: + bool parseActivate; + std::string activateJID; +}; + +} diff --git a/Swiften/Parser/PayloadParsers/SearchPayloadParser.cpp b/Swiften/Parser/PayloadParsers/SearchPayloadParser.cpp index 9daf842..f4de503 100644 --- a/Swiften/Parser/PayloadParsers/SearchPayloadParser.cpp +++ b/Swiften/Parser/PayloadParsers/SearchPayloadParser.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/SearchPayloadParser.h" +#include <Swiften/Parser/PayloadParsers/SearchPayloadParser.h> #include <boost/cast.hpp> -#include "Swiften/Parser/PayloadParsers/FormParserFactory.h" -#include "Swiften/Parser/PayloadParsers/FormParser.h" +#include <Swiften/Parser/PayloadParsers/FormParserFactory.h> +#include <Swiften/Parser/PayloadParsers/FormParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/SearchPayloadParser.h b/Swiften/Parser/PayloadParsers/SearchPayloadParser.h index 01441e8..006e0d9 100644 --- a/Swiften/Parser/PayloadParsers/SearchPayloadParser.h +++ b/Swiften/Parser/PayloadParsers/SearchPayloadParser.h @@ -8,8 +8,8 @@ #include <boost/optional.hpp> -#include "Swiften/Elements/SearchPayload.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/SearchPayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class FormParserFactory; diff --git a/Swiften/Parser/PayloadParsers/SearchPayloadParserFactory.h b/Swiften/Parser/PayloadParsers/SearchPayloadParserFactory.h deleted file mode 100644 index 0f8a6c7..0000000 --- a/Swiften/Parser/PayloadParsers/SearchPayloadParserFactory.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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/Parser/GenericPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/SearchPayloadParser.h" - -namespace Swift { - class SearchPayloadParserFactory : public GenericPayloadParserFactory<SearchPayloadParser> { - public: - SearchPayloadParserFactory() : GenericPayloadParserFactory<SearchPayloadParser>("query", "jabber:iq:search") {} - }; -} diff --git a/Swiften/Parser/PayloadParsers/SecurityLabelParser.cpp b/Swiften/Parser/PayloadParsers/SecurityLabelParser.cpp index b769a47..4177baa 100644 --- a/Swiften/Parser/PayloadParsers/SecurityLabelParser.cpp +++ b/Swiften/Parser/PayloadParsers/SecurityLabelParser.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/SecurityLabelParser.h" -#include "Swiften/Parser/SerializingParser.h" +#include <Swiften/Parser/PayloadParsers/SecurityLabelParser.h> +#include <Swiften/Parser/SerializingParser.h> namespace Swift { @@ -62,7 +62,7 @@ void SecurityLabelParser::handleCharacterData(const std::string& data) { } } -boost::shared_ptr<SecurityLabel> SecurityLabelParser::getLabelPayload() { +boost::shared_ptr<SecurityLabel> SecurityLabelParser::getLabelPayload() const { return getPayloadInternal(); } diff --git a/Swiften/Parser/PayloadParsers/SecurityLabelParser.h b/Swiften/Parser/PayloadParsers/SecurityLabelParser.h index b54c3be..5357028 100644 --- a/Swiften/Parser/PayloadParsers/SecurityLabelParser.h +++ b/Swiften/Parser/PayloadParsers/SecurityLabelParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_SecurityLabelParser_H -#define SWIFTEN_SecurityLabelParser_H +#pragma once -#include "Swiften/Elements/SecurityLabel.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/SecurityLabel.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class SerializingParser; @@ -20,7 +19,7 @@ namespace Swift { virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); virtual void handleEndElement(const std::string& element, const std::string&); virtual void handleCharacterData(const std::string& data); - boost::shared_ptr<SecurityLabel> getLabelPayload(); + boost::shared_ptr<SecurityLabel> getLabelPayload() const; private: enum Level { TopLevel = 0, @@ -33,5 +32,3 @@ namespace Swift { std::string currentText_; }; } - -#endif diff --git a/Swiften/Parser/PayloadParsers/SecurityLabelParserFactory.h b/Swiften/Parser/PayloadParsers/SecurityLabelParserFactory.h index 538d4a1..47c4a0c 100644 --- a/Swiften/Parser/PayloadParsers/SecurityLabelParserFactory.h +++ b/Swiften/Parser/PayloadParsers/SecurityLabelParserFactory.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_SecurityLabelParserFactory_H -#define SWIFTEN_SecurityLabelParserFactory_H +#pragma once -#include "Swiften/Parser/GenericPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/SecurityLabelParser.h" +#include <Swiften/Parser/GenericPayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/SecurityLabelParser.h> namespace Swift { class SecurityLabelParserFactory : public GenericPayloadParserFactory<SecurityLabelParser> { @@ -16,5 +15,3 @@ namespace Swift { SecurityLabelParserFactory() : GenericPayloadParserFactory<SecurityLabelParser>("securitylabel", "urn:xmpp:sec-label:0") {} }; } - -#endif diff --git a/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.cpp b/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.cpp index 6a366b3..e90573f 100644 --- a/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.cpp +++ b/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.cpp @@ -4,9 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h" -#include "Swiften/Parser/PayloadParsers/SecurityLabelParserFactory.h" -#include "Swiften/Parser/PayloadParsers/SecurityLabelParser.h" +#include <Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h> +#include <Swiften/Parser/PayloadParsers/SecurityLabelParserFactory.h> +#include <Swiften/Parser/PayloadParsers/SecurityLabelParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h b/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h index ca422d1..d50faa4 100644 --- a/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h +++ b/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_SecurityLabelsCatalogParser_H -#define SWIFTEN_SecurityLabelsCatalogParser_H +#pragma once -#include "Swiften/Elements/SecurityLabelsCatalog.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/SecurityLabelsCatalog.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class SecurityLabelParserFactory; @@ -36,5 +35,3 @@ namespace Swift { boost::shared_ptr<SecurityLabelsCatalog::Item> currentItem_; }; } - -#endif diff --git a/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParserFactory.h b/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParserFactory.h deleted file mode 100644 index a148d81..0000000 --- a/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParserFactory.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#ifndef SWIFTEN_SecurityLabelsCatalogParserFactory_H -#define SWIFTEN_SecurityLabelsCatalogParserFactory_H - -#include "Swiften/Parser/GenericPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h" - -namespace Swift { - class SecurityLabelsCatalogParserFactory : public GenericPayloadParserFactory<SecurityLabelsCatalogParser> { - public: - SecurityLabelsCatalogParserFactory() : GenericPayloadParserFactory<SecurityLabelsCatalogParser>("catalog", "urn:xmpp:sec-label:catalog:2") {} - }; -} - -#endif diff --git a/Swiften/Parser/PayloadParsers/SoftwareVersionParser.cpp b/Swiften/Parser/PayloadParsers/SoftwareVersionParser.cpp index f8e61c7..b1c3e18 100644 --- a/Swiften/Parser/PayloadParsers/SoftwareVersionParser.cpp +++ b/Swiften/Parser/PayloadParsers/SoftwareVersionParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/SoftwareVersionParser.h" +#include <Swiften/Parser/PayloadParsers/SoftwareVersionParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/SoftwareVersionParser.h b/Swiften/Parser/PayloadParsers/SoftwareVersionParser.h index 4272e5a..01d5ed8 100644 --- a/Swiften/Parser/PayloadParsers/SoftwareVersionParser.h +++ b/Swiften/Parser/PayloadParsers/SoftwareVersionParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_SoftwareVersionParser_H -#define SWIFTEN_SoftwareVersionParser_H +#pragma once -#include "Swiften/Elements/SoftwareVersion.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/SoftwareVersion.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class SoftwareVersionParser : public GenericPayloadParser<SoftwareVersion> { @@ -28,5 +27,3 @@ namespace Swift { std::string currentText_; }; } - -#endif diff --git a/Swiften/Parser/PayloadParsers/StartSessionParser.h b/Swiften/Parser/PayloadParsers/StartSessionParser.h index ba6e3c8..ce78ae7 100644 --- a/Swiften/Parser/PayloadParsers/StartSessionParser.h +++ b/Swiften/Parser/PayloadParsers/StartSessionParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StartSessionParser_H -#define SWIFTEN_StartSessionParser_H +#pragma once -#include "Swiften/Elements/StartSession.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/StartSession.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class StartSessionParser : public GenericPayloadParser<StartSession> { @@ -20,5 +19,3 @@ namespace Swift { virtual void handleCharacterData(const std::string&) {} }; } - -#endif diff --git a/Swiften/Parser/PayloadParsers/StatusParser.cpp b/Swiften/Parser/PayloadParsers/StatusParser.cpp index a5d00de..1394d46 100644 --- a/Swiften/Parser/PayloadParsers/StatusParser.cpp +++ b/Swiften/Parser/PayloadParsers/StatusParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/StatusParser.h" +#include <Swiften/Parser/PayloadParsers/StatusParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/StatusParser.h b/Swiften/Parser/PayloadParsers/StatusParser.h index 4c6f4ac..9d7493e 100644 --- a/Swiften/Parser/PayloadParsers/StatusParser.h +++ b/Swiften/Parser/PayloadParsers/StatusParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StatusParser_H -#define SWIFTEN_StatusParser_H +#pragma once -#include "Swiften/Elements/Status.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/Status.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class StatusParser : public GenericPayloadParser<Status> { @@ -24,5 +23,3 @@ namespace Swift { std::string text_; }; } - -#endif diff --git a/Swiften/Parser/PayloadParsers/StatusShowParser.cpp b/Swiften/Parser/PayloadParsers/StatusShowParser.cpp index 774f27d..f5814ec 100644 --- a/Swiften/Parser/PayloadParsers/StatusShowParser.cpp +++ b/Swiften/Parser/PayloadParsers/StatusShowParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/StatusShowParser.h" +#include <Swiften/Parser/PayloadParsers/StatusShowParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/StatusShowParser.h b/Swiften/Parser/PayloadParsers/StatusShowParser.h index b4100a3..6e72c13 100644 --- a/Swiften/Parser/PayloadParsers/StatusShowParser.h +++ b/Swiften/Parser/PayloadParsers/StatusShowParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StatusShowParser_H -#define SWIFTEN_StatusShowParser_H +#pragma once -#include "Swiften/Elements/StatusShow.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/StatusShow.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class StatusShowParser : public GenericPayloadParser<StatusShow> { @@ -24,5 +23,3 @@ namespace Swift { std::string text_; }; } - -#endif diff --git a/Swiften/Parser/PayloadParsers/StorageParser.cpp b/Swiften/Parser/PayloadParsers/StorageParser.cpp index 94cd0ce..05e24e7 100644 --- a/Swiften/Parser/PayloadParsers/StorageParser.cpp +++ b/Swiften/Parser/PayloadParsers/StorageParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/StorageParser.h" +#include <Swiften/Parser/PayloadParsers/StorageParser.h> #include <cassert> diff --git a/Swiften/Parser/PayloadParsers/StorageParser.h b/Swiften/Parser/PayloadParsers/StorageParser.h index 16fd869..76dce90 100644 --- a/Swiften/Parser/PayloadParsers/StorageParser.h +++ b/Swiften/Parser/PayloadParsers/StorageParser.h @@ -8,8 +8,8 @@ #include <boost/optional.hpp> -#include "Swiften/Elements/Storage.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/Storage.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class StorageParser : public GenericPayloadParser<Storage> { diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.cpp b/Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.cpp new file mode 100644 index 0000000..0a13844 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "StreamInitiationFileInfoParser.h" + +#include <boost/optional.hpp> +#include <boost/lexical_cast.hpp> + +#include <Swiften/Base/DateTime.h> +#include <Swiften/Base/Log.h> + +namespace Swift { + +StreamInitiationFileInfoParser::StreamInitiationFileInfoParser() : level(0), parseDescription(false) { + +} + +void StreamInitiationFileInfoParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) { + if (level == 0) { + getPayloadInternal()->setName(attributes.getAttributeValue("name").get_value_or("")); + getPayloadInternal()->setHash(attributes.getAttributeValue("hash").get_value_or("")); + getPayloadInternal()->setAlgo(attributes.getAttributeValue("algo").get_value_or("md5")); + try { + getPayloadInternal()->setSize(boost::lexical_cast<boost::uintmax_t>(attributes.getAttributeValue("size").get_value_or("0"))); + } catch (boost::bad_lexical_cast &) { + getPayloadInternal()->setSize(0); + } + getPayloadInternal()->setDate(stringToDateTime(attributes.getAttributeValue("date").get_value_or(""))); + } else if (level == 1) { + if (element == "desc") { + parseDescription = true; + } else { + parseDescription = false; + if (element == "range") { + int offset = 0; + try { + offset = boost::lexical_cast<boost::uintmax_t>(attributes.getAttributeValue("offset").get_value_or("0")); + } catch (boost::bad_lexical_cast &) { + offset = 0; + } + if (offset == 0) { + getPayloadInternal()->setSupportsRangeRequests(true); + } else { + getPayloadInternal()->setRangeOffset(offset); + } + } + } + } + ++level; +} + +void StreamInitiationFileInfoParser::handleEndElement(const std::string& element, const std::string&) { + --level; + if (parseDescription && element == "desc") { + parseDescription = false; + getPayloadInternal()->setDescription(desc); + } +} + +void StreamInitiationFileInfoParser::handleCharacterData(const std::string& data) { + if (parseDescription) { + desc += data; + } +} + +} diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h b/Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h new file mode 100644 index 0000000..6d3591d --- /dev/null +++ b/Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/StreamInitiationFileInfo.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + +class StreamInitiationFileInfoParser : public GenericPayloadParser<StreamInitiationFileInfo> { + public: + StreamInitiationFileInfoParser(); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + + private: + int level; + bool parseDescription; + std::string desc; +}; + +} diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp b/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp index 1cf7fcf..fd3d019 100644 --- a/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp +++ b/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/StreamInitiationParser.h" +#include <Swiften/Parser/PayloadParsers/StreamInitiationParser.h> #include <boost/lexical_cast.hpp> #include <boost/cast.hpp> -#include "Swiften/Parser/PayloadParsers/FormParserFactory.h" -#include "Swiften/Parser/PayloadParsers/FormParser.h" -#include "Swiften/Base/foreach.h" +#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" @@ -38,11 +38,11 @@ void StreamInitiationParser::handleStartElement(const std::string& element, cons if (element == "file") { inFile = true; currentFile = StreamInitiationFileInfo(); - currentFile.name = attributes.getAttribute("name"); + currentFile.setName(attributes.getAttribute("name")); try { - currentFile.size = boost::lexical_cast<int>(attributes.getAttribute("size")); + currentFile.setSize(boost::lexical_cast<int>(attributes.getAttribute("size"))); } - catch (boost::bad_lexical_cast& e) { + catch (boost::bad_lexical_cast&) { } } else if (element == "feature" && ns == FEATURE_NEG_NS) { @@ -83,7 +83,7 @@ void StreamInitiationParser::handleEndElement(const std::string& element, const } else if (level == FileOrFeatureLevel) { if (inFile && element == "desc") { - currentFile.description = currentText; + currentFile.setDescription(currentText); } else if (formParser) { Form::ref form = formParser->getPayloadInternal(); diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationParser.h b/Swiften/Parser/PayloadParsers/StreamInitiationParser.h index 46f5b2f..c2ffd07 100644 --- a/Swiften/Parser/PayloadParsers/StreamInitiationParser.h +++ b/Swiften/Parser/PayloadParsers/StreamInitiationParser.h @@ -8,8 +8,8 @@ #include <boost/optional.hpp> -#include "Swiften/Elements/StreamInitiation.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/StreamInitiation.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class FormParserFactory; diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationParserFactory.h b/Swiften/Parser/PayloadParsers/StreamInitiationParserFactory.h deleted file mode 100644 index ee5ed09..0000000 --- a/Swiften/Parser/PayloadParsers/StreamInitiationParserFactory.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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/Parser/GenericPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/StreamInitiationParser.h" - -namespace Swift { - class StreamInitiationParserFactory : public GenericPayloadParserFactory<StreamInitiationParser> { - public: - StreamInitiationParserFactory() : GenericPayloadParserFactory<StreamInitiationParser>("si", "http://jabber.org/protocol/si") {} - }; -} diff --git a/Swiften/Parser/PayloadParsers/SubjectParser.cpp b/Swiften/Parser/PayloadParsers/SubjectParser.cpp index d7d9af8..276a05a 100644 --- a/Swiften/Parser/PayloadParsers/SubjectParser.cpp +++ b/Swiften/Parser/PayloadParsers/SubjectParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/SubjectParser.h" +#include <Swiften/Parser/PayloadParsers/SubjectParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/SubjectParser.h b/Swiften/Parser/PayloadParsers/SubjectParser.h index 78e5a9e..1d7d2ce 100644 --- a/Swiften/Parser/PayloadParsers/SubjectParser.h +++ b/Swiften/Parser/PayloadParsers/SubjectParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Elements/Subject.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/Subject.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class SubjectParser : public GenericPayloadParser<Subject> { diff --git a/Swiften/Parser/PayloadParsers/UnitTest/BodyParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/BodyParserTest.cpp index bb53586..fe91088 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/BodyParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/BodyParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/BodyParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/BodyParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/CommandParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/CommandParserTest.cpp index 7ebcbac..3e4971b 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/CommandParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/CommandParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" -#include "Swiften/Elements/Command.h" +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> +#include <Swiften/Elements/Command.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/DiscoInfoParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/DiscoInfoParserTest.cpp index 793e0c2..bfbc312 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/DiscoInfoParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/DiscoInfoParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/DiscoInfoParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/DiscoInfoParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/ErrorParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/ErrorParserTest.cpp index 02c2f7d..005fc09 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/ErrorParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/ErrorParserTest.cpp @@ -7,14 +7,16 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/ErrorParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/ErrorParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> +#include <Swiften/Elements/Delay.h> using namespace Swift; class ErrorParserTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(ErrorParserTest); CPPUNIT_TEST(testParse); + CPPUNIT_TEST(testParseWithPayload); CPPUNIT_TEST_SUITE_END(); public: @@ -31,7 +33,26 @@ class ErrorParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(ErrorPayload::BadRequest, payload->getCondition()); CPPUNIT_ASSERT_EQUAL(ErrorPayload::Modify, payload->getType()); CPPUNIT_ASSERT_EQUAL(std::string("boo"), payload->getText()); + CPPUNIT_ASSERT(!payload->getPayload()); } + + void testParseWithPayload() { + PayloadsParserTester parser; + + CPPUNIT_ASSERT(parser.parse( + "<error type=\"modify\">" + "<bad-request xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>" + "<delay xmlns='urn:xmpp:delay' from='juliet@capulet.com/balcony' stamp='2002-09-10T23:41:07Z'/>" + "<text xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">boo</text>" + "</error>")); + + ErrorPayload::ref payload = boost::dynamic_pointer_cast<ErrorPayload>(parser.getPayload()); + CPPUNIT_ASSERT_EQUAL(ErrorPayload::BadRequest, payload->getCondition()); + CPPUNIT_ASSERT_EQUAL(ErrorPayload::Modify, payload->getType()); + CPPUNIT_ASSERT_EQUAL(std::string("boo"), payload->getText()); + CPPUNIT_ASSERT(boost::dynamic_pointer_cast<Delay>(payload->getPayload())); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(ErrorParserTest); diff --git a/Swiften/Parser/PayloadParsers/UnitTest/FormParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/FormParserTest.cpp index 6ec825b..86845be 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/FormParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/FormParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" -#include "Swiften/Elements/Form.h" +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> +#include <Swiften/Elements/Form.h> using namespace Swift; @@ -77,7 +77,6 @@ class FormParserTest : public CppUnit::TestFixture { "</field>" "<field var=\"untyped\">" "<value>foo</value>" - "<value>baz</value>" "</field>" "</x>")); @@ -114,8 +113,7 @@ class FormParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(JID("baz@fum.org"), boost::dynamic_pointer_cast<JIDMultiFormField>(payload->getFields()[8])->getValue()[1]); CPPUNIT_ASSERT_EQUAL(std::string("Tell all your friends about your new bot!"), payload->getFields()[8]->getDescription()); - CPPUNIT_ASSERT_EQUAL(std::string("foo"), boost::dynamic_pointer_cast<UntypedFormField>(payload->getFields()[9])->getValue()[0]); - CPPUNIT_ASSERT_EQUAL(std::string("baz"), boost::dynamic_pointer_cast<UntypedFormField>(payload->getFields()[9])->getValue()[1]); + CPPUNIT_ASSERT_EQUAL(std::string("foo"), boost::dynamic_pointer_cast<TextSingleFormField>(payload->getFields()[9])->getValue()); } }; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/IBBParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/IBBParserTest.cpp index b4229f2..90d7b6b 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/IBBParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/IBBParserTest.cpp @@ -4,13 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" -#include "Swiften/Elements/IBB.h" +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> +#include <Swiften/Elements/IBB.h> using namespace Swift; @@ -32,7 +32,7 @@ class IBBParserTest : public CppUnit::TestFixture { IBB::ref ibb = parser.getPayload<IBB>(); CPPUNIT_ASSERT(ibb->getAction() == IBB::Data); - CPPUNIT_ASSERT_EQUAL(ByteArray("abcdefgihjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890\x0a"), ibb->getData()); + CPPUNIT_ASSERT(createByteArray("abcdefgihjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890\x0a") == ibb->getData()); CPPUNIT_ASSERT_EQUAL(4, ibb->getSequenceNumber()); } }; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp new file mode 100644 index 0000000..f1f25cd --- /dev/null +++ b/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp @@ -0,0 +1,709 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> +#include <Swiften/Elements/JinglePayload.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/Elements/JingleFileTransferDescription.h> +#include <Swiften/Elements/StreamInitiationFileInfo.h> +#include <Swiften/Elements/JingleFileTransferReceived.h> +#include <Swiften/Elements/JingleFileTransferHash.h> +#include <Swiften/Base/DateTime.h> + +#include <Swiften/Base/Log.h> + +using namespace Swift; + +class JingleParserTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(JingleParserTest); + CPPUNIT_TEST(testParse_Xep0166_Example3); + CPPUNIT_TEST(testParse_Xep0166_Example8); + + CPPUNIT_TEST(testParse_Xep0261_Example1); + CPPUNIT_TEST(testParse_Xep0261_Example3); + CPPUNIT_TEST(testParse_Xep0261_Example9); + CPPUNIT_TEST(testParse_Xep0261_Example13); + + CPPUNIT_TEST(testParse_Xep0234_Example1); + CPPUNIT_TEST(testParse_Xep0234_Example3); + CPPUNIT_TEST(testParse_Xep0234_Example5); + CPPUNIT_TEST(testParse_Xep0234_Example8); + CPPUNIT_TEST(testParse_Xep0234_Example10); + CPPUNIT_TEST(testParse_Xep0234_Example11); + CPPUNIT_TEST(testParse_Xep0234_Example12); + + CPPUNIT_TEST(testParse_Xep0260_Example1); + CPPUNIT_TEST(testParse_Xep0260_Example3); + CPPUNIT_TEST_SUITE_END(); + + public: + //http://xmpp.org/extensions/xep-0166.html#example-3 + void testParse_Xep0166_Example3() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='session-terminate'\n" + " sid='a73sjjvkla37jfea'>\n" + " <reason>\n" + " <success/>\n" + " </reason>\n" + "</jingle>\n" + )); + + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionTerminate, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); + CPPUNIT_ASSERT_EQUAL(JinglePayload::Reason::Success, + jingle->getReason().get_value_or(JinglePayload::Reason(JinglePayload::Reason::UnknownType, "")).type); + } + + //http://xmpp.org/extensions/xep-0166.html#example-8 + void testParse_Xep0166_Example8() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='session-terminate'\n" + " sid='a73sjjvkla37jfea'>\n" + " <reason>\n" + " <success/>\n" + " <text>Sorry, gotta go!</text>\n" + " </reason>\n" + "</jingle>\n" + )); + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionTerminate, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); + CPPUNIT_ASSERT_EQUAL(JinglePayload::Reason::Success, + jingle->getReason().get_value_or(JinglePayload::Reason(JinglePayload::Reason::UnknownType, "")).type); + CPPUNIT_ASSERT_EQUAL(std::string("Sorry, gotta go!"), + jingle->getReason().get_value_or(JinglePayload::Reason(JinglePayload::Reason::UnknownType, "")).text); + } + + // IBB Transport Method Examples + + // http://xmpp.org/extensions/xep-0261.html#example-1 + void testParse_Xep0261_Example1() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='session-initiate'\n" + " initiator='romeo@montague.lit/orchard'\n" + " sid='a73sjjvkla37jfea'>\n" + " <content creator='initiator' name='ex'>\n" + " <description xmlns='urn:xmpp:example'/>\n" + " <transport xmlns='urn:xmpp:jingle:transports:ibb:1'\n" + " block-size='4096'\n" + " sid='ch3d9s71'/>\n" + " </content>\n" + "</jingle>\n" + )); + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInitiate, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); + + std::vector<JingleContentPayload::ref> payloads = jingle->getContents(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payloads.size()); + JingleContentPayload::ref payload = payloads[0]; + CPPUNIT_ASSERT_EQUAL(JingleContentPayload::InitiatorCreator, payload->getCreator()); + CPPUNIT_ASSERT_EQUAL(std::string("ex"), payload->getName()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payload->getTransports().size()); + + JingleIBBTransportPayload::ref transportPaylod = payload->getTransport<JingleIBBTransportPayload>(); + CPPUNIT_ASSERT(transportPaylod); + CPPUNIT_ASSERT_EQUAL(4096, transportPaylod->getBlockSize()); + CPPUNIT_ASSERT_EQUAL(std::string("ch3d9s71"), transportPaylod->getSessionID()); + } + + // http://xmpp.org/extensions/xep-0261.html#example-1 + void testParse_Xep0261_Example3() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='session-accept'\n" + " initiator='romeo@montague.lit/orchard'\n" + " responder='juliet@capulet.lit/balcony'\n" + " sid='a73sjjvkla37jfea'>\n" + " <content creator='initiator' name='ex'>\n" + " <description xmlns='urn:xmpp:example'/>\n" + " <transport xmlns='urn:xmpp:jingle:transports:ibb:1'\n" + " block-size='2048'\n" + " sid='ch3d9s71'/>\n" + " </content>\n" + " </jingle>\n" + )); + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionAccept, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(JID("juliet@capulet.lit/balcony"), jingle->getResponder()); + CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); + + std::vector<JingleContentPayload::ref> payloads = jingle->getContents(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payloads.size()); + JingleContentPayload::ref payload = payloads[0]; + CPPUNIT_ASSERT_EQUAL(JingleContentPayload::InitiatorCreator, payload->getCreator()); + CPPUNIT_ASSERT_EQUAL(std::string("ex"), payload->getName()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payload->getTransports().size()); + + JingleIBBTransportPayload::ref transportPaylod = payload->getTransport<JingleIBBTransportPayload>(); + CPPUNIT_ASSERT(transportPaylod); + CPPUNIT_ASSERT_EQUAL(2048, transportPaylod->getBlockSize()); + CPPUNIT_ASSERT_EQUAL(std::string("ch3d9s71"), transportPaylod->getSessionID()); + } + + // http://xmpp.org/extensions/xep-0261.html#example-9 + void testParse_Xep0261_Example9() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='transport-info'\n" + " initiator='romeo@montague.lit/orchard'\n" + " sid='a73sjjvkla37jfea'>\n" + " <content creator='initiator' name='ex'>\n" + " <transport xmlns='urn:xmpp:jingle:transports:ibb:1'\n" + " block-size='2048'\n" + " sid='bt8a71h6'/>\n" + " </content>\n" + "</jingle>\n" + )); + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::TransportInfo, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); + + std::vector<JingleContentPayload::ref> payloads = jingle->getContents(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payloads.size()); + JingleContentPayload::ref payload = payloads[0]; + CPPUNIT_ASSERT_EQUAL(JingleContentPayload::InitiatorCreator, payload->getCreator()); + CPPUNIT_ASSERT_EQUAL(std::string("ex"), payload->getName()); + + JingleIBBTransportPayload::ref transportPaylod = payload->getTransport<JingleIBBTransportPayload>(); + CPPUNIT_ASSERT(transportPaylod); + CPPUNIT_ASSERT_EQUAL(2048, transportPaylod->getBlockSize()); + CPPUNIT_ASSERT_EQUAL(std::string("bt8a71h6"), transportPaylod->getSessionID()); + } + + // http://xmpp.org/extensions/xep-0261.html#example-13 + void testParse_Xep0261_Example13() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='session-terminate'\n" + " initiator='romeo@montague.lit/orchard'\n" + " sid='a73sjjvkla37jfea'>\n" + " <reason><success/></reason>\n" + " </jingle>\n" + )); + + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionTerminate, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); + CPPUNIT_ASSERT_EQUAL(JinglePayload::Reason::Success, jingle->getReason().get_value_or(JinglePayload::Reason()).type); + + } + + // Jingle File Transfer Examples + + // http://xmpp.org/extensions/xep-0234.html#example-1 + void testParse_Xep0234_Example1() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='session-initiate'\n" + " initiator='romeo@montague.lit/orchard'\n" + " sid='851ba2'>\n" + " <content creator='initiator' name='a-file-offer'>\n" + " <description xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n" + " <offer>\n" + " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" + " date='1969-07-21T02:56:15Z'\n" + " hash='552da749930852c69ae5d2141d3766b1'\n" + " name='test.txt'\n" + " size='1022'>\n" + " <desc>This is a test. If this were a real file...</desc>\n" + " <range/>\n" + " </file>\n" + " </offer>\n" + " </description>\n" + " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n" + " mode='tcp'\n" + " sid='vj3hs98y'>\n" + " <candidate cid='hft54dqy'\n" + " host='192.168.4.1'\n" + " jid='romeo@montague.lit/orchard'\n" + " port='5086'\n" + " priority='8257636'\n" + " type='direct'/>\n" + " <candidate cid='hutr46fe'\n" + " host='24.24.24.1'\n" + " jid='romeo@montague.lit/orchard'\n" + " port='5087'\n" + " priority='8258636'\n" + " type='direct'/>\n" + " </transport>\n" + " </content>\n" + " </jingle>\n" + )); + + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInitiate, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(std::string("851ba2"), jingle->getSessionID()); + + std::vector<JingleContentPayload::ref> contents = jingle->getContents(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), contents.size()); + + JingleFileTransferDescription::ref description = contents[0]->getDescription<JingleFileTransferDescription>(); + + + std::vector<StreamInitiationFileInfo> offers = description->getOffers(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), offers.size()); + CPPUNIT_ASSERT_EQUAL(std::string("test.txt"), offers[0].getName()); + CPPUNIT_ASSERT_EQUAL(std::string("552da749930852c69ae5d2141d3766b1"), offers[0].getHash()); + CPPUNIT_ASSERT(1022 == offers[0].getSize()); + CPPUNIT_ASSERT_EQUAL(std::string("This is a test. If this were a real file..."), offers[0].getDescription()); + CPPUNIT_ASSERT_EQUAL(true, offers[0].getSupportsRangeRequests()); + CPPUNIT_ASSERT(stringToDateTime("1969-07-21T02:56:15Z") == offers[0].getDate()); + CPPUNIT_ASSERT_EQUAL(std::string("md5"), offers[0].getAlgo()); + } + + // http://xmpp.org/extensions/xep-0234.html#example-3 + void testParse_Xep0234_Example3() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='session-accept'\n" + " initiator='romeo@montague.lit/orchard'\n" + " sid='851ba2'>\n" + " <content creator='initiator' name='a-file-offer'>\n" + " <description xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n" + " <offer>\n" + " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" + " name='test.txt'\n" + " size='1022'\n" + " hash='552da749930852c69ae5d2141d3766b1'\n" + " date='1969-07-21T02:56:15Z'>\n" + " <desc>This is a test. If this were a real file...</desc>\n" + " <range/>\n" + " </file>\n" + " </offer>\n" + " </description>\n" + " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n" + " mode='tcp'\n" + " sid='vj3hs98y'>\n" + " <candidate cid='ht567dq'\n" + " host='192.169.1.10'\n" + " jid='juliet@capulet.lit/balcony'\n" + " port='6539'\n" + " priority='8257636'\n" + " type='direct'/>\n" + " <candidate cid='hr65dqyd'\n" + " host='134.102.201.180'\n" + " jid='juliet@capulet.lit/balcony'\n" + " port='16453'\n" + " priority='7929856'\n" + " type='assisted'/>\n" + " <candidate cid='grt654q2'\n" + " host='2001:638:708:30c9:219:d1ff:fea4:a17d'\n" + " jid='juliet@capulet.lit/balcony'\n" + " port='6539'\n" + " priority='8257606'\n" + " type='direct'/>\n" + " </transport>\n" + " </content>\n" + "</jingle>\n" + )); + + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionAccept, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(std::string("851ba2"), jingle->getSessionID()); + + std::vector<JingleContentPayload::ref> contents = jingle->getContents(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), contents.size()); + + JingleFileTransferDescription::ref description = contents[0]->getDescription<JingleFileTransferDescription>(); + + + std::vector<StreamInitiationFileInfo> offers = description->getOffers(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), offers.size()); + CPPUNIT_ASSERT_EQUAL(std::string("test.txt"), offers[0].getName()); + CPPUNIT_ASSERT_EQUAL(std::string("552da749930852c69ae5d2141d3766b1"), offers[0].getHash()); + CPPUNIT_ASSERT(1022 == offers[0].getSize()); + CPPUNIT_ASSERT_EQUAL(std::string("This is a test. If this were a real file..."), offers[0].getDescription()); + CPPUNIT_ASSERT_EQUAL(true, offers[0].getSupportsRangeRequests()); + CPPUNIT_ASSERT(stringToDateTime("1969-07-21T02:56:15Z") == offers[0].getDate()); + CPPUNIT_ASSERT_EQUAL(std::string("md5"), offers[0].getAlgo()); + } + + // http://xmpp.org/extensions/xep-0234.html#example-5 + void testParse_Xep0234_Example5() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='transport-info'\n" + " initiator='romeo@montague.lit/orchard'\n" + " sid='a73sjjvkla37jfea'>\n" + " <content creator='initiator' name='ex'>\n" + " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n" + " sid='vj3hs98y'>\n" + " <candidate-used cid='hr65dqyd'/>\n" + " </transport>\n" + " </content>\n" + "</jingle>\n" + )); + + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::TransportInfo, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); + + std::vector<JingleContentPayload::ref> contents = jingle->getContents(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), contents.size()); + + JingleS5BTransportPayload::ref transport = contents[0]->getTransport<JingleS5BTransportPayload>(); + CPPUNIT_ASSERT(transport); + + CPPUNIT_ASSERT_EQUAL(std::string("vj3hs98y"), transport->getSessionID()); + CPPUNIT_ASSERT_EQUAL(std::string("hr65dqyd"), transport->getCandidateUsed()); + } + + // http://xmpp.org/extensions/xep-0234.html#example-8 + void testParse_Xep0234_Example8() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='session-info'\n" + " initiator='romeo@montague.lit/orchard'\n" + " sid='a73sjjvkla37jfea'>\n" + " <checksum xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n" + " <file>\n" + " <hashes xmlns='urn:xmpp:hashes:0'>\n" + " <hash algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>\n" + " </hashes>\n" + " </file>\n" + " </checksum>\n" + "</jingle>\n" + )); + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInfo, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); + + JingleFileTransferHash::ref hash = jingle->getPayload<JingleFileTransferHash>(); + CPPUNIT_ASSERT(hash); + CPPUNIT_ASSERT_EQUAL(std::string("552da749930852c69ae5d2141d3766b1"), hash->getHashes().find("sha-1")->second); + + } + + // http://xmpp.org/extensions/xep-0234.html#example-10 + void testParse_Xep0234_Example10() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='session-initiate'\n" + " initiator='romeo@montague.lit/orchard'\n" + " sid='uj3b2'>\n" + " <content creator='initiator' name='a-file-request'>\n" + " <description xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n" + " <request>\n" + " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" + " hash='552da749930852c69ae5d2141d3766b1'>\n" + " <range offset='270336'/>\n" + " </file>\n" + " </request>\n" + " </description>\n" + " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n" + " mode='tcp'\n" + " sid='xig361fj'>\n" + " <candidate cid='ht567dq'\n" + " host='192.169.1.10'\n" + " jid='juliet@capulet.lit/balcony'\n" + " port='6539'\n" + " priority='8257636'\n" + " type='direct'/>\n" + " <candidate cid='hr65dqyd'\n" + " host='134.102.201.180'\n" + " jid='juliet@capulet.lit/balcony'\n" + " port='16453'\n" + " priority='7929856'\n" + " type='assisted'/>\n" + " <candidate cid='grt654q2'\n" + " host='2001:638:708:30c9:219:d1ff:fea4:a17d'\n" + " jid='juliet@capulet.lit/balcony'\n" + " port='6539'\n" + " priority='8257606'\n" + " type='direct'/>\n" + " </transport>\n" + " </content>\n" + "</jingle>\n" + )); + + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInitiate, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(std::string("uj3b2"), jingle->getSessionID()); + + JingleContentPayload::ref content = jingle->getPayload<JingleContentPayload>(); + CPPUNIT_ASSERT(content); + + StreamInitiationFileInfo file = content->getDescription<JingleFileTransferDescription>()->getRequests()[0]; + CPPUNIT_ASSERT_EQUAL(std::string("552da749930852c69ae5d2141d3766b1"), file.getHash()); + CPPUNIT_ASSERT_EQUAL(270336, file.getRangeOffset()); + CPPUNIT_ASSERT_EQUAL(true, file.getSupportsRangeRequests()); + } + + // http://xmpp.org/extensions/xep-0234.html#example-11 + void testParse_Xep0234_Example11() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='session-initiate'\n" + " initiator='romeo@montague.lit/orchard'\n" + " sid='h2va419i'>\n" + " <content creator='initiator' name='a-file-offer'>\n" + " <description xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n" + " <offer>\n" + " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" + " date='2011-06-01T15:58:15Z'\n" + " hash='a749930852c69ae5d2141d3766b1552d'\n" + " name='somefile.txt'\n" + " size='1234'/>\n" + " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" + " date='2011-06-01T15:58:15Z'\n" + " hash='930852c69ae5d2141d3766b1552da749'\n" + " name='anotherfile.txt'\n" + " size='2345'/>\n" + " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" + " date='2011-06-01T15:58:15Z'\n" + " hash='52c69ae5d2141d3766b1552da7499308'\n" + " name='yetanotherfile.txt'\n" + " size='3456'/>\n" + " </offer>\n" + " </description>\n" + " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n" + " mode='tcp'\n" + " sid='vj3hs98y'>\n" + " <candidate cid='hft54dqy'\n" + " host='192.168.4.1'\n" + " jid='romeo@montague.lit/orchard'\n" + " port='5086'\n" + " priority='8257636'\n" + " type='direct'/>\n" + " <candidate cid='hutr46fe'\n" + " host='24.24.24.1'\n" + " jid='romeo@montague.lit/orchard'\n" + " port='5087'\n" + " priority='8258636'\n" + " type='direct'/>\n" + " </transport>\n" + " </content>\n" + "</jingle>\n" + )); + + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInitiate, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(std::string("h2va419i"), jingle->getSessionID()); + + JingleContentPayload::ref content = jingle->getPayload<JingleContentPayload>(); + CPPUNIT_ASSERT(content); + CPPUNIT_ASSERT_EQUAL(JingleContentPayload::InitiatorCreator, content->getCreator()); + CPPUNIT_ASSERT_EQUAL(std::string("a-file-offer"), content->getName()); + + std::vector<StreamInitiationFileInfo> offers = content->getDescription<JingleFileTransferDescription>()->getOffers(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), offers.size()); + } + + // http://xmpp.org/extensions/xep-0234.html#example-12 + void testParse_Xep0234_Example12() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='session-info'\n" + " initiator='romeo@montague.lit/orchard'\n" + " sid='a73sjjvkla37jfea'>\n" + " <received xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n" + " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" + " hash='a749930852c69ae5d2141d3766b1552d'/>\n" + " </received>\n" + "</jingle>\n" + )); + + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInfo, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); + + boost::shared_ptr<JingleFileTransferReceived> received = jingle->getPayload<JingleFileTransferReceived>(); + CPPUNIT_ASSERT(received); + CPPUNIT_ASSERT_EQUAL(std::string("a749930852c69ae5d2141d3766b1552d"), received->getFileInfo().getHash()); + } + + // http://xmpp.org/extensions/xep-0260.html#example-1 + void testParse_Xep0260_Example1() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='session-initiate'\n" + " initiator='romeo@montague.lit/orchard'\n" + " sid='a73sjjvkla37jfea'>\n" + " <content creator='initiator' name='ex'>\n" + " <description xmlns='urn:xmpp:example'/>\n" + " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n" + " mode='tcp'\n" + " sid='vj3hs98y'>\n" + " <candidate cid='hft54dqy'\n" + " host='192.168.4.1'\n" + " jid='romeo@montague.lit/orchard'\n" + " port='5086'\n" + " priority='8257636'\n" + " type='direct'/>\n" + " <candidate cid='hutr46fe'\n" + " host='24.24.24.1'\n" + " jid='romeo@montague.lit/orchard'\n" + " port='5087'\n" + " priority='8258636'\n" + " type='direct'/>\n" + " </transport>\n" + " </content>\n" + "</jingle>\n" + )); + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInitiate, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); + + JingleContentPayload::ref content = jingle->getPayload<JingleContentPayload>(); + CPPUNIT_ASSERT(content); + + JingleS5BTransportPayload::ref s5bPayload = content->getTransport<JingleS5BTransportPayload>(); + CPPUNIT_ASSERT(s5bPayload); + + CPPUNIT_ASSERT_EQUAL(std::string("vj3hs98y"), s5bPayload->getSessionID()); + CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::TCPMode, s5bPayload->getMode()); + CPPUNIT_ASSERT_EQUAL(false, s5bPayload->hasCandidateError()); + CPPUNIT_ASSERT_EQUAL(false, s5bPayload->hasProxyError()); + CPPUNIT_ASSERT_EQUAL(std::string(), s5bPayload->getActivated()); + CPPUNIT_ASSERT_EQUAL(std::string(), s5bPayload->getCandidateUsed()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), s5bPayload->getCandidates().size()); + + JingleS5BTransportPayload::Candidate candidate; + candidate = s5bPayload->getCandidates()[0]; + CPPUNIT_ASSERT_EQUAL(std::string("hft54dqy"), candidate.cid); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), candidate.jid); + CPPUNIT_ASSERT(HostAddressPort(HostAddress("192.168.4.1"), 5086) == candidate.hostPort); + CPPUNIT_ASSERT_EQUAL(8257636, candidate.priority); + CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::DirectType, candidate.type); + + candidate = s5bPayload->getCandidates()[1]; + CPPUNIT_ASSERT_EQUAL(std::string("hutr46fe"), candidate.cid); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), candidate.jid); + CPPUNIT_ASSERT(HostAddressPort(HostAddress("24.24.24.1"), 5087) == candidate.hostPort); + CPPUNIT_ASSERT_EQUAL(8258636, candidate.priority); + CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::DirectType, candidate.type); + } + + // http://xmpp.org/extensions/xep-0260.html#example-3 + void testParse_Xep0260_Example3() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle xmlns='urn:xmpp:jingle:1'\n" + " action='session-accept'\n" + " initiator='romeo@montague.lit/orchard'\n" + " sid='a73sjjvkla37jfea'>\n" + " <content creator='initiator' name='ex'>\n" + " <description xmlns='urn:xmpp:example'/>\n" + " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n" + " mode='tcp'\n" + " sid='vj3hs98y'>\n" + " <candidate cid='ht567dq'\n" + " host='192.169.1.10'\n" + " jid='juliet@capulet.lit/balcony'\n" + " port='6539'\n" + " priority='8257636'\n" + " type='direct'/>\n" + " <candidate cid='hr65dqyd'\n" + " host='134.102.201.180'\n" + " jid='juliet@capulet.lit/balcony'\n" + " port='16453'\n" + " priority='7929856'\n" + " type='assisted'/>\n" + " <candidate cid='grt654q2'\n" + " host='2001:638:708:30c9:219:d1ff:fea4:a17d'\n" + " jid='juliet@capulet.lit/balcony'\n" + " port='6539'\n" + " priority='8257606'\n" + " type='direct'/>\n" + " </transport>\n" + " </content>\n" + "</jingle>\n" + )); + + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionAccept, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); + + JingleContentPayload::ref content = jingle->getPayload<JingleContentPayload>(); + CPPUNIT_ASSERT(content); + + JingleS5BTransportPayload::ref s5bPayload = content->getTransport<JingleS5BTransportPayload>(); + CPPUNIT_ASSERT(s5bPayload); + + CPPUNIT_ASSERT_EQUAL(std::string("vj3hs98y"), s5bPayload->getSessionID()); + CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::TCPMode, s5bPayload->getMode()); + CPPUNIT_ASSERT_EQUAL(false, s5bPayload->hasCandidateError()); + CPPUNIT_ASSERT_EQUAL(false, s5bPayload->hasProxyError()); + CPPUNIT_ASSERT_EQUAL(std::string(), s5bPayload->getActivated()); + CPPUNIT_ASSERT_EQUAL(std::string(), s5bPayload->getCandidateUsed()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), s5bPayload->getCandidates().size()); + + JingleS5BTransportPayload::Candidate candidate; + candidate = s5bPayload->getCandidates()[0]; + CPPUNIT_ASSERT_EQUAL(std::string("ht567dq"), candidate.cid); + CPPUNIT_ASSERT_EQUAL(JID("juliet@capulet.lit/balcony"), candidate.jid); + CPPUNIT_ASSERT(HostAddressPort(HostAddress("192.169.1.10"), 6539) == candidate.hostPort); + CPPUNIT_ASSERT_EQUAL(8257636, candidate.priority); + CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::DirectType, candidate.type); + + candidate = s5bPayload->getCandidates()[1]; + CPPUNIT_ASSERT_EQUAL(std::string("hr65dqyd"), candidate.cid); + CPPUNIT_ASSERT_EQUAL(JID("juliet@capulet.lit/balcony"), candidate.jid); + CPPUNIT_ASSERT(HostAddressPort(HostAddress("134.102.201.180"), 16453) == candidate.hostPort); + CPPUNIT_ASSERT_EQUAL(7929856, candidate.priority); + CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::AssistedType, candidate.type); + + candidate = s5bPayload->getCandidates()[2]; + CPPUNIT_ASSERT_EQUAL(std::string("grt654q2"), candidate.cid); + CPPUNIT_ASSERT_EQUAL(JID("juliet@capulet.lit/balcony"), candidate.jid); + CPPUNIT_ASSERT(HostAddressPort(HostAddress("2001:638:708:30c9:219:d1ff:fea4:a17d"), 6539) == candidate.hostPort); + CPPUNIT_ASSERT_EQUAL(8257606, candidate.priority); + CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::DirectType, candidate.type); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(JingleParserTest); diff --git a/Swiften/Parser/PayloadParsers/UnitTest/MUCAdminPayloadParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/MUCAdminPayloadParserTest.cpp new file mode 100644 index 0000000..0648f58 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/UnitTest/MUCAdminPayloadParserTest.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Parser/PayloadParsers/MUCAdminPayloadParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> + +using namespace Swift; + +class MUCAdminPayloadParserTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(MUCAdminPayloadParserTest); + CPPUNIT_TEST(testParse); + CPPUNIT_TEST_SUITE_END(); + + public: + MUCAdminPayloadParserTest() {} + + void testParse() { + PayloadsParserTester parser; + + CPPUNIT_ASSERT(parser.parse("<query xmlns=\"http://jabber.org/protocol/muc#admin\"><item affiliation=\"owner\" role=\"visitor\"><actor jid=\"kev@tester.lit\"/><reason>malice</reason></item></query>")); + + MUCAdminPayload::ref payload = boost::dynamic_pointer_cast<MUCAdminPayload>(parser.getPayload()); + MUCItem item = payload->getItems()[0]; + CPPUNIT_ASSERT_EQUAL(MUCOccupant::Owner, item.affiliation.get()); + CPPUNIT_ASSERT_EQUAL(MUCOccupant::Visitor, item.role.get()); + CPPUNIT_ASSERT_EQUAL(JID("kev@tester.lit"), item.actor.get()); + CPPUNIT_ASSERT_EQUAL(std::string("malice"), item.reason.get()); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(MUCAdminPayloadParserTest); + + + diff --git a/Swiften/Parser/PayloadParsers/UnitTest/MUCUserPayloadParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/MUCUserPayloadParserTest.cpp new file mode 100644 index 0000000..45862e2 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/UnitTest/MUCUserPayloadParserTest.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h> +#include <Swiften/Elements/MUCDestroyPayload.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> + +using namespace Swift; + +class MUCUserPayloadParserTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(MUCUserPayloadParserTest); + CPPUNIT_TEST(testParseEmpty); + CPPUNIT_TEST(testParse); + CPPUNIT_TEST(testParseDestroy); + CPPUNIT_TEST_SUITE_END(); + + public: + MUCUserPayloadParserTest() {} + + void testParse() { + PayloadsParserTester parser; + + CPPUNIT_ASSERT(parser.parse("<x xmlns=\"http://jabber.org/protocol/muc#user\"><status code='110'/><item affiliation=\"owner\" role=\"visitor\"><actor jid=\"kev@tester.lit\"/><reason>malice</reason></item><status code='210'/></x>")); + + bool found110 = false; + bool found210 = false; + + MUCUserPayload::ref payload = boost::dynamic_pointer_cast<MUCUserPayload>(parser.getPayload()); + + foreach (MUCUserPayload::StatusCode status, payload->getStatusCodes()) { + if (status.code == 110) found110 = true; + if (status.code == 210) found210 = true; + } + + MUCItem item = payload->getItems()[0]; + CPPUNIT_ASSERT_EQUAL(MUCOccupant::Owner, item.affiliation.get()); + CPPUNIT_ASSERT_EQUAL(MUCOccupant::Visitor, item.role.get()); + CPPUNIT_ASSERT_EQUAL(JID("kev@tester.lit"), item.actor.get()); + CPPUNIT_ASSERT_EQUAL(std::string("malice"), item.reason.get()); + CPPUNIT_ASSERT(found110); + CPPUNIT_ASSERT(found210); + } + + void testParseEmpty() { + PayloadsParserTester parser; + + CPPUNIT_ASSERT(parser.parse("<x xmlns=\"http://jabber.org/protocol/muc#user\"/>")); + + MUCUserPayload::ref payload = boost::dynamic_pointer_cast<MUCUserPayload>(parser.getPayload()); + CPPUNIT_ASSERT(payload); + CPPUNIT_ASSERT(payload->getItems().empty()); + } + + void testParseDestroy() { + PayloadsParserTester parser; + + CPPUNIT_ASSERT(parser.parse("<x xmlns=\"http://jabber.org/protocol/muc#user\"><destroy jid='alice@wonderland.lit'><reason>bert</reason></destroy></x>")); + + MUCUserPayload::ref payload = boost::dynamic_pointer_cast<MUCUserPayload>(parser.getPayload()); + CPPUNIT_ASSERT(payload); + MUCDestroyPayload::ref destroy = boost::dynamic_pointer_cast<MUCDestroyPayload>(payload->getPayload()); + CPPUNIT_ASSERT(destroy); + CPPUNIT_ASSERT_EQUAL(std::string("bert"), destroy->getReason()); + CPPUNIT_ASSERT_EQUAL(JID("alice@wonderland.lit"), destroy->getNewVenue()); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(MUCUserPayloadParserTest); diff --git a/Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h b/Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h index 32fc56c..b0f68ab 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h +++ b/Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Parser/UnitTest/ParserTester.h" -#include "Swiften/Parser/PayloadParser.h" +#include <Swiften/Parser/UnitTest/ParserTester.h> +#include <Swiften/Parser/PayloadParser.h> namespace Swift { typedef ParserTester<PayloadParser> PayloadParserTester; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h b/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h index 2c88955..213cd06 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h +++ b/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h @@ -8,12 +8,12 @@ #include <cppunit/extensions/HelperMacros.h> -#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" -#include "Swiften/Parser/XMLParser.h" -#include "Swiften/Parser/XMLParserClient.h" -#include "Swiften/Parser/PlatformXMLParserFactory.h" -#include "Swiften/Elements/Payload.h" -#include "Swiften/Parser/PayloadParser.h" +#include <Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h> +#include <Swiften/Parser/XMLParser.h> +#include <Swiften/Parser/XMLParserClient.h> +#include <Swiften/Parser/PlatformXMLParserFactory.h> +#include <Swiften/Elements/Payload.h> +#include <Swiften/Parser/PayloadParser.h> namespace Swift { class PayloadsParserTester : public XMLParserClient { @@ -62,7 +62,7 @@ namespace Swift { private: XMLParser* xmlParser; FullPayloadParserFactoryCollection factories; - std::auto_ptr<PayloadParser> payloadParser; + boost::shared_ptr<PayloadParser> payloadParser; int level; }; } diff --git a/Swiften/Parser/PayloadParsers/UnitTest/PriorityParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/PriorityParserTest.cpp index 68a2e4f..0974aec 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/PriorityParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/PriorityParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/PriorityParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/PriorityParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> using namespace Swift; @@ -24,7 +24,7 @@ class PriorityParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(parser.parse("<priority>-120</priority>")); - Priority::ref payload = boost::dynamic_pointer_cast<Priority>(parser.getPayload()); + boost::shared_ptr<Priority> payload = boost::dynamic_pointer_cast<Priority>(parser.getPayload()); CPPUNIT_ASSERT_EQUAL(-120, payload->getPriority()); } @@ -33,7 +33,7 @@ class PriorityParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(parser.parse("<priority>invalid</priority>")); - Priority::ref payload = boost::dynamic_pointer_cast<Priority>(parser.getPayload()); + boost::shared_ptr<Priority> payload = boost::dynamic_pointer_cast<Priority>(parser.getPayload()); CPPUNIT_ASSERT_EQUAL(0, payload->getPriority()); } }; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/PrivateStorageParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/PrivateStorageParserTest.cpp index 867b25f..ef6ed9a 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/PrivateStorageParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/PrivateStorageParserTest.cpp @@ -7,10 +7,10 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Elements/Storage.h" -#include "Swiften/Parser/PayloadParsers/PrivateStorageParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h" +#include <Swiften/Elements/Storage.h> +#include <Swiften/Parser/PayloadParsers/PrivateStorageParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/RawXMLPayloadParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/RawXMLPayloadParserTest.cpp index 8885974..4862584 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/RawXMLPayloadParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/RawXMLPayloadParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/RawXMLPayloadParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h" +#include <Swiften/Parser/PayloadParsers/RawXMLPayloadParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/ReplaceTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/ReplaceTest.cpp new file mode 100644 index 0000000..c3f410f --- /dev/null +++ b/Swiften/Parser/PayloadParsers/UnitTest/ReplaceTest.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 Vlad Voicu + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Parser/PayloadParsers/ReplaceParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> + +using namespace Swift; + +class ReplaceParserTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(ReplaceParserTest); + CPPUNIT_TEST(testParseTrivial); + CPPUNIT_TEST(testParseChild); + CPPUNIT_TEST_SUITE_END(); + + public: + void testParseTrivial() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse("<replace id='bad1' xmlns='http://swift.im/protocol/replace'/>")); + Replace::ref payload = boost::dynamic_pointer_cast <Replace>(parser.getPayload()); + CPPUNIT_ASSERT_EQUAL(std::string("bad1"), payload->getID()); + } + void testParseChild() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse("<replace id='bad1' xmlns='http://swift.im/protocol/replace' ><child xmlns='blah' id=\"hi\"/></replace>")); + Replace::ref payload = boost::dynamic_pointer_cast <Replace>(parser.getPayload()); + CPPUNIT_ASSERT_EQUAL(std::string("bad1"), payload->getID()); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(ReplaceParserTest); diff --git a/Swiften/Parser/PayloadParsers/UnitTest/ResourceBindParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/ResourceBindParserTest.cpp index 026ef2c..663a81c 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/ResourceBindParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/ResourceBindParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/ResourceBindParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/ResourceBindParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/RosterItemExchangeParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/RosterItemExchangeParserTest.cpp new file mode 100644 index 0000000..1a18d6d --- /dev/null +++ b/Swiften/Parser/PayloadParsers/UnitTest/RosterItemExchangeParserTest.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Parser/PayloadParsers/RosterItemExchangeParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> + +using namespace Swift; + +class RosterItemExchangeParserTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(RosterItemExchangeParserTest); + CPPUNIT_TEST(testParse); + CPPUNIT_TEST_SUITE_END(); + + public: + void testParse() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<x xmlns=\"http://jabber.org/protocol/rosterx\">" + "<item action=\"add\" jid=\"foo@bar.com\" name=\"Foo @ Bar\">" + "<group>Group 1</group>" + "<group>Group 2</group>" + "</item>" + "<item action=\"modify\" jid=\"baz@blo.com\" name=\"Baz\"/>" + "</x>")); + + RosterItemExchangePayload* payload = dynamic_cast<RosterItemExchangePayload*>(parser.getPayload().get()); + const RosterItemExchangePayload::RosterItemExchangePayloadItems& items = payload->getItems(); + + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), items.size()); + + CPPUNIT_ASSERT_EQUAL(JID("foo@bar.com"), items[0].getJID()); + CPPUNIT_ASSERT_EQUAL(std::string("Foo @ Bar"), items[0].getName()); + CPPUNIT_ASSERT_EQUAL(RosterItemExchangePayload::Item::Add, items[0].getAction()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), items[0].getGroups().size()); + CPPUNIT_ASSERT_EQUAL(std::string("Group 1"), items[0].getGroups()[0]); + CPPUNIT_ASSERT_EQUAL(std::string("Group 2"), items[0].getGroups()[1]); + + CPPUNIT_ASSERT_EQUAL(JID("baz@blo.com"), items[1].getJID()); + CPPUNIT_ASSERT_EQUAL(std::string("Baz"), items[1].getName()); + CPPUNIT_ASSERT_EQUAL(RosterItemExchangePayload::Item::Modify, items[1].getAction()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), items[1].getGroups().size()); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(RosterItemExchangeParserTest); diff --git a/Swiften/Parser/PayloadParsers/UnitTest/RosterParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/RosterParserTest.cpp index 1bcea0e..6cb5dbc 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/RosterParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/RosterParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/RosterParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/RosterParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> using namespace Swift; @@ -17,6 +17,8 @@ class RosterParserTest : public CppUnit::TestFixture CPPUNIT_TEST_SUITE(RosterParserTest); CPPUNIT_TEST(testParse); CPPUNIT_TEST(testParse_ItemWithUnknownContent); + CPPUNIT_TEST(testParse_WithVersion); + CPPUNIT_TEST(testParse_WithEmptyVersion); CPPUNIT_TEST_SUITE_END(); public: @@ -32,6 +34,8 @@ class RosterParserTest : public CppUnit::TestFixture "</query>")); RosterPayload* payload = dynamic_cast<RosterPayload*>(parser.getPayload().get()); + + CPPUNIT_ASSERT(!payload->getVersion()); const RosterPayload::RosterItemPayloads& items = payload->getItems(); CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), items.size()); @@ -74,6 +78,24 @@ class RosterParserTest : public CppUnit::TestFixture "<baz xmlns=\"jabber:iq:roster\"><fum xmlns=\"jabber:iq:roster\">foo</fum></baz>" ), items[0].getUnknownContent()); } + + void testParse_WithVersion() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse("<query xmlns='jabber:iq:roster' ver='ver10'/>")); + + RosterPayload* payload = dynamic_cast<RosterPayload*>(parser.getPayload().get()); + CPPUNIT_ASSERT(payload->getVersion()); + CPPUNIT_ASSERT_EQUAL(std::string("ver10"), *payload->getVersion()); + } + + void testParse_WithEmptyVersion() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse("<query xmlns='jabber:iq:roster' ver=''/>")); + + RosterPayload* payload = dynamic_cast<RosterPayload*>(parser.getPayload().get()); + CPPUNIT_ASSERT(payload->getVersion()); + CPPUNIT_ASSERT_EQUAL(std::string(""), *payload->getVersion()); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(RosterParserTest); diff --git a/Swiften/Parser/PayloadParsers/UnitTest/SearchPayloadParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/SearchPayloadParserTest.cpp index 3d3bc7b..c07cd7f 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/SearchPayloadParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/SearchPayloadParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" -#include "Swiften/Elements/SearchPayload.h" +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> +#include <Swiften/Elements/SearchPayload.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/SecurityLabelParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/SecurityLabelParserTest.cpp index 0812c6b..5083a07 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/SecurityLabelParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/SecurityLabelParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/SecurityLabelParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/SecurityLabelParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/SecurityLabelsCatalogParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/SecurityLabelsCatalogParserTest.cpp index e1e8594..395daf5 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/SecurityLabelsCatalogParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/SecurityLabelsCatalogParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/SoftwareVersionParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/SoftwareVersionParserTest.cpp index 3689f10..d22d207 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/SoftwareVersionParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/SoftwareVersionParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/SoftwareVersionParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/SoftwareVersionParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/StatusParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/StatusParserTest.cpp index 7791f5f..358ff88 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/StatusParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/StatusParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/StatusParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/StatusParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/StatusShowParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/StatusShowParserTest.cpp index 17617b4..924a87f 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/StatusShowParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/StatusShowParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/StatusShowParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/StatusShowParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/StorageParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/StorageParserTest.cpp index 88730b7..4fd8ae5 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/StorageParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/StorageParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/StorageParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/StorageParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/StreamInitiationParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/StreamInitiationParserTest.cpp index 8001487..63a6c9b 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/StreamInitiationParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/StreamInitiationParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" -#include "Swiften/Elements/StreamInitiation.h" +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> +#include <Swiften/Elements/StreamInitiation.h> using namespace Swift; @@ -42,9 +42,9 @@ class StreamInitiationParserTest : public CppUnit::TestFixture { StreamInitiation::ref si = parser.getPayload<StreamInitiation>(); CPPUNIT_ASSERT(si->getIsFileTransfer()); CPPUNIT_ASSERT(si->getFileInfo()); - CPPUNIT_ASSERT_EQUAL(std::string("test.txt"), si->getFileInfo()->name); - CPPUNIT_ASSERT_EQUAL(1022, si->getFileInfo()->size); - CPPUNIT_ASSERT_EQUAL(std::string("This is info about the file."), si->getFileInfo()->description); + CPPUNIT_ASSERT_EQUAL(std::string("test.txt"), si->getFileInfo()->getName()); + CPPUNIT_ASSERT(1022 == si->getFileInfo()->getSize()); + CPPUNIT_ASSERT_EQUAL(std::string("This is info about the file."), si->getFileInfo()->getDescription()); CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(si->getProvidedMethods().size())); CPPUNIT_ASSERT_EQUAL(std::string("http://jabber.org/protocol/bytestreams"), si->getProvidedMethods()[0]); CPPUNIT_ASSERT_EQUAL(std::string("jabber:iq:oob"), si->getProvidedMethods()[1]); diff --git a/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp index 909401d..f1e6635 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp @@ -4,13 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/VCardParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/VCardParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> using namespace Swift; @@ -93,7 +94,7 @@ class VCardParserTest : public CppUnit::TestFixture { VCard* payload = dynamic_cast<VCard*>(parser.getPayload().get()); CPPUNIT_ASSERT_EQUAL(std::string("image/jpeg"), payload->getPhotoType()); - CPPUNIT_ASSERT_EQUAL(ByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"), payload->getPhoto()); + CPPUNIT_ASSERT_EQUAL(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"), payload->getPhoto()); } void testParse_Nickname() { diff --git a/Swiften/Parser/PayloadParsers/UnitTest/VCardUpdateParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/VCardUpdateParserTest.cpp index b8ea4fb..fe69242 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/VCardUpdateParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/VCardUpdateParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParsers/VCardUpdateParser.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include <Swiften/Parser/PayloadParsers/VCardUpdateParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/PayloadParsers/VCardParser.cpp b/Swiften/Parser/PayloadParsers/VCardParser.cpp index 61af0ba..553d26a 100644 --- a/Swiften/Parser/PayloadParsers/VCardParser.cpp +++ b/Swiften/Parser/PayloadParsers/VCardParser.cpp @@ -4,10 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/VCardParser.h" -#include "Swiften/Base/foreach.h" -#include "Swiften/StringCodecs/Base64.h" -#include "Swiften/Parser/SerializingParser.h" +#include <Swiften/Parser/PayloadParsers/VCardParser.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/StringCodecs/Base64.h> +#include <Swiften/Parser/SerializingParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/VCardParser.h b/Swiften/Parser/PayloadParsers/VCardParser.h index c858e61..1475277 100644 --- a/Swiften/Parser/PayloadParsers/VCardParser.h +++ b/Swiften/Parser/PayloadParsers/VCardParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Elements/VCard.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/VCard.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class SerializingParser; diff --git a/Swiften/Parser/PayloadParsers/VCardParserFactory.h b/Swiften/Parser/PayloadParsers/VCardParserFactory.h deleted file mode 100644 index 305d42e..0000000 --- a/Swiften/Parser/PayloadParsers/VCardParserFactory.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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/Parser/GenericPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/VCardParser.h" - -namespace Swift { - class VCardParserFactory : public GenericPayloadParserFactory<VCardParser> { - public: - VCardParserFactory() : GenericPayloadParserFactory<VCardParser>("vCard", "vcard-temp") {} - }; -} diff --git a/Swiften/Parser/PayloadParsers/VCardUpdateParser.cpp b/Swiften/Parser/PayloadParsers/VCardUpdateParser.cpp index 2218d75..d4703da 100644 --- a/Swiften/Parser/PayloadParsers/VCardUpdateParser.cpp +++ b/Swiften/Parser/PayloadParsers/VCardUpdateParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PayloadParsers/VCardUpdateParser.h" +#include <Swiften/Parser/PayloadParsers/VCardUpdateParser.h> namespace Swift { diff --git a/Swiften/Parser/PayloadParsers/VCardUpdateParser.h b/Swiften/Parser/PayloadParsers/VCardUpdateParser.h index b91c17b..4954f0a 100644 --- a/Swiften/Parser/PayloadParsers/VCardUpdateParser.h +++ b/Swiften/Parser/PayloadParsers/VCardUpdateParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Elements/VCardUpdate.h" -#include "Swiften/Parser/GenericPayloadParser.h" +#include <Swiften/Elements/VCardUpdate.h> +#include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { class SerializingParser; diff --git a/Swiften/Parser/PayloadParsers/VCardUpdateParserFactory.h b/Swiften/Parser/PayloadParsers/VCardUpdateParserFactory.h deleted file mode 100644 index 562f253..0000000 --- a/Swiften/Parser/PayloadParsers/VCardUpdateParserFactory.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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/Parser/GenericPayloadParserFactory.h" -#include "Swiften/Parser/PayloadParsers/VCardUpdateParser.h" - -namespace Swift { - class VCardUpdateParserFactory : public GenericPayloadParserFactory<VCardUpdateParser> { - public: - VCardUpdateParserFactory() : GenericPayloadParserFactory<VCardUpdateParser>("x", "vcard-temp:x:update") {} - }; -} diff --git a/Swiften/Parser/PlatformXMLParserFactory.cpp b/Swiften/Parser/PlatformXMLParserFactory.cpp index 078e562..18acdc2 100644 --- a/Swiften/Parser/PlatformXMLParserFactory.cpp +++ b/Swiften/Parser/PlatformXMLParserFactory.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/PlatformXMLParserFactory.h" +#include <Swiften/Parser/PlatformXMLParserFactory.h> #include <cassert> #ifdef HAVE_LIBXML -#include "Swiften/Parser/LibXMLParser.h" +#include <Swiften/Parser/LibXMLParser.h> #else -#include "Swiften/Parser/ExpatParser.h" +#include <Swiften/Parser/ExpatParser.h> #endif diff --git a/Swiften/Parser/PlatformXMLParserFactory.h b/Swiften/Parser/PlatformXMLParserFactory.h index ea1bfd7..16756ee 100644 --- a/Swiften/Parser/PlatformXMLParserFactory.h +++ b/Swiften/Parser/PlatformXMLParserFactory.h @@ -4,10 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_PlatformXMLParserFactory_H -#define SWIFTEN_PlatformXMLParserFactory_H +#pragma once -#include "Swiften/Parser/XMLParserFactory.h" +#include <Swiften/Parser/XMLParserFactory.h> namespace Swift { class PlatformXMLParserFactory : public XMLParserFactory { @@ -17,5 +16,3 @@ namespace Swift { virtual XMLParser* createXMLParser(XMLParserClient*); }; } - -#endif diff --git a/Swiften/Parser/PresenceParser.cpp b/Swiften/Parser/PresenceParser.cpp index 845ccf0..39305c0 100644 --- a/Swiften/Parser/PresenceParser.cpp +++ b/Swiften/Parser/PresenceParser.cpp @@ -5,8 +5,9 @@ */ #include <iostream> +#include <boost/optional.hpp> -#include "Swiften/Parser/PresenceParser.h" +#include <Swiften/Parser/PresenceParser.h> namespace Swift { @@ -15,31 +16,31 @@ PresenceParser::PresenceParser(PayloadParserFactoryCollection* factories) : } void PresenceParser::handleStanzaAttributes(const AttributeMap& attributes) { - AttributeMap::const_iterator type = attributes.find("type"); - if (type != attributes.end()) { - if (type->second == "unavailable") { + boost::optional<std::string> type = attributes.getAttributeValue("type"); + if (type) { + if (*type == "unavailable") { getStanzaGeneric()->setType(Presence::Unavailable); } - else if (type->second == "probe") { + else if (*type == "probe") { getStanzaGeneric()->setType(Presence::Probe); } - else if (type->second == "subscribe") { + else if (*type == "subscribe") { getStanzaGeneric()->setType(Presence::Subscribe); } - else if (type->second == "subscribed") { + else if (*type == "subscribed") { getStanzaGeneric()->setType(Presence::Subscribed); } - else if (type->second == "unsubscribe") { + else if (*type == "unsubscribe") { getStanzaGeneric()->setType(Presence::Unsubscribe); } - else if (type->second == "unsubscribed") { + else if (*type == "unsubscribed") { getStanzaGeneric()->setType(Presence::Unsubscribed); } - else if (type->second == "error") { + else if (*type == "error") { getStanzaGeneric()->setType(Presence::Error); } else { - std::cerr << "Unknown Presence type: " << type->second << std::endl; + std::cerr << "Unknown Presence type: " << *type << std::endl; getStanzaGeneric()->setType(Presence::Available); } } diff --git a/Swiften/Parser/PresenceParser.h b/Swiften/Parser/PresenceParser.h index cfecedf..19f90b3 100644 --- a/Swiften/Parser/PresenceParser.h +++ b/Swiften/Parser/PresenceParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_PresenceParser_H -#define SWIFTEN_PresenceParser_H +#pragma once -#include "Swiften/Parser/GenericStanzaParser.h" -#include "Swiften/Elements/Presence.h" +#include <Swiften/Parser/GenericStanzaParser.h> +#include <Swiften/Elements/Presence.h> namespace Swift { class PresenceParser : public GenericStanzaParser<Presence> { @@ -19,5 +18,3 @@ namespace Swift { virtual void handleStanzaAttributes(const AttributeMap&); }; } - -#endif diff --git a/Swiften/Parser/SConscript b/Swiften/Parser/SConscript index cbb2190..1cef02c 100644 --- a/Swiften/Parser/SConscript +++ b/Swiften/Parser/SConscript @@ -6,6 +6,7 @@ myenv.MergeFlags(swiften_env.get("LIBXML_FLAGS", "")) myenv.MergeFlags(swiften_env.get("EXPAT_FLAGS", "")) sources = [ + "AttributeMap.cpp", "AuthRequestParser.cpp", "AuthChallengeParser.cpp", "AuthSuccessParser.cpp", @@ -16,6 +17,7 @@ sources = [ "MessageParser.cpp", "PayloadParser.cpp", "StanzaAckParser.cpp", + "BOSHBodyExtractor.cpp", "ComponentHandshakeParser.cpp", "PayloadParserFactory.cpp", "PayloadParserFactoryCollection.cpp", @@ -25,10 +27,18 @@ sources = [ "PayloadParsers/CapsInfoParser.cpp", "PayloadParsers/DiscoInfoParser.cpp", "PayloadParsers/DiscoItemsParser.cpp", - "PayloadParsers/DelayParserFactory.cpp", "PayloadParsers/ErrorParser.cpp", "PayloadParsers/FormParser.cpp", "PayloadParsers/IBBParser.cpp", + "PayloadParsers/JingleParser.cpp", + "PayloadParsers/JingleReasonParser.cpp", + "PayloadParsers/JingleContentPayloadParser.cpp", + "PayloadParsers/JingleIBBTransportMethodPayloadParser.cpp", + "PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp", + "PayloadParsers/JingleFileTransferDescriptionParser.cpp", + "PayloadParsers/JingleFileTransferReceivedParser.cpp", + "PayloadParsers/JingleFileTransferHashParser.cpp", + "PayloadParsers/StreamInitiationFileInfoParser.cpp", "PayloadParsers/CommandParser.cpp", "PayloadParsers/InBandRegistrationPayloadParser.cpp", "PayloadParsers/SearchPayloadParser.cpp", @@ -37,6 +47,7 @@ sources = [ "PayloadParsers/PrivateStorageParser.cpp", "PayloadParsers/RawXMLPayloadParser.cpp", "PayloadParsers/ResourceBindParser.cpp", + "PayloadParsers/RosterItemExchangeParser.cpp", "PayloadParsers/RosterParser.cpp", "PayloadParsers/SecurityLabelParser.cpp", "PayloadParsers/SecurityLabelsCatalogParser.cpp", @@ -50,13 +61,26 @@ sources = [ "PayloadParsers/VCardUpdateParser.cpp", "PayloadParsers/DelayParser.cpp", "PayloadParsers/MUCUserPayloadParser.cpp", + "PayloadParsers/MUCAdminPayloadParser.cpp", + "PayloadParsers/MUCOwnerPayloadParser.cpp", + "PayloadParsers/MUCDestroyPayloadParser.cpp", + "PayloadParsers/MUCItemParser.cpp", "PayloadParsers/NicknameParser.cpp", + "PayloadParsers/ReplaceParser.cpp", + "PayloadParsers/LastParser.cpp", + "PayloadParsers/S5BProxyRequestParser.cpp", "PlatformXMLParserFactory.cpp", "PresenceParser.cpp", "SerializingParser.cpp", "StanzaParser.cpp", "StreamErrorParser.cpp", "StreamFeaturesParser.cpp", + "StreamManagementEnabledParser.cpp", + "StreamResumeParser.cpp", + "StreamResumedParser.cpp", + "Tree/ParserElement.cpp", + "Tree/NullParserElement.cpp", + "Tree/TreeReparser.cpp", "XMLParser.cpp", "XMLParserClient.cpp", "XMLParserFactory.cpp", diff --git a/Swiften/Parser/SerializingParser.cpp b/Swiften/Parser/SerializingParser.cpp index 43dfc51..cd044cc 100644 --- a/Swiften/Parser/SerializingParser.cpp +++ b/Swiften/Parser/SerializingParser.cpp @@ -4,10 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/SerializingParser.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" -#include "Swiften/Base/foreach.h" -#include <iostream> +#include <Swiften/Parser/SerializingParser.h> + +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Base/foreach.h> namespace Swift { @@ -15,9 +17,10 @@ SerializingParser::SerializingParser() { } void SerializingParser::handleStartElement(const std::string& tag, const std::string& ns, const AttributeMap& attributes) { - boost::shared_ptr<XMLElement> element(new XMLElement(tag, ns)); - for (AttributeMap::const_iterator i = attributes.begin(); i != attributes.end(); ++i) { - element->setAttribute((*i).first, (*i).second); + boost::shared_ptr<XMLElement> element = boost::make_shared<XMLElement>(tag, ns); + // FIXME: Ignoring attribute namespace + foreach (const AttributeMap::Entry& e, attributes.getEntries()) { + element->setAttribute(e.getAttribute().getName(), e.getValue()); } if (elementStack_.empty()) { @@ -36,7 +39,7 @@ void SerializingParser::handleEndElement(const std::string&, const std::string&) void SerializingParser::handleCharacterData(const std::string& data) { if (!elementStack_.empty()) { - (*(elementStack_.end()-1))->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(data))); + (*(elementStack_.end()-1))->addNode(boost::make_shared<XMLTextNode>(data)); } } diff --git a/Swiften/Parser/SerializingParser.h b/Swiften/Parser/SerializingParser.h index 6276ea0..5f2c0cd 100644 --- a/Swiften/Parser/SerializingParser.h +++ b/Swiften/Parser/SerializingParser.h @@ -4,12 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_SerializingParser_H -#define SWIFTEN_SerializingParser_H +#pragma once #include <string> -#include "Swiften/Parser/AttributeMap.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Parser/AttributeMap.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { class SerializingParser { @@ -27,5 +26,3 @@ namespace Swift { boost::shared_ptr<XMLElement> rootElement_; }; } - -#endif diff --git a/Swiften/Parser/StanzaAckParser.cpp b/Swiften/Parser/StanzaAckParser.cpp index 9d029cc..1730493 100644 --- a/Swiften/Parser/StanzaAckParser.cpp +++ b/Swiften/Parser/StanzaAckParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/StanzaAckParser.h" +#include <Swiften/Parser/StanzaAckParser.h> #include <boost/lexical_cast.hpp> diff --git a/Swiften/Parser/StanzaAckParser.h b/Swiften/Parser/StanzaAckParser.h index 4078dc1..c188878 100644 --- a/Swiften/Parser/StanzaAckParser.h +++ b/Swiften/Parser/StanzaAckParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/StanzaAck.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/StanzaAck.h> namespace Swift { class StanzaAckParser : public GenericElementParser<StanzaAck> { diff --git a/Swiften/Parser/StanzaAckRequestParser.h b/Swiften/Parser/StanzaAckRequestParser.h index 82290c6..9a2ccd1 100644 --- a/Swiften/Parser/StanzaAckRequestParser.h +++ b/Swiften/Parser/StanzaAckRequestParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/StanzaAckRequest.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/StanzaAckRequest.h> namespace Swift { class StanzaAckRequestParser : public GenericElementParser<StanzaAckRequest> { diff --git a/Swiften/Parser/StanzaParser.cpp b/Swiften/Parser/StanzaParser.cpp index 64c4901..271fbf0 100644 --- a/Swiften/Parser/StanzaParser.cpp +++ b/Swiften/Parser/StanzaParser.cpp @@ -4,15 +4,16 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/StanzaParser.h" +#include <Swiften/Parser/StanzaParser.h> #include <iostream> +#include <boost/optional.hpp> #include <cassert> -#include "Swiften/Parser/PayloadParser.h" -#include "Swiften/Parser/PayloadParserFactory.h" -#include "Swiften/Parser/PayloadParserFactoryCollection.h" -#include "Swiften/Parser/UnknownPayloadParser.h" +#include <Swiften/Parser/PayloadParser.h> +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/UnknownPayloadParser.h> namespace Swift { @@ -26,7 +27,7 @@ StanzaParser::~StanzaParser() { void StanzaParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { if (inStanza()) { if (!inPayload()) { - assert(!currentPayloadParser_.get()); + assert(!currentPayloadParser_); PayloadParserFactory* payloadParserFactory = factories_->getPayloadParserFactory(element, ns, attributes); if (payloadParserFactory) { currentPayloadParser_.reset(payloadParserFactory->createPayloadParser()); @@ -35,21 +36,21 @@ void StanzaParser::handleStartElement(const std::string& element, const std::str currentPayloadParser_.reset(new UnknownPayloadParser()); } } - assert(currentPayloadParser_.get()); + assert(currentPayloadParser_); currentPayloadParser_->handleStartElement(element, ns, attributes); } else { - AttributeMap::const_iterator from = attributes.find("from"); - if (from != attributes.end()) { - getStanza()->setFrom(JID(from->second)); + boost::optional<std::string> from = attributes.getAttributeValue("from"); + if (from) { + getStanza()->setFrom(JID(*from)); } - AttributeMap::const_iterator to = attributes.find("to"); - if (to != attributes.end()) { - getStanza()->setTo(JID(to->second)); + boost::optional<std::string> to = attributes.getAttributeValue("to"); + if (to) { + getStanza()->setTo(JID(*to)); } - AttributeMap::const_iterator id = attributes.find("id"); - if (id != attributes.end()) { - getStanza()->setID(id->second); + boost::optional<std::string> id = attributes.getAttributeValue("id"); + if (id) { + getStanza()->setID(*id); } handleStanzaAttributes(attributes); } @@ -59,7 +60,7 @@ void StanzaParser::handleStartElement(const std::string& element, const std::str void StanzaParser::handleEndElement(const std::string& element, const std::string& ns) { assert(inStanza()); if (inPayload()) { - assert(currentPayloadParser_.get()); + assert(currentPayloadParser_); currentPayloadParser_->handleEndElement(element, ns); --currentDepth_; if (!inPayload()) { @@ -76,7 +77,7 @@ void StanzaParser::handleEndElement(const std::string& element, const std::strin } void StanzaParser::handleCharacterData(const std::string& data) { - if (currentPayloadParser_.get()) { + if (currentPayloadParser_) { currentPayloadParser_->handleCharacterData(data); } } diff --git a/Swiften/Parser/StanzaParser.h b/Swiften/Parser/StanzaParser.h index df01943..6887981 100644 --- a/Swiften/Parser/StanzaParser.h +++ b/Swiften/Parser/StanzaParser.h @@ -4,15 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StanzaParser_H -#define SWIFTEN_StanzaParser_H +#pragma once #include <boost/noncopyable.hpp> +#include <boost/shared_ptr.hpp> #include <string> -#include "Swiften/Elements/Stanza.h" -#include "Swiften/Parser/ElementParser.h" -#include "Swiften/Parser/AttributeMap.h" +#include <Swiften/Elements/Stanza.h> +#include <Swiften/Parser/ElementParser.h> +#include <Swiften/Parser/AttributeMap.h> namespace Swift { class PayloadParser; @@ -47,8 +47,6 @@ namespace Swift { private: int currentDepth_; PayloadParserFactoryCollection* factories_; - std::auto_ptr<PayloadParser> currentPayloadParser_; + boost::shared_ptr<PayloadParser> currentPayloadParser_; }; } - -#endif diff --git a/Swiften/Parser/StartTLSFailureParser.h b/Swiften/Parser/StartTLSFailureParser.h index 29b2d90..41ecafb 100644 --- a/Swiften/Parser/StartTLSFailureParser.h +++ b/Swiften/Parser/StartTLSFailureParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StartTLSFailureParser_H -#define SWIFTEN_StartTLSFailureParser_H +#pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/StartTLSFailure.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/StartTLSFailure.h> namespace Swift { class StartTLSFailureParser : public GenericElementParser<StartTLSFailure> { @@ -16,5 +15,3 @@ namespace Swift { StartTLSFailureParser() : GenericElementParser<StartTLSFailure>() {} }; } - -#endif diff --git a/Swiften/Parser/StartTLSParser.h b/Swiften/Parser/StartTLSParser.h index 3822c3f..9bc7576 100644 --- a/Swiften/Parser/StartTLSParser.h +++ b/Swiften/Parser/StartTLSParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StartTLSParser_H -#define SWIFTEN_StartTLSParser_H +#pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/StartTLSRequest.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/StartTLSRequest.h> namespace Swift { class StartTLSParser : public GenericElementParser<StartTLSRequest> { @@ -16,5 +15,3 @@ namespace Swift { StartTLSParser() : GenericElementParser<StartTLSRequest>() {} }; } - -#endif diff --git a/Swiften/Parser/StreamFeaturesParser.cpp b/Swiften/Parser/StreamFeaturesParser.cpp index 377f215..6a527ce 100644 --- a/Swiften/Parser/StreamFeaturesParser.cpp +++ b/Swiften/Parser/StreamFeaturesParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/StreamFeaturesParser.h" +#include <Swiften/Parser/StreamFeaturesParser.h> namespace Swift { @@ -31,6 +31,9 @@ void StreamFeaturesParser::handleStartElement(const std::string& element, const else if (element == "compression" && ns == "http://jabber.org/features/compress") { inCompression_ = true; } + else if (element == "ver" && ns == "urn:xmpp:features:rosterver") { + getElementGeneric()->setHasRosterVersioning(); + } } else if (currentDepth_ == 2) { if (inCompression_ && element == "method") { diff --git a/Swiften/Parser/StreamFeaturesParser.h b/Swiften/Parser/StreamFeaturesParser.h index ee65a2a..d55abe9 100644 --- a/Swiften/Parser/StreamFeaturesParser.h +++ b/Swiften/Parser/StreamFeaturesParser.h @@ -4,12 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_STREAMFEATURESPARSER_H -#define SWIFTEN_STREAMFEATURESPARSER_H +#pragma once #include <string> -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/StreamFeatures.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/StreamFeatures.h> namespace Swift { class StreamFeaturesParser : public GenericElementParser<StreamFeatures> { @@ -30,5 +29,3 @@ namespace Swift { bool inCompressionMethod_; }; } - -#endif diff --git a/Swiften/Parser/StreamManagementEnabledParser.cpp b/Swiften/Parser/StreamManagementEnabledParser.cpp new file mode 100644 index 0000000..906e071 --- /dev/null +++ b/Swiften/Parser/StreamManagementEnabledParser.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Parser/StreamManagementEnabledParser.h> + +using namespace Swift; + +StreamManagementEnabledParser::StreamManagementEnabledParser() : level(TopLevel) { +} + +StreamManagementEnabledParser::~StreamManagementEnabledParser() { +} + +void StreamManagementEnabledParser::handleStartElement(const std::string&, const std::string&, const AttributeMap& attributes) { + if (level == TopLevel) { + if (attributes.getBoolAttribute("resume", false)) { + getElementGeneric()->setResumeSupported(); + } + getElementGeneric()->setResumeID(attributes.getAttribute("id")); + } + ++level; +} + +void StreamManagementEnabledParser::handleEndElement(const std::string&, const std::string&) { + --level; +} diff --git a/Swiften/Parser/StreamManagementEnabledParser.h b/Swiften/Parser/StreamManagementEnabledParser.h index adc45ab..db616af 100644 --- a/Swiften/Parser/StreamManagementEnabledParser.h +++ b/Swiften/Parser/StreamManagementEnabledParser.h @@ -1,17 +1,27 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2011 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/StreamManagementEnabled.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/StreamManagementEnabled.h> namespace Swift { class StreamManagementEnabledParser : public GenericElementParser<StreamManagementEnabled> { public: - StreamManagementEnabledParser() : GenericElementParser<StreamManagementEnabled>() {} + StreamManagementEnabledParser(); + ~StreamManagementEnabledParser(); + + virtual void handleStartElement(const std::string&, const std::string&, const AttributeMap&); + virtual void handleEndElement(const std::string&, const std::string&); + + private: + enum Level { + TopLevel = 0 + }; + int level; }; } diff --git a/Swiften/Parser/StreamManagementFailedParser.h b/Swiften/Parser/StreamManagementFailedParser.h index 07f5935..6c111d0 100644 --- a/Swiften/Parser/StreamManagementFailedParser.h +++ b/Swiften/Parser/StreamManagementFailedParser.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/StreamManagementFailed.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/StreamManagementFailed.h> namespace Swift { class StreamManagementFailedParser : public GenericElementParser<StreamManagementFailed> { diff --git a/Swiften/Parser/StreamResumeParser.cpp b/Swiften/Parser/StreamResumeParser.cpp new file mode 100644 index 0000000..cb1a61d --- /dev/null +++ b/Swiften/Parser/StreamResumeParser.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Parser/StreamResumeParser.h> + +#include <boost/lexical_cast.hpp> + +using namespace Swift; + +StreamResumeParser::StreamResumeParser() : level(TopLevel) { +} + +StreamResumeParser::~StreamResumeParser() { +} + +void StreamResumeParser::handleStartElement(const std::string&, const std::string&, const AttributeMap& attributes) { + if (level == TopLevel) { + boost::optional<std::string> handledStanzasCount = attributes.getAttributeValue("h"); + if (handledStanzasCount) { + try { + getElementGeneric()->setHandledStanzasCount(boost::lexical_cast<unsigned int>(*handledStanzasCount)); + } + catch (const boost::bad_lexical_cast &) { + } + } + getElementGeneric()->setResumeID(attributes.getAttribute("previd")); + } + ++level; +} + +void StreamResumeParser::handleEndElement(const std::string&, const std::string&) { + --level; +} diff --git a/Swiften/Parser/StreamResumeParser.h b/Swiften/Parser/StreamResumeParser.h new file mode 100644 index 0000000..0ccd24c --- /dev/null +++ b/Swiften/Parser/StreamResumeParser.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/StreamResume.h> + +namespace Swift { + class StreamResumeParser : public GenericElementParser<StreamResume> { + public: + StreamResumeParser(); + ~StreamResumeParser(); + + virtual void handleStartElement(const std::string&, const std::string&, const AttributeMap&); + virtual void handleEndElement(const std::string&, const std::string&); + + private: + enum Level { + TopLevel = 0 + }; + int level; + }; +} diff --git a/Swiften/Parser/StreamResumedParser.cpp b/Swiften/Parser/StreamResumedParser.cpp new file mode 100644 index 0000000..4b39c04 --- /dev/null +++ b/Swiften/Parser/StreamResumedParser.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Parser/StreamResumedParser.h> + +#include <boost/lexical_cast.hpp> + +using namespace Swift; + +StreamResumedParser::StreamResumedParser() : level(TopLevel) { +} + +StreamResumedParser::~StreamResumedParser() { +} + +void StreamResumedParser::handleStartElement(const std::string&, const std::string&, const AttributeMap& attributes) { + if (level == TopLevel) { + boost::optional<std::string> handledStanzasCount = attributes.getAttributeValue("h"); + if (handledStanzasCount) { + try { + getElementGeneric()->setHandledStanzasCount(boost::lexical_cast<unsigned int>(*handledStanzasCount)); + } + catch (const boost::bad_lexical_cast &) { + } + } + getElementGeneric()->setResumeID(attributes.getAttribute("previd")); + } + ++level; +} + +void StreamResumedParser::handleEndElement(const std::string&, const std::string&) { + --level; +} diff --git a/Swiften/Parser/StreamResumedParser.h b/Swiften/Parser/StreamResumedParser.h new file mode 100644 index 0000000..f2377aa --- /dev/null +++ b/Swiften/Parser/StreamResumedParser.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/StreamResumed.h> + +namespace Swift { + class StreamResumedParser : public GenericElementParser<StreamResumed> { + public: + StreamResumedParser(); + ~StreamResumedParser(); + + virtual void handleStartElement(const std::string&, const std::string&, const AttributeMap&); + virtual void handleEndElement(const std::string&, const std::string&); + + private: + enum Level { + TopLevel = 0 + }; + int level; + }; +} diff --git a/Swiften/Parser/TLSProceedParser.h b/Swiften/Parser/TLSProceedParser.h index 20a44d7..d36f088 100644 --- a/Swiften/Parser/TLSProceedParser.h +++ b/Swiften/Parser/TLSProceedParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_TLSProceedParser_H -#define SWIFTEN_TLSProceedParser_H +#pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/TLSProceed.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/TLSProceed.h> namespace Swift { class TLSProceedParser : public GenericElementParser<TLSProceed> { @@ -16,5 +15,3 @@ namespace Swift { TLSProceedParser() : GenericElementParser<TLSProceed>() {} }; } - -#endif diff --git a/Swiften/Parser/Tree/NullParserElement.cpp b/Swiften/Parser/Tree/NullParserElement.cpp new file mode 100644 index 0000000..7dda9c3 --- /dev/null +++ b/Swiften/Parser/Tree/NullParserElement.cpp @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Parser/Tree/NullParserElement.h> + +namespace Swift { + +boost::shared_ptr<NullParserElement> NullParserElement::element = boost::make_shared<NullParserElement>(); + +} diff --git a/Swiften/Parser/Tree/NullParserElement.h b/Swiften/Parser/Tree/NullParserElement.h new file mode 100644 index 0000000..8dd9bc1 --- /dev/null +++ b/Swiften/Parser/Tree/NullParserElement.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <string> +#include <Swiften/Parser/Tree/ParserElement.h> + +namespace Swift { + class NullParserElement : public ParserElement { + public: + NullParserElement() : ParserElement("", "", AttributeMap()) {} + + virtual operator bool() { return false; } + + static boost::shared_ptr<NullParserElement> element; + }; +} diff --git a/Swiften/Parser/Tree/ParserElement.cpp b/Swiften/Parser/Tree/ParserElement.cpp new file mode 100644 index 0000000..9d9b9b6 --- /dev/null +++ b/Swiften/Parser/Tree/ParserElement.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + + +#include <Swiften/Parser/Tree/ParserElement.h> +#include <Swiften/Parser/Tree/NullParserElement.h> + +#include <iostream> + +namespace Swift{ + +ParserElement::ParserElement(const std::string& name, const std::string& xmlns, const AttributeMap& attributes) : name_(name), xmlns_(xmlns), attributes_(attributes) { +} + +ParserElement::~ParserElement() { +} + +ParserElement::ref ParserElement::addChild(const std::string& name, const std::string& xmlns, const AttributeMap& attributes) { + ParserElement::ref child = boost::make_shared<ParserElement>(name, xmlns, attributes); + children_.push_back(child); + return child; +} + +void ParserElement::appendCharacterData(const std::string& data) { + text_ += data; +} + +struct DoesntMatch { + public: + DoesntMatch(const std::string& tagName, const std::string& ns) : tagName(tagName), ns(ns) {} + bool operator()(ParserElement::ref element) { return element->getName() != tagName || element->getNamespace() != ns; } + private: + std::string tagName; + std::string ns; +}; + + +std::vector<ParserElement::ref> ParserElement::getChildren(const std::string& name, const std::string& xmlns) const { + std::vector<ParserElement::ref> result; + std::remove_copy_if(children_.begin(), children_.end(), std::back_inserter(result), DoesntMatch(name, xmlns)); + return result; +} + +ParserElement::ref ParserElement::getChild(const std::string& name, const std::string& xmlns) const { + std::vector<ParserElement::ref> results = getChildren(name, xmlns); + ParserElement::ref result = results.empty() ? NullParserElement::element : results[0]; + return result; +} + +} diff --git a/Swiften/Parser/Tree/ParserElement.h b/Swiften/Parser/Tree/ParserElement.h new file mode 100644 index 0000000..b268c76 --- /dev/null +++ b/Swiften/Parser/Tree/ParserElement.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + + +#pragma once + +#include <string> +#include <vector> +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Parser/AttributeMap.h> +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +namespace Swift { + class ParserElement { + public: + typedef boost::shared_ptr<ParserElement> ref; + + ParserElement(const std::string& name, const std::string& xmlns, const AttributeMap& attributes); + virtual ~ParserElement(); + + const std::string& getText() const { return text_; } + const std::string& getName() const { return name_; } + const std::string& getNamespace() const { return xmlns_; } + const AttributeMap& getAttributes() const { return attributes_; } + + ParserElement::ref addChild(const std::string& name, const std::string& xmlns, const AttributeMap& attributes); + void appendCharacterData(const std::string& data); + + std::vector<ParserElement::ref> getChildren(const std::string& name, const std::string& xmlns) const; + const std::vector<ParserElement::ref>& getAllChildren() const {return children_;} + ParserElement::ref getChild(const std::string& name, const std::string& xmlns) const; + + virtual operator bool() { + return true; + } + + private: + std::vector<ParserElement::ref> children_; + std::string name_; + std::string xmlns_; + AttributeMap attributes_; + std::string text_; + }; +} diff --git a/Swiften/Parser/Tree/TreeReparser.cpp b/Swiften/Parser/Tree/TreeReparser.cpp new file mode 100644 index 0000000..9d09831 --- /dev/null +++ b/Swiften/Parser/Tree/TreeReparser.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Parser/Tree/TreeReparser.h> + +#include <boost/lexical_cast.hpp> +#include <utility> +#include <deque> + +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Parser/PayloadParser.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Elements/MUCOccupant.h> + +namespace Swift { + +typedef std::pair<ParserElement::ref, bool> ElementState; + +boost::shared_ptr<Payload> TreeReparser::parseTree(ParserElement::ref root, PayloadParserFactoryCollection* collection) { + PayloadParser* parser = collection->getPayloadParserFactory(root->getName(), root->getNamespace(), root->getAttributes())->createPayloadParser(); + std::deque<ElementState > stack; + stack.push_back(ElementState(root, true)); + while (!stack.empty()) { + ElementState current = stack.back(); + stack.pop_back(); + if (current.second) { + stack.push_back(ElementState(current.first, false)); + parser->handleStartElement(current.first->getName(), current.first->getNamespace(), current.first->getAttributes()); + foreach(ParserElement::ref child, current.first->getAllChildren()) { + stack.push_back(ElementState(child, true)); + } + } else { + parser->handleCharacterData(current.first->getText()); + parser->handleEndElement(current.first->getName(), current.first->getNamespace()); + } + + } + + boost::shared_ptr<Payload> payload = parser->getPayload(); + delete parser; + return payload; +} + +} diff --git a/Swiften/Parser/Tree/TreeReparser.h b/Swiften/Parser/Tree/TreeReparser.h new file mode 100644 index 0000000..212c518 --- /dev/null +++ b/Swiften/Parser/Tree/TreeReparser.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Parser/GenericPayloadTreeParser.h> +#include <Swiften/Parser/PayloadParsers/MUCItemParser.h> + +namespace Swift { + class PayloadParserFactoryCollection; + class TreeReparser { + public: + static boost::shared_ptr<Payload> parseTree(ParserElement::ref root, PayloadParserFactoryCollection* collection); + + }; +} diff --git a/Swiften/Parser/UnitTest/AttributeMapTest.cpp b/Swiften/Parser/UnitTest/AttributeMapTest.cpp index fb68f29..d6c3c01 100644 --- a/Swiften/Parser/UnitTest/AttributeMapTest.cpp +++ b/Swiften/Parser/UnitTest/AttributeMapTest.cpp @@ -7,13 +7,14 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/AttributeMap.h" +#include <Swiften/Parser/AttributeMap.h> using namespace Swift; class AttributeMapTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(AttributeMapTest); + CPPUNIT_TEST(testGetAttribute_Namespaced); CPPUNIT_TEST(testGetBoolAttribute_True); CPPUNIT_TEST(testGetBoolAttribute_1); CPPUNIT_TEST(testGetBoolAttribute_False); @@ -24,39 +25,46 @@ class AttributeMapTest : public CppUnit::TestFixture CPPUNIT_TEST_SUITE_END(); public: - AttributeMapTest() {} + void testGetAttribute_Namespaced() { + AttributeMap testling; + testling.addAttribute("lang", "", "nl"); + testling.addAttribute("lang", "http://www.w3.org/XML/1998/namespace", "en"); + testling.addAttribute("lang", "", "fr"); + + CPPUNIT_ASSERT_EQUAL(std::string("en"), testling.getAttribute("lang", "http://www.w3.org/XML/1998/namespace")); + } void testGetBoolAttribute_True() { AttributeMap testling; - testling["foo"] = "true"; + testling.addAttribute("foo", "", "true"); CPPUNIT_ASSERT(testling.getBoolAttribute("foo")); } void testGetBoolAttribute_1() { AttributeMap testling; - testling["foo"] = "1"; + testling.addAttribute("foo", "", "1"); CPPUNIT_ASSERT(testling.getBoolAttribute("foo")); } void testGetBoolAttribute_False() { AttributeMap testling; - testling["foo"] = "false"; + testling.addAttribute("foo", "", "false"); CPPUNIT_ASSERT(!testling.getBoolAttribute("foo", true)); } void testGetBoolAttribute_0() { AttributeMap testling; - testling["foo"] = "0"; + testling.addAttribute("foo", "", "0"); CPPUNIT_ASSERT(!testling.getBoolAttribute("foo", true)); } void testGetBoolAttribute_Invalid() { AttributeMap testling; - testling["foo"] = "bla"; + testling.addAttribute("foo", "", "bla"); CPPUNIT_ASSERT(!testling.getBoolAttribute("foo", true)); } diff --git a/Swiften/Parser/UnitTest/BOSHBodyExtractorTest.cpp b/Swiften/Parser/UnitTest/BOSHBodyExtractorTest.cpp new file mode 100644 index 0000000..fc7d17b --- /dev/null +++ b/Swiften/Parser/UnitTest/BOSHBodyExtractorTest.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Parser/PlatformXMLParserFactory.h> +#include <Swiften/Parser/BOSHBodyExtractor.h> + +using namespace Swift; + +class BOSHBodyExtractorTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(BOSHBodyExtractorTest); + CPPUNIT_TEST(testGetBody); + CPPUNIT_TEST(testGetBody_EmptyContent); + CPPUNIT_TEST(testGetBody_EmptyContent2); + CPPUNIT_TEST(testGetBody_EmptyElementEmptyContent); + CPPUNIT_TEST(testGetBody_InvalidStartTag); + CPPUNIT_TEST(testGetBody_InvalidStartTag2); + CPPUNIT_TEST(testGetBody_IncompleteStartTag); + CPPUNIT_TEST(testGetBody_InvalidEndTag); + CPPUNIT_TEST(testGetBody_InvalidEndTag2); + CPPUNIT_TEST_SUITE_END(); + + public: + void testGetBody() { + BOSHBodyExtractor testling(&parserFactory, createByteArray( + "<body a1='a\"1' a2=\"a'2\" boo='bar' >" + "foo <message> <body> bar" + "</body > ")); + + CPPUNIT_ASSERT(testling.getBody()); + CPPUNIT_ASSERT_EQUAL(std::string("a\"1"), testling.getBody()->attributes.getAttribute("a1")); + CPPUNIT_ASSERT_EQUAL(std::string("foo <message> <body> bar"), testling.getBody()->content); + } + + void testGetBody_EmptyContent() { + BOSHBodyExtractor testling(&parserFactory, createByteArray( + "<body foo='bar'/>")); + + CPPUNIT_ASSERT(testling.getBody()); + CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getBody()->attributes.getAttribute("foo")); + CPPUNIT_ASSERT(testling.getBody()->content.empty()); + } + + void testGetBody_EmptyContent2() { + BOSHBodyExtractor testling(&parserFactory, createByteArray( + "<body foo='bar'></body>")); + + CPPUNIT_ASSERT(testling.getBody()); + CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getBody()->attributes.getAttribute("foo")); + CPPUNIT_ASSERT(testling.getBody()->content.empty()); + } + + void testGetBody_EmptyElementEmptyContent() { + BOSHBodyExtractor testling(&parserFactory, createByteArray( + "<body/>")); + + CPPUNIT_ASSERT(testling.getBody()); + } + + void testGetBody_InvalidStartTag() { + BOSHBodyExtractor testling(&parserFactory, createByteArray( + "<bodi></body>")); + + CPPUNIT_ASSERT(!testling.getBody()); + } + + void testGetBody_InvalidStartTag2() { + BOSHBodyExtractor testling(&parserFactory, createByteArray( + "<bodyy></body>")); + + CPPUNIT_ASSERT(!testling.getBody()); + } + + void testGetBody_IncompleteStartTag() { + BOSHBodyExtractor testling(&parserFactory, createByteArray( + "<body")); + + CPPUNIT_ASSERT(!testling.getBody()); + } + + void testGetBody_InvalidEndTag() { + BOSHBodyExtractor testling(&parserFactory, createByteArray( + "<body></bodi>")); + + CPPUNIT_ASSERT(!testling.getBody()); + } + + void testGetBody_InvalidEndTag2() { + BOSHBodyExtractor testling(&parserFactory, createByteArray( + "<body><b/body>")); + + CPPUNIT_ASSERT(!testling.getBody()); + } + + private: + PlatformXMLParserFactory parserFactory; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(BOSHBodyExtractorTest); diff --git a/Swiften/Parser/UnitTest/ElementParserTester.h b/Swiften/Parser/UnitTest/ElementParserTester.h index ba39eb7..76b8870 100644 --- a/Swiften/Parser/UnitTest/ElementParserTester.h +++ b/Swiften/Parser/UnitTest/ElementParserTester.h @@ -4,13 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_ElementParserTester_H -#define SWIFTEN_ElementParserTester_H +#pragma once -#include "Swiften/Parser/UnitTest/ParserTester.h" + +#include <Swiften/Parser/UnitTest/ParserTester.h> namespace Swift { typedef ParserTester<ElementParser> ElementParserTester; } - -#endif diff --git a/Swiften/Parser/UnitTest/GenericPayloadTreeParserTest.cpp b/Swiften/Parser/UnitTest/GenericPayloadTreeParserTest.cpp new file mode 100644 index 0000000..d095afc --- /dev/null +++ b/Swiften/Parser/UnitTest/GenericPayloadTreeParserTest.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Parser/GenericPayloadTreeParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h> +#include <Swiften/Elements/RawXMLPayload.h> + +using namespace Swift; + +class GenericPayloadTreeParserTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(GenericPayloadTreeParserTest); + CPPUNIT_TEST(testTree); + CPPUNIT_TEST_SUITE_END(); + + public: + void testTree() { + MyParser testling; + + std::string data = "<topLevel xmlns='urn:test:top'><firstLevelInheritedEmpty/><firstLevelInherited><secondLevelMultiChildren num='1'/><secondLevelMultiChildren num='2'/></firstLevelInherited><firstLevelNS xmlns='urn:test:first'/></topLevel>"; + + PayloadParserTester tester(&testling); + tester.parse(data); + + ParserElement::ref tree = testling.tree; + + CPPUNIT_ASSERT_EQUAL(std::string("topLevel"), tree->getName()); + CPPUNIT_ASSERT_EQUAL(std::string("urn:test:top"), tree->getNamespace()); + CPPUNIT_ASSERT(tree->getChild("firstLevelInheritedEmpty", "urn:test:top")); + CPPUNIT_ASSERT(!*tree->getChild("firstLevelInheritedEmpty", "")); + CPPUNIT_ASSERT(tree->getChild("firstLevelInherited", "urn:test:top")); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), tree->getChild("firstLevelInherited", "urn:test:top")->getChildren("secondLevelMultiChildren", "urn:test:top").size()); + CPPUNIT_ASSERT_EQUAL(std::string("1"), tree->getChild("firstLevelInherited", "urn:test:top")->getChildren("secondLevelMultiChildren", "urn:test:top")[0]->getAttributes().getAttribute("num")); + CPPUNIT_ASSERT_EQUAL(std::string("2"), tree->getChild("firstLevelInherited", "urn:test:top")->getChildren("secondLevelMultiChildren", "urn:test:top")[1]->getAttributes().getAttribute("num")); + CPPUNIT_ASSERT(tree->getChild("firstLevelNS", "urn:test:first")); + } + + private: + + + class MyParser : public GenericPayloadTreeParser<RawXMLPayload> + { + public: + virtual ~MyParser() {} + virtual void handleTree(ParserElement::ref root) { + tree = root; + } + ParserElement::ref tree; + }; + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(GenericPayloadTreeParserTest); diff --git a/Swiften/Parser/UnitTest/IQParserTest.cpp b/Swiften/Parser/UnitTest/IQParserTest.cpp index 3cc7d45..3c86a5d 100644 --- a/Swiften/Parser/UnitTest/IQParserTest.cpp +++ b/Swiften/Parser/UnitTest/IQParserTest.cpp @@ -7,9 +7,9 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/IQParser.h" -#include "Swiften/Parser/PayloadParserFactoryCollection.h" -#include "Swiften/Parser/UnitTest/StanzaParserTester.h" +#include <Swiften/Parser/IQParser.h> +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/UnitTest/StanzaParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/UnitTest/MessageParserTest.cpp b/Swiften/Parser/UnitTest/MessageParserTest.cpp index 7615fa3..8ab59ed 100644 --- a/Swiften/Parser/UnitTest/MessageParserTest.cpp +++ b/Swiften/Parser/UnitTest/MessageParserTest.cpp @@ -7,9 +7,9 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/MessageParser.h" -#include "Swiften/Parser/PayloadParserFactoryCollection.h" -#include "Swiften/Parser/UnitTest/StanzaParserTester.h" +#include <Swiften/Parser/MessageParser.h> +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/UnitTest/StanzaParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/UnitTest/ParserTester.h b/Swiften/Parser/UnitTest/ParserTester.h index 970c1be..73f013c 100644 --- a/Swiften/Parser/UnitTest/ParserTester.h +++ b/Swiften/Parser/UnitTest/ParserTester.h @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_ParserTester_H -#define SWIFTEN_ParserTester_H +#pragma once -#include "Swiften/Parser/XMLParserClient.h" -#include "Swiften/Parser/PlatformXMLParserFactory.h" -#include "Swiften/Parser/XMLParser.h" + +#include <Swiften/Parser/XMLParserClient.h> +#include <Swiften/Parser/PlatformXMLParserFactory.h> +#include <Swiften/Parser/XMLParser.h> namespace Swift { class XMLParser; @@ -46,5 +46,3 @@ namespace Swift { ParserType* parser_; }; } - -#endif diff --git a/Swiften/Parser/UnitTest/PayloadParserFactoryCollectionTest.cpp b/Swiften/Parser/UnitTest/PayloadParserFactoryCollectionTest.cpp index 8e49764..fea64e2 100644 --- a/Swiften/Parser/UnitTest/PayloadParserFactoryCollectionTest.cpp +++ b/Swiften/Parser/UnitTest/PayloadParserFactoryCollectionTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PayloadParserFactoryCollection.h" -#include "Swiften/Parser/PayloadParserFactory.h" +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/PayloadParserFactory.h> using namespace Swift; diff --git a/Swiften/Parser/UnitTest/PresenceParserTest.cpp b/Swiften/Parser/UnitTest/PresenceParserTest.cpp index f68db40..f9d6cf6 100644 --- a/Swiften/Parser/UnitTest/PresenceParserTest.cpp +++ b/Swiften/Parser/UnitTest/PresenceParserTest.cpp @@ -7,9 +7,9 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/PresenceParser.h" -#include "Swiften/Parser/PayloadParserFactoryCollection.h" -#include "Swiften/Parser/UnitTest/StanzaParserTester.h" +#include <Swiften/Parser/PresenceParser.h> +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/UnitTest/StanzaParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/UnitTest/SerializingParserTest.cpp b/Swiften/Parser/UnitTest/SerializingParserTest.cpp index c0af493..aef1dfb 100644 --- a/Swiften/Parser/UnitTest/SerializingParserTest.cpp +++ b/Swiften/Parser/UnitTest/SerializingParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/SerializingParser.h" -#include "Swiften/Parser/UnitTest/StanzaParserTester.h" +#include <Swiften/Parser/SerializingParser.h> +#include <Swiften/Parser/UnitTest/StanzaParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/UnitTest/StanzaAckParserTest.cpp b/Swiften/Parser/UnitTest/StanzaAckParserTest.cpp index b90af6e..b68fb30 100644 --- a/Swiften/Parser/UnitTest/StanzaAckParserTest.cpp +++ b/Swiften/Parser/UnitTest/StanzaAckParserTest.cpp @@ -7,9 +7,9 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/StanzaAckParser.h" -#include "Swiften/Parser/PayloadParserFactoryCollection.h" -#include "Swiften/Parser/UnitTest/ElementParserTester.h" +#include <Swiften/Parser/StanzaAckParser.h> +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Parser/UnitTest/ElementParserTester.h> using namespace Swift; diff --git a/Swiften/Parser/UnitTest/StanzaParserTest.cpp b/Swiften/Parser/UnitTest/StanzaParserTest.cpp index d57f798..b2ddb39 100644 --- a/Swiften/Parser/UnitTest/StanzaParserTest.cpp +++ b/Swiften/Parser/UnitTest/StanzaParserTest.cpp @@ -7,12 +7,12 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/StanzaParser.h" -#include "Swiften/Parser/GenericPayloadParser.h" -#include "Swiften/Parser/PayloadParserFactory.h" -#include "Swiften/Parser/PayloadParserFactoryCollection.h" -#include "Swiften/Elements/Stanza.h" -#include "Swiften/Elements/Payload.h" +#include <Swiften/Parser/StanzaParser.h> +#include <Swiften/Parser/GenericPayloadParser.h> +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Elements/Stanza.h> +#include <Swiften/Elements/Payload.h> using namespace Swift; @@ -40,8 +40,8 @@ class StanzaParserTest : public CppUnit::TestFixture { MyStanzaParser testling(factoryCollection_); AttributeMap attributes; - attributes["foo"] = "fum"; - attributes["bar"] = "baz"; + attributes.addAttribute("foo", "", "fum"); + attributes.addAttribute("bar", "", "baz"); testling.handleStartElement("mystanza", "", attributes); testling.handleStartElement("mypayload1", "", attributes); testling.handleStartElement("child", "", attributes); @@ -107,9 +107,9 @@ class StanzaParserTest : public CppUnit::TestFixture { MyStanzaParser testling(factoryCollection_); AttributeMap attributes; - attributes["to"] = "foo@example.com/blo"; - attributes["from"] = "bar@example.com/baz"; - attributes["id"] = "id-123"; + attributes.addAttribute("to", "", "foo@example.com/blo"); + attributes.addAttribute("from", "", "bar@example.com/baz"); + attributes.addAttribute("id", "", "id-123"); testling.handleStartElement("mystanza", "", attributes); testling.handleEndElement("mypayload1", ""); diff --git a/Swiften/Parser/UnitTest/StanzaParserTester.h b/Swiften/Parser/UnitTest/StanzaParserTester.h index eb3a18b..e4ce48e 100644 --- a/Swiften/Parser/UnitTest/StanzaParserTester.h +++ b/Swiften/Parser/UnitTest/StanzaParserTester.h @@ -4,14 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StanzaParserTester_H -#define SWIFTEN_StanzaParserTester_H +#pragma once -#include "Swiften/Parser/StanzaParser.h" -#include "Swiften/Parser/UnitTest/ParserTester.h" +#include <Swiften/Parser/StanzaParser.h> +#include <Swiften/Parser/UnitTest/ParserTester.h> namespace Swift { typedef ParserTester<StanzaParser> StanzaParserTester; } - -#endif diff --git a/Swiften/Parser/UnitTest/StreamFeaturesParserTest.cpp b/Swiften/Parser/UnitTest/StreamFeaturesParserTest.cpp index 1cdaf54..4bc971f 100644 --- a/Swiften/Parser/UnitTest/StreamFeaturesParserTest.cpp +++ b/Swiften/Parser/UnitTest/StreamFeaturesParserTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Parser/StreamFeaturesParser.h" -#include "Swiften/Parser/UnitTest/ElementParserTester.h" +#include <Swiften/Parser/StreamFeaturesParser.h> +#include <Swiften/Parser/UnitTest/ElementParserTester.h> using namespace Swift; @@ -37,6 +37,7 @@ class StreamFeaturesParserTest : public CppUnit::TestFixture { "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/>" "<sm xmlns='urn:xmpp:sm:2'/>" "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/>" + "<ver xmlns=\"urn:xmpp:features:rosterver\"/>" "</stream:features>")); StreamFeatures::ref element = boost::dynamic_pointer_cast<StreamFeatures>(testling.getElement()); @@ -49,6 +50,7 @@ class StreamFeaturesParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(element->hasAuthenticationMechanism("DIGEST-MD5")); CPPUNIT_ASSERT(element->hasAuthenticationMechanism("PLAIN")); CPPUNIT_ASSERT(element->hasStreamManagement()); + CPPUNIT_ASSERT(element->hasRosterVersioning()); } void testParse_Empty() { diff --git a/Swiften/Parser/UnitTest/StreamManagementEnabledParserTest.cpp b/Swiften/Parser/UnitTest/StreamManagementEnabledParserTest.cpp new file mode 100644 index 0000000..07b7b31 --- /dev/null +++ b/Swiften/Parser/UnitTest/StreamManagementEnabledParserTest.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Parser/StreamManagementEnabledParser.h> +#include <Swiften/Parser/UnitTest/ElementParserTester.h> + +using namespace Swift; + +class StreamManagementEnabledParserTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(StreamManagementEnabledParserTest); + CPPUNIT_TEST(testParse); + CPPUNIT_TEST_SUITE_END(); + + public: + void testParse() { + StreamManagementEnabledParser testling; + ElementParserTester parser(&testling); + + CPPUNIT_ASSERT(parser.parse( + "<enabled xmlns=\"urn:xmpp:sm:3\" id=\"some-long-sm-id\" resume=\"true\"/>")); + + boost::shared_ptr<StreamManagementEnabled> element = boost::dynamic_pointer_cast<StreamManagementEnabled>(testling.getElement()); + CPPUNIT_ASSERT(element->getResumeSupported()); + CPPUNIT_ASSERT_EQUAL(std::string("some-long-sm-id"), element->getResumeID()); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(StreamManagementEnabledParserTest); diff --git a/Swiften/Parser/UnitTest/XMLParserTest.cpp b/Swiften/Parser/UnitTest/XMLParserTest.cpp index 2086ece..8ff56c0 100644 --- a/Swiften/Parser/UnitTest/XMLParserTest.cpp +++ b/Swiften/Parser/UnitTest/XMLParserTest.cpp @@ -9,12 +9,12 @@ #include <vector> #include <string> -#include "Swiften/Parser/XMLParserClient.h" +#include <Swiften/Parser/XMLParserClient.h> #ifdef HAVE_EXPAT -#include "Swiften/Parser/ExpatParser.h" +#include <Swiften/Parser/ExpatParser.h> #endif #ifdef HAVE_LIBXML -#include "Swiften/Parser/LibXMLParser.h" +#include <Swiften/Parser/LibXMLParser.h> #endif using namespace Swift; @@ -32,6 +32,8 @@ class XMLParserTest : public CppUnit::TestFixture { CPPUNIT_TEST(testParse_InErrorState); CPPUNIT_TEST(testParse_Incremental); CPPUNIT_TEST(testParse_WhitespaceInAttribute); + CPPUNIT_TEST(testParse_AttributeWithoutNamespace); + CPPUNIT_TEST(testParse_AttributeWithNamespace); CPPUNIT_TEST(testParse_BillionLaughs); CPPUNIT_TEST_SUITE_END(); @@ -48,13 +50,13 @@ class XMLParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); CPPUNIT_ASSERT_EQUAL(std::string("iq"), client_.events[0].data); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[0].attributes.size()); - CPPUNIT_ASSERT_EQUAL(std::string("get"), client_.events[0].attributes["type"]); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[0].attributes.getEntries().size()); + CPPUNIT_ASSERT_EQUAL(std::string("get"), client_.events[0].attributes.getAttribute("type")); CPPUNIT_ASSERT_EQUAL(std::string(), client_.events[0].ns); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[1].type); CPPUNIT_ASSERT_EQUAL(std::string("query"), client_.events[1].data); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), client_.events[1].attributes.size()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), client_.events[1].attributes.getEntries().size()); CPPUNIT_ASSERT_EQUAL(std::string("jabber:iq:version"), client_.events[1].ns); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[2].type); @@ -78,7 +80,7 @@ class XMLParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); CPPUNIT_ASSERT_EQUAL(std::string("query"), client_.events[0].data); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), client_.events[0].attributes.size()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), client_.events[0].attributes.getEntries().size()); CPPUNIT_ASSERT_EQUAL(std::string("jabber:iq:version"), client_.events[0].ns); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[1].type); @@ -228,6 +230,28 @@ class XMLParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(std::string("presence"), client_.events[2].data); } + void testParse_AttributeWithoutNamespace() { + ParserType testling(&client_); + + CPPUNIT_ASSERT(testling.parse( + "<query xmlns='http://swift.im' attr='3'/>")); + + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[0].attributes.getEntries().size()); + CPPUNIT_ASSERT_EQUAL(std::string("attr"), client_.events[0].attributes.getEntries()[0].getAttribute().getName()); + CPPUNIT_ASSERT_EQUAL(std::string(""), client_.events[0].attributes.getEntries()[0].getAttribute().getNamespace()); + } + + void testParse_AttributeWithNamespace() { + ParserType testling(&client_); + + CPPUNIT_ASSERT(testling.parse( + "<query xmlns='http://swift.im' xmlns:f='http://swift.im/f' f:attr='3'/>")); + + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[0].attributes.getEntries().size()); + CPPUNIT_ASSERT_EQUAL(std::string("attr"), client_.events[0].attributes.getEntries()[0].getAttribute().getName()); + CPPUNIT_ASSERT_EQUAL(std::string("http://swift.im/f"), client_.events[0].attributes.getEntries()[0].getAttribute().getNamespace()); + } + void testParse_BillionLaughs() { ParserType testling(&client_); @@ -246,7 +270,6 @@ class XMLParserTest : public CppUnit::TestFixture { "]>" "<lolz>&lol9;</lolz>" )); - } private: diff --git a/Swiften/Parser/UnitTest/XMPPParserTest.cpp b/Swiften/Parser/UnitTest/XMPPParserTest.cpp index 8ce96d8..dbee18a 100644 --- a/Swiften/Parser/UnitTest/XMPPParserTest.cpp +++ b/Swiften/Parser/UnitTest/XMPPParserTest.cpp @@ -8,17 +8,17 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <vector> -#include "Swiften/Elements/ProtocolHeader.h" +#include <Swiften/Elements/ProtocolHeader.h> #include <string> -#include "Swiften/Parser/XMPPParser.h" -#include "Swiften/Parser/ElementParser.h" -#include "Swiften/Parser/XMPPParserClient.h" -#include "Swiften/Parser/PayloadParserFactoryCollection.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/Message.h" -#include "Swiften/Elements/StreamFeatures.h" -#include "Swiften/Elements/UnknownElement.h" +#include <Swiften/Parser/XMPPParser.h> +#include <Swiften/Parser/ElementParser.h> +#include <Swiften/Parser/XMPPParserClient.h> +#include <Swiften/Parser/PayloadParserFactoryCollection.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Elements/IQ.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/StreamFeatures.h> +#include <Swiften/Elements/UnknownElement.h> using namespace Swift; diff --git a/Swiften/Parser/UnknownElementParser.h b/Swiften/Parser/UnknownElementParser.h index 6ff885f..59133de 100644 --- a/Swiften/Parser/UnknownElementParser.h +++ b/Swiften/Parser/UnknownElementParser.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_UnknownElementParser_H -#define SWIFTEN_UnknownElementParser_H +#pragma once -#include "Swiften/Parser/GenericElementParser.h" -#include "Swiften/Elements/UnknownElement.h" +#include <Swiften/Parser/GenericElementParser.h> +#include <Swiften/Elements/UnknownElement.h> namespace Swift { class UnknownElementParser : public GenericElementParser<UnknownElement> { @@ -16,5 +15,3 @@ namespace Swift { UnknownElementParser() : GenericElementParser<UnknownElement>() {} }; } - -#endif diff --git a/Swiften/Parser/UnknownPayloadParser.h b/Swiften/Parser/UnknownPayloadParser.h index 8750f22..0843f41 100644 --- a/Swiften/Parser/UnknownPayloadParser.h +++ b/Swiften/Parser/UnknownPayloadParser.h @@ -4,16 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_UNKNOWNPAYLOADPARSER_H -#define SWIFTEN_UNKNOWNPAYLOADPARSER_H +#pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Parser/PayloadParser.h" +#include <Swiften/Parser/PayloadParser.h> namespace Swift { - - class UnknownPayloadParser : public PayloadParser { public: UnknownPayloadParser() {} @@ -27,5 +24,3 @@ namespace Swift { } }; } - -#endif diff --git a/Swiften/Parser/XMLParser.cpp b/Swiften/Parser/XMLParser.cpp index a2e73fc..cd7baea 100644 --- a/Swiften/Parser/XMLParser.cpp +++ b/Swiften/Parser/XMLParser.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/XMLParser.h" +#include <Swiften/Parser/XMLParser.h> namespace Swift { diff --git a/Swiften/Parser/XMLParserClient.cpp b/Swiften/Parser/XMLParserClient.cpp index c0e7853..46d57b7 100644 --- a/Swiften/Parser/XMLParserClient.cpp +++ b/Swiften/Parser/XMLParserClient.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/XMLParserClient.h" +#include <Swiften/Parser/XMLParserClient.h> namespace Swift { diff --git a/Swiften/Parser/XMLParserClient.h b/Swiften/Parser/XMLParserClient.h index 089ef35..ff706a0 100644 --- a/Swiften/Parser/XMLParserClient.h +++ b/Swiften/Parser/XMLParserClient.h @@ -7,7 +7,7 @@ #ifndef XMLPARSERCLIENT_H #define XMLPARSERCLIENT_H -#include "Swiften/Parser/AttributeMap.h" +#include <Swiften/Parser/AttributeMap.h> namespace Swift { diff --git a/Swiften/Parser/XMLParserFactory.cpp b/Swiften/Parser/XMLParserFactory.cpp index 9da0747..af719bf 100644 --- a/Swiften/Parser/XMLParserFactory.cpp +++ b/Swiften/Parser/XMLParserFactory.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/XMLParserFactory.h" +#include <Swiften/Parser/XMLParserFactory.h> namespace Swift { diff --git a/Swiften/Parser/XMLParserFactory.h b/Swiften/Parser/XMLParserFactory.h index 369c454..32665cb 100644 --- a/Swiften/Parser/XMLParserFactory.h +++ b/Swiften/Parser/XMLParserFactory.h @@ -4,8 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_XMLParserFactory_H -#define SWIFTEN_XMLParserFactory_H +#pragma once namespace Swift { class XMLParser; @@ -18,5 +17,3 @@ namespace Swift { virtual XMLParser* createXMLParser(XMLParserClient*) = 0; }; } - -#endif diff --git a/Swiften/Parser/XMPPParser.cpp b/Swiften/Parser/XMPPParser.cpp index 1fb7682..6779b86 100644 --- a/Swiften/Parser/XMPPParser.cpp +++ b/Swiften/Parser/XMPPParser.cpp @@ -4,41 +4,43 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/XMPPParser.h" +#include <Swiften/Parser/XMPPParser.h> #include <iostream> #include <cassert> -#include "Swiften/Elements/ProtocolHeader.h" +#include <Swiften/Elements/ProtocolHeader.h> #include <string> -#include "Swiften/Parser/XMLParser.h" -#include "Swiften/Parser/PlatformXMLParserFactory.h" -#include "Swiften/Parser/XMPPParserClient.h" -#include "Swiften/Parser/XMPPParser.h" -#include "Swiften/Parser/ElementParser.h" -#include "Swiften/Parser/PresenceParser.h" -#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" -#include "Swiften/Parser/AuthChallengeParser.h" -#include "Swiften/Parser/AuthResponseParser.h" -#include "Swiften/Parser/EnableStreamManagementParser.h" -#include "Swiften/Parser/StreamManagementEnabledParser.h" -#include "Swiften/Parser/StreamManagementFailedParser.h" -#include "Swiften/Parser/StanzaAckParser.h" -#include "Swiften/Parser/StanzaAckRequestParser.h" -#include "Swiften/Parser/StartTLSParser.h" -#include "Swiften/Parser/StartTLSFailureParser.h" -#include "Swiften/Parser/CompressParser.h" -#include "Swiften/Parser/CompressFailureParser.h" -#include "Swiften/Parser/CompressedParser.h" -#include "Swiften/Parser/UnknownElementParser.h" -#include "Swiften/Parser/TLSProceedParser.h" -#include "Swiften/Parser/ComponentHandshakeParser.h" +#include <Swiften/Parser/XMLParser.h> +#include <Swiften/Parser/PlatformXMLParserFactory.h> +#include <Swiften/Parser/XMPPParserClient.h> +#include <Swiften/Parser/XMPPParser.h> +#include <Swiften/Parser/ElementParser.h> +#include <Swiften/Parser/PresenceParser.h> +#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> +#include <Swiften/Parser/AuthChallengeParser.h> +#include <Swiften/Parser/AuthResponseParser.h> +#include <Swiften/Parser/EnableStreamManagementParser.h> +#include <Swiften/Parser/StreamManagementEnabledParser.h> +#include <Swiften/Parser/StreamManagementFailedParser.h> +#include <Swiften/Parser/StreamResumeParser.h> +#include <Swiften/Parser/StreamResumedParser.h> +#include <Swiften/Parser/StanzaAckParser.h> +#include <Swiften/Parser/StanzaAckRequestParser.h> +#include <Swiften/Parser/StartTLSParser.h> +#include <Swiften/Parser/StartTLSFailureParser.h> +#include <Swiften/Parser/CompressParser.h> +#include <Swiften/Parser/CompressFailureParser.h> +#include <Swiften/Parser/CompressedParser.h> +#include <Swiften/Parser/UnknownElementParser.h> +#include <Swiften/Parser/TLSProceedParser.h> +#include <Swiften/Parser/ComponentHandshakeParser.h> // TODO: Whenever an error occurs in the handlers, stop the parser by returing // a bool value, and stopping the XML parser @@ -182,6 +184,12 @@ ElementParser* XMPPParser::createElementParser(const std::string& element, const else if (element == "failed" && ns == "urn:xmpp:sm:2") { return new StreamManagementFailedParser(); } + else if (element == "resume" && ns == "urn:xmpp:sm:2") { + return new StreamResumeParser(); + } + else if (element == "resumed" && ns == "urn:xmpp:sm:2") { + return new StreamResumedParser(); + } else if (element == "a" && ns == "urn:xmpp:sm:2") { return new StanzaAckParser(); } diff --git a/Swiften/Parser/XMPPParser.h b/Swiften/Parser/XMPPParser.h index 8a00995..b5d6d24 100644 --- a/Swiften/Parser/XMPPParser.h +++ b/Swiften/Parser/XMPPParser.h @@ -4,14 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_XMPPPARSER_H -#define SWIFTEN_XMPPPARSER_H +#pragma once #include <boost/shared_ptr.hpp> #include <boost/noncopyable.hpp> -#include "Swiften/Parser/XMLParserClient.h" -#include "Swiften/Parser/AttributeMap.h" +#include <Swiften/Parser/XMLParserClient.h> +#include <Swiften/Parser/AttributeMap.h> namespace Swift { class XMLParser; @@ -53,5 +52,3 @@ namespace Swift { bool parseErrorOccurred_; }; } - -#endif diff --git a/Swiften/Parser/XMPPParserClient.cpp b/Swiften/Parser/XMPPParserClient.cpp index 3761e4f..4b7da04 100644 --- a/Swiften/Parser/XMPPParserClient.cpp +++ b/Swiften/Parser/XMPPParserClient.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Parser/XMPPParserClient.h" +#include <Swiften/Parser/XMPPParserClient.h> namespace Swift { diff --git a/Swiften/Parser/XMPPParserClient.h b/Swiften/Parser/XMPPParserClient.h index 1ddb86d..e613f8e 100644 --- a/Swiften/Parser/XMPPParserClient.h +++ b/Swiften/Parser/XMPPParserClient.h @@ -8,7 +8,7 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> namespace Swift { diff --git a/Swiften/Presence/DirectedPresenceSender.cpp b/Swiften/Presence/DirectedPresenceSender.cpp index d824554..ec0bd3f 100644 --- a/Swiften/Presence/DirectedPresenceSender.cpp +++ b/Swiften/Presence/DirectedPresenceSender.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Presence/DirectedPresenceSender.h" -#include "Swiften/Base/foreach.h" +#include <Swiften/Presence/DirectedPresenceSender.h> +#include <Swiften/Base/foreach.h> namespace Swift { diff --git a/Swiften/Presence/DirectedPresenceSender.h b/Swiften/Presence/DirectedPresenceSender.h index 207de3e..7dbdd37 100644 --- a/Swiften/Presence/DirectedPresenceSender.h +++ b/Swiften/Presence/DirectedPresenceSender.h @@ -8,8 +8,8 @@ #include <set> -#include "Swiften/Elements/Presence.h" -#include "Swiften/Presence/PresenceSender.h" +#include <Swiften/Elements/Presence.h> +#include <Swiften/Presence/PresenceSender.h> namespace Swift { class DirectedPresenceSender : public PresenceSender { diff --git a/Swiften/Presence/PayloadAddingPresenceSender.cpp b/Swiften/Presence/PayloadAddingPresenceSender.cpp index c3d1638..5e8cd81 100644 --- a/Swiften/Presence/PayloadAddingPresenceSender.cpp +++ b/Swiften/Presence/PayloadAddingPresenceSender.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Presence/PayloadAddingPresenceSender.h" +#include <Swiften/Presence/PayloadAddingPresenceSender.h> namespace Swift { @@ -34,11 +34,15 @@ bool PayloadAddingPresenceSender::isAvailable() const { return sender->isAvailable(); } -void PayloadAddingPresenceSender::setPayload(Payload::ref payload) { +void PayloadAddingPresenceSender::setPayload(boost::shared_ptr<Payload> payload) { this->payload = payload; if (lastSentPresence) { sendPresence(lastSentPresence); } } +void PayloadAddingPresenceSender::reset() { + lastSentPresence.reset(); +} + } diff --git a/Swiften/Presence/PayloadAddingPresenceSender.h b/Swiften/Presence/PayloadAddingPresenceSender.h index ae82970..333842a 100644 --- a/Swiften/Presence/PayloadAddingPresenceSender.h +++ b/Swiften/Presence/PayloadAddingPresenceSender.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Presence/PresenceSender.h" -#include "Swiften/Elements/Payload.h" +#include <Swiften/Presence/PresenceSender.h> +#include <Swiften/Elements/Payload.h> namespace Swift { class StanzaChannel; @@ -21,20 +21,28 @@ namespace Swift { public: PayloadAddingPresenceSender(PresenceSender*); - void sendPresence(Presence::ref); + void sendPresence(boost::shared_ptr<Presence>); bool isAvailable() const; /** * Sets the payload to be added to outgoing presences. * If initial presence has been sent, this will resend the last sent presence * with an updated payload. Initial presence is reset when unavailable presence is - * sent. + * sent, or when reset() is called. */ - void setPayload(Payload::ref); + void setPayload(boost::shared_ptr<Payload>); + + /** + * Resets the presence sender. + * This puts the presence sender back in the initial state (before initial + * presence has been sent). + * This also resets the chained sender. + */ + void reset(); private: - Presence::ref lastSentPresence; + boost::shared_ptr<Presence> lastSentPresence; PresenceSender* sender; - Payload::ref payload; + boost::shared_ptr<Payload> payload; }; } diff --git a/Swiften/Presence/PresenceOracle.cpp b/Swiften/Presence/PresenceOracle.cpp index 90e403c..bfb5a3d 100644 --- a/Swiften/Presence/PresenceOracle.cpp +++ b/Swiften/Presence/PresenceOracle.cpp @@ -8,7 +8,7 @@ #include <boost/bind.hpp> -#include "Swiften/Client/StanzaChannel.h" +#include <Swiften/Client/StanzaChannel.h> namespace Swift { @@ -84,7 +84,7 @@ std::vector<Presence::ref> PresenceOracle::getAllPresence(const JID& bareJID) co } PresenceMap presenceMap = i->second; PresenceMap::const_iterator j = presenceMap.begin(); - for (; j != presenceMap.end(); j++) { + for (; j != presenceMap.end(); ++j) { Presence::ref current = j->second; results.push_back(current); } @@ -99,7 +99,7 @@ Presence::ref PresenceOracle::getHighestPriorityPresence(const JID& bareJID) con PresenceMap presenceMap = i->second; PresenceMap::const_iterator j = presenceMap.begin(); Presence::ref highest; - for (; j != presenceMap.end(); j++) { + for (; j != presenceMap.end(); ++j) { Presence::ref current = j->second; if (!highest || current->getPriority() > highest->getPriority() diff --git a/Swiften/Presence/PresenceOracle.h b/Swiften/Presence/PresenceOracle.h index f98e1cd..09126ea 100644 --- a/Swiften/Presence/PresenceOracle.h +++ b/Swiften/Presence/PresenceOracle.h @@ -9,9 +9,9 @@ #include <map> #include <string> -#include "Swiften/Elements/Presence.h" +#include <Swiften/Elements/Presence.h> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> namespace Swift { class StanzaChannel; diff --git a/Swiften/Presence/PresenceSender.cpp b/Swiften/Presence/PresenceSender.cpp index 50d75eb..b75141d 100644 --- a/Swiften/Presence/PresenceSender.cpp +++ b/Swiften/Presence/PresenceSender.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Presence/PresenceSender.h" +#include <Swiften/Presence/PresenceSender.h> namespace Swift { diff --git a/Swiften/Presence/PresenceSender.h b/Swiften/Presence/PresenceSender.h index 5abf2f3..c302074 100644 --- a/Swiften/Presence/PresenceSender.h +++ b/Swiften/Presence/PresenceSender.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Elements/Presence.h" +#include <Swiften/Elements/Presence.h> namespace Swift { class PresenceSender { diff --git a/Swiften/Presence/StanzaChannelPresenceSender.cpp b/Swiften/Presence/StanzaChannelPresenceSender.cpp index 654b7e7..5863a2d 100644 --- a/Swiften/Presence/StanzaChannelPresenceSender.cpp +++ b/Swiften/Presence/StanzaChannelPresenceSender.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Presence/StanzaChannelPresenceSender.h" -#include "Swiften/Client/StanzaChannel.h" +#include <Swiften/Presence/StanzaChannelPresenceSender.h> +#include <Swiften/Client/StanzaChannel.h> namespace Swift { diff --git a/Swiften/Presence/StanzaChannelPresenceSender.h b/Swiften/Presence/StanzaChannelPresenceSender.h index 23230ab..d60d29d 100644 --- a/Swiften/Presence/StanzaChannelPresenceSender.h +++ b/Swiften/Presence/StanzaChannelPresenceSender.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Presence/PresenceSender.h" +#include <Swiften/Presence/PresenceSender.h> namespace Swift { class StanzaChannel; diff --git a/Swiften/Presence/SubscriptionManager.cpp b/Swiften/Presence/SubscriptionManager.cpp index 004309e..01525dd 100644 --- a/Swiften/Presence/SubscriptionManager.cpp +++ b/Swiften/Presence/SubscriptionManager.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Presence/SubscriptionManager.h" +#include <Swiften/Presence/SubscriptionManager.h> #include <boost/bind.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Client/StanzaChannel.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Client/StanzaChannel.h> namespace Swift { diff --git a/Swiften/Presence/SubscriptionManager.h b/Swiften/Presence/SubscriptionManager.h index ad55f9d..efa3e1c 100644 --- a/Swiften/Presence/SubscriptionManager.h +++ b/Swiften/Presence/SubscriptionManager.h @@ -9,9 +9,9 @@ #include <map> #include <string> -#include "Swiften/JID/JID.h" -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/Elements/Presence.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Elements/Presence.h> namespace Swift { class StanzaChannel; diff --git a/Swiften/Presence/UnitTest/DirectedPresenceSenderTest.cpp b/Swiften/Presence/UnitTest/DirectedPresenceSenderTest.cpp index 80f5ebd..5b385c2 100644 --- a/Swiften/Presence/UnitTest/DirectedPresenceSenderTest.cpp +++ b/Swiften/Presence/UnitTest/DirectedPresenceSenderTest.cpp @@ -7,9 +7,9 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Client/DummyStanzaChannel.h" -#include "Swiften/Presence/DirectedPresenceSender.h" -#include "Swiften/Presence/StanzaChannelPresenceSender.h" +#include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/Presence/DirectedPresenceSender.h> +#include <Swiften/Presence/StanzaChannelPresenceSender.h> using namespace Swift; @@ -41,7 +41,7 @@ class DirectedPresenceSenderTest : public CppUnit::TestFixture { } void testSendPresence() { - std::auto_ptr<DirectedPresenceSender> testling(createPresenceSender()); + boost::shared_ptr<DirectedPresenceSender> testling(createPresenceSender()); testling->sendPresence(testPresence); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(channel->sentStanzas.size())); @@ -50,7 +50,7 @@ class DirectedPresenceSenderTest : public CppUnit::TestFixture { } void testSendPresence_UndirectedPresenceWithDirectedPresenceReceivers() { - std::auto_ptr<DirectedPresenceSender> testling(createPresenceSender()); + boost::shared_ptr<DirectedPresenceSender> testling(createPresenceSender()); testling->addDirectedPresenceReceiver(JID("alice@wonderland.lit/teaparty"), DirectedPresenceSender::AndSendPresence); testling->sendPresence(testPresence); @@ -64,7 +64,7 @@ class DirectedPresenceSenderTest : public CppUnit::TestFixture { } void testSendPresence_DirectedPresenceWithDirectedPresenceReceivers() { - std::auto_ptr<DirectedPresenceSender> testling(createPresenceSender()); + boost::shared_ptr<DirectedPresenceSender> testling(createPresenceSender()); testling->addDirectedPresenceReceiver(JID("alice@wonderland.lit/teaparty"), DirectedPresenceSender::AndSendPresence); channel->sentStanzas.clear(); @@ -77,7 +77,7 @@ class DirectedPresenceSenderTest : public CppUnit::TestFixture { } void testAddDirectedPresenceReceiver() { - std::auto_ptr<DirectedPresenceSender> testling(createPresenceSender()); + boost::shared_ptr<DirectedPresenceSender> testling(createPresenceSender()); testling->sendPresence(testPresence); channel->sentStanzas.clear(); @@ -90,7 +90,7 @@ class DirectedPresenceSenderTest : public CppUnit::TestFixture { } void testAddDirectedPresenceReceiver_WithoutSendingPresence() { - std::auto_ptr<DirectedPresenceSender> testling(createPresenceSender()); + boost::shared_ptr<DirectedPresenceSender> testling(createPresenceSender()); testling->sendPresence(testPresence); channel->sentStanzas.clear(); @@ -100,7 +100,7 @@ class DirectedPresenceSenderTest : public CppUnit::TestFixture { } void testAddDirectedPresenceReceiver_AfterSendingDirectedPresence() { - std::auto_ptr<DirectedPresenceSender> testling(createPresenceSender()); + boost::shared_ptr<DirectedPresenceSender> testling(createPresenceSender()); testling->sendPresence(testPresence); secondTestPresence->setTo(JID("foo@bar.com")); testling->sendPresence(secondTestPresence); @@ -115,7 +115,7 @@ class DirectedPresenceSenderTest : public CppUnit::TestFixture { } void testRemoveDirectedPresenceReceiver() { - std::auto_ptr<DirectedPresenceSender> testling(createPresenceSender()); + boost::shared_ptr<DirectedPresenceSender> testling(createPresenceSender()); testling->addDirectedPresenceReceiver(JID("alice@wonderland.lit/teaparty"), DirectedPresenceSender::DontSendPresence); testling->removeDirectedPresenceReceiver(JID("alice@wonderland.lit/teaparty"), DirectedPresenceSender::AndSendPresence); @@ -127,7 +127,7 @@ class DirectedPresenceSenderTest : public CppUnit::TestFixture { } void testRemoveDirectedPresenceReceiver_WithoutSendingPresence() { - std::auto_ptr<DirectedPresenceSender> testling(createPresenceSender()); + boost::shared_ptr<DirectedPresenceSender> testling(createPresenceSender()); testling->addDirectedPresenceReceiver(JID("alice@wonderland.lit/teaparty"), DirectedPresenceSender::AndSendPresence); channel->sentStanzas.clear(); diff --git a/Swiften/Presence/UnitTest/PayloadAddingPresenceSenderTest.cpp b/Swiften/Presence/UnitTest/PayloadAddingPresenceSenderTest.cpp index 132c865..3a6ab31 100644 --- a/Swiften/Presence/UnitTest/PayloadAddingPresenceSenderTest.cpp +++ b/Swiften/Presence/UnitTest/PayloadAddingPresenceSenderTest.cpp @@ -9,10 +9,10 @@ #include <vector> #include <boost/bind.hpp> -#include "Swiften/Presence/PayloadAddingPresenceSender.h" -#include "Swiften/Presence/StanzaChannelPresenceSender.h" -#include "Swiften/Elements/Body.h" -#include "Swiften/Client/DummyStanzaChannel.h" +#include <Swiften/Presence/PayloadAddingPresenceSender.h> +#include <Swiften/Presence/StanzaChannelPresenceSender.h> +#include <Swiften/Elements/Body.h> +#include <Swiften/Client/DummyStanzaChannel.h> using namespace Swift; @@ -23,6 +23,7 @@ class PayloadAddingPresenceSenderTest : public CppUnit::TestFixture { CPPUNIT_TEST(testSendPresenceDoesNotAlterOriginalPayload); CPPUNIT_TEST(testSetPayloadAfterInitialPresenceResendsPresence); CPPUNIT_TEST(testSetPayloadAfterUnavailablePresenceDoesNotResendPresence); + CPPUNIT_TEST(testSetPayloadAfterResetDoesNotResendPresence); CPPUNIT_TEST(testSendDirectedPresenceIsNotResent); CPPUNIT_TEST_SUITE_END(); @@ -38,7 +39,7 @@ class PayloadAddingPresenceSenderTest : public CppUnit::TestFixture { } void testSetPayloadAddsPayloadOnPresenceSend() { - std::auto_ptr<PayloadAddingPresenceSender> testling(createSender()); + boost::shared_ptr<PayloadAddingPresenceSender> testling(createSender()); testling->setPayload(MyPayload::create("foo")); testling->sendPresence(Presence::create("bar")); @@ -49,7 +50,7 @@ class PayloadAddingPresenceSenderTest : public CppUnit::TestFixture { } void testSetNullPayloadDoesNotAddPayloadOnPresenceSend() { - std::auto_ptr<PayloadAddingPresenceSender> testling(createSender()); + boost::shared_ptr<PayloadAddingPresenceSender> testling(createSender()); testling->setPayload(MyPayload::ref()); testling->sendPresence(Presence::create("bar")); @@ -60,7 +61,7 @@ class PayloadAddingPresenceSenderTest : public CppUnit::TestFixture { } void testSendPresenceDoesNotAlterOriginalPayload() { - std::auto_ptr<PayloadAddingPresenceSender> testling(createSender()); + boost::shared_ptr<PayloadAddingPresenceSender> testling(createSender()); testling->setPayload(MyPayload::create("foo")); Presence::ref presence(Presence::create("bar")); @@ -70,7 +71,7 @@ class PayloadAddingPresenceSenderTest : public CppUnit::TestFixture { } void testSetPayloadAfterInitialPresenceResendsPresence() { - std::auto_ptr<PayloadAddingPresenceSender> testling(createSender()); + boost::shared_ptr<PayloadAddingPresenceSender> testling(createSender()); testling->sendPresence(Presence::create("bar")); testling->setPayload(MyPayload::create("foo")); @@ -81,7 +82,9 @@ class PayloadAddingPresenceSenderTest : public CppUnit::TestFixture { } void testSetPayloadAfterUnavailablePresenceDoesNotResendPresence() { - std::auto_ptr<PayloadAddingPresenceSender> testling(createSender()); + boost::shared_ptr<PayloadAddingPresenceSender> testling(createSender()); + + testling->sendPresence(Presence::create("bar")); Presence::ref presence = Presence::create("bar"); presence->setType(Presence::Unavailable); @@ -89,11 +92,21 @@ class PayloadAddingPresenceSenderTest : public CppUnit::TestFixture { testling->setPayload(MyPayload::create("foo")); + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); + } + + void testSetPayloadAfterResetDoesNotResendPresence() { + boost::shared_ptr<PayloadAddingPresenceSender> testling(createSender()); + testling->sendPresence(Presence::create("bar")); + + testling->reset(); + testling->setPayload(MyPayload::create("foo")); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(stanzaChannel->sentStanzas.size())); } void testSendDirectedPresenceIsNotResent() { - std::auto_ptr<PayloadAddingPresenceSender> testling(createSender()); + boost::shared_ptr<PayloadAddingPresenceSender> testling(createSender()); testling->sendPresence(Presence::create("bar")); Presence::ref directedPresence = Presence::create("baz"); @@ -106,8 +119,8 @@ class PayloadAddingPresenceSenderTest : public CppUnit::TestFixture { } private: - std::auto_ptr<PayloadAddingPresenceSender> createSender() { - std::auto_ptr<PayloadAddingPresenceSender> sender(new PayloadAddingPresenceSender(presenceSender)); + boost::shared_ptr<PayloadAddingPresenceSender> createSender() { + boost::shared_ptr<PayloadAddingPresenceSender> sender(new PayloadAddingPresenceSender(presenceSender)); return sender; } diff --git a/Swiften/Presence/UnitTest/PresenceOracleTest.cpp b/Swiften/Presence/UnitTest/PresenceOracleTest.cpp index 24cc62c..179538e 100644 --- a/Swiften/Presence/UnitTest/PresenceOracleTest.cpp +++ b/Swiften/Presence/UnitTest/PresenceOracleTest.cpp @@ -9,9 +9,9 @@ #include <boost/bind.hpp> #include <boost/shared_ptr.hpp> -#include "Swiften/Presence/PresenceOracle.h" -#include "Swiften/Client/DummyStanzaChannel.h" -#include "Swiften/Presence/SubscriptionManager.h" +#include <Swiften/Presence/PresenceOracle.h> +#include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/Presence/SubscriptionManager.h> using namespace Swift; diff --git a/Swiften/QA/ClientTest/ClientTest.cpp b/Swiften/QA/ClientTest/ClientTest.cpp index 35bb096..584f644 100644 --- a/Swiften/QA/ClientTest/ClientTest.cpp +++ b/Swiften/QA/ClientTest/ClientTest.cpp @@ -6,14 +6,15 @@ #include <boost/bind.hpp> #include <boost/thread.hpp> +#include <iostream> -#include "Swiften/Client/Client.h" -#include "Swiften/Network/TimerFactory.h" -#include "Swiften/Network/BoostNetworkFactories.h" -#include "Swiften/EventLoop/EventLoop.h" -#include "Swiften/EventLoop/SimpleEventLoop.h" -#include "Swiften/Roster/GetRosterRequest.h" -#include "Swiften/Client/ClientXMLTracer.h" +#include <Swiften/Client/Client.h> +#include <Swiften/Network/TimerFactory.h> +#include <Swiften/Network/BoostNetworkFactories.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/EventLoop/SimpleEventLoop.h> +#include <Swiften/Roster/GetRosterRequest.h> +#include <Swiften/Client/ClientXMLTracer.h> using namespace Swift; diff --git a/Swiften/QA/DNSSDTest/DNSSDTest.cpp b/Swiften/QA/DNSSDTest/DNSSDTest.cpp index 1bf0965..7e2a189 100644 --- a/Swiften/QA/DNSSDTest/DNSSDTest.cpp +++ b/Swiften/QA/DNSSDTest/DNSSDTest.cpp @@ -9,18 +9,17 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/bind.hpp> -#include <algorithm> - -#include "Swiften/Base/sleep.h" -#include "Swiften/Base/ByteArray.h" -#include "Swiften/EventLoop/DummyEventLoop.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" +#include <Swiften/Base/sleep.h> +#include <Swiften/Base/Algorithm.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/EventLoop/DummyEventLoop.h> +#include <Swiften/LinkLocal/LinkLocalServiceInfo.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDQuerier.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h> +#include <Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h> #ifdef HAVE_AVAHI -#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h" +#include <Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h> #endif #define SLEEP_INTERVALS 20 @@ -95,7 +94,7 @@ class DNSSDTest : public CppUnit::TestFixture { toRemove.clear(); toRemove.insert(toRemove.begin(), added.begin(), added.end()); registerQuery->unregisterService(); - while (toRemove.size() > 0) { + while (!toRemove.empty()) { Swift::sleep(100); eventLoop->processEvents(); } @@ -112,7 +111,7 @@ class DNSSDTest : public CppUnit::TestFixture { void handleServiceRemoved(const DNSSDServiceID& id) { CPPUNIT_ASSERT(std::find(toRemove.begin(), toRemove.end(), id) != toRemove.end()); - toRemove.erase(std::remove(toRemove.begin(), toRemove.end(), id)); + erase(toRemove, id); } void handleRegisterFinished(boost::optional<DNSSDServiceID> id) { diff --git a/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp index 82a8be2..14da358 100644 --- a/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp +++ b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp @@ -9,9 +9,9 @@ #include <boost/shared_ptr.hpp> #include <string> -#include "Swiften/Network/BoostConnectionServer.h" -#include "Swiften/Network/BoostIOServiceThread.h" -#include "Swiften/EventLoop/DummyEventLoop.h" +#include <Swiften/Network/BoostConnectionServer.h> +#include <Swiften/Network/BoostIOServiceThread.h> +#include <Swiften/EventLoop/DummyEventLoop.h> using namespace Swift; diff --git a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp index 928e3db..335f2d2 100644 --- a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp +++ b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp @@ -10,12 +10,13 @@ #include <boost/smart_ptr/make_shared.hpp> #include <string> -#include "Swiften/Base/sleep.h" -#include "Swiften/Network/BoostConnection.h" -#include "Swiften/Network/HostAddress.h" -#include "Swiften/Network/HostAddressPort.h" -#include "Swiften/Network/BoostIOServiceThread.h" -#include "Swiften/EventLoop/DummyEventLoop.h" +#include <Swiften/Base/Algorithm.h> +#include <Swiften/Base/sleep.h> +#include <Swiften/Network/BoostConnection.h> +#include <Swiften/Network/HostAddress.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Network/BoostIOServiceThread.h> +#include <Swiften/EventLoop/DummyEventLoop.h> const unsigned char* address = reinterpret_cast<const unsigned char*>("\x41\x63\xde\x89"); @@ -70,7 +71,7 @@ class BoostConnectionTest : public CppUnit::TestFixture { testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); testling->connect(HostAddressPort(HostAddress("65.99.222.137"), 5222)); - while (receivedData.isEmpty()) { + while (receivedData.empty()) { Swift::sleep(10); eventLoop_->processEvents(); } @@ -83,7 +84,7 @@ class BoostConnectionTest : public CppUnit::TestFixture { testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); testling->connect(HostAddressPort(HostAddress("2001:470:1f0e:852::2"), 80)); - while (receivedData.isEmpty()) { + while (receivedData.empty()) { Swift::sleep(10); eventLoop_->processEvents(); } @@ -102,9 +103,9 @@ class BoostConnectionTest : public CppUnit::TestFixture { eventLoop_->processEvents(); } - testling->write(ByteArray("<stream:strea")); - testling->write(ByteArray("m")); - testling->write(ByteArray(">")); + testling->write(createSafeByteArray("<stream:strea")); + testling->write(createSafeByteArray("m")); + testling->write(createSafeByteArray(">")); // Check that we only did one write event, the others are queued /*int runHandlers = */boostIOService->poll(); @@ -112,7 +113,7 @@ class BoostConnectionTest : public CppUnit::TestFixture { // this test doesn't really work any more. We'll have to trust that things are queued. //CPPUNIT_ASSERT_EQUAL(1, runHandlers); // Process the other events - while (receivedData.isEmpty()) { + while (receivedData.empty()) { boostIOService->run_one(); eventLoop_->processEvents(); } @@ -126,12 +127,12 @@ class BoostConnectionTest : public CppUnit::TestFixture { } void doWrite(BoostConnection* connection) { - connection->write(ByteArray("<stream:stream>")); - connection->write(ByteArray("\r\n\r\n")); // Temporarily, while we don't have an xmpp server running on ipv6 + connection->write(createSafeByteArray("<stream:stream>")); + connection->write(createSafeByteArray("\r\n\r\n")); // Temporarily, while we don't have an xmpp server running on ipv6 } - void handleDataRead(const ByteArray& data) { - receivedData += data; + void handleDataRead(boost::shared_ptr<SafeByteArray> data) { + append(receivedData, *data); } void handleDisconnected() { diff --git a/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp b/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp index a0a7e7b..7cb9ed3 100644 --- a/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp +++ b/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp @@ -10,13 +10,13 @@ #include <algorithm> -#include "Swiften/Base/sleep.h" +#include <Swiften/Base/sleep.h> #include <string> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Network/PlatformDomainNameResolver.h" -#include "Swiften/Network/DomainNameAddressQuery.h" -#include "Swiften/Network/DomainNameServiceQuery.h" -#include "Swiften/EventLoop/DummyEventLoop.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Network/PlatformDomainNameResolver.h> +#include <Swiften/Network/DomainNameAddressQuery.h> +#include <Swiften/Network/DomainNameServiceQuery.h> +#include <Swiften/EventLoop/DummyEventLoop.h> using namespace Swift; diff --git a/Swiften/QA/ProxyProviderTest/.gitignore b/Swiften/QA/ProxyProviderTest/.gitignore new file mode 100644 index 0000000..9d4b9b8 --- /dev/null +++ b/Swiften/QA/ProxyProviderTest/.gitignore @@ -0,0 +1 @@ +ProxyProviderTest diff --git a/Swiften/QA/ProxyProviderTest/ProxyProviderTest.cpp b/Swiften/QA/ProxyProviderTest/ProxyProviderTest.cpp new file mode 100644 index 0000000..ddaee01 --- /dev/null +++ b/Swiften/QA/ProxyProviderTest/ProxyProviderTest.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010 Thilo Cestonaro + * Licensed under the BSD License. + * See Documentation/Licenses/BSD.txt for more information. + */ + +#include <iostream> + +#include <Swiften/Network/PlatformProxyProvider.h> +#include <Swiften/Base/foreach.h> + +using namespace Swift; + +int main(void) +{ + int ret = 0; + HostAddressPort hap; + + std::cout << "constructing PlatfromProxyProvider instance ..." << std::endl; + PlatformProxyProvider ppp; + + hap = ppp.getSOCKS5Proxy(); + std::cout << "SOCKS5 Proxy configured: " << hap.isValid() << std::endl; + if(hap.isValid()) { + std::cout << "SOCKS5 Proxy: " << hap.getAddress().toString() << ":" << hap.getPort() << std::endl; + } + + hap = ppp.getHTTPConnectProxy(); + std::cout << "HTTPConnect Proxy configured: " << hap.isValid() << std::endl; + if(hap.isValid()) { + std::cout << "HTTPConnect Proxy: " << hap.getAddress().toString() << ":" << hap.getPort() << std::endl; + } + + return ret; +} diff --git a/Swiften/QA/ProxyProviderTest/SConscript b/Swiften/QA/ProxyProviderTest/SConscript new file mode 100644 index 0000000..2eb123d --- /dev/null +++ b/Swiften/QA/ProxyProviderTest/SConscript @@ -0,0 +1,11 @@ +import os + +Import("env") + +myenv = env.Clone() +myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) +myenv.MergeFlags(myenv["SWIFTEN_DEP_FLAGS"]) + +myenv.Program("ProxyProviderTest", [ + "ProxyProviderTest.cpp", + ]) diff --git a/Swiften/QA/ReconnectTest/ReconnectTest.cpp b/Swiften/QA/ReconnectTest/ReconnectTest.cpp index 117cfa3..933d5d2 100644 --- a/Swiften/QA/ReconnectTest/ReconnectTest.cpp +++ b/Swiften/QA/ReconnectTest/ReconnectTest.cpp @@ -7,14 +7,14 @@ #include <boost/bind.hpp> #include <boost/thread.hpp> -#include "Swiften/Client/Client.h" -#include "Swiften/Network/BoostTimer.h" -#include "Swiften/EventLoop/EventLoop.h" -#include "Swiften/EventLoop/SimpleEventLoop.h" -#include "Swiften/Roster/GetRosterRequest.h" -#include "Swiften/Client/ClientXMLTracer.h" -#include "Swiften/Network/BoostIOServiceThread.h" -#include "Swiften/Network/MainBoostIOServiceThread.h" +#include <Swiften/Client/Client.h> +#include <Swiften/Network/BoostTimer.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/EventLoop/SimpleEventLoop.h> +#include <Swiften/Roster/GetRosterRequest.h> +#include <Swiften/Client/ClientXMLTracer.h> +#include <Swiften/Network/BoostIOServiceThread.h> +#include <Swiften/Network/MainBoostIOServiceThread.h> using namespace Swift; diff --git a/Swiften/QA/SConscript b/Swiften/QA/SConscript index 25ba814..2f2be6e 100644 --- a/Swiften/QA/SConscript +++ b/Swiften/QA/SConscript @@ -5,7 +5,8 @@ SConscript(dirs = [ # "ReconnectTest", "ClientTest", # "DNSSDTest", - "StorageTest", +# "StorageTest", "TLSTest", "ScriptedTests", + "ProxyProviderTest", ]) diff --git a/Swiften/QA/StorageTest/FileReadBytestreamTest.cpp b/Swiften/QA/StorageTest/FileReadBytestreamTest.cpp index 925c775..e090c6c 100644 --- a/Swiften/QA/StorageTest/FileReadBytestreamTest.cpp +++ b/Swiften/QA/StorageTest/FileReadBytestreamTest.cpp @@ -7,7 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/FileTransfer/FileReadBytestream.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/FileTransfer/FileReadBytestream.h> #include "SwifTools/Application/PlatformApplicationPathProvider.h" using namespace Swift; @@ -30,24 +31,24 @@ class FileReadBytestreamTest : public CppUnit::TestFixture { } void testRead() { - std::auto_ptr<FileReadBytestream> testling(createTestling()); + boost::shared_ptr<FileReadBytestream> testling(createTestling()); - ByteArray result = testling->read(10); + std::vector<unsigned char> result = testling->read(10); - CPPUNIT_ASSERT_EQUAL(std::string("/*\n * Copy"), result.toString()); + CPPUNIT_ASSERT(ByteArray::create("/*\n * Copy") == result); } void testRead_Twice() { - std::auto_ptr<FileReadBytestream> testling(createTestling()); + boost::shared_ptr<FileReadBytestream> testling(createTestling()); testling->read(10); - ByteArray result = testling->read(10); + ByteArray result(testling->read(10)); CPPUNIT_ASSERT_EQUAL(std::string("right (c) "), result.toString()); } void testIsFinished_NotFinished() { - std::auto_ptr<FileReadBytestream> testling(createTestling()); + boost::shared_ptr<FileReadBytestream> testling(createTestling()); testling->read(10); @@ -55,7 +56,7 @@ class FileReadBytestreamTest : public CppUnit::TestFixture { } void testIsFinished_IsFinished() { - std::auto_ptr<FileReadBytestream> testling(createTestling()); + boost::shared_ptr<FileReadBytestream> testling(createTestling()); testling->read(4096); diff --git a/Swiften/QA/StorageTest/VCardFileStorageTest.cpp b/Swiften/QA/StorageTest/VCardFileStorageTest.cpp index fb51568..7667176 100644 --- a/Swiften/QA/StorageTest/VCardFileStorageTest.cpp +++ b/Swiften/QA/StorageTest/VCardFileStorageTest.cpp @@ -9,10 +9,10 @@ #include <boost/algorithm/string.hpp> #include <sstream> -#include "Swiften/VCards/VCardFileStorage.h" -#include "Swiften/JID/JID.h" +#include <Swiften/VCards/VCardFileStorage.h> +#include <Swiften/JID/JID.h> #include "SwifTools/Application/PlatformApplicationPathProvider.h" -#include "Swiften/Elements/VCard.h" +#include <Swiften/Elements/VCard.h> using namespace Swift; @@ -40,7 +40,7 @@ class VCardFileStorageTest : public CppUnit::TestFixture { } void testSetVCard() { - std::auto_ptr<VCardFileStorage> testling(createTestling()); + boost::shared_ptr<VCardFileStorage> testling(createTestling()); VCard::ref vcard(new VCard()); vcard->setFullName("Alice In Wonderland"); @@ -70,7 +70,7 @@ class VCardFileStorageTest : public CppUnit::TestFixture { } void testGetVCard() { - std::auto_ptr<VCardFileStorage> testling(createTestling()); + boost::shared_ptr<VCardFileStorage> testling(createTestling()); VCard::ref vcard(new VCard()); vcard->setFullName("Alice In Wonderland"); testling->setVCard(JID("alice@wonderland.lit"), vcard); @@ -96,7 +96,7 @@ class VCardFileStorageTest : public CppUnit::TestFixture { } void testGetVCard_FileDoesNotExist() { - std::auto_ptr<VCardFileStorage> testling(createTestling()); + boost::shared_ptr<VCardFileStorage> testling(createTestling()); VCard::ref result = testling->getVCard(JID("alice@wonderland.lit")); CPPUNIT_ASSERT(!result); } diff --git a/Swiften/QA/TLSTest/CertificateTest.cpp b/Swiften/QA/TLSTest/CertificateTest.cpp index 0f37fde..67ca064 100644 --- a/Swiften/QA/TLSTest/CertificateTest.cpp +++ b/Swiften/QA/TLSTest/CertificateTest.cpp @@ -10,7 +10,8 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/bind.hpp> -#include "Swiften/TLS/CertificateFactory.h" +#include <QA/Checker/IO.h> +#include <Swiften/TLS/CertificateFactory.h> #include "SwifTools/Application/PlatformApplicationPathProvider.h" using namespace Swift; @@ -30,7 +31,7 @@ class CertificateTest : public CppUnit::TestFixture { public: void setUp() { pathProvider = new PlatformApplicationPathProvider("FileReadBytestreamTest"); - certificateData.readFromFile((pathProvider->getExecutableDir() / "jabber_org.crt").string()); + readByteArrayFromFile(certificateData, (pathProvider->getExecutableDir() / "jabber_org.crt").string()); certificateFactory = new CERTIFICATE_FACTORY(); } @@ -95,6 +96,6 @@ class CertificateTest : public CppUnit::TestFixture { }; #ifdef HAVE_OPENSSL -#include "Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h" +#include <Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h> CPPUNIT_TEST_SUITE_REGISTRATION(CertificateTest<OpenSSLCertificateFactory>); #endif diff --git a/Swiften/Queries/DummyIQChannel.h b/Swiften/Queries/DummyIQChannel.h index f740b5c..6adcdb1 100644 --- a/Swiften/Queries/DummyIQChannel.h +++ b/Swiften/Queries/DummyIQChannel.h @@ -8,7 +8,7 @@ #include <vector> -#include "Swiften/Queries/IQChannel.h" +#include <Swiften/Queries/IQChannel.h> namespace Swift { class DummyIQChannel : public IQChannel { diff --git a/Swiften/Queries/GenericRequest.h b/Swiften/Queries/GenericRequest.h index a8e3409..9fd934f 100644 --- a/Swiften/Queries/GenericRequest.h +++ b/Swiften/Queries/GenericRequest.h @@ -6,9 +6,9 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> -#include "Swiften/Queries/Request.h" +#include <Swiften/Queries/Request.h> namespace Swift { template<typename PAYLOAD_TYPE> @@ -22,6 +22,15 @@ namespace Swift { Request(type, receiver, payload, router) { } + GenericRequest( + IQ::Type type, + const JID& sender, + const JID& receiver, + boost::shared_ptr<Payload> payload, + IQRouter* router) : + Request(type, sender, receiver, payload, router) { + } + virtual void handleResponse(boost::shared_ptr<Payload> payload, ErrorPayload::ref error) { onResponse(boost::dynamic_pointer_cast<PAYLOAD_TYPE>(payload), error); } diff --git a/Swiften/Queries/GetResponder.h b/Swiften/Queries/GetResponder.h index ca3b677..bca507a 100644 --- a/Swiften/Queries/GetResponder.h +++ b/Swiften/Queries/GetResponder.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Queries/Responder.h" +#include <Swiften/Queries/Responder.h> namespace Swift { template<typename T> diff --git a/Swiften/Queries/IQChannel.cpp b/Swiften/Queries/IQChannel.cpp index 959d87d..815a617 100644 --- a/Swiften/Queries/IQChannel.cpp +++ b/Swiften/Queries/IQChannel.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Queries/IQChannel.h" +#include <Swiften/Queries/IQChannel.h> namespace Swift { diff --git a/Swiften/Queries/IQChannel.h b/Swiften/Queries/IQChannel.h index 22b7572..71a6dd4 100644 --- a/Swiften/Queries/IQChannel.h +++ b/Swiften/Queries/IQChannel.h @@ -4,14 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_IQChannel_H -#define SWIFTEN_IQChannel_H +#pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> #include <string> -#include "Swiften/Elements/IQ.h" +#include <Swiften/Elements/IQ.h> namespace Swift { class IQChannel { @@ -26,5 +25,3 @@ namespace Swift { boost::signal<void (boost::shared_ptr<IQ>)> onIQReceived; }; } - -#endif diff --git a/Swiften/Queries/IQHandler.cpp b/Swiften/Queries/IQHandler.cpp index fe65c71..01e4387 100644 --- a/Swiften/Queries/IQHandler.cpp +++ b/Swiften/Queries/IQHandler.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Queries/IQHandler.h" -#include "Swiften/Queries/IQRouter.h" +#include <Swiften/Queries/IQHandler.h> +#include <Swiften/Queries/IQRouter.h> namespace Swift { diff --git a/Swiften/Queries/IQHandler.h b/Swiften/Queries/IQHandler.h index 616f9fa..c9af5ea 100644 --- a/Swiften/Queries/IQHandler.h +++ b/Swiften/Queries/IQHandler.h @@ -4,12 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_IQHandler_H -#define SWIFTEN_IQHandler_H +#pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/IQ.h" +#include <Swiften/Elements/IQ.h> namespace Swift { class IQRouter; @@ -21,5 +20,3 @@ namespace Swift { virtual bool handleIQ(boost::shared_ptr<IQ>) = 0; }; } - -#endif diff --git a/Swiften/Queries/IQRouter.cpp b/Swiften/Queries/IQRouter.cpp index 1bfff70..c84e1bb 100644 --- a/Swiften/Queries/IQRouter.cpp +++ b/Swiften/Queries/IQRouter.cpp @@ -4,15 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Queries/IQRouter.h" +#include <Swiften/Queries/IQRouter.h> -#include <algorithm> #include <boost/bind.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Queries/IQHandler.h" -#include "Swiften/Queries/IQChannel.h" -#include "Swiften/Elements/ErrorPayload.h" +#include <Swiften/Base/Algorithm.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Queries/IQHandler.h> +#include <Swiften/Queries/IQChannel.h> +#include <Swiften/Elements/ErrorPayload.h> namespace Swift { @@ -54,7 +54,7 @@ void IQRouter::handleIQ(boost::shared_ptr<IQ> iq) { void IQRouter::processPendingRemoves() { foreach(boost::shared_ptr<IQHandler> handler, queuedRemoves_) { - handlers_.erase(std::remove(handlers_.begin(), handlers_.end(), handler), handlers_.end()); + erase(handlers_, handler); } queuedRemoves_.clear(); } @@ -76,12 +76,12 @@ void IQRouter::removeHandler(boost::shared_ptr<IQHandler> handler) { queuedRemoves_.push_back(handler); } else { - handlers_.erase(std::remove(handlers_.begin(), handlers_.end(), handler), handlers_.end()); + erase(handlers_, handler); } } void IQRouter::sendIQ(boost::shared_ptr<IQ> iq) { - if (from_.isValid()) { + if (from_.isValid() && !iq->getFrom().isValid()) { iq->setFrom(from_); } channel_->sendIQ(iq); diff --git a/Swiften/Queries/IQRouter.h b/Swiften/Queries/IQRouter.h index 961ff59..de2822b 100644 --- a/Swiften/Queries/IQRouter.h +++ b/Swiften/Queries/IQRouter.h @@ -10,7 +10,7 @@ #include <vector> #include <string> -#include "Swiften/Elements/IQ.h" +#include <Swiften/Elements/IQ.h> namespace Swift { class IQChannel; @@ -31,7 +31,7 @@ namespace Swift { jid_ = jid; } - const JID& getJID() { + const JID& getJID() const { return jid_; } diff --git a/Swiften/Queries/RawRequest.h b/Swiften/Queries/RawRequest.h index 477952f..e5b3a1d 100644 --- a/Swiften/Queries/RawRequest.h +++ b/Swiften/Queries/RawRequest.h @@ -31,7 +31,7 @@ namespace Swift { RawRequest(IQ::Type type, const JID& receiver, const std::string& data, IQRouter* router) : Request(type, receiver, boost::make_shared<RawXMLPayload>(data), router) { } - virtual void handleResponse(Payload::ref payload, ErrorPayload::ref error) { + virtual void handleResponse(boost::shared_ptr<Payload> payload, ErrorPayload::ref error) { if (error) { onResponse(ErrorSerializer().serializePayload(error)); } diff --git a/Swiften/Queries/Request.cpp b/Swiften/Queries/Request.cpp index 95fd25e..f3f56c9 100644 --- a/Swiften/Queries/Request.cpp +++ b/Swiften/Queries/Request.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Queries/Request.h" -#include "Swiften/Queries/IQRouter.h" +#include <Swiften/Queries/Request.h> +#include <Swiften/Queries/IQRouter.h> #include <Swiften/Elements/RawXMLPayload.h> namespace Swift { @@ -16,6 +16,12 @@ Request::Request(IQ::Type type, const JID& receiver, boost::shared_ptr<Payload> Request::Request(IQ::Type type, const JID& receiver, IQRouter* router) : router_(router), type_(type), receiver_(receiver), sent_(false) { } +Request::Request(IQ::Type type, const JID& sender, const JID& receiver, boost::shared_ptr<Payload> payload, IQRouter* router) : router_(router), type_(type), sender_(sender), receiver_(receiver), payload_(payload), sent_(false) { +} + +Request::Request(IQ::Type type, const JID& sender, const JID& receiver, IQRouter* router) : router_(router), type_(type), sender_(sender), receiver_(receiver), sent_(false) { +} + void Request::send() { assert(payload_); assert(!sent_); @@ -23,6 +29,7 @@ void Request::send() { boost::shared_ptr<IQ> iq(new IQ(type_)); iq->setTo(receiver_); + iq->setFrom(sender_); iq->addPayload(payload_); id_ = router_->getNewIQID(); iq->setID(id_); @@ -67,16 +74,13 @@ bool Request::handleIQ(boost::shared_ptr<IQ> iq) { } bool Request::isCorrectSender(const JID& jid) { - if (isAccountJID(receiver_)) { - return isAccountJID(jid); + if (router_->isAccountJID(receiver_)) { + return router_->isAccountJID(jid); } else { return jid.equals(receiver_, JID::WithResource); } } -bool Request::isAccountJID(const JID& jid) { - return jid.isValid() ? router_->getJID().toBare().equals(jid, JID::WithResource) : true; -} } diff --git a/Swiften/Queries/Request.h b/Swiften/Queries/Request.h index c710548..668ed04 100644 --- a/Swiften/Queries/Request.h +++ b/Swiften/Queries/Request.h @@ -4,19 +4,18 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_Request_H -#define SWIFTEN_Request_H +#pragma once #include <boost/shared_ptr.hpp> #include <boost/optional.hpp> #include <boost/enable_shared_from_this.hpp> #include <string> -#include "Swiften/Queries/IQHandler.h" -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/Payload.h" -#include "Swiften/Elements/ErrorPayload.h" -#include "Swiften/JID/JID.h" +#include <Swiften/Queries/IQHandler.h> +#include <Swiften/Elements/IQ.h> +#include <Swiften/Elements/Payload.h> +#include <Swiften/Elements/ErrorPayload.h> +#include <Swiften/JID/JID.h> namespace Swift { /** @@ -40,6 +39,19 @@ namespace Swift { const JID& receiver, boost::shared_ptr<Payload> payload, IQRouter* router); + + /** + * Constructs a request of a certain type to a specific receiver from a specific sender, and attaches the given + * payload. + */ + Request( + IQ::Type type, + const JID& sender, + const JID& receiver, + boost::shared_ptr<Payload> payload, + IQRouter* router); + + /** * Constructs a request of a certain type to a specific receiver. */ @@ -48,29 +60,37 @@ namespace Swift { const JID& receiver, IQRouter* router); - virtual void setPayload(Payload::ref payload) { + /** + * Constructs a request of a certain type to a specific receiver from a specific sender. + */ + Request( + IQ::Type type, + const JID& sender, + const JID& receiver, + IQRouter* router); + + + virtual void setPayload(boost::shared_ptr<Payload> payload) { payload_ = payload; } - Payload::ref getPayload() const { + boost::shared_ptr<Payload> getPayload() const { return payload_; } - virtual void handleResponse(Payload::ref, ErrorPayload::ref) = 0; + virtual void handleResponse(boost::shared_ptr<Payload>, boost::shared_ptr<ErrorPayload>) = 0; private: bool handleIQ(boost::shared_ptr<IQ>); bool isCorrectSender(const JID& jid); - bool isAccountJID(const JID& jid); private: IQRouter* router_; IQ::Type type_; + JID sender_; JID receiver_; boost::shared_ptr<Payload> payload_; std::string id_; bool sent_; }; } - -#endif diff --git a/Swiften/Queries/Requests/GetInBandRegistrationFormRequest.cpp b/Swiften/Queries/Requests/GetInBandRegistrationFormRequest.cpp index 5f6be03..337375e 100644 --- a/Swiften/Queries/Requests/GetInBandRegistrationFormRequest.cpp +++ b/Swiften/Queries/Requests/GetInBandRegistrationFormRequest.cpp @@ -4,4 +4,4 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Queries/Requests/GetInBandRegistrationFormRequest.h" +#include <Swiften/Queries/Requests/GetInBandRegistrationFormRequest.h> diff --git a/Swiften/Queries/Requests/GetInBandRegistrationFormRequest.h b/Swiften/Queries/Requests/GetInBandRegistrationFormRequest.h index aa0866a..c0488ad 100644 --- a/Swiften/Queries/Requests/GetInBandRegistrationFormRequest.h +++ b/Swiften/Queries/Requests/GetInBandRegistrationFormRequest.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Queries/GenericRequest.h" -#include "Swiften/Elements/InBandRegistrationPayload.h" +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Elements/InBandRegistrationPayload.h> namespace Swift { diff --git a/Swiften/Queries/Requests/GetPrivateStorageRequest.h b/Swiften/Queries/Requests/GetPrivateStorageRequest.h index f0b95d8..b0eefb2 100644 --- a/Swiften/Queries/Requests/GetPrivateStorageRequest.h +++ b/Swiften/Queries/Requests/GetPrivateStorageRequest.h @@ -6,12 +6,12 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Queries/Request.h" -#include "Swiften/Elements/PrivateStorage.h" -#include "Swiften/Elements/ErrorPayload.h" +#include <Swiften/Queries/Request.h> +#include <Swiften/Elements/PrivateStorage.h> +#include <Swiften/Elements/ErrorPayload.h> namespace Swift { template<typename PAYLOAD_TYPE> diff --git a/Swiften/Queries/Requests/GetSecurityLabelsCatalogRequest.h b/Swiften/Queries/Requests/GetSecurityLabelsCatalogRequest.h index 51794da..a6f782b 100644 --- a/Swiften/Queries/Requests/GetSecurityLabelsCatalogRequest.h +++ b/Swiften/Queries/Requests/GetSecurityLabelsCatalogRequest.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Queries/GenericRequest.h" -#include "Swiften/Elements/SecurityLabelsCatalog.h" +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Elements/SecurityLabelsCatalog.h> namespace Swift { diff --git a/Swiften/Queries/Requests/GetSoftwareVersionRequest.h b/Swiften/Queries/Requests/GetSoftwareVersionRequest.h index 442ec88..18461bb 100644 --- a/Swiften/Queries/Requests/GetSoftwareVersionRequest.h +++ b/Swiften/Queries/Requests/GetSoftwareVersionRequest.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Queries/GenericRequest.h" -#include "Swiften/Elements/SoftwareVersion.h" +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Elements/SoftwareVersion.h> #include <boost/smart_ptr/make_shared.hpp> diff --git a/Swiften/Queries/Requests/SetPrivateStorageRequest.h b/Swiften/Queries/Requests/SetPrivateStorageRequest.h index 69eb001..f795742 100644 --- a/Swiften/Queries/Requests/SetPrivateStorageRequest.h +++ b/Swiften/Queries/Requests/SetPrivateStorageRequest.h @@ -6,12 +6,12 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Queries/Request.h" -#include "Swiften/Elements/PrivateStorage.h" -#include "Swiften/Elements/ErrorPayload.h" +#include <Swiften/Queries/Request.h> +#include <Swiften/Elements/PrivateStorage.h> +#include <Swiften/Elements/ErrorPayload.h> namespace Swift { template<typename PAYLOAD_TYPE> diff --git a/Swiften/Queries/Requests/SubmitInBandRegistrationFormRequest.cpp b/Swiften/Queries/Requests/SubmitInBandRegistrationFormRequest.cpp index f28c878..f010e96 100644 --- a/Swiften/Queries/Requests/SubmitInBandRegistrationFormRequest.cpp +++ b/Swiften/Queries/Requests/SubmitInBandRegistrationFormRequest.cpp @@ -4,4 +4,4 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Queries/Requests/SubmitInBandRegistrationFormRequest.h" +#include <Swiften/Queries/Requests/SubmitInBandRegistrationFormRequest.h> diff --git a/Swiften/Queries/Requests/SubmitInBandRegistrationFormRequest.h b/Swiften/Queries/Requests/SubmitInBandRegistrationFormRequest.h index 0700c65..8e0862b 100644 --- a/Swiften/Queries/Requests/SubmitInBandRegistrationFormRequest.h +++ b/Swiften/Queries/Requests/SubmitInBandRegistrationFormRequest.h @@ -6,11 +6,11 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Queries/Request.h" -#include "Swiften/Elements/InBandRegistrationPayload.h" +#include <Swiften/Queries/Request.h> +#include <Swiften/Elements/InBandRegistrationPayload.h> namespace Swift { @@ -26,11 +26,11 @@ namespace Swift { SetInBandRegistrationRequest(const JID& to, InBandRegistrationPayload::ref payload, IQRouter* router) : Request(IQ::Set, to, InBandRegistrationPayload::ref(payload), router) { } - virtual void handleResponse(Payload::ref payload, ErrorPayload::ref error) { + virtual void handleResponse(boost::shared_ptr<Payload> payload, ErrorPayload::ref error) { onResponse(payload, error); } public: - boost::signal<void (Payload::ref, ErrorPayload::ref)> onResponse; + boost::signal<void (boost::shared_ptr<Payload>, ErrorPayload::ref)> onResponse; }; } diff --git a/Swiften/Queries/Requests/UnitTest/GetPrivateStorageRequestTest.cpp b/Swiften/Queries/Requests/UnitTest/GetPrivateStorageRequestTest.cpp index b7c36cb..f3ecfb7 100644 --- a/Swiften/Queries/Requests/UnitTest/GetPrivateStorageRequestTest.cpp +++ b/Swiften/Queries/Requests/UnitTest/GetPrivateStorageRequestTest.cpp @@ -9,10 +9,10 @@ #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> -#include "Swiften/Queries/Requests/GetPrivateStorageRequest.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Queries/DummyIQChannel.h" -#include "Swiften/Elements/Payload.h" +#include <Swiften/Queries/Requests/GetPrivateStorageRequest.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Queries/DummyIQChannel.h> +#include <Swiften/Elements/Payload.h> using namespace Swift; diff --git a/Swiften/Queries/Responder.h b/Swiften/Queries/Responder.h index 28628e6..2ba9c24 100644 --- a/Swiften/Queries/Responder.h +++ b/Swiften/Queries/Responder.h @@ -6,9 +6,9 @@ #pragma once -#include "Swiften/Queries/IQHandler.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Elements/ErrorPayload.h" +#include <Swiften/Queries/IQHandler.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Elements/ErrorPayload.h> namespace Swift { /** diff --git a/Swiften/Queries/Responders/SoftwareVersionResponder.cpp b/Swiften/Queries/Responders/SoftwareVersionResponder.cpp index 445dcc7..3f9616a 100644 --- a/Swiften/Queries/Responders/SoftwareVersionResponder.cpp +++ b/Swiften/Queries/Responders/SoftwareVersionResponder.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Queries/Responders/SoftwareVersionResponder.h" -#include "Swiften/Queries/IQRouter.h" +#include <Swiften/Queries/Responders/SoftwareVersionResponder.h> +#include <Swiften/Queries/IQRouter.h> namespace Swift { diff --git a/Swiften/Queries/Responders/SoftwareVersionResponder.h b/Swiften/Queries/Responders/SoftwareVersionResponder.h index cbda54c..a2929df 100644 --- a/Swiften/Queries/Responders/SoftwareVersionResponder.h +++ b/Swiften/Queries/Responders/SoftwareVersionResponder.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Queries/GetResponder.h" -#include "Swiften/Elements/SoftwareVersion.h" +#include <Swiften/Queries/GetResponder.h> +#include <Swiften/Elements/SoftwareVersion.h> namespace Swift { class IQRouter; diff --git a/Swiften/Queries/SetResponder.h b/Swiften/Queries/SetResponder.h index ec3460c..331aa46 100644 --- a/Swiften/Queries/SetResponder.h +++ b/Swiften/Queries/SetResponder.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Queries/Responder.h" +#include <Swiften/Queries/Responder.h> namespace Swift { template<typename T> diff --git a/Swiften/Queries/UnitTest/IQRouterTest.cpp b/Swiften/Queries/UnitTest/IQRouterTest.cpp index ef5da23..f06b967 100644 --- a/Swiften/Queries/UnitTest/IQRouterTest.cpp +++ b/Swiften/Queries/UnitTest/IQRouterTest.cpp @@ -9,9 +9,9 @@ #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> -#include "Swiften/Queries/IQHandler.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Queries/DummyIQChannel.h" +#include <Swiften/Queries/IQHandler.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Queries/DummyIQChannel.h> using namespace Swift; diff --git a/Swiften/Queries/UnitTest/RequestTest.cpp b/Swiften/Queries/UnitTest/RequestTest.cpp index 75e0a1d..52d62fb 100644 --- a/Swiften/Queries/UnitTest/RequestTest.cpp +++ b/Swiften/Queries/UnitTest/RequestTest.cpp @@ -10,10 +10,10 @@ #include <boost/bind.hpp> #include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/Queries/GenericRequest.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Queries/DummyIQChannel.h" -#include "Swiften/Elements/Payload.h" +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Queries/DummyIQChannel.h> +#include <Swiften/Elements/Payload.h> #include <Swiften/Elements/RawXMLPayload.h> using namespace Swift; diff --git a/Swiften/Queries/UnitTest/ResponderTest.cpp b/Swiften/Queries/UnitTest/ResponderTest.cpp index c087827..a256346 100644 --- a/Swiften/Queries/UnitTest/ResponderTest.cpp +++ b/Swiften/Queries/UnitTest/ResponderTest.cpp @@ -9,10 +9,10 @@ #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> -#include "Swiften/Queries/Responder.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Queries/DummyIQChannel.h" -#include "Swiften/Elements/SoftwareVersion.h" +#include <Swiften/Queries/Responder.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Queries/DummyIQChannel.h> +#include <Swiften/Elements/SoftwareVersion.h> using namespace Swift; diff --git a/Swiften/Roster/GetRosterRequest.h b/Swiften/Roster/GetRosterRequest.h index 00cf77f..e7146d2 100644 --- a/Swiften/Roster/GetRosterRequest.h +++ b/Swiften/Roster/GetRosterRequest.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Queries/GenericRequest.h" -#include "Swiften/Elements/RosterPayload.h" +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Elements/RosterPayload.h> namespace Swift { @@ -19,6 +19,12 @@ namespace Swift { return ref(new GetRosterRequest(router)); } + static ref create(IQRouter* router, const std::string& version) { + ref result(new GetRosterRequest(router)); + result->getPayloadGeneric()->setVersion(version); + return result; + } + private: GetRosterRequest(IQRouter* router) : GenericRequest<RosterPayload>(IQ::Get, JID(), boost::shared_ptr<Payload>(new RosterPayload()), router) { diff --git a/Swiften/Roster/RosterMemoryStorage.cpp b/Swiften/Roster/RosterMemoryStorage.cpp new file mode 100644 index 0000000..cbf4563 --- /dev/null +++ b/Swiften/Roster/RosterMemoryStorage.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Roster/RosterMemoryStorage.h> + +#include <boost/smart_ptr/make_shared.hpp> + +namespace Swift { + +RosterMemoryStorage::RosterMemoryStorage() { +} + +void RosterMemoryStorage::setRoster(boost::shared_ptr<RosterPayload> r) { + roster.reset(); + if (r) { + roster = boost::make_shared<RosterPayload>(*r); + } +} + +} diff --git a/Swiften/Roster/RosterMemoryStorage.h b/Swiften/Roster/RosterMemoryStorage.h new file mode 100644 index 0000000..b659d77 --- /dev/null +++ b/Swiften/Roster/RosterMemoryStorage.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Roster/RosterStorage.h> + +namespace Swift { + class RosterMemoryStorage : public RosterStorage { + public: + RosterMemoryStorage(); + + virtual boost::shared_ptr<RosterPayload> getRoster() const { + return roster; + } + + virtual void setRoster(boost::shared_ptr<RosterPayload>); + + private: + boost::shared_ptr<RosterPayload> roster; + }; +} diff --git a/Swiften/Roster/RosterPushResponder.h b/Swiften/Roster/RosterPushResponder.h index 4e0bc4e..74d300c 100644 --- a/Swiften/Roster/RosterPushResponder.h +++ b/Swiften/Roster/RosterPushResponder.h @@ -6,10 +6,10 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> -#include "Swiften/Queries/SetResponder.h" -#include "Swiften/Elements/RosterPayload.h" +#include <Swiften/Queries/SetResponder.h> +#include <Swiften/Elements/RosterPayload.h> namespace Swift { class RosterPushResponder : public SetResponder<RosterPayload> { diff --git a/Swiften/Roster/RosterStorage.cpp b/Swiften/Roster/RosterStorage.cpp new file mode 100644 index 0000000..6bf58de --- /dev/null +++ b/Swiften/Roster/RosterStorage.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Roster/RosterStorage.h> + +namespace Swift { + +RosterStorage::~RosterStorage() { +} + +} diff --git a/Swiften/Roster/RosterStorage.h b/Swiften/Roster/RosterStorage.h new file mode 100644 index 0000000..ba24cb3 --- /dev/null +++ b/Swiften/Roster/RosterStorage.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2011 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/RosterPayload.h> + +namespace Swift { + class RosterStorage { + public: + virtual ~RosterStorage(); + + virtual boost::shared_ptr<RosterPayload> getRoster() const = 0; + virtual void setRoster(boost::shared_ptr<RosterPayload>) = 0; + }; +} diff --git a/Swiften/Roster/SetRosterRequest.h b/Swiften/Roster/SetRosterRequest.h index e5ae974..6f4d79d 100644 --- a/Swiften/Roster/SetRosterRequest.h +++ b/Swiften/Roster/SetRosterRequest.h @@ -6,11 +6,11 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Queries/Request.h" -#include "Swiften/Elements/RosterPayload.h" +#include <Swiften/Queries/Request.h> +#include <Swiften/Elements/RosterPayload.h> namespace Swift { @@ -19,11 +19,15 @@ namespace Swift { typedef boost::shared_ptr<SetRosterRequest> ref; static ref create(RosterPayload::ref payload, IQRouter* router) { - return ref(new SetRosterRequest(payload, router)); + return ref(new SetRosterRequest(JID(), payload, router)); + } + + static ref create(RosterPayload::ref payload, const JID& to, IQRouter* router) { + return ref(new SetRosterRequest(to, payload, router)); } private: - SetRosterRequest(boost::shared_ptr<RosterPayload> payload, IQRouter* router) : Request(IQ::Set, JID(), boost::shared_ptr<RosterPayload>(payload), router) { + SetRosterRequest(const JID& to, boost::shared_ptr<RosterPayload> payload, IQRouter* router) : Request(IQ::Set, to, boost::shared_ptr<RosterPayload>(payload), router) { } virtual void handleResponse(boost::shared_ptr<Payload> /*payload*/, ErrorPayload::ref error) { diff --git a/Swiften/Roster/UnitTest/XMPPRosterControllerTest.cpp b/Swiften/Roster/UnitTest/XMPPRosterControllerTest.cpp index 997840f..f1bdf86 100644 --- a/Swiften/Roster/UnitTest/XMPPRosterControllerTest.cpp +++ b/Swiften/Roster/UnitTest/XMPPRosterControllerTest.cpp @@ -8,24 +8,33 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/Roster/UnitTest/XMPPRosterSignalHandler.h" -#include "Swiften/Roster/XMPPRosterController.h" -#include "Swiften/Elements/Payload.h" -#include "Swiften/Elements/RosterItemPayload.h" -#include "Swiften/Elements/RosterPayload.h" -#include "Swiften/Client/DummyStanzaChannel.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Roster/XMPPRosterImpl.h" +#include <Swiften/Roster/UnitTest/XMPPRosterSignalHandler.h> +#include <Swiften/Roster/XMPPRosterController.h> +#include <Swiften/Elements/Payload.h> +#include <Swiften/Elements/RosterItemPayload.h> +#include <Swiften/Elements/RosterPayload.h> +#include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Roster/XMPPRosterImpl.h> +#include <Swiften/Roster/RosterMemoryStorage.h> using namespace Swift; class XMPPRosterControllerTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(XMPPRosterControllerTest); + CPPUNIT_TEST(testGet_Response); CPPUNIT_TEST(testGet_EmptyResponse); + CPPUNIT_TEST(testGet_NoRosterInStorage); + CPPUNIT_TEST(testGet_NoVersionInStorage); + CPPUNIT_TEST(testGet_VersionInStorage); + CPPUNIT_TEST(testGet_ServerDoesNotSupportVersion); + CPPUNIT_TEST(testGet_ResponseWithoutNewVersion); + CPPUNIT_TEST(testGet_ResponseWithNewVersion); CPPUNIT_TEST(testAdd); CPPUNIT_TEST(testAddFromNonAccount); CPPUNIT_TEST(testModify); CPPUNIT_TEST(testRemove); + CPPUNIT_TEST(testRemove_RosterStorageUpdated); CPPUNIT_TEST(testMany); CPPUNIT_TEST_SUITE_END(); @@ -36,20 +45,36 @@ class XMPPRosterControllerTest : public CppUnit::TestFixture { router_->setJID("me@bla.com"); xmppRoster_ = new XMPPRosterImpl(); handler_ = new XMPPRosterSignalHandler(xmppRoster_); + rosterStorage_ = new RosterMemoryStorage(); jid1_ = JID("foo@bar.com"); jid2_ = JID("alice@wonderland.lit"); jid3_ = JID("jane@austen.lit"); } void tearDown() { + delete rosterStorage_; delete handler_; delete xmppRoster_; delete router_; delete channel_; } + void testGet_Response() { + boost::shared_ptr<XMPPRosterController> testling(createController()); + + testling->requestRoster(); + boost::shared_ptr<RosterPayload> payload = boost::make_shared<RosterPayload>(); + payload->addItem(RosterItemPayload(jid1_, "Bob", RosterItemPayload::Both)); + payload->addItem(RosterItemPayload(jid2_, "Alice", RosterItemPayload::Both)); + channel_->onIQReceived(IQ::createResult("foo@bar.com", channel_->sentStanzas[0]->getID(), payload)); + + CPPUNIT_ASSERT_EQUAL(2, handler_->getEventCount()); + CPPUNIT_ASSERT(xmppRoster_->getItem(jid1_)); + CPPUNIT_ASSERT(xmppRoster_->getItem(jid2_)); + } + void testGet_EmptyResponse() { - XMPPRosterController controller(router_, xmppRoster_); + XMPPRosterController controller(router_, xmppRoster_, rosterStorage_); controller.requestRoster(); @@ -57,7 +82,7 @@ class XMPPRosterControllerTest : public CppUnit::TestFixture { } void testAdd() { - XMPPRosterController controller(router_, xmppRoster_); + XMPPRosterController controller(router_, xmppRoster_, rosterStorage_); boost::shared_ptr<RosterPayload> payload(new RosterPayload()); payload->addItem(RosterItemPayload(jid1_, "Bob", RosterItemPayload::Both)); @@ -70,8 +95,115 @@ class XMPPRosterControllerTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(std::string("Bob"), xmppRoster_->getNameForJID(jid1_)); } + void testGet_NoRosterInStorage() { + boost::shared_ptr<XMPPRosterController> testling(createController()); + testling->setUseVersioning(true); + + testling->requestRoster(); + + boost::shared_ptr<RosterPayload> roster = channel_->sentStanzas[0]->getPayload<RosterPayload>(); + CPPUNIT_ASSERT(roster->getVersion()); + CPPUNIT_ASSERT_EQUAL(std::string(""), *roster->getVersion()); + } + + void testGet_NoVersionInStorage() { + boost::shared_ptr<XMPPRosterController> testling(createController()); + testling->setUseVersioning(true); + rosterStorage_->setRoster(boost::make_shared<RosterPayload>()); + + testling->requestRoster(); + + boost::shared_ptr<RosterPayload> roster = channel_->sentStanzas[0]->getPayload<RosterPayload>(); + CPPUNIT_ASSERT(roster->getVersion()); + CPPUNIT_ASSERT_EQUAL(std::string(""), *roster->getVersion()); + } + + void testGet_VersionInStorage() { + boost::shared_ptr<XMPPRosterController> testling(createController()); + testling->setUseVersioning(true); + boost::shared_ptr<RosterPayload> payload(new RosterPayload()); + payload->setVersion("foover"); + rosterStorage_->setRoster(payload); + + testling->requestRoster(); + + boost::shared_ptr<RosterPayload> roster = channel_->sentStanzas[0]->getPayload<RosterPayload>(); + CPPUNIT_ASSERT(roster->getVersion()); + CPPUNIT_ASSERT_EQUAL(std::string("foover"), *roster->getVersion()); + } + + void testGet_ServerDoesNotSupportVersion() { + boost::shared_ptr<XMPPRosterController> testling(createController()); + boost::shared_ptr<RosterPayload> payload(new RosterPayload()); + payload->setVersion("foover"); + rosterStorage_->setRoster(payload); + + testling->requestRoster(); + + boost::shared_ptr<RosterPayload> roster = channel_->sentStanzas[0]->getPayload<RosterPayload>(); + CPPUNIT_ASSERT(!roster->getVersion()); + } + + void testGet_ResponseWithoutNewVersion() { + boost::shared_ptr<XMPPRosterController> testling(createController()); + testling->setUseVersioning(true); + boost::shared_ptr<RosterPayload> storedRoster(new RosterPayload()); + storedRoster->setVersion("version10"); + storedRoster->addItem(RosterItemPayload(jid1_, "Bob", RosterItemPayload::Both)); + storedRoster->addItem(RosterItemPayload(jid2_, "Alice", RosterItemPayload::Both)); + rosterStorage_->setRoster(storedRoster); + testling->requestRoster(); + + channel_->onIQReceived(IQ::createResult("foo@bar.com", channel_->sentStanzas[0]->getID(), boost::shared_ptr<RosterPayload>())); + + CPPUNIT_ASSERT_EQUAL(2, handler_->getEventCount()); + CPPUNIT_ASSERT(xmppRoster_->getItem(jid1_)); + CPPUNIT_ASSERT(xmppRoster_->getItem(jid2_)); + CPPUNIT_ASSERT_EQUAL(Add, handler_->getLastEvent()); + CPPUNIT_ASSERT_EQUAL(jid2_, handler_->getLastJID()); + CPPUNIT_ASSERT(rosterStorage_->getRoster()); + CPPUNIT_ASSERT(rosterStorage_->getRoster()->getVersion()); + CPPUNIT_ASSERT_EQUAL(std::string("version10"), *rosterStorage_->getRoster()->getVersion()); + CPPUNIT_ASSERT(rosterStorage_->getRoster()->getItem(jid1_)); + CPPUNIT_ASSERT(rosterStorage_->getRoster()->getItem(jid2_)); + } + + void testGet_ResponseWithNewVersion() { + boost::shared_ptr<XMPPRosterController> testling(createController()); + testling->setUseVersioning(true); + boost::shared_ptr<RosterPayload> storedRoster(new RosterPayload()); + storedRoster->setVersion("version10"); + storedRoster->addItem(RosterItemPayload(jid1_, "Bob", RosterItemPayload::Both)); + rosterStorage_->setRoster(storedRoster); + testling->requestRoster(); + + boost::shared_ptr<RosterPayload> serverRoster(new RosterPayload()); + serverRoster->setVersion("version12"); + serverRoster->addItem(RosterItemPayload(jid2_, "Alice", RosterItemPayload::Both)); + std::vector<std::string> groups; + groups.push_back("foo"); + groups.push_back("bar"); + serverRoster->addItem(RosterItemPayload(jid3_, "Rabbit", RosterItemPayload::Both, groups)); + channel_->onIQReceived(IQ::createResult("foo@bar.com", channel_->sentStanzas[0]->getID(), serverRoster)); + + + CPPUNIT_ASSERT_EQUAL(2, handler_->getEventCount()); + CPPUNIT_ASSERT(!xmppRoster_->getItem(jid1_)); + CPPUNIT_ASSERT(xmppRoster_->getItem(jid2_)); + CPPUNIT_ASSERT(xmppRoster_->getItem(jid3_)); + CPPUNIT_ASSERT_EQUAL(jid3_, handler_->getLastJID()); + CPPUNIT_ASSERT_EQUAL(Add, handler_->getLastEvent()); + CPPUNIT_ASSERT(rosterStorage_->getRoster()); + CPPUNIT_ASSERT(rosterStorage_->getRoster()->getVersion()); + CPPUNIT_ASSERT_EQUAL(std::string("version12"), *rosterStorage_->getRoster()->getVersion()); + CPPUNIT_ASSERT(!rosterStorage_->getRoster()->getItem(jid1_)); + CPPUNIT_ASSERT(rosterStorage_->getRoster()->getItem(jid2_)); + CPPUNIT_ASSERT(rosterStorage_->getRoster()->getItem(jid3_)); + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(rosterStorage_->getRoster()->getItem(jid3_)->getGroups().size())); + } + void testAddFromNonAccount() { - XMPPRosterController controller(router_, xmppRoster_); + boost::shared_ptr<XMPPRosterController> testling(createController()); boost::shared_ptr<RosterPayload> payload(new RosterPayload()); payload->addItem(RosterItemPayload(jid1_, "Bob", RosterItemPayload::Both)); @@ -83,7 +215,7 @@ class XMPPRosterControllerTest : public CppUnit::TestFixture { } void testModify() { - XMPPRosterController controller(router_, xmppRoster_); + XMPPRosterController controller(router_, xmppRoster_, rosterStorage_); boost::shared_ptr<RosterPayload> payload1(new RosterPayload()); payload1->addItem(RosterItemPayload(jid1_, "Bob", RosterItemPayload::Both)); channel_->onIQReceived(IQ::createRequest(IQ::Set, JID(), "id1", payload1)); @@ -101,9 +233,9 @@ class XMPPRosterControllerTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(std::string("Bob2"), xmppRoster_->getNameForJID(jid1_)); } - + void testRemove() { - XMPPRosterController controller(router_, xmppRoster_); + XMPPRosterController controller(router_, xmppRoster_, rosterStorage_); boost::shared_ptr<RosterPayload> payload1(new RosterPayload()); payload1->addItem(RosterItemPayload(jid1_, "Bob", RosterItemPayload::Both)); channel_->onIQReceived(IQ::createRequest(IQ::Set, JID(), "id1", payload1)); @@ -121,8 +253,31 @@ class XMPPRosterControllerTest : public CppUnit::TestFixture { } + void testRemove_RosterStorageUpdated() { + boost::shared_ptr<XMPPRosterController> testling(createController()); + testling->setUseVersioning(true); + boost::shared_ptr<RosterPayload> storedRoster(new RosterPayload()); + storedRoster->setVersion("version10"); + storedRoster->addItem(RosterItemPayload(jid1_, "Bob", RosterItemPayload::Both)); + storedRoster->addItem(RosterItemPayload(jid2_, "Alice", RosterItemPayload::Both)); + rosterStorage_->setRoster(storedRoster); + testling->requestRoster(); + channel_->onIQReceived(IQ::createResult("foo@bar.com", channel_->sentStanzas[0]->getID(), boost::shared_ptr<RosterPayload>())); + + boost::shared_ptr<RosterPayload> payload2(new RosterPayload()); + payload2->setVersion("version15"); + payload2->addItem(RosterItemPayload(jid1_, "Bob", RosterItemPayload::Remove)); + channel_->onIQReceived(IQ::createRequest(IQ::Set, JID(), "id2", payload2)); + + CPPUNIT_ASSERT(rosterStorage_->getRoster()); + CPPUNIT_ASSERT(rosterStorage_->getRoster()->getVersion()); + CPPUNIT_ASSERT_EQUAL(std::string("version15"), *rosterStorage_->getRoster()->getVersion()); + CPPUNIT_ASSERT(!rosterStorage_->getRoster()->getItem(jid1_)); + CPPUNIT_ASSERT(rosterStorage_->getRoster()->getItem(jid2_)); + } + void testMany() { - XMPPRosterController controller(router_, xmppRoster_); + XMPPRosterController controller(router_, xmppRoster_, rosterStorage_); boost::shared_ptr<RosterPayload> payload1(new RosterPayload()); payload1->addItem(RosterItemPayload(jid1_, "Bob", RosterItemPayload::Both)); channel_->onIQReceived(IQ::createRequest(IQ::Set, JID(), "id1", payload1)); @@ -185,12 +340,18 @@ class XMPPRosterControllerTest : public CppUnit::TestFixture { handler_->reset(); } + + private: + XMPPRosterController* createController() { + return new XMPPRosterController(router_, xmppRoster_, rosterStorage_); + } private: DummyStanzaChannel* channel_; IQRouter* router_; XMPPRosterImpl* xmppRoster_; XMPPRosterSignalHandler* handler_; + RosterMemoryStorage* rosterStorage_; JID jid1_; JID jid2_; JID jid3_; diff --git a/Swiften/Roster/UnitTest/XMPPRosterImplTest.cpp b/Swiften/Roster/UnitTest/XMPPRosterImplTest.cpp index edb8271..692779f 100644 --- a/Swiften/Roster/UnitTest/XMPPRosterImplTest.cpp +++ b/Swiften/Roster/UnitTest/XMPPRosterImplTest.cpp @@ -9,8 +9,8 @@ #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> -#include "Swiften/Roster/UnitTest/XMPPRosterSignalHandler.h" -#include "Swiften/Roster/XMPPRosterImpl.h" +#include <Swiften/Roster/UnitTest/XMPPRosterSignalHandler.h> +#include <Swiften/Roster/XMPPRosterImpl.h> using namespace Swift; diff --git a/Swiften/Roster/UnitTest/XMPPRosterSignalHandler.cpp b/Swiften/Roster/UnitTest/XMPPRosterSignalHandler.cpp new file mode 100644 index 0000000..d89644a --- /dev/null +++ b/Swiften/Roster/UnitTest/XMPPRosterSignalHandler.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010-2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Roster/UnitTest/XMPPRosterSignalHandler.h> + +#include <boost/bind.hpp> +#include <cassert> + +using namespace Swift; + +XMPPRosterSignalHandler::XMPPRosterSignalHandler(Swift::XMPPRoster* roster) : eventCount(0) { + lastEvent_ = None; + roster->onJIDAdded.connect(boost::bind(&XMPPRosterSignalHandler::handleJIDAdded, this, _1)); + roster->onJIDRemoved.connect(boost::bind(&XMPPRosterSignalHandler::handleJIDRemoved, this, _1)); + roster->onJIDUpdated.connect(boost::bind(&XMPPRosterSignalHandler::handleJIDUpdated, this, _1, _2, _3)); +} + +void XMPPRosterSignalHandler::handleJIDUpdated(const Swift::JID& jid, const std::string& oldName, const std::vector<std::string>& oldGroups) { + assert(lastEvent_ == None); + lastJID_ = jid; + lastOldName_ = oldName; + lastOldGroups_ = oldGroups; + lastEvent_ = Update; + eventCount++; +} diff --git a/Swiften/Roster/UnitTest/XMPPRosterSignalHandler.h b/Swiften/Roster/UnitTest/XMPPRosterSignalHandler.h index 1bbd8e9..5c51ec3 100644 --- a/Swiften/Roster/UnitTest/XMPPRosterSignalHandler.h +++ b/Swiften/Roster/UnitTest/XMPPRosterSignalHandler.h @@ -3,34 +3,25 @@ * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ + #pragma once -#include <boost/shared_ptr.hpp> -#include <boost/bind.hpp> +#include <boost/shared_ptr.hpp> #include <vector> - -#include "Swiften/Roster/XMPPRosterImpl.h" - -using namespace Swift; - +#include <Swiften/Roster/XMPPRosterImpl.h> enum XMPPRosterEvents {None, Add, Remove, Update}; class XMPPRosterSignalHandler { public: - XMPPRosterSignalHandler(XMPPRoster* roster) { - lastEvent_ = None; - roster->onJIDAdded.connect(boost::bind(&XMPPRosterSignalHandler::handleJIDAdded, this, _1)); - roster->onJIDRemoved.connect(boost::bind(&XMPPRosterSignalHandler::handleJIDRemoved, this, _1)); - roster->onJIDUpdated.connect(boost::bind(&XMPPRosterSignalHandler::handleJIDUpdated, this, _1, _2, _3)); - } + XMPPRosterSignalHandler(Swift::XMPPRoster* roster); XMPPRosterEvents getLastEvent() { return lastEvent_; } - JID getLastJID() { + Swift::JID getLastJID() { return lastJID_; } @@ -46,28 +37,28 @@ public: lastEvent_ = None; } + int getEventCount() const { + return eventCount; + } + private: - void handleJIDAdded(const JID& jid) { + void handleJIDAdded(const Swift::JID& jid) { lastJID_ = jid; lastEvent_ = Add; + eventCount++; } - void handleJIDRemoved(const JID& jid) { + void handleJIDRemoved(const Swift::JID& jid) { lastJID_ = jid; lastEvent_ = Remove; + eventCount++; } - void handleJIDUpdated(const JID& jid, const std::string& oldName, const std::vector<std::string>& oldGroups) { - CPPUNIT_ASSERT_EQUAL(None, lastEvent_); - lastJID_ = jid; - lastOldName_ = oldName; - lastOldGroups_ = oldGroups; - lastEvent_ = Update; - } + void handleJIDUpdated(const Swift::JID& jid, const std::string& oldName, const std::vector<std::string>& oldGroups); XMPPRosterEvents lastEvent_; - JID lastJID_; + Swift::JID lastJID_; std::string lastOldName_; std::vector<std::string> lastOldGroups_; - + int eventCount; }; diff --git a/Swiften/Roster/XMPPRoster.cpp b/Swiften/Roster/XMPPRoster.cpp index 61630b4..730569d 100644 --- a/Swiften/Roster/XMPPRoster.cpp +++ b/Swiften/Roster/XMPPRoster.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Roster/XMPPRoster.h" +#include <Swiften/Roster/XMPPRoster.h> namespace Swift { diff --git a/Swiften/Roster/XMPPRoster.h b/Swiften/Roster/XMPPRoster.h index be3494d..4b18940 100644 --- a/Swiften/Roster/XMPPRoster.h +++ b/Swiften/Roster/XMPPRoster.h @@ -9,11 +9,11 @@ #include <boost/optional.hpp> #include <vector> #include <set> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <string> -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/RosterItemPayload.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/RosterItemPayload.h> #include <Swiften/Roster/XMPPRosterItem.h> namespace Swift { diff --git a/Swiften/Roster/XMPPRosterController.cpp b/Swiften/Roster/XMPPRosterController.cpp index a294d35..c34c6ec 100644 --- a/Swiften/Roster/XMPPRosterController.cpp +++ b/Swiften/Roster/XMPPRosterController.cpp @@ -4,23 +4,25 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Roster/XMPPRosterController.h" +#include <Swiften/Roster/XMPPRosterController.h> #include <boost/bind.hpp> +#include <iostream> -#include "Swiften/Base/foreach.h" -#include "Swiften/Elements/RosterItemPayload.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Roster/GetRosterRequest.h" -#include "Swiften/Roster/XMPPRosterImpl.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Elements/RosterItemPayload.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Roster/GetRosterRequest.h> +#include <Swiften/Roster/XMPPRosterImpl.h> +#include <Swiften/Roster/RosterStorage.h> namespace Swift { /** * The controller does not gain ownership of these parameters. */ -XMPPRosterController::XMPPRosterController(IQRouter* iqRouter, XMPPRosterImpl* xmppRoster) : iqRouter_(iqRouter), rosterPushResponder_(iqRouter), xmppRoster_(xmppRoster) { - rosterPushResponder_.onRosterReceived.connect(boost::bind(&XMPPRosterController::handleRosterReceived, this, _1, false)); +XMPPRosterController::XMPPRosterController(IQRouter* iqRouter, XMPPRosterImpl* xmppRoster, RosterStorage* rosterStorage) : iqRouter_(iqRouter), rosterPushResponder_(iqRouter), xmppRoster_(xmppRoster), rosterStorage_(rosterStorage), useVersioning(false) { + rosterPushResponder_.onRosterReceived.connect(boost::bind(&XMPPRosterController::handleRosterReceived, this, _1, false, boost::shared_ptr<RosterPayload>())); rosterPushResponder_.start(); } @@ -30,12 +32,24 @@ XMPPRosterController::~XMPPRosterController() { void XMPPRosterController::requestRoster() { xmppRoster_->clear(); - GetRosterRequest::ref rosterRequest = GetRosterRequest::create(iqRouter_); - rosterRequest->onResponse.connect(boost::bind(&XMPPRosterController::handleRosterReceived, this, _1, true)); + + boost::shared_ptr<RosterPayload> storedRoster = rosterStorage_->getRoster(); + GetRosterRequest::ref rosterRequest; + if (useVersioning) { + std::string version = ""; + if (storedRoster && storedRoster->getVersion()) { + version = *storedRoster->getVersion(); + } + rosterRequest = GetRosterRequest::create(iqRouter_, version); + } + else { + rosterRequest = GetRosterRequest::create(iqRouter_); + } + rosterRequest->onResponse.connect(boost::bind(&XMPPRosterController::handleRosterReceived, this, _1, true, storedRoster)); rosterRequest->send(); } -void XMPPRosterController::handleRosterReceived(boost::shared_ptr<RosterPayload> rosterPayload, bool initial) { +void XMPPRosterController::handleRosterReceived(boost::shared_ptr<RosterPayload> rosterPayload, bool initial, boost::shared_ptr<RosterPayload> previousRoster) { if (rosterPayload) { foreach(const RosterItemPayload& item, rosterPayload->getItems()) { //Don't worry about the updated case, the XMPPRoster sorts that out. @@ -46,9 +60,33 @@ void XMPPRosterController::handleRosterReceived(boost::shared_ptr<RosterPayload> } } } + else if (previousRoster) { + // The cached version hasn't changed; emit all items + foreach(const RosterItemPayload& item, previousRoster->getItems()) { + if (item.getSubscription() != RosterItemPayload::Remove) { + xmppRoster_->addContact(item.getJID(), item.getName(), item.getGroups(), item.getSubscription()); + } + else { + std::cerr << "ERROR: Stored invalid roster item" << std::endl; + } + } + } if (initial) { xmppRoster_->onInitialRosterPopulated(); } + if (rosterPayload && rosterPayload->getVersion() && useVersioning) { + saveRoster(*rosterPayload->getVersion()); + } +} + +void XMPPRosterController::saveRoster(const std::string& version) { + std::vector<XMPPRosterItem> items = xmppRoster_->getItems(); + boost::shared_ptr<RosterPayload> roster(new RosterPayload()); + roster->setVersion(version); + foreach(const XMPPRosterItem& item, items) { + roster->addItem(RosterItemPayload(item.getJID(), item.getName(), item.getSubscription(), item.getGroups())); + } + rosterStorage_->setRoster(roster); } } diff --git a/Swiften/Roster/XMPPRosterController.h b/Swiften/Roster/XMPPRosterController.h index eeb84f6..f105463 100644 --- a/Swiften/Roster/XMPPRosterController.h +++ b/Swiften/Roster/XMPPRosterController.h @@ -8,31 +8,39 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/JID/JID.h" +#include <Swiften/JID/JID.h> #include <string> -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/RosterPayload.h" -#include "Swiften/Roster/RosterPushResponder.h" -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Elements/IQ.h> +#include <Swiften/Elements/RosterPayload.h> +#include <Swiften/Roster/RosterPushResponder.h> +#include <Swiften/Base/boost_bsignals.h> namespace Swift { class IQRouter; class XMPPRosterImpl; + class RosterStorage; class XMPPRosterController { public: - XMPPRosterController(IQRouter *iqRouter, XMPPRosterImpl* xmppRoster); + XMPPRosterController(IQRouter *iqRouter, XMPPRosterImpl* xmppRoster, RosterStorage* storage); ~XMPPRosterController(); void requestRoster(); + void setUseVersioning(bool b) { + useVersioning = b; + } + private: - void handleRosterReceived(boost::shared_ptr<RosterPayload> rosterPayload, bool initial); + void handleRosterReceived(boost::shared_ptr<RosterPayload> rosterPayload, bool initial, boost::shared_ptr<RosterPayload> previousRoster); + void saveRoster(const std::string& version); private: IQRouter* iqRouter_; RosterPushResponder rosterPushResponder_; XMPPRosterImpl* xmppRoster_; + RosterStorage* rosterStorage_; + bool useVersioning; }; } diff --git a/Swiften/Roster/XMPPRosterImpl.h b/Swiften/Roster/XMPPRosterImpl.h index a44a1ce..cbb3166 100644 --- a/Swiften/Roster/XMPPRosterImpl.h +++ b/Swiften/Roster/XMPPRosterImpl.h @@ -9,7 +9,7 @@ #include <map> #include <set> -#include "Swiften/Roster/XMPPRoster.h" +#include <Swiften/Roster/XMPPRoster.h> namespace Swift { class XMPPRosterImpl : public XMPPRoster { diff --git a/Swiften/SASL/ClientAuthenticator.cpp b/Swiften/SASL/ClientAuthenticator.cpp index 533f172..e0900a3 100644 --- a/Swiften/SASL/ClientAuthenticator.cpp +++ b/Swiften/SASL/ClientAuthenticator.cpp @@ -1,10 +1,10 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2011 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/SASL/ClientAuthenticator.h" +#include <Swiften/SASL/ClientAuthenticator.h> namespace Swift { diff --git a/Swiften/SASL/ClientAuthenticator.h b/Swiften/SASL/ClientAuthenticator.h index 33db75f..8710ac8 100644 --- a/Swiften/SASL/ClientAuthenticator.h +++ b/Swiften/SASL/ClientAuthenticator.h @@ -7,9 +7,11 @@ #pragma once #include <boost/optional.hpp> - #include <string> -#include "Swiften/Base/ByteArray.h" +#include <vector> + +#include <Swiften/Base/SafeByteArray.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { class ClientAuthenticator { @@ -21,13 +23,13 @@ namespace Swift { return name; } - void setCredentials(const std::string& authcid, const std::string& password, const std::string& authzid = std::string()) { + void setCredentials(const std::string& authcid, const SafeByteArray& password, const std::string& authzid = std::string()) { this->authcid = authcid; this->password = password; this->authzid = authzid; } - virtual boost::optional<ByteArray> getResponse() const = 0; + virtual boost::optional<SafeByteArray> getResponse() const = 0; virtual bool setChallenge(const boost::optional<ByteArray>&) = 0; const std::string& getAuthenticationID() const { @@ -38,14 +40,14 @@ namespace Swift { return authzid; } - const std::string& getPassword() const { + const SafeByteArray& getPassword() const { return password; } private: std::string name; std::string authcid; - std::string password; + SafeByteArray password; std::string authzid; }; } diff --git a/Swiften/SASL/DIGESTMD5ClientAuthenticator.cpp b/Swiften/SASL/DIGESTMD5ClientAuthenticator.cpp index 6892948..5e78ee2 100644 --- a/Swiften/SASL/DIGESTMD5ClientAuthenticator.cpp +++ b/Swiften/SASL/DIGESTMD5ClientAuthenticator.cpp @@ -4,21 +4,23 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/SASL/DIGESTMD5ClientAuthenticator.h" +#include <Swiften/SASL/DIGESTMD5ClientAuthenticator.h> #include <cassert> -#include "Swiften/StringCodecs/MD5.h" -#include "Swiften/StringCodecs/Hexify.h" +#include <Swiften/StringCodecs/MD5.h> +#include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/Base/Concat.h> +#include <Swiften/Base/Algorithm.h> namespace Swift { DIGESTMD5ClientAuthenticator::DIGESTMD5ClientAuthenticator(const std::string& host, const std::string& nonce) : ClientAuthenticator("DIGEST-MD5"), step(Initial), host(host), cnonce(nonce) { } -boost::optional<ByteArray> DIGESTMD5ClientAuthenticator::getResponse() const { +boost::optional<SafeByteArray> DIGESTMD5ClientAuthenticator::getResponse() const { if (step == Initial) { - return boost::optional<ByteArray>(); + return boost::optional<SafeByteArray>(); } else if (step == Response) { std::string realm; @@ -30,16 +32,20 @@ boost::optional<ByteArray> DIGESTMD5ClientAuthenticator::getResponse() const { std::string nc = "00000001"; // Compute the response value - ByteArray A1 = MD5::getHash(getAuthenticationID() + ":" + realm + ":" + getPassword()) + ":" + *challenge.getValue("nonce") + ":" + cnonce; + ByteArray A1 = concat( + MD5::getHash( + concat(createSafeByteArray(getAuthenticationID().c_str()), createSafeByteArray(":"), createSafeByteArray(realm.c_str()), createSafeByteArray(":"), getPassword())), + createByteArray(":"), createByteArray(*challenge.getValue("nonce")), createByteArray(":"), createByteArray(cnonce)); if (!getAuthorizationID().empty()) { - A1 += ":" + getAuthenticationID(); + append(A1, createByteArray(":" + getAuthenticationID())); } - std::string A2 = "AUTHENTICATE:" + digestURI; + ByteArray A2 = createByteArray("AUTHENTICATE:" + digestURI); + + std::string responseValue = Hexify::hexify(MD5::getHash(createByteArray( + Hexify::hexify(MD5::getHash(A1)) + ":" + + *challenge.getValue("nonce") + ":" + nc + ":" + cnonce + ":" + qop + ":" + + Hexify::hexify(MD5::getHash(A2))))); - std::string responseValue = Hexify::hexify(MD5::getHash( - Hexify::hexify(MD5::getHash(A1)) + ":" - + *challenge.getValue("nonce") + ":" + nc + ":" + cnonce + ":" + qop + ":" - + Hexify::hexify(MD5::getHash(A2)))); DIGESTMD5Properties response; response.setValue("username", getAuthenticationID()); @@ -56,10 +62,10 @@ boost::optional<ByteArray> DIGESTMD5ClientAuthenticator::getResponse() const { if (!getAuthorizationID().empty()) { response.setValue("authzid", getAuthorizationID()); } - return response.serialize(); + return createSafeByteArray(response.serialize()); } else { - return boost::optional<ByteArray>(); + return boost::optional<SafeByteArray>(); } } diff --git a/Swiften/SASL/DIGESTMD5ClientAuthenticator.h b/Swiften/SASL/DIGESTMD5ClientAuthenticator.h index 50dd9aa..55bd592 100644 --- a/Swiften/SASL/DIGESTMD5ClientAuthenticator.h +++ b/Swiften/SASL/DIGESTMD5ClientAuthenticator.h @@ -9,17 +9,18 @@ #include <map> #include <string> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/SASL/ClientAuthenticator.h" -#include "Swiften/SASL/DIGESTMD5Properties.h" +#include <vector> +#include <Swiften/SASL/ClientAuthenticator.h> +#include <Swiften/SASL/DIGESTMD5Properties.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class DIGESTMD5ClientAuthenticator : public ClientAuthenticator { public: DIGESTMD5ClientAuthenticator(const std::string& host, const std::string& nonce); - virtual boost::optional<ByteArray> getResponse() const; - virtual bool setChallenge(const boost::optional<ByteArray>&); + virtual boost::optional<SafeByteArray> getResponse() const; + virtual bool setChallenge(const boost::optional<std::vector<unsigned char> >&); private: enum Step { diff --git a/Swiften/SASL/DIGESTMD5Properties.cpp b/Swiften/SASL/DIGESTMD5Properties.cpp index dfff9c8..6d406e0 100644 --- a/Swiften/SASL/DIGESTMD5Properties.cpp +++ b/Swiften/SASL/DIGESTMD5Properties.cpp @@ -4,20 +4,21 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/SASL/DIGESTMD5Properties.h" +#include <Swiften/SASL/DIGESTMD5Properties.h> +#include <Swiften/Base/Algorithm.h> namespace Swift { namespace { bool insideQuotes(const ByteArray& v) { - if (v.getSize() == 0) { + if (v.empty()) { return false; } - else if (v.getSize() == 1) { + else if (v.size() == 1) { return v[0] == '"'; } else if (v[0] == '"') { - return v[v.getSize() - 1] != '"'; + return v[v.size() - 1] != '"'; } else { return false; @@ -25,16 +26,16 @@ namespace { } ByteArray stripQuotes(const ByteArray& v) { - const char* data = reinterpret_cast<const char*>(v.getData()); - size_t size = v.getSize(); + const char* data = reinterpret_cast<const char*>(vecptr(v)); + size_t size = v.size(); if (v[0] == '"') { data++; size--; } - if (v[v.getSize() - 1] == '"') { + if (v[v.size() - 1] == '"') { size--; } - return ByteArray(data, size); + return createByteArray(data, size); } } @@ -46,42 +47,42 @@ DIGESTMD5Properties DIGESTMD5Properties::parse(const ByteArray& data) { bool inKey = true; ByteArray currentKey; ByteArray currentValue; - for (size_t i = 0; i < data.getSize(); ++i) { + for (size_t i = 0; i < data.size(); ++i) { char c = data[i]; if (inKey) { if (c == '=') { inKey = false; } else { - currentKey += c; + currentKey.push_back(c); } } else { if (c == ',' && !insideQuotes(currentValue)) { - std::string key = currentKey.toString(); + std::string key = byteArrayToString(currentKey); if (isQuoted(key)) { - result.setValue(key, stripQuotes(currentValue).toString()); + result.setValue(key, byteArrayToString(stripQuotes(currentValue))); } else { - result.setValue(key, currentValue.toString()); + result.setValue(key, byteArrayToString(currentValue)); } inKey = true; currentKey = ByteArray(); currentValue = ByteArray(); } else { - currentValue += c; + currentValue.push_back(c); } } } - if (!currentKey.isEmpty()) { - std::string key = currentKey.toString(); + if (!currentKey.empty()) { + std::string key = byteArrayToString(currentKey); if (isQuoted(key)) { - result.setValue(key, stripQuotes(currentValue).toString()); + result.setValue(key, byteArrayToString(stripQuotes(currentValue))); } else { - result.setValue(key, currentValue.toString()); + result.setValue(key, byteArrayToString(currentValue)); } } @@ -92,15 +93,17 @@ ByteArray DIGESTMD5Properties::serialize() const { ByteArray result; for(DIGESTMD5PropertiesMap::const_iterator i = properties.begin(); i != properties.end(); ++i) { if (i != properties.begin()) { - result += ','; + result.push_back(','); } - result += i->first; - result += '='; + append(result, createByteArray(i->first)); + result.push_back('='); if (isQuoted(i->first)) { - result += "\"" + i->second + "\""; + append(result, createByteArray("\"")); + append(result, i->second); + append(result, createByteArray("\"")); } else { - result += i->second; + append(result, i->second); } } return result; @@ -109,7 +112,7 @@ ByteArray DIGESTMD5Properties::serialize() const { boost::optional<std::string> DIGESTMD5Properties::getValue(const std::string& key) const { DIGESTMD5PropertiesMap::const_iterator i = properties.find(key); if (i != properties.end()) { - return i->second.toString(); + return byteArrayToString(i->second); } else { return boost::optional<std::string>(); @@ -117,7 +120,7 @@ boost::optional<std::string> DIGESTMD5Properties::getValue(const std::string& ke } void DIGESTMD5Properties::setValue(const std::string& key, const std::string& value) { - properties.insert(DIGESTMD5PropertiesMap::value_type(key, ByteArray(value))); + properties.insert(DIGESTMD5PropertiesMap::value_type(key, createByteArray(value))); } bool DIGESTMD5Properties::isQuoted(const std::string& p) { diff --git a/Swiften/SASL/DIGESTMD5Properties.h b/Swiften/SASL/DIGESTMD5Properties.h index 6e2e592..ef87574 100644 --- a/Swiften/SASL/DIGESTMD5Properties.h +++ b/Swiften/SASL/DIGESTMD5Properties.h @@ -10,7 +10,7 @@ #include <boost/optional.hpp> #include <string> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> namespace Swift { class DIGESTMD5Properties { diff --git a/Swiften/SASL/PLAINClientAuthenticator.cpp b/Swiften/SASL/PLAINClientAuthenticator.cpp index 2ea2425..7872174 100644 --- a/Swiften/SASL/PLAINClientAuthenticator.cpp +++ b/Swiften/SASL/PLAINClientAuthenticator.cpp @@ -4,15 +4,16 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/SASL/PLAINClientAuthenticator.h" +#include <Swiften/SASL/PLAINClientAuthenticator.h> +#include <Swiften/Base/Concat.h> namespace Swift { PLAINClientAuthenticator::PLAINClientAuthenticator() : ClientAuthenticator("PLAIN") { } -boost::optional<ByteArray> PLAINClientAuthenticator::getResponse() const { - return ByteArray(getAuthorizationID()) + '\0' + ByteArray(getAuthenticationID()) + '\0' + ByteArray(getPassword()); +boost::optional<SafeByteArray> PLAINClientAuthenticator::getResponse() const { + return concat(createSafeByteArray(getAuthorizationID()), createSafeByteArray('\0'), createSafeByteArray(getAuthenticationID()), createSafeByteArray('\0'), getPassword()); } bool PLAINClientAuthenticator::setChallenge(const boost::optional<ByteArray>&) { diff --git a/Swiften/SASL/PLAINClientAuthenticator.h b/Swiften/SASL/PLAINClientAuthenticator.h index 959244d..83e45c1 100644 --- a/Swiften/SASL/PLAINClientAuthenticator.h +++ b/Swiften/SASL/PLAINClientAuthenticator.h @@ -6,14 +6,15 @@ #pragma once -#include "Swiften/SASL/ClientAuthenticator.h" +#include <Swiften/SASL/ClientAuthenticator.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { class PLAINClientAuthenticator : public ClientAuthenticator { public: PLAINClientAuthenticator(); - virtual boost::optional<ByteArray> getResponse() const; + virtual boost::optional<SafeByteArray> getResponse() const; virtual bool setChallenge(const boost::optional<ByteArray>&); }; } diff --git a/Swiften/SASL/PLAINMessage.cpp b/Swiften/SASL/PLAINMessage.cpp index 3728b39..20ffea7 100644 --- a/Swiften/SASL/PLAINMessage.cpp +++ b/Swiften/SASL/PLAINMessage.cpp @@ -4,41 +4,41 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/SASL/PLAINMessage.h" +#include <Swiften/SASL/PLAINMessage.h> +#include <Swiften/Base/Concat.h> namespace Swift { -PLAINMessage::PLAINMessage(const std::string& authcid, const std::string& password, const std::string& authzid) : authcid(authcid), authzid(authzid), password(password) { +PLAINMessage::PLAINMessage(const std::string& authcid, const SafeByteArray& password, const std::string& authzid) : authcid(authcid), authzid(authzid), password(password) { } -PLAINMessage::PLAINMessage(const ByteArray& value) { +PLAINMessage::PLAINMessage(const SafeByteArray& value) { size_t i = 0; - while (i < value.getSize() && value[i] != '\0') { + while (i < value.size() && value[i] != '\0') { authzid += value[i]; ++i; } - if (i == value.getSize()) { + if (i == value.size()) { return; } ++i; - while (i < value.getSize() && value[i] != '\0') { + while (i < value.size() && value[i] != '\0') { authcid += value[i]; ++i; } - if (i == value.getSize()) { + if (i == value.size()) { authcid = ""; return; } ++i; - while (i < value.getSize()) { - password += value[i]; + while (i < value.size()) { + password.push_back(value[i]); ++i; } } -ByteArray PLAINMessage::getValue() const { - std::string s = authzid + '\0' + authcid + '\0' + password; - return ByteArray(s.c_str(), s.size()); +SafeByteArray PLAINMessage::getValue() const { + return concat(createSafeByteArray(authzid), createSafeByteArray('\0'), createSafeByteArray(authcid), createSafeByteArray('\0'), password); } } diff --git a/Swiften/SASL/PLAINMessage.h b/Swiften/SASL/PLAINMessage.h index d08d70d..46ee8f7 100644 --- a/Swiften/SASL/PLAINMessage.h +++ b/Swiften/SASL/PLAINMessage.h @@ -9,21 +9,21 @@ #pragma once #include <string> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class PLAINMessage { public: - PLAINMessage(const std::string& authcid, const std::string& password, const std::string& authzid = ""); - PLAINMessage(const ByteArray& value); + PLAINMessage(const std::string& authcid, const SafeByteArray& password, const std::string& authzid = ""); + PLAINMessage(const SafeByteArray& value); - ByteArray getValue() const; + SafeByteArray getValue() const; const std::string& getAuthenticationID() const { return authcid; } - const std::string& getPassword() const { + const SafeByteArray& getPassword() const { return password; } @@ -34,6 +34,6 @@ namespace Swift { private: std::string authcid; std::string authzid; - std::string password; + SafeByteArray password; }; } diff --git a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp index 33de014..7842b4f 100644 --- a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp +++ b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp @@ -4,17 +4,18 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/SASL/SCRAMSHA1ClientAuthenticator.h" +#include <Swiften/SASL/SCRAMSHA1ClientAuthenticator.h> #include <cassert> #include <map> #include <boost/lexical_cast.hpp> -#include "Swiften/StringCodecs/SHA1.h" -#include "Swiften/StringCodecs/Base64.h" -#include "Swiften/StringCodecs/HMACSHA1.h" -#include "Swiften/StringCodecs/PBKDF2.h" -#include "Swiften/IDN/StringPrep.h" +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/StringCodecs/Base64.h> +#include <Swiften/StringCodecs/HMAC_SHA1.h> +#include <Swiften/StringCodecs/PBKDF2.h> +#include <Swiften/IDN/StringPrep.h> +#include <Swiften/Base/Concat.h> namespace Swift { @@ -38,23 +39,23 @@ static std::string escape(const std::string& s) { SCRAMSHA1ClientAuthenticator::SCRAMSHA1ClientAuthenticator(const std::string& nonce, bool useChannelBinding) : ClientAuthenticator(useChannelBinding ? "SCRAM-SHA-1-PLUS" : "SCRAM-SHA-1"), step(Initial), clientnonce(nonce), useChannelBinding(useChannelBinding) { } -boost::optional<ByteArray> SCRAMSHA1ClientAuthenticator::getResponse() const { +boost::optional<SafeByteArray> SCRAMSHA1ClientAuthenticator::getResponse() const { if (step == Initial) { - return getGS2Header() + getInitialBareClientMessage(); + return createSafeByteArray(concat(getGS2Header(), getInitialBareClientMessage())); } else if (step == Proof) { - ByteArray clientKey = HMACSHA1::getResult(saltedPassword, "Client Key"); + ByteArray clientKey = HMAC_SHA1()(saltedPassword, createByteArray("Client Key")); ByteArray storedKey = SHA1::getHash(clientKey); - ByteArray clientSignature = HMACSHA1::getResult(storedKey, authMessage); + ByteArray clientSignature = HMAC_SHA1()(createSafeByteArray(storedKey), authMessage); ByteArray clientProof = clientKey; - for (unsigned int i = 0; i < clientProof.getSize(); ++i) { + for (unsigned int i = 0; i < clientProof.size(); ++i) { clientProof[i] ^= clientSignature[i]; } - ByteArray result = getFinalMessageWithoutProof() + ",p=" + Base64::encode(clientProof); - return result; + ByteArray result = concat(getFinalMessageWithoutProof(), createByteArray(",p="), createByteArray(Base64::encode(clientProof))); + return createSafeByteArray(result); } else { - return boost::optional<ByteArray>(); + return boost::optional<SafeByteArray>(); } } @@ -65,7 +66,7 @@ bool SCRAMSHA1ClientAuthenticator::setChallenge(const boost::optional<ByteArray> } initialServerMessage = *challenge; - std::map<char, std::string> keys = parseMap(initialServerMessage.toString()); + std::map<char, std::string> keys = parseMap(byteArrayToString(initialServerMessage)); // Extract the salt ByteArray salt = Base64::decode(keys['s']); @@ -79,7 +80,7 @@ bool SCRAMSHA1ClientAuthenticator::setChallenge(const boost::optional<ByteArray> if (receivedClientNonce != clientnonce) { return false; } - serverNonce = clientServerNonce.substr(clientnonce.size(), clientServerNonce.npos); + serverNonce = createByteArray(clientServerNonce.substr(clientnonce.size(), clientServerNonce.npos)); // Extract the number of iterations int iterations = 0; @@ -100,19 +101,19 @@ bool SCRAMSHA1ClientAuthenticator::setChallenge(const boost::optional<ByteArray> // Compute all the values needed for the server signature try { - saltedPassword = PBKDF2::encode(StringPrep::getPrepared(getPassword(), StringPrep::SASLPrep), salt, iterations); + saltedPassword = PBKDF2::encode<HMAC_SHA1>(StringPrep::getPrepared(getPassword(), StringPrep::SASLPrep), salt, iterations); } catch (const std::exception&) { } - authMessage = getInitialBareClientMessage() + "," + initialServerMessage + "," + getFinalMessageWithoutProof(); - ByteArray serverKey = HMACSHA1::getResult(saltedPassword, "Server Key"); - serverSignature = HMACSHA1::getResult(serverKey, authMessage); + authMessage = concat(getInitialBareClientMessage(), createByteArray(","), initialServerMessage, createByteArray(","), getFinalMessageWithoutProof()); + ByteArray serverKey = HMAC_SHA1()(saltedPassword, createByteArray("Server Key")); + serverSignature = HMAC_SHA1()(serverKey, authMessage); step = Proof; return true; } else if (step == Proof) { - ByteArray result = ByteArray("v=") + ByteArray(Base64::encode(serverSignature)); + ByteArray result = concat(createByteArray("v="), createByteArray(Base64::encode(serverSignature))); step = Final; return challenge && challenge == result; } @@ -135,7 +136,7 @@ std::map<char, std::string> SCRAMSHA1ClientAuthenticator::parseMap(const std::st i++; } else if (s[i] == ',') { - result[key] = value; + result[static_cast<size_t>(key)] = value; value = ""; expectKey = true; } @@ -152,24 +153,24 @@ std::map<char, std::string> SCRAMSHA1ClientAuthenticator::parseMap(const std::st ByteArray SCRAMSHA1ClientAuthenticator::getInitialBareClientMessage() const { std::string authenticationID; try { - authenticationID = StringPrep::getPrepared(getAuthenticationID(), StringPrep::SASLPrep); + authenticationID = StringPrep::getPrepared(getAuthenticationID(), StringPrep::SASLPrep); } catch (const std::exception&) { } - return ByteArray(std::string("n=" + escape(authenticationID) + ",r=" + clientnonce)); + return createByteArray(std::string("n=" + escape(authenticationID) + ",r=" + clientnonce)); } ByteArray SCRAMSHA1ClientAuthenticator::getGS2Header() const { - ByteArray channelBindingHeader("n"); + ByteArray channelBindingHeader(createByteArray("n")); if (tlsChannelBindingData) { if (useChannelBinding) { - channelBindingHeader = ByteArray("p=tls-unique"); + channelBindingHeader = createByteArray("p=tls-unique"); } else { - channelBindingHeader = ByteArray("y"); + channelBindingHeader = createByteArray("y"); } } - return channelBindingHeader + ByteArray(",") + (getAuthorizationID().empty() ? "" : "a=" + escape(getAuthorizationID())) + ","; + return concat(channelBindingHeader, createByteArray(","), (getAuthorizationID().empty() ? ByteArray() : createByteArray("a=" + escape(getAuthorizationID()))), createByteArray(",")); } void SCRAMSHA1ClientAuthenticator::setTLSChannelBindingData(const ByteArray& channelBindingData) { @@ -181,7 +182,7 @@ ByteArray SCRAMSHA1ClientAuthenticator::getFinalMessageWithoutProof() const { if (useChannelBinding && tlsChannelBindingData) { channelBindData = *tlsChannelBindingData; } - return ByteArray("c=") + Base64::encode(getGS2Header() + channelBindData) + ",r=" + clientnonce + serverNonce; + return concat(createByteArray("c=" + Base64::encode(concat(getGS2Header(), channelBindData)) + ",r=" + clientnonce), serverNonce); } diff --git a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h index 602fc94..d140013 100644 --- a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h +++ b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h @@ -10,8 +10,8 @@ #include <boost/optional.hpp> #include <string> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/SASL/ClientAuthenticator.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/SASL/ClientAuthenticator.h> namespace Swift { class SCRAMSHA1ClientAuthenticator : public ClientAuthenticator { @@ -20,7 +20,7 @@ namespace Swift { void setTLSChannelBindingData(const ByteArray& channelBindingData); - virtual boost::optional<ByteArray> getResponse() const; + virtual boost::optional<SafeByteArray> getResponse() const; virtual bool setChallenge(const boost::optional<ByteArray>&); private: diff --git a/Swiften/SASL/SConscript b/Swiften/SASL/SConscript index 5a0cdef..085e49d 100644 --- a/Swiften/SASL/SConscript +++ b/Swiften/SASL/SConscript @@ -12,6 +12,7 @@ objects = myenv.SwiftenObject([ "DIGESTMD5ClientAuthenticator.cpp", ]) swiften_env.Append(SWIFTEN_OBJECTS = [objects]) + env.Append(UNITTEST_SOURCES = [ File("UnitTest/PLAINMessageTest.cpp"), File("UnitTest/PLAINClientAuthenticatorTest.cpp"), diff --git a/Swiften/SASL/UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp b/Swiften/SASL/UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp index 54f0571..38bab15 100644 --- a/Swiften/SASL/UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp +++ b/Swiften/SASL/UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp @@ -4,11 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ +#include <QA/Checker/IO.h> + #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/SASL/DIGESTMD5ClientAuthenticator.h" -#include "Swiften/Base/ByteArray.h" +#include <Swiften/SASL/DIGESTMD5ClientAuthenticator.h> +#include <Swiften/Base/ByteArray.h> using namespace Swift; @@ -30,29 +32,29 @@ class DIGESTMD5ClientAuthenticatorTest : public CppUnit::TestFixture { void testGetResponse() { DIGESTMD5ClientAuthenticator testling("xmpp.example.com", "abcdefgh"); - testling.setCredentials("user", "pass", ""); - testling.setChallenge(ByteArray( + testling.setCredentials("user", createSafeByteArray("pass"), ""); + testling.setChallenge(createByteArray( "realm=\"example.com\"," "nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\"," "qop=auth,charset=utf-8,algorithm=md5-sess")); - ByteArray response = *testling.getResponse(); + SafeByteArray response = *testling.getResponse(); - CPPUNIT_ASSERT_EQUAL(std::string("charset=utf-8,cnonce=\"abcdefgh\",digest-uri=\"xmpp/xmpp.example.com\",nc=00000001,nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\",qop=auth,realm=\"example.com\",response=088891c800ecff1b842159ad6459104a,username=\"user\""), response.toString()); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("charset=utf-8,cnonce=\"abcdefgh\",digest-uri=\"xmpp/xmpp.example.com\",nc=00000001,nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\",qop=auth,realm=\"example.com\",response=088891c800ecff1b842159ad6459104a,username=\"user\""), response); } void testGetResponse_WithAuthorizationID() { DIGESTMD5ClientAuthenticator testling("xmpp.example.com", "abcdefgh"); - testling.setCredentials("user", "pass", "myauthzid"); - testling.setChallenge(ByteArray( + testling.setCredentials("user", createSafeByteArray("pass"), "myauthzid"); + testling.setChallenge(createByteArray( "realm=\"example.com\"," "nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\"," "qop=auth,charset=utf-8,algorithm=md5-sess")); - ByteArray response = *testling.getResponse(); + SafeByteArray response = *testling.getResponse(); - CPPUNIT_ASSERT_EQUAL(std::string("authzid=\"myauthzid\",charset=utf-8,cnonce=\"abcdefgh\",digest-uri=\"xmpp/xmpp.example.com\",nc=00000001,nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\",qop=auth,realm=\"example.com\",response=4293834432b6e7889a2dee7e8fe7dd06,username=\"user\""), response.toString()); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("authzid=\"myauthzid\",charset=utf-8,cnonce=\"abcdefgh\",digest-uri=\"xmpp/xmpp.example.com\",nc=00000001,nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\",qop=auth,realm=\"example.com\",response=4293834432b6e7889a2dee7e8fe7dd06,username=\"user\""), response); } }; diff --git a/Swiften/SASL/UnitTest/DIGESTMD5PropertiesTest.cpp b/Swiften/SASL/UnitTest/DIGESTMD5PropertiesTest.cpp index 152a41e..d664f14 100644 --- a/Swiften/SASL/UnitTest/DIGESTMD5PropertiesTest.cpp +++ b/Swiften/SASL/UnitTest/DIGESTMD5PropertiesTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/SASL/DIGESTMD5Properties.h" +#include <Swiften/SASL/DIGESTMD5Properties.h> using namespace Swift; @@ -19,7 +19,7 @@ class DIGESTMD5PropertiesTest : public CppUnit::TestFixture { public: void testParse() { - DIGESTMD5Properties properties = DIGESTMD5Properties::parse(ByteArray( + DIGESTMD5Properties properties = DIGESTMD5Properties::parse(createByteArray( "realm=\"myrealm1\",realm=\"myrealm2\",nonce=\"mynonce\"," "algorithm=md5-sess,charset=utf-8")); @@ -47,8 +47,8 @@ class DIGESTMD5PropertiesTest : public CppUnit::TestFixture { properties.setValue("username", "myuser"); ByteArray result = properties.serialize(); - ByteArray expected("authzid=\"myauthzid\",charset=utf-8,cnonce=\"mycnonce\",digest-uri=\"mydigesturi\",nc=1,nonce=\"mynonce\",qop=auth,realm=\"myrealm\",response=myresponse,username=\"myuser\""); - CPPUNIT_ASSERT_EQUAL(expected.toString(), result.toString()); + ByteArray expected(createByteArray("authzid=\"myauthzid\",charset=utf-8,cnonce=\"mycnonce\",digest-uri=\"mydigesturi\",nc=1,nonce=\"mynonce\",qop=auth,realm=\"myrealm\",response=myresponse,username=\"myuser\"")); + CPPUNIT_ASSERT_EQUAL(byteArrayToString(expected), byteArrayToString(result)); } }; diff --git a/Swiften/SASL/UnitTest/PLAINClientAuthenticatorTest.cpp b/Swiften/SASL/UnitTest/PLAINClientAuthenticatorTest.cpp index 33914b2..3416923 100644 --- a/Swiften/SASL/UnitTest/PLAINClientAuthenticatorTest.cpp +++ b/Swiften/SASL/UnitTest/PLAINClientAuthenticatorTest.cpp @@ -4,8 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/SASL/PLAINClientAuthenticator.h" +#include <Swiften/SASL/PLAINClientAuthenticator.h> +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> @@ -21,17 +22,17 @@ class PLAINClientAuthenticatorTest : public CppUnit::TestFixture { void testGetResponse_WithoutAuthzID() { PLAINClientAuthenticator testling; - testling.setCredentials("user", "pass"); + testling.setCredentials("user", createSafeByteArray("pass")); - CPPUNIT_ASSERT_EQUAL(*testling.getResponse(), ByteArray("\0user\0pass", 10)); + CPPUNIT_ASSERT_EQUAL(*testling.getResponse(), createSafeByteArray("\0user\0pass", 10)); } void testGetResponse_WithAuthzID() { PLAINClientAuthenticator testling; - testling.setCredentials("user", "pass", "authz"); + testling.setCredentials("user", createSafeByteArray("pass"), "authz"); - CPPUNIT_ASSERT_EQUAL(*testling.getResponse(), ByteArray("authz\0user\0pass", 15)); + CPPUNIT_ASSERT_EQUAL(*testling.getResponse(), createSafeByteArray("authz\0user\0pass", 15)); } }; diff --git a/Swiften/SASL/UnitTest/PLAINMessageTest.cpp b/Swiften/SASL/UnitTest/PLAINMessageTest.cpp index d517f0d..e917af5 100644 --- a/Swiften/SASL/UnitTest/PLAINMessageTest.cpp +++ b/Swiften/SASL/UnitTest/PLAINMessageTest.cpp @@ -4,12 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/SASL/PLAINMessage.h" +#include <Swiften/SASL/PLAINMessage.h> using namespace Swift; @@ -28,39 +29,39 @@ class PLAINMessageTest : public CppUnit::TestFixture PLAINMessageTest() {} void testGetValue_WithoutAuthzID() { - PLAINMessage message("user", "pass"); - CPPUNIT_ASSERT_EQUAL(message.getValue(), ByteArray("\0user\0pass", 10)); + PLAINMessage message("user", createSafeByteArray("pass")); + CPPUNIT_ASSERT_EQUAL(message.getValue(), createSafeByteArray("\0user\0pass", 10)); } void testGetValue_WithAuthzID() { - PLAINMessage message("user", "pass", "authz"); - CPPUNIT_ASSERT_EQUAL(message.getValue(), ByteArray("authz\0user\0pass", 15)); + PLAINMessage message("user", createSafeByteArray("pass"), "authz"); + CPPUNIT_ASSERT_EQUAL(message.getValue(), createSafeByteArray("authz\0user\0pass", 15)); } void testConstructor_WithoutAuthzID() { - PLAINMessage message(ByteArray("\0user\0pass", 10)); + PLAINMessage message(createSafeByteArray("\0user\0pass", 10)); CPPUNIT_ASSERT_EQUAL(std::string(""), message.getAuthorizationID()); CPPUNIT_ASSERT_EQUAL(std::string("user"), message.getAuthenticationID()); - CPPUNIT_ASSERT_EQUAL(std::string("pass"), message.getPassword()); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("pass"), message.getPassword()); } void testConstructor_WithAuthzID() { - PLAINMessage message(ByteArray("authz\0user\0pass", 15)); + PLAINMessage message(createSafeByteArray("authz\0user\0pass", 15)); CPPUNIT_ASSERT_EQUAL(std::string("authz"), message.getAuthorizationID()); CPPUNIT_ASSERT_EQUAL(std::string("user"), message.getAuthenticationID()); - CPPUNIT_ASSERT_EQUAL(std::string("pass"), message.getPassword()); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("pass"), message.getPassword()); } void testConstructor_NoAuthcid() { - PLAINMessage message(ByteArray("authzid", 7)); + PLAINMessage message(createSafeByteArray("authzid", 7)); CPPUNIT_ASSERT_EQUAL(std::string(""), message.getAuthenticationID()); } void testConstructor_NoPassword() { - PLAINMessage message(ByteArray("authzid\0authcid", 15)); + PLAINMessage message(createSafeByteArray("authzid\0authcid", 15)); CPPUNIT_ASSERT_EQUAL(std::string(""), message.getAuthenticationID()); } diff --git a/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp b/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp index 5d0edbd..f0ca01c 100644 --- a/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp +++ b/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp @@ -4,11 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ +#include <QA/Checker/IO.h> + #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/SASL/SCRAMSHA1ClientAuthenticator.h" -#include "Swiften/Base/ByteArray.h" +#include <Swiften/SASL/SCRAMSHA1ClientAuthenticator.h> +#include <Swiften/Base/ByteArray.h> using namespace Swift; @@ -41,179 +43,179 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture { void testGetInitialResponse() { SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH"); - testling.setCredentials("user", "pass", ""); + testling.setCredentials("user", createSafeByteArray("pass"), ""); - ByteArray response = *testling.getResponse(); + SafeByteArray response = *testling.getResponse(); - CPPUNIT_ASSERT_EQUAL(std::string("n,,n=user,r=abcdefghABCDEFGH"), response.toString()); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("n,,n=user,r=abcdefghABCDEFGH"), response); } void testGetInitialResponse_UsernameHasSpecialChars() { SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH"); - testling.setCredentials(",us=,er=", "pass", ""); + testling.setCredentials(",us=,er=", createSafeByteArray("pass"), ""); - ByteArray response = *testling.getResponse(); + SafeByteArray response = *testling.getResponse(); - CPPUNIT_ASSERT_EQUAL(std::string("n,,n==2Cus=3D=2Cer=3D,r=abcdefghABCDEFGH"), response.toString()); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("n,,n==2Cus=3D=2Cer=3D,r=abcdefghABCDEFGH"), response); } void testGetInitialResponse_WithAuthorizationID() { SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH"); - testling.setCredentials("user", "pass", "auth"); + testling.setCredentials("user", createSafeByteArray("pass"), "auth"); - ByteArray response = *testling.getResponse(); + SafeByteArray response = *testling.getResponse(); - CPPUNIT_ASSERT_EQUAL(std::string("n,a=auth,n=user,r=abcdefghABCDEFGH"), response.toString()); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("n,a=auth,n=user,r=abcdefghABCDEFGH"), response); } void testGetInitialResponse_WithAuthorizationIDWithSpecialChars() { SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH"); - testling.setCredentials("user", "pass", "a=u,th"); + testling.setCredentials("user", createSafeByteArray("pass"), "a=u,th"); - ByteArray response = *testling.getResponse(); + SafeByteArray response = *testling.getResponse(); - CPPUNIT_ASSERT_EQUAL(std::string("n,a=a=3Du=2Cth,n=user,r=abcdefghABCDEFGH"), response.toString()); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("n,a=a=3Du=2Cth,n=user,r=abcdefghABCDEFGH"), response); } void testGetInitialResponse_WithoutChannelBindingWithTLSChannelBindingData() { SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", false); - testling.setTLSChannelBindingData("xyza"); - testling.setCredentials("user", "pass", ""); + testling.setTLSChannelBindingData(createByteArray("xyza")); + testling.setCredentials("user", createSafeByteArray("pass"), ""); - ByteArray response = *testling.getResponse(); + SafeByteArray response = *testling.getResponse(); - CPPUNIT_ASSERT_EQUAL(std::string("y,,n=user,r=abcdefghABCDEFGH"), response.toString()); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("y,,n=user,r=abcdefghABCDEFGH"), response); } void testGetInitialResponse_WithChannelBindingWithTLSChannelBindingData() { SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", true); - testling.setTLSChannelBindingData("xyza"); - testling.setCredentials("user", "pass", ""); + testling.setTLSChannelBindingData(createByteArray("xyza")); + testling.setCredentials("user", createSafeByteArray("pass"), ""); - ByteArray response = *testling.getResponse(); + SafeByteArray response = *testling.getResponse(); - CPPUNIT_ASSERT_EQUAL(std::string("p=tls-unique,,n=user,r=abcdefghABCDEFGH"), response.toString()); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("p=tls-unique,,n=user,r=abcdefghABCDEFGH"), response); } void testGetFinalResponse() { SCRAMSHA1ClientAuthenticator testling("abcdefgh"); - testling.setCredentials("user", "pass", ""); - testling.setChallenge(ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); + testling.setCredentials("user", createSafeByteArray("pass"), ""); + testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); - ByteArray response = *testling.getResponse(); + SafeByteArray response = *testling.getResponse(); - CPPUNIT_ASSERT_EQUAL(std::string("c=biws,r=abcdefghABCDEFGH,p=CZbjGDpIteIJwQNBgO0P8pKkMGY="), response.toString()); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("c=biws,r=abcdefghABCDEFGH,p=CZbjGDpIteIJwQNBgO0P8pKkMGY="), response); } void testGetFinalResponse_WithoutChannelBindingWithTLSChannelBindingData() { SCRAMSHA1ClientAuthenticator testling("abcdefgh", false); - testling.setCredentials("user", "pass", ""); - testling.setTLSChannelBindingData("xyza"); - testling.setChallenge(ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); + testling.setCredentials("user", createSafeByteArray("pass"), ""); + testling.setTLSChannelBindingData(createByteArray("xyza")); + testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); - ByteArray response = *testling.getResponse(); + SafeByteArray response = *testling.getResponse(); - CPPUNIT_ASSERT_EQUAL(std::string("c=eSws,r=abcdefghABCDEFGH,p=JNpsiFEcxZvNZ1+FFBBqrYvYxMk="), response.toString()); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("c=eSws,r=abcdefghABCDEFGH,p=JNpsiFEcxZvNZ1+FFBBqrYvYxMk="), response); } void testGetFinalResponse_WithChannelBindingWithTLSChannelBindingData() { SCRAMSHA1ClientAuthenticator testling("abcdefgh", true); - testling.setCredentials("user", "pass", ""); - testling.setTLSChannelBindingData("xyza"); - testling.setChallenge(ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); + testling.setCredentials("user", createSafeByteArray("pass"), ""); + testling.setTLSChannelBindingData(createByteArray("xyza")); + testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); - ByteArray response = *testling.getResponse(); + SafeByteArray response = *testling.getResponse(); - CPPUNIT_ASSERT_EQUAL(std::string("c=cD10bHMtdW5pcXVlLCx4eXph,r=abcdefghABCDEFGH,p=i6Rghite81P1ype8XxaVAa5l7v0="), response.toString()); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("c=cD10bHMtdW5pcXVlLCx4eXph,r=abcdefghABCDEFGH,p=i6Rghite81P1ype8XxaVAa5l7v0="), response); } void testSetFinalChallenge() { SCRAMSHA1ClientAuthenticator testling("abcdefgh"); - testling.setCredentials("user", "pass", ""); - testling.setChallenge(ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); + testling.setCredentials("user", createSafeByteArray("pass"), ""); + testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); - bool result = testling.setChallenge(ByteArray("v=Dd+Q20knZs9jeeK0pi1Mx1Se+yo=")); + bool result = testling.setChallenge(createByteArray("v=Dd+Q20knZs9jeeK0pi1Mx1Se+yo=")); CPPUNIT_ASSERT(result); } void testSetChallenge() { SCRAMSHA1ClientAuthenticator testling("abcdefgh"); - testling.setCredentials("user", "pass", ""); + testling.setCredentials("user", createSafeByteArray("pass"), ""); - bool result = testling.setChallenge(ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); + bool result = testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); CPPUNIT_ASSERT(result); } void testSetChallenge_InvalidClientNonce() { SCRAMSHA1ClientAuthenticator testling("abcdefgh"); - testling.setCredentials("user", "pass", ""); + testling.setCredentials("user", createSafeByteArray("pass"), ""); - bool result = testling.setChallenge(ByteArray("r=abcdefgiABCDEFGH,s=MTIzNDU2NzgK,i=4096")); + bool result = testling.setChallenge(createByteArray("r=abcdefgiABCDEFGH,s=MTIzNDU2NzgK,i=4096")); CPPUNIT_ASSERT(!result); } void testSetChallenge_OnlyClientNonce() { SCRAMSHA1ClientAuthenticator testling("abcdefgh"); - testling.setCredentials("user", "pass", ""); + testling.setCredentials("user", createSafeByteArray("pass"), ""); - bool result = testling.setChallenge(ByteArray("r=abcdefgh,s=MTIzNDU2NzgK,i=4096")); + bool result = testling.setChallenge(createByteArray("r=abcdefgh,s=MTIzNDU2NzgK,i=4096")); CPPUNIT_ASSERT(!result); } void testSetChallenge_InvalidIterations() { SCRAMSHA1ClientAuthenticator testling("abcdefgh"); - testling.setCredentials("user", "pass", ""); + testling.setCredentials("user", createSafeByteArray("pass"), ""); - bool result = testling.setChallenge(ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=bla")); + bool result = testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=bla")); CPPUNIT_ASSERT(!result); } void testSetChallenge_MissingIterations() { SCRAMSHA1ClientAuthenticator testling("abcdefgh"); - testling.setCredentials("user", "pass", ""); + testling.setCredentials("user", createSafeByteArray("pass"), ""); - bool result = testling.setChallenge(ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK")); + bool result = testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK")); CPPUNIT_ASSERT(!result); } void testSetChallenge_ZeroIterations() { SCRAMSHA1ClientAuthenticator testling("abcdefgh"); - testling.setCredentials("user", "pass", ""); + testling.setCredentials("user", createSafeByteArray("pass"), ""); - bool result = testling.setChallenge(ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=0")); + bool result = testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=0")); CPPUNIT_ASSERT(!result); } void testSetChallenge_NegativeIterations() { SCRAMSHA1ClientAuthenticator testling("abcdefgh"); - testling.setCredentials("user", "pass", ""); + testling.setCredentials("user", createSafeByteArray("pass"), ""); - bool result = testling.setChallenge(ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=-1")); + bool result = testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=-1")); CPPUNIT_ASSERT(!result); } void testSetFinalChallenge_InvalidChallenge() { SCRAMSHA1ClientAuthenticator testling("abcdefgh"); - testling.setCredentials("user", "pass", ""); - testling.setChallenge(ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); - bool result = testling.setChallenge(ByteArray("v=e26kI69ICb6zosapLLxrER/631A=")); + testling.setCredentials("user", createSafeByteArray("pass"), ""); + testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); + bool result = testling.setChallenge(createByteArray("v=e26kI69ICb6zosapLLxrER/631A=")); CPPUNIT_ASSERT(!result); } void testGetResponseAfterFinalChallenge() { SCRAMSHA1ClientAuthenticator testling("abcdefgh"); - testling.setCredentials("user", "pass", ""); - testling.setChallenge(ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); - testling.setChallenge(ByteArray("v=Dd+Q20knZs9jeeK0pi1Mx1Se+yo=")); + testling.setCredentials("user", createSafeByteArray("pass"), ""); + testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); + testling.setChallenge(createByteArray("v=Dd+Q20knZs9jeeK0pi1Mx1Se+yo=")); CPPUNIT_ASSERT(!testling.getResponse()); } diff --git a/Swiften/SConscript b/Swiften/SConscript index 12c7456..e650e2a 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -1,4 +1,4 @@ -import os, re, Version +import os, re, Version, os.path Import("env") @@ -6,7 +6,7 @@ Import("env") # Flags ################################################################################ -swiften_dep_modules = ["BOOST", "LIBIDN", "ZLIB", "OPENSSL", "LIBXML", "EXPAT", "AVAHI"] +swiften_dep_modules = ["BOOST", "GCONF", "LIBIDN", "ZLIB", "OPENSSL", "LIBXML", "EXPAT", "AVAHI", "LIBMINIUPNPC", "LIBNATPMP"] if env["SCONS_STAGE"] == "flags" : env["SWIFTEN_VERSION"] = Version.getBuildVersion(env.Dir("#").abspath, "swift") @@ -21,6 +21,7 @@ if env["SCONS_STAGE"] == "flags" : env["SWIFTEN_LIBRARY"] = "Swiften" env["SWIFTEN_LIBRARY_FILE"] = "Swiften" env["SWIFTEN_LIBRARY_ALIASES"] = [] + if ARGUMENTS.get("swiften_dll", False) : if env["PLATFORM"] == "win32" : pass @@ -49,6 +50,7 @@ if env["SCONS_STAGE"] == "flags" : "CPPFLAGS": e.get("CPPFLAGS", []), "LIBPATH": e.get("LIBPATH", []), "LIBS": e.get("LIBS", []), + "FRAMEWORKS": e.get("FRAMEWORKS", []), } ################################################################################ @@ -76,25 +78,38 @@ if env["SCONS_STAGE"] == "build" : "Client/ClientSessionStanzaChannel.cpp", "Client/CoreClient.cpp", "Client/Client.cpp", + "Client/ClientXMLTracer.cpp", "Client/ClientSession.cpp", + "Client/BlockList.cpp", + "Client/BlockListImpl.cpp", + "Client/ClientBlockListManager.cpp", "Client/MemoryStorages.cpp", - "Client/FileStorages.cpp", "Client/NickResolver.cpp", "Client/NickManager.cpp", "Client/NickManagerImpl.cpp", + "Client/Storages.cpp", + "Client/XMLBeautifier.cpp", "Compress/ZLibCodecompressor.cpp", "Compress/ZLibDecompressor.cpp", "Compress/ZLibCompressor.cpp", "Elements/DiscoInfo.cpp", + "Elements/Presence.cpp", "Elements/Form.cpp", + "Elements/StreamFeatures.cpp", "Elements/Element.cpp", "Elements/IQ.cpp", "Elements/Payload.cpp", + "Elements/RosterItemExchangePayload.cpp", "Elements/RosterPayload.cpp", "Elements/Stanza.cpp", + "Elements/StatusShow.cpp", + "Elements/StreamManagementEnabled.cpp", + "Elements/StreamResume.cpp", + "Elements/StreamResumed.cpp", "Elements/VCard.cpp", "Elements/MUCOccupant.cpp", "Entity/Entity.cpp", + "Entity/PayloadPersister.cpp", "MUC/MUC.cpp", "MUC/MUCManager.cpp", "MUC/MUCRegistry.cpp", @@ -106,6 +121,8 @@ if env["SCONS_STAGE"] == "build" : "Queries/Requests/GetInBandRegistrationFormRequest.cpp", "Queries/Requests/SubmitInBandRegistrationFormRequest.cpp", "Queries/Responders/SoftwareVersionResponder.cpp", + "Roster/RosterStorage.cpp", + "Roster/RosterMemoryStorage.cpp", "Roster/XMPPRoster.cpp", "Roster/XMPPRosterImpl.cpp", "Roster/XMPPRosterController.cpp", @@ -116,6 +133,9 @@ if env["SCONS_STAGE"] == "build" : "Serializer/CompressRequestSerializer.cpp", "Serializer/ElementSerializer.cpp", "Serializer/MessageSerializer.cpp", + "Serializer/StreamManagementEnabledSerializer.cpp", + "Serializer/StreamResumeSerializer.cpp", + "Serializer/StreamResumedSerializer.cpp", "Serializer/ComponentHandshakeSerializer.cpp", "Serializer/PayloadSerializer.cpp", "Serializer/PayloadSerializerCollection.cpp", @@ -128,8 +148,11 @@ if env["SCONS_STAGE"] == "build" : "Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp", "Serializer/PayloadSerializers/MUCPayloadSerializer.cpp", "Serializer/PayloadSerializers/MUCUserPayloadSerializer.cpp", + "Serializer/PayloadSerializers/MUCAdminPayloadSerializer.cpp", "Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.cpp", + "Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.cpp", "Serializer/PayloadSerializers/ResourceBindSerializer.cpp", + "Serializer/PayloadSerializers/RosterItemExchangeSerializer.cpp", "Serializer/PayloadSerializers/RosterSerializer.cpp", "Serializer/PayloadSerializers/SecurityLabelSerializer.cpp", "Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp", @@ -146,6 +169,14 @@ if env["SCONS_STAGE"] == "build" : "Serializer/PayloadSerializers/SearchPayloadSerializer.cpp", "Serializer/PayloadSerializers/FormSerializer.cpp", "Serializer/PayloadSerializers/NicknameSerializer.cpp", + "Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.cpp", + "Serializer/PayloadSerializers/JinglePayloadSerializer.cpp", + "Serializer/PayloadSerializers/JingleContentPayloadSerializer.cpp", + "Serializer/PayloadSerializers/JingleFileTransferHashSerializer.cpp", + "Serializer/PayloadSerializers/JingleFileTransferReceivedSerializer.cpp", + "Serializer/PayloadSerializers/JingleIBBTransportPayloadSerializer.cpp", + "Serializer/PayloadSerializers/JingleS5BTransportPayloadSerializer.cpp", + "Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.cpp", "Serializer/PresenceSerializer.cpp", "Serializer/StanzaSerializer.cpp", "Serializer/StreamErrorSerializer.cpp", @@ -154,13 +185,13 @@ if env["SCONS_STAGE"] == "build" : "Serializer/XML/XMLNode.cpp", "Serializer/XMPPSerializer.cpp", "Session/Session.cpp", + "Session/SessionTracer.cpp", "Session/SessionStream.cpp", "Session/BasicSessionStream.cpp", "StringCodecs/Base64.cpp", "StringCodecs/SHA1.cpp", - "StringCodecs/HMACSHA1.cpp", + "StringCodecs/SHA256.cpp", "StringCodecs/MD5.cpp", - "StringCodecs/PBKDF2.cpp", "StringCodecs/Hexify.cpp", ] @@ -184,16 +215,20 @@ if env["SCONS_STAGE"] == "build" : "LinkLocal", "StreamManagement", "Component", - "Config", + "AdHoc" ]) - SConscript(test_only = True, dirs = [ + if env["build_examples"] : + SConscript(dirs = [ + "Config", + "Examples" + ]) + env.SConscript(test_only = True, dirs = [ "QA", ]) - SConscript(dirs = [ - "Examples" - ]) myenv = swiften_env.Clone() + if myenv["PLATFORM"] != "darwin" and myenv["PLATFORM"] != "win32" and myenv.get("HAVE_GCONF", 0) : + env.MergeFlags(env["GCONF_FLAGS"]) if ARGUMENTS.get("swiften_dll", False) : if myenv["PLATFORM"] == "posix" : myenv.Append(LINKFLAGS = ["-Wl,-soname,libSwiften.so.$SWIFTEN_VERSION_MAJOR"]) @@ -214,6 +249,7 @@ if env["SCONS_STAGE"] == "build" : File("Avatars/UnitTest/CombinedAvatarProviderTest.cpp"), File("Base/UnitTest/IDGeneratorTest.cpp"), File("Base/UnitTest/StringTest.cpp"), + File("Base/UnitTest/DateTimeTest.cpp"), File("Base/UnitTest/ByteArrayTest.cpp"), File("Chat/UnitTest/ChatStateNotifierTest.cpp"), # File("Chat/UnitTest/ChatStateTrackerTest.cpp"), @@ -234,8 +270,6 @@ if env["SCONS_STAGE"] == "build" : File("Elements/UnitTest/FormTest.cpp"), File("EventLoop/UnitTest/EventLoopTest.cpp"), File("EventLoop/UnitTest/SimpleEventLoopTest.cpp"), - File("FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp"), - File("FileTransfer/UnitTest/IBBSendSessionTest.cpp"), # File("History/UnitTest/SQLiteHistoryManagerTest.cpp"), File("JID/UnitTest/JIDTest.cpp"), File("LinkLocal/UnitTest/LinkLocalConnectorTest.cpp"), @@ -245,6 +279,8 @@ if env["SCONS_STAGE"] == "build" : File("MUC/UnitTest/MUCTest.cpp"), File("Network/UnitTest/HostAddressTest.cpp"), File("Network/UnitTest/ConnectorTest.cpp"), + File("Network/UnitTest/ChainedConnectorTest.cpp"), + File("Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp"), File("Parser/PayloadParsers/UnitTest/BodyParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/DiscoInfoParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/ErrorParserTest.cpp"), @@ -253,8 +289,10 @@ if env["SCONS_STAGE"] == "build" : File("Parser/PayloadParsers/UnitTest/PriorityParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/RawXMLPayloadParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/ResourceBindParserTest.cpp"), + File("Parser/PayloadParsers/UnitTest/RosterItemExchangeParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/RosterParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/IBBParserTest.cpp"), + File("Parser/PayloadParsers/UnitTest/JingleParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/SearchPayloadParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/SecurityLabelParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/SecurityLabelsCatalogParserTest.cpp"), @@ -266,8 +304,13 @@ if env["SCONS_STAGE"] == "build" : File("Parser/PayloadParsers/UnitTest/StorageParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/PrivateStorageParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/VCardUpdateParserTest.cpp"), + File("Parser/PayloadParsers/UnitTest/ReplaceTest.cpp"), + File("Parser/PayloadParsers/UnitTest/MUCAdminPayloadParserTest.cpp"), + File("Parser/PayloadParsers/UnitTest/MUCUserPayloadParserTest.cpp"), + File("Parser/UnitTest/BOSHBodyExtractorTest.cpp"), File("Parser/UnitTest/AttributeMapTest.cpp"), File("Parser/UnitTest/IQParserTest.cpp"), + File("Parser/UnitTest/GenericPayloadTreeParserTest.cpp"), File("Parser/UnitTest/MessageParserTest.cpp"), File("Parser/UnitTest/PayloadParserFactoryCollectionTest.cpp"), File("Parser/UnitTest/PresenceParserTest.cpp"), @@ -275,6 +318,7 @@ if env["SCONS_STAGE"] == "build" : File("Parser/UnitTest/SerializingParserTest.cpp"), File("Parser/UnitTest/StanzaParserTest.cpp"), File("Parser/UnitTest/StreamFeaturesParserTest.cpp"), + File("Parser/UnitTest/StreamManagementEnabledParserTest.cpp"), File("Parser/UnitTest/XMLParserTest.cpp"), File("Parser/UnitTest/XMPPParserTest.cpp"), File("Presence/UnitTest/PresenceOracleTest.cpp"), @@ -286,6 +330,7 @@ if env["SCONS_STAGE"] == "build" : File("Queries/UnitTest/ResponderTest.cpp"), File("Roster/UnitTest/XMPPRosterImplTest.cpp"), File("Roster/UnitTest/XMPPRosterControllerTest.cpp"), + File("Roster/UnitTest/XMPPRosterSignalHandler.cpp"), File("Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.cpp"), File("Serializer/PayloadSerializers/UnitTest/CapsInfoSerializerTest.cpp"), File("Serializer/PayloadSerializers/UnitTest/FormSerializerTest.cpp"), @@ -293,6 +338,7 @@ if env["SCONS_STAGE"] == "build" : File("Serializer/PayloadSerializers/UnitTest/ErrorSerializerTest.cpp"), File("Serializer/PayloadSerializers/UnitTest/PrioritySerializerTest.cpp"), File("Serializer/PayloadSerializers/UnitTest/ResourceBindSerializerTest.cpp"), + File("Serializer/PayloadSerializers/UnitTest/RosterItemExchangeSerializerTest.cpp"), File("Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp"), File("Serializer/PayloadSerializers/UnitTest/SearchPayloadSerializerTest.cpp"), File("Serializer/PayloadSerializers/UnitTest/SecurityLabelSerializerTest.cpp"), @@ -306,6 +352,9 @@ if env["SCONS_STAGE"] == "build" : File("Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp"), File("Serializer/PayloadSerializers/UnitTest/StorageSerializerTest.cpp"), File("Serializer/PayloadSerializers/UnitTest/PrivateStorageSerializerTest.cpp"), + File("Serializer/PayloadSerializers/UnitTest/ReplaceSerializerTest.cpp"), + File("Serializer/PayloadSerializers/UnitTest/MUCAdminPayloadSerializerTest.cpp"), + File("Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp"), File("Serializer/UnitTest/StreamFeaturesSerializerTest.cpp"), File("Serializer/UnitTest/AuthSuccessSerializerTest.cpp"), File("Serializer/UnitTest/AuthChallengeSerializerTest.cpp"), @@ -319,9 +368,10 @@ if env["SCONS_STAGE"] == "build" : File("StreamStack/UnitTest/XMPPLayerTest.cpp"), File("StringCodecs/UnitTest/Base64Test.cpp"), File("StringCodecs/UnitTest/SHA1Test.cpp"), + File("StringCodecs/UnitTest/SHA256Test.cpp"), File("StringCodecs/UnitTest/MD5Test.cpp"), File("StringCodecs/UnitTest/HexifyTest.cpp"), - File("StringCodecs/UnitTest/HMACSHA1Test.cpp"), + File("StringCodecs/UnitTest/HMACTest.cpp"), File("StringCodecs/UnitTest/PBKDF2Test.cpp"), File("TLS/UnitTest/ServerIdentityVerifierTest.cpp"), File("TLS/UnitTest/CertificateTest.cpp"), @@ -329,6 +379,9 @@ if env["SCONS_STAGE"] == "build" : ]) # Generate the Swiften header + def relpath(path, start) : + i = len(os.path.commonprefix([path, start])) + return path[i+1:] swiften_header = "#pragma once\n" swiften_includes = [] top_path = env.Dir("..").abspath @@ -338,7 +391,9 @@ if env["SCONS_STAGE"] == "build" : for file in files : if not file.endswith(".h") : continue - include = os.path.relpath(os.path.join(root, file), top_path) + include = relpath(os.path.join(root, file), top_path) + if swiften_env["PLATFORM"] == "win32" : + include = include.replace("\\", "/") swiften_includes.append(include) # Private modules if root.endswith("Config") or root.endswith("Compress") : @@ -349,11 +404,11 @@ if env["SCONS_STAGE"] == "build" : continue # Library-specific files - if file.startswith("CAres") or file.startswith("LibXML") or file.startswith("Expat") or file.startswith("SQLite") : + if file.startswith("CAres") or file.startswith("LibXML") or file.startswith("Expat") or file.startswith("GConf") or file.startswith("MacOSX") or file.startswith("Windows") or file.startswith("SQLite") or file.startswith("NATPMP") or file.startswith("MiniUPnP") : continue # Specific headers we don't want to globally include - if file == "Swiften.h" or file == "foreach.h" or file == "Log.h" or file == "format.h" : + if file == "Swiften.h" or file == "foreach.h" or file == "Log.h" or file == "format.h" or file == "CompressionLayer.h": continue swiften_header += "#include <" + include + ">\n" swiften_includes.append(include) diff --git a/Swiften/Serializer/AuthChallengeSerializer.cpp b/Swiften/Serializer/AuthChallengeSerializer.cpp index dcded43..1ddc165 100644 --- a/Swiften/Serializer/AuthChallengeSerializer.cpp +++ b/Swiften/Serializer/AuthChallengeSerializer.cpp @@ -4,29 +4,30 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/AuthChallengeSerializer.h" +#include <Swiften/Serializer/AuthChallengeSerializer.h> -#include "Swiften/Elements/AuthChallenge.h" -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/Elements/AuthChallenge.h> +#include <Swiften/StringCodecs/Base64.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { AuthChallengeSerializer::AuthChallengeSerializer() { } -std::string AuthChallengeSerializer::serialize(boost::shared_ptr<Element> element) const { +SafeByteArray AuthChallengeSerializer::serialize(boost::shared_ptr<Element> element) const { boost::shared_ptr<AuthChallenge> authChallenge(boost::dynamic_pointer_cast<AuthChallenge>(element)); std::string value; - boost::optional<ByteArray> message = authChallenge->getValue(); + boost::optional<std::vector<unsigned char> > message = authChallenge->getValue(); if (message) { - if ((*message).isEmpty()) { + if ((*message).empty()) { value = "="; } else { - value = Base64::encode(*message); + value = Base64::encode(ByteArray(*message)); } } - return "<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" + value + "</challenge>"; + return createSafeByteArray("<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" + value + "</challenge>"); } } diff --git a/Swiften/Serializer/AuthChallengeSerializer.h b/Swiften/Serializer/AuthChallengeSerializer.h index a62efb3..d485473 100644 --- a/Swiften/Serializer/AuthChallengeSerializer.h +++ b/Swiften/Serializer/AuthChallengeSerializer.h @@ -8,14 +8,14 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/AuthChallenge.h" -#include "Swiften/Serializer/GenericElementSerializer.h" +#include <Swiften/Elements/AuthChallenge.h> +#include <Swiften/Serializer/GenericElementSerializer.h> namespace Swift { class AuthChallengeSerializer : public GenericElementSerializer<AuthChallenge> { public: AuthChallengeSerializer(); - virtual std::string serialize(boost::shared_ptr<Element> element) const; + virtual SafeByteArray serialize(boost::shared_ptr<Element> element) const; }; } diff --git a/Swiften/Serializer/AuthFailureSerializer.h b/Swiften/Serializer/AuthFailureSerializer.h index 477d98c..090f0c4 100644 --- a/Swiften/Serializer/AuthFailureSerializer.h +++ b/Swiften/Serializer/AuthFailureSerializer.h @@ -4,14 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_AuthFailureSerializer_H -#define SWIFTEN_AuthFailureSerializer_H +#pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/AuthFailure.h" -#include "Swiften/Serializer/GenericElementSerializer.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Elements/AuthFailure.h> +#include <Swiften/Serializer/GenericElementSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { class AuthFailureSerializer : public GenericElementSerializer<AuthFailure> { @@ -19,10 +18,8 @@ namespace Swift { AuthFailureSerializer() : GenericElementSerializer<AuthFailure>() { } - virtual std::string serialize(boost::shared_ptr<Element>) const { - return XMLElement("failure", "urn:ietf:params:xml:ns:xmpp-sasl").serialize(); + virtual SafeByteArray serialize(boost::shared_ptr<Element>) const { + return createSafeByteArray(XMLElement("failure", "urn:ietf:params:xml:ns:xmpp-sasl").serialize()); } }; } - -#endif diff --git a/Swiften/Serializer/AuthRequestSerializer.cpp b/Swiften/Serializer/AuthRequestSerializer.cpp index 0bee302..7f25c93 100644 --- a/Swiften/Serializer/AuthRequestSerializer.cpp +++ b/Swiften/Serializer/AuthRequestSerializer.cpp @@ -4,29 +4,31 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/AuthRequestSerializer.h" +#include <Swiften/Serializer/AuthRequestSerializer.h> -#include "Swiften/Elements/AuthRequest.h" -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/Elements/AuthRequest.h> +#include <Swiften/StringCodecs/Base64.h> +#include <Swiften/Base/SafeByteArray.h> +#include <Swiften/Base/Concat.h> namespace Swift { AuthRequestSerializer::AuthRequestSerializer() { } -std::string AuthRequestSerializer::serialize(boost::shared_ptr<Element> element) const { +SafeByteArray AuthRequestSerializer::serialize(boost::shared_ptr<Element> element) const { boost::shared_ptr<AuthRequest> authRequest(boost::dynamic_pointer_cast<AuthRequest>(element)); - std::string value; - boost::optional<ByteArray> message = authRequest->getMessage(); + SafeByteArray value; + boost::optional<SafeByteArray> message = authRequest->getMessage(); if (message) { - if ((*message).isEmpty()) { - value = "="; + if ((*message).empty()) { + value = createSafeByteArray("="); } else { value = Base64::encode(*message); } } - return "<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"" + authRequest->getMechanism() + "\">" + value + "</auth>"; + return concat(createSafeByteArray("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"" + authRequest->getMechanism() + "\">"), value, createSafeByteArray("</auth>")); } } diff --git a/Swiften/Serializer/AuthRequestSerializer.h b/Swiften/Serializer/AuthRequestSerializer.h index 18ef5dd..add7983 100644 --- a/Swiften/Serializer/AuthRequestSerializer.h +++ b/Swiften/Serializer/AuthRequestSerializer.h @@ -4,21 +4,18 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_AuthRequestSerializer_H -#define SWIFTEN_AuthRequestSerializer_H +#pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/AuthRequest.h" -#include "Swiften/Serializer/GenericElementSerializer.h" +#include <Swiften/Elements/AuthRequest.h> +#include <Swiften/Serializer/GenericElementSerializer.h> namespace Swift { class AuthRequestSerializer : public GenericElementSerializer<AuthRequest> { public: AuthRequestSerializer(); - virtual std::string serialize(boost::shared_ptr<Element> element) const; + virtual SafeByteArray serialize(boost::shared_ptr<Element> element) const; }; } - -#endif diff --git a/Swiften/Serializer/AuthResponseSerializer.cpp b/Swiften/Serializer/AuthResponseSerializer.cpp index a93b4dd..86b7fbe 100644 --- a/Swiften/Serializer/AuthResponseSerializer.cpp +++ b/Swiften/Serializer/AuthResponseSerializer.cpp @@ -4,29 +4,31 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/AuthResponseSerializer.h" +#include <Swiften/Serializer/AuthResponseSerializer.h> -#include "Swiften/Elements/AuthResponse.h" -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/Elements/AuthResponse.h> +#include <Swiften/StringCodecs/Base64.h> +#include <Swiften/Base/SafeByteArray.h> +#include <Swiften/Base/Concat.h> namespace Swift { AuthResponseSerializer::AuthResponseSerializer() { } -std::string AuthResponseSerializer::serialize(boost::shared_ptr<Element> element) const { +SafeByteArray AuthResponseSerializer::serialize(boost::shared_ptr<Element> element) const { boost::shared_ptr<AuthResponse> authResponse(boost::dynamic_pointer_cast<AuthResponse>(element)); - std::string value; - boost::optional<ByteArray> message = authResponse->getValue(); + SafeByteArray value; + boost::optional<SafeByteArray> message = authResponse->getValue(); if (message) { - if ((*message).isEmpty()) { - value = "="; + if ((*message).empty()) { + value = createSafeByteArray("="); } else { value = Base64::encode(*message); } } - return "<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" + value + "</response>"; + return concat(createSafeByteArray("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"), value, createSafeByteArray("</response>")); } } diff --git a/Swiften/Serializer/AuthResponseSerializer.h b/Swiften/Serializer/AuthResponseSerializer.h index cee8ff3..495f8cc 100644 --- a/Swiften/Serializer/AuthResponseSerializer.h +++ b/Swiften/Serializer/AuthResponseSerializer.h @@ -8,14 +8,14 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/AuthResponse.h" -#include "Swiften/Serializer/GenericElementSerializer.h" +#include <Swiften/Elements/AuthResponse.h> +#include <Swiften/Serializer/GenericElementSerializer.h> namespace Swift { class AuthResponseSerializer : public GenericElementSerializer<AuthResponse> { public: AuthResponseSerializer(); - virtual std::string serialize(boost::shared_ptr<Element> element) const; + virtual SafeByteArray serialize(boost::shared_ptr<Element> element) const; }; } diff --git a/Swiften/Serializer/AuthSuccessSerializer.cpp b/Swiften/Serializer/AuthSuccessSerializer.cpp index 443c740..26b58c3 100644 --- a/Swiften/Serializer/AuthSuccessSerializer.cpp +++ b/Swiften/Serializer/AuthSuccessSerializer.cpp @@ -4,29 +4,30 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/AuthSuccessSerializer.h" +#include <Swiften/Serializer/AuthSuccessSerializer.h> -#include "Swiften/Elements/AuthSuccess.h" -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/Elements/AuthSuccess.h> +#include <Swiften/StringCodecs/Base64.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { AuthSuccessSerializer::AuthSuccessSerializer() { } -std::string AuthSuccessSerializer::serialize(boost::shared_ptr<Element> element) const { +SafeByteArray AuthSuccessSerializer::serialize(boost::shared_ptr<Element> element) const { boost::shared_ptr<AuthSuccess> authSuccess(boost::dynamic_pointer_cast<AuthSuccess>(element)); std::string value; - boost::optional<ByteArray> message = authSuccess->getValue(); + boost::optional<std::vector<unsigned char> > message = authSuccess->getValue(); if (message) { - if ((*message).isEmpty()) { + if ((*message).empty()) { value = "="; } else { - value = Base64::encode(*message); + value = Base64::encode(ByteArray(*message)); } } - return "<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" + value + "</success>"; + return createSafeByteArray("<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" + value + "</success>"); } } diff --git a/Swiften/Serializer/AuthSuccessSerializer.h b/Swiften/Serializer/AuthSuccessSerializer.h index eb3279c..8163d16 100644 --- a/Swiften/Serializer/AuthSuccessSerializer.h +++ b/Swiften/Serializer/AuthSuccessSerializer.h @@ -8,14 +8,14 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/AuthSuccess.h" -#include "Swiften/Serializer/GenericElementSerializer.h" +#include <Swiften/Elements/AuthSuccess.h> +#include <Swiften/Serializer/GenericElementSerializer.h> namespace Swift { class AuthSuccessSerializer : public GenericElementSerializer<AuthSuccess> { public: AuthSuccessSerializer(); - virtual std::string serialize(boost::shared_ptr<Element> element) const; + virtual SafeByteArray serialize(boost::shared_ptr<Element> element) const; }; } diff --git a/Swiften/Serializer/ComponentHandshakeSerializer.cpp b/Swiften/Serializer/ComponentHandshakeSerializer.cpp index cf44ea4..e7837d3 100644 --- a/Swiften/Serializer/ComponentHandshakeSerializer.cpp +++ b/Swiften/Serializer/ComponentHandshakeSerializer.cpp @@ -4,18 +4,18 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/ComponentHandshakeSerializer.h" +#include <Swiften/Serializer/ComponentHandshakeSerializer.h> -#include "Swiften/Elements/ComponentHandshake.h" +#include <Swiften/Elements/ComponentHandshake.h> namespace Swift { ComponentHandshakeSerializer::ComponentHandshakeSerializer() { } -std::string ComponentHandshakeSerializer::serialize(boost::shared_ptr<Element> element) const { +SafeByteArray ComponentHandshakeSerializer::serialize(boost::shared_ptr<Element> element) const { boost::shared_ptr<ComponentHandshake> handshake(boost::dynamic_pointer_cast<ComponentHandshake>(element)); - return "<handshake>" + handshake->getData() + "</handshake>"; + return createSafeByteArray("<handshake>" + handshake->getData() + "</handshake>"); } } diff --git a/Swiften/Serializer/ComponentHandshakeSerializer.h b/Swiften/Serializer/ComponentHandshakeSerializer.h index 7681e56..1145ed9 100644 --- a/Swiften/Serializer/ComponentHandshakeSerializer.h +++ b/Swiften/Serializer/ComponentHandshakeSerializer.h @@ -8,14 +8,14 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/ComponentHandshake.h" -#include "Swiften/Serializer/GenericElementSerializer.h" +#include <Swiften/Elements/ComponentHandshake.h> +#include <Swiften/Serializer/GenericElementSerializer.h> namespace Swift { class ComponentHandshakeSerializer : public GenericElementSerializer<ComponentHandshake> { public: ComponentHandshakeSerializer(); - virtual std::string serialize(boost::shared_ptr<Element> element) const; + virtual SafeByteArray serialize(boost::shared_ptr<Element> element) const; }; } diff --git a/Swiften/Serializer/CompressFailureSerializer.h b/Swiften/Serializer/CompressFailureSerializer.h index 02a4b46..27a638f 100644 --- a/Swiften/Serializer/CompressFailureSerializer.h +++ b/Swiften/Serializer/CompressFailureSerializer.h @@ -4,14 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_CompressFailureSerializer_H -#define SWIFTEN_CompressFailureSerializer_H +#pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/CompressFailure.h" -#include "Swiften/Serializer/GenericElementSerializer.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Elements/CompressFailure.h> +#include <Swiften/Serializer/GenericElementSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { class CompressFailureSerializer : public GenericElementSerializer<CompressFailure> { @@ -19,10 +18,8 @@ namespace Swift { CompressFailureSerializer() : GenericElementSerializer<CompressFailure>() { } - virtual std::string serialize(boost::shared_ptr<Element>) const { - return XMLElement("failure", "http://jabber.org/protocol/compress").serialize(); + virtual SafeByteArray serialize(boost::shared_ptr<Element>) const { + return createSafeByteArray(XMLElement("failure", "http://jabber.org/protocol/compress").serialize()); } }; } - -#endif diff --git a/Swiften/Serializer/CompressRequestSerializer.cpp b/Swiften/Serializer/CompressRequestSerializer.cpp index 7733169..af7f7db 100644 --- a/Swiften/Serializer/CompressRequestSerializer.cpp +++ b/Swiften/Serializer/CompressRequestSerializer.cpp @@ -4,22 +4,22 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/CompressRequestSerializer.h" +#include <Swiften/Serializer/CompressRequestSerializer.h> -#include "Swiften/Elements/CompressRequest.h" +#include <Swiften/Elements/CompressRequest.h> namespace Swift { CompressRequestSerializer::CompressRequestSerializer() { } -std::string CompressRequestSerializer::serialize(boost::shared_ptr<Element> element) const { +SafeByteArray CompressRequestSerializer::serialize(boost::shared_ptr<Element> element) const { boost::shared_ptr<CompressRequest> compressRequest(boost::dynamic_pointer_cast<CompressRequest>(element)); - return "<compress xmlns='http://jabber.org/protocol/compress'><method>" + compressRequest->getMethod() + "</method></compress>"; + return createSafeByteArray("<compress xmlns='http://jabber.org/protocol/compress'><method>" + compressRequest->getMethod() + "</method></compress>"); } bool CompressRequestSerializer::canSerialize(boost::shared_ptr<Element> element) const { - return dynamic_cast<CompressRequest*>(element.get()) != 0; + return boost::dynamic_pointer_cast<CompressRequest>(element) != 0; } } diff --git a/Swiften/Serializer/CompressRequestSerializer.h b/Swiften/Serializer/CompressRequestSerializer.h index 0a14fb1..4d68c98 100644 --- a/Swiften/Serializer/CompressRequestSerializer.h +++ b/Swiften/Serializer/CompressRequestSerializer.h @@ -4,21 +4,18 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_COMPRESSREQUESTSERIALIZER_H -#define SWIFTEN_COMPRESSREQUESTSERIALIZER_H +#pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Serializer/ElementSerializer.h" +#include <Swiften/Serializer/ElementSerializer.h> namespace Swift { class CompressRequestSerializer : public ElementSerializer { public: CompressRequestSerializer(); - virtual std::string serialize(boost::shared_ptr<Element> element) const; + virtual SafeByteArray serialize(boost::shared_ptr<Element> element) const; virtual bool canSerialize(boost::shared_ptr<Element> element) const; }; } - -#endif diff --git a/Swiften/Serializer/ElementSerializer.cpp b/Swiften/Serializer/ElementSerializer.cpp index 6b9fdd5..8cfb294 100644 --- a/Swiften/Serializer/ElementSerializer.cpp +++ b/Swiften/Serializer/ElementSerializer.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/ElementSerializer.h" +#include <Swiften/Serializer/ElementSerializer.h> namespace Swift { diff --git a/Swiften/Serializer/ElementSerializer.h b/Swiften/Serializer/ElementSerializer.h index 3abdf08..ba59106 100644 --- a/Swiften/Serializer/ElementSerializer.h +++ b/Swiften/Serializer/ElementSerializer.h @@ -4,22 +4,19 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_ELEMENTSERIALIZER_H -#define SWIFTEN_ELEMENTSERIALIZER_H +#pragma once #include <boost/shared_ptr.hpp> -#include <string> -#include "Swiften/Elements/Element.h" +#include <Swiften/Elements/Element.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class ElementSerializer { public: virtual ~ElementSerializer(); - virtual std::string serialize(boost::shared_ptr<Element> element) const = 0; + virtual SafeByteArray serialize(boost::shared_ptr<Element> element) const = 0; virtual bool canSerialize(boost::shared_ptr<Element> element) const = 0; }; } - -#endif diff --git a/Swiften/Serializer/EnableStreamManagementSerializer.h b/Swiften/Serializer/EnableStreamManagementSerializer.h index e224a9c..384753b 100644 --- a/Swiften/Serializer/EnableStreamManagementSerializer.h +++ b/Swiften/Serializer/EnableStreamManagementSerializer.h @@ -8,9 +8,9 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/EnableStreamManagement.h" -#include "Swiften/Serializer/GenericElementSerializer.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Elements/EnableStreamManagement.h> +#include <Swiften/Serializer/GenericElementSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { class EnableStreamManagementSerializer : public GenericElementSerializer<EnableStreamManagement> { @@ -18,8 +18,8 @@ namespace Swift { EnableStreamManagementSerializer() : GenericElementSerializer<EnableStreamManagement>() { } - virtual std::string serialize(boost::shared_ptr<Element>) const { - return XMLElement("enable", "urn:xmpp:sm:2").serialize(); + virtual SafeByteArray serialize(boost::shared_ptr<Element>) const { + return createSafeByteArray(XMLElement("enable", "urn:xmpp:sm:2").serialize()); } }; } diff --git a/Swiften/Serializer/GenericElementSerializer.h b/Swiften/Serializer/GenericElementSerializer.h index 903c205..e56f156 100644 --- a/Swiften/Serializer/GenericElementSerializer.h +++ b/Swiften/Serializer/GenericElementSerializer.h @@ -14,7 +14,7 @@ namespace Swift { template<typename T> class GenericElementSerializer : public ElementSerializer { public: - virtual std::string serialize(boost::shared_ptr<Element> element) const = 0; + virtual SafeByteArray serialize(boost::shared_ptr<Element> element) const = 0; virtual bool canSerialize(boost::shared_ptr<Element> element) const { return boost::dynamic_pointer_cast<T>(element); diff --git a/Swiften/Serializer/GenericStanzaSerializer.h b/Swiften/Serializer/GenericStanzaSerializer.h index 2f0fccf..4129ca8 100644 --- a/Swiften/Serializer/GenericStanzaSerializer.h +++ b/Swiften/Serializer/GenericStanzaSerializer.h @@ -4,10 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_GENERICSTANZASERIALIZER_H -#define SWIFTEN_GENERICSTANZASERIALIZER_H +#pragma once -#include "Swiften/Serializer/StanzaSerializer.h" +#include <Swiften/Serializer/StanzaSerializer.h> namespace Swift { template<typename STANZA_TYPE> @@ -31,5 +30,3 @@ namespace Swift { XMLElement&) const = 0; }; } - -#endif diff --git a/Swiften/Serializer/IQSerializer.h b/Swiften/Serializer/IQSerializer.h index 21ec300..76a9cb7 100644 --- a/Swiften/Serializer/IQSerializer.h +++ b/Swiften/Serializer/IQSerializer.h @@ -4,14 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_IQSerializer_H -#define SWIFTEN_IQSerializer_H +#pragma once -#include <cassert> - -#include "Swiften/Serializer/GenericStanzaSerializer.h" -#include "Swiften/Elements/IQ.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Serializer/GenericStanzaSerializer.h> +#include <Swiften/Elements/IQ.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { class IQSerializer : public GenericStanzaSerializer<IQ> { @@ -32,5 +29,3 @@ namespace Swift { } }; } - -#endif diff --git a/Swiften/Serializer/MessageSerializer.cpp b/Swiften/Serializer/MessageSerializer.cpp index cea9a1d..c221680 100644 --- a/Swiften/Serializer/MessageSerializer.cpp +++ b/Swiften/Serializer/MessageSerializer.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/MessageSerializer.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Serializer/MessageSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { diff --git a/Swiften/Serializer/MessageSerializer.h b/Swiften/Serializer/MessageSerializer.h index 873cc5a..8e9e941 100644 --- a/Swiften/Serializer/MessageSerializer.h +++ b/Swiften/Serializer/MessageSerializer.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_MessageSerializer_H -#define SWIFTEN_MessageSerializer_H +#pragma once -#include "Swiften/Serializer/GenericStanzaSerializer.h" -#include "Swiften/Elements/Message.h" +#include <Swiften/Serializer/GenericStanzaSerializer.h> +#include <Swiften/Elements/Message.h> namespace Swift { class XMLElement; @@ -23,5 +22,3 @@ namespace Swift { XMLElement& element) const; }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializer.cpp index db13ade..be73676 100644 --- a/Swiften/Serializer/PayloadSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializer.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializer.h" +#include <Swiften/Serializer/PayloadSerializer.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializer.h b/Swiften/Serializer/PayloadSerializer.h index 34e6679..c4ad23b 100644 --- a/Swiften/Serializer/PayloadSerializer.h +++ b/Swiften/Serializer/PayloadSerializer.h @@ -4,15 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_PAYLOADSERIALIZER_H -#define SWIFTEN_PAYLOADSERIALIZER_H - -#include <boost/shared_ptr.hpp> +#pragma once #include <string> -#include "Swiften/Elements/Payload.h" +#include <boost/shared_ptr.hpp> namespace Swift { + class Payload; + class PayloadSerializer { public: virtual ~PayloadSerializer(); @@ -21,5 +20,3 @@ namespace Swift { virtual std::string serialize(boost::shared_ptr<Payload>) const = 0; }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializerCollection.cpp b/Swiften/Serializer/PayloadSerializerCollection.cpp index 548dd32..ab2b4f4 100644 --- a/Swiften/Serializer/PayloadSerializerCollection.cpp +++ b/Swiften/Serializer/PayloadSerializerCollection.cpp @@ -7,8 +7,8 @@ #include <boost/bind.hpp> #include <algorithm> -#include "Swiften/Serializer/PayloadSerializerCollection.h" -#include "Swiften/Serializer/PayloadSerializer.h" +#include <Swiften/Serializer/PayloadSerializerCollection.h> +#include <Swiften/Serializer/PayloadSerializer.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializerCollection.h b/Swiften/Serializer/PayloadSerializerCollection.h index 1b3cbc5..f922a45 100644 --- a/Swiften/Serializer/PayloadSerializerCollection.h +++ b/Swiften/Serializer/PayloadSerializerCollection.h @@ -9,7 +9,7 @@ #include <vector> #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> namespace Swift { class PayloadSerializer; diff --git a/Swiften/Serializer/PayloadSerializers/BlockSerializer.h b/Swiften/Serializer/PayloadSerializers/BlockSerializer.h new file mode 100644 index 0000000..345463c --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/BlockSerializer.h @@ -0,0 +1,34 @@ +/* + * 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/smart_ptr/make_shared.hpp> + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Base/foreach.h> + +namespace Swift { + template<typename BLOCK_ELEMENT> + class BlockSerializer : public GenericPayloadSerializer<BLOCK_ELEMENT> { + public: + BlockSerializer(std::string tag) : GenericPayloadSerializer<BLOCK_ELEMENT>(), tag(tag) { + } + + virtual std::string serializePayload(boost::shared_ptr<BLOCK_ELEMENT> payload) const { + XMLElement element(tag, "urn:xmpp:blocking"); + foreach (const JID& jid, payload->getItems()) { + boost::shared_ptr<XMLElement> item = boost::make_shared<XMLElement>("item"); + item->setAttribute("jid", jid); + } + return element.serialize(); + } + + private: + std::string tag; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/BodySerializer.h b/Swiften/Serializer/PayloadSerializers/BodySerializer.h index 6fc6e6d..99df0f5 100644 --- a/Swiften/Serializer/PayloadSerializers/BodySerializer.h +++ b/Swiften/Serializer/PayloadSerializers/BodySerializer.h @@ -4,12 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_BodySerializer_H -#define SWIFTEN_BodySerializer_H +#pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" -#include "Swiften/Elements/Body.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Elements/Body.h> namespace Swift { class BodySerializer : public GenericPayloadSerializer<Body> { @@ -22,5 +21,3 @@ namespace Swift { } }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.cpp b/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.cpp index f9b89f3..beb84dd 100644 --- a/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.h> #include <boost/shared_ptr.hpp> #include <boost/lexical_cast.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/PayloadSerializerCollection.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/PayloadSerializerCollection.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.h b/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.h index d9b14db..0e58eb0 100644 --- a/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/Bytestreams.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/Bytestreams.h> namespace Swift { class PayloadSerializerCollection; diff --git a/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.cpp b/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.cpp index ced0d62..2466958 100644 --- a/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.cpp @@ -4,11 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h b/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h index de0a871..2587ee0 100644 --- a/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_CapsInfoSerializer_H -#define SWIFTEN_CapsInfoSerializer_H +#pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/CapsInfo.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/CapsInfo.h> namespace Swift { class CapsInfoSerializer : public GenericPayloadSerializer<CapsInfo> { @@ -18,5 +17,3 @@ namespace Swift { virtual std::string serializePayload(boost::shared_ptr<CapsInfo>) const; }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.cpp b/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.cpp index 3e877eb..ee468bb 100644 --- a/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h b/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h index a786901..d71873d 100644 --- a/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/ChatState.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/ChatState.h> namespace Swift { class ChatStateSerializer : public GenericPayloadSerializer<ChatState> { diff --git a/Swiften/Serializer/PayloadSerializers/CommandSerializer.cpp b/Swiften/Serializer/PayloadSerializers/CommandSerializer.cpp index 0fa45ce..2fb86b0 100644 --- a/Swiften/Serializer/PayloadSerializers/CommandSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/CommandSerializer.cpp @@ -4,16 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/CommandSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/CommandSerializer.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" -#include "Swiften/Serializer/XML/XMLRawTextNode.h" -#include "Swiften/Serializer/PayloadSerializerCollection.h" -#include "Swiften/Serializer/PayloadSerializers/FormSerializer.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/PayloadSerializers/FormSerializer.h> namespace Swift { @@ -21,7 +20,7 @@ CommandSerializer::CommandSerializer() { } std::string CommandSerializer::serializePayload(boost::shared_ptr<Command> command) const { - XMLElement commandElement("command", "http://jabber.org/protocol/comands"); + XMLElement commandElement("command", "http://jabber.org/protocol/commands"); commandElement.setAttribute("node", command->getNode()); if (!command->getSessionID().empty()) { diff --git a/Swiften/Serializer/PayloadSerializers/CommandSerializer.h b/Swiften/Serializer/PayloadSerializers/CommandSerializer.h index b1db825..03b6aa0 100644 --- a/Swiften/Serializer/PayloadSerializers/CommandSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/CommandSerializer.h @@ -6,12 +6,10 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/Command.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/Command.h> namespace Swift { - class PayloadSerializerCollection; - class CommandSerializer : public GenericPayloadSerializer<Command> { public: CommandSerializer(); diff --git a/Swiften/Serializer/PayloadSerializers/DelaySerializer.cpp b/Swiften/Serializer/PayloadSerializers/DelaySerializer.cpp index 4922042..6148632 100644 --- a/Swiften/Serializer/PayloadSerializers/DelaySerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/DelaySerializer.cpp @@ -4,12 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/DelaySerializer.h" +#include <Swiften/Serializer/PayloadSerializers/DelaySerializer.h> #include <boost/shared_ptr.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> #include <Swiften/Base/String.h> -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Base/DateTime.h> namespace Swift { @@ -21,16 +23,8 @@ std::string DelaySerializer::serializePayload(boost::shared_ptr<Delay> delay) c if (delay->getFrom()) { delayElement.setAttribute("from", delay->getFrom()->toString()); } - std::string stampString = boostPTimeToXEP0082(delay->getStamp()); - delayElement.setAttribute("stamp", stampString); + delayElement.setAttribute("stamp", dateTimeToString(delay->getStamp())); return delayElement.serialize(); } -std::string DelaySerializer::boostPTimeToXEP0082(const boost::posix_time::ptime& time) { - std::string stampString = std::string(boost::posix_time::to_iso_extended_string(time)); - String::replaceAll(stampString, ',', "."); - stampString += "Z"; - return stampString; -} - } diff --git a/Swiften/Serializer/PayloadSerializers/DelaySerializer.h b/Swiften/Serializer/PayloadSerializers/DelaySerializer.h index c37dc02..06c7665 100644 --- a/Swiften/Serializer/PayloadSerializers/DelaySerializer.h +++ b/Swiften/Serializer/PayloadSerializers/DelaySerializer.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/Delay.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/Delay.h> namespace Swift { class DelaySerializer : public GenericPayloadSerializer<Delay> { @@ -15,7 +15,6 @@ namespace Swift { DelaySerializer(); virtual std::string serializePayload(boost::shared_ptr<Delay>) const; - static std::string boostPTimeToXEP0082(const boost::posix_time::ptime& time); }; } diff --git a/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.cpp b/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.cpp index 65b0a38..e2c6f59 100644 --- a/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLRawTextNode.h" -#include "Swiften/Serializer/PayloadSerializers/FormSerializer.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/PayloadSerializers/FormSerializer.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h b/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h index 46e7ce2..3e028e1 100644 --- a/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_DiscoInfoSerializer_H -#define SWIFTEN_DiscoInfoSerializer_H +#pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/DiscoInfo.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/DiscoInfo.h> namespace Swift { class DiscoInfoSerializer : public GenericPayloadSerializer<DiscoInfo> { @@ -18,5 +17,3 @@ namespace Swift { virtual std::string serializePayload(boost::shared_ptr<DiscoInfo>) const; }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/DiscoItemsSerializer.cpp b/Swiften/Serializer/PayloadSerializers/DiscoItemsSerializer.cpp index cb1b7c1..dd52b70 100644 --- a/Swiften/Serializer/PayloadSerializers/DiscoItemsSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/DiscoItemsSerializer.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/DiscoItemsSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/DiscoItemsSerializer.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/DiscoItemsSerializer.h b/Swiften/Serializer/PayloadSerializers/DiscoItemsSerializer.h index 3b00a17..a8785c2 100644 --- a/Swiften/Serializer/PayloadSerializers/DiscoItemsSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/DiscoItemsSerializer.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/DiscoItems.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/DiscoItems.h> namespace Swift { class DiscoItemsSerializer : public GenericPayloadSerializer<DiscoItems> { diff --git a/Swiften/Serializer/PayloadSerializers/ErrorSerializer.cpp b/Swiften/Serializer/PayloadSerializers/ErrorSerializer.cpp index 15d13d7..e3bfd54 100644 --- a/Swiften/Serializer/PayloadSerializers/ErrorSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/ErrorSerializer.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/ErrorSerializer.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" +#include <Swiften/Serializer/PayloadSerializers/ErrorSerializer.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/ErrorSerializer.h b/Swiften/Serializer/PayloadSerializers/ErrorSerializer.h index 7fc4dad..d06efc8 100644 --- a/Swiften/Serializer/PayloadSerializers/ErrorSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/ErrorSerializer.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_ErrorSerializer_H -#define SWIFTEN_ErrorSerializer_H +#pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/ErrorPayload.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/ErrorPayload.h> namespace Swift { class ErrorSerializer : public GenericPayloadSerializer<ErrorPayload> { @@ -18,5 +17,3 @@ namespace Swift { virtual std::string serializePayload(boost::shared_ptr<ErrorPayload> error) const; }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/FormSerializer.cpp b/Swiften/Serializer/PayloadSerializers/FormSerializer.cpp index 53b4241..7a6bb79 100644 --- a/Swiften/Serializer/PayloadSerializers/FormSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/FormSerializer.cpp @@ -4,16 +4,17 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/FormSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/FormSerializer.h> #include <boost/shared_ptr.hpp> #include <iostream> #include <string> -#include "Swiften/Base/String.h" -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" -#include "Swiften/Serializer/XML/XMLRawTextNode.h" +#include <Swiften/Base/String.h> +#include <Swiften/Base/Algorithm.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> using namespace Swift; @@ -129,14 +130,6 @@ boost::shared_ptr<XMLElement> FormSerializer::fieldToXML(boost::shared_ptr<FormF fieldType = "text-multi"; multiLineify(boost::dynamic_pointer_cast<TextMultiFormField>(field)->getValue(), "value", fieldElement); } - else if (boost::dynamic_pointer_cast<UntypedFormField>(field)) { - std::vector<std::string> lines = boost::dynamic_pointer_cast<UntypedFormField>(field)->getValue(); - foreach(const std::string& line, lines) { - boost::shared_ptr<XMLElement> valueElement(new XMLElement("value")); - valueElement->addNode(XMLTextNode::create(line)); - fieldElement->addNode(valueElement); - } - } else { assert(false); } @@ -162,7 +155,7 @@ boost::shared_ptr<XMLElement> FormSerializer::fieldToXML(boost::shared_ptr<FormF void FormSerializer::multiLineify(const std::string& text, const std::string& elementName, boost::shared_ptr<XMLElement> element) const { std::string unRdText(text); - unRdText.erase(std::remove(unRdText.begin(), unRdText.end(), '\r'), unRdText.end()); + erase(unRdText, '\r'); std::vector<std::string> lines = String::split(unRdText, '\n'); foreach (std::string line, lines) { boost::shared_ptr<XMLElement> lineElement(new XMLElement(elementName)); diff --git a/Swiften/Serializer/PayloadSerializers/FormSerializer.h b/Swiften/Serializer/PayloadSerializers/FormSerializer.h index 86c8dee..43db9e8 100644 --- a/Swiften/Serializer/PayloadSerializers/FormSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/FormSerializer.h @@ -6,10 +6,10 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/Form.h" -#include "Swiften/Elements/FormField.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/Form.h> +#include <Swiften/Elements/FormField.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { class FormSerializer : public GenericPayloadSerializer<Form> { diff --git a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp index 1bbcbf2..f3e22d2 100644 --- a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp +++ b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp @@ -4,42 +4,61 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h" -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/PayloadSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/IBBSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/BodySerializer.h" -#include "Swiften/Serializer/PayloadSerializers/SubjectSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/PrioritySerializer.h" -#include "Swiften/Serializer/PayloadSerializers/ErrorSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/RosterSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/StatusSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/DiscoItemsSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/StartSessionSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/VCardSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/RawXMLPayloadSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/StorageSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/DelaySerializer.h" -#include "Swiften/Serializer/PayloadSerializers/FormSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/CommandSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/NicknameSerializer.h" -#include "Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Elements/BlockPayload.h> +#include <Swiften/Elements/UnblockPayload.h> +#include <Swiften/Elements/BlockListPayload.h> +#include <Swiften/Serializer/PayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/IBBSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/BodySerializer.h> +#include <Swiften/Serializer/PayloadSerializers/BlockSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/SubjectSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/PrioritySerializer.h> +#include <Swiften/Serializer/PayloadSerializers/ErrorSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/RosterSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/RosterItemExchangeSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/MUCAdminPayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/StatusSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/DiscoItemsSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/StartSessionSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/VCardSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/RawXMLPayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/StorageSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/DelaySerializer.h> +#include <Swiften/Serializer/PayloadSerializers/FormSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/CommandSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/NicknameSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/ReplaceSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/LastSerializer.h> + +#include <Swiften/Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/JingleContentPayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/JingleFileTransferHashSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/JingleFileTransferReceivedSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/JingleIBBTransportPayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/JingleS5BTransportPayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/JinglePayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/S5BProxyRequestSerializer.h> namespace Swift { @@ -51,15 +70,21 @@ FullPayloadSerializerCollection::FullPayloadSerializerCollection() { serializers_.push_back(new PrioritySerializer()); serializers_.push_back(new ErrorSerializer()); serializers_.push_back(new RosterSerializer()); + serializers_.push_back(new RosterItemExchangeSerializer()); serializers_.push_back(new MUCPayloadSerializer()); - serializers_.push_back(new MUCUserPayloadSerializer()); + serializers_.push_back(new MUCDestroyPayloadSerializer()); + serializers_.push_back(new MUCAdminPayloadSerializer()); serializers_.push_back(new MUCOwnerPayloadSerializer(this)); + serializers_.push_back(new MUCUserPayloadSerializer(this)); serializers_.push_back(new SoftwareVersionSerializer()); serializers_.push_back(new StatusSerializer()); serializers_.push_back(new StatusShowSerializer()); serializers_.push_back(new DiscoInfoSerializer()); serializers_.push_back(new DiscoItemsSerializer()); serializers_.push_back(new CapsInfoSerializer()); + serializers_.push_back(new BlockSerializer<BlockPayload>("block")); + serializers_.push_back(new BlockSerializer<UnblockPayload>("unblock")); + serializers_.push_back(new BlockSerializer<BlockListPayload>("blocklist")); serializers_.push_back(new ResourceBindSerializer()); serializers_.push_back(new StartSessionSerializer()); serializers_.push_back(new SecurityLabelSerializer()); @@ -77,6 +102,19 @@ FullPayloadSerializerCollection::FullPayloadSerializerCollection() { serializers_.push_back(new InBandRegistrationPayloadSerializer()); serializers_.push_back(new NicknameSerializer()); serializers_.push_back(new SearchPayloadSerializer()); + serializers_.push_back(new ReplaceSerializer()); + serializers_.push_back(new LastSerializer()); + + serializers_.push_back(new StreamInitiationFileInfoSerializer()); + serializers_.push_back(new JingleContentPayloadSerializer()); + serializers_.push_back(new JingleFileTransferDescriptionSerializer()); + serializers_.push_back(new JingleFileTransferHashSerializer()); + serializers_.push_back(new JingleFileTransferReceivedSerializer()); + serializers_.push_back(new JingleIBBTransportPayloadSerializer()); + serializers_.push_back(new JingleS5BTransportPayloadSerializer()); + serializers_.push_back(new JinglePayloadSerializer(this)); + serializers_.push_back(new S5BProxyRequestSerializer()); + foreach(PayloadSerializer* serializer, serializers_) { addSerializer(serializer); } diff --git a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h index bf86f27..bfe7d76 100644 --- a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h +++ b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h @@ -4,12 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_FULLPAYLOADSERIALIZERCOLLECTION_H -#define SWIFTEN_FULLPAYLOADSERIALIZERCOLLECTION_H +#pragma once #include <vector> -#include "Swiften/Serializer/PayloadSerializerCollection.h" +#include <Swiften/Serializer/PayloadSerializerCollection.h> namespace Swift { class FullPayloadSerializerCollection : public PayloadSerializerCollection { @@ -21,5 +20,3 @@ namespace Swift { std::vector<PayloadSerializer*> serializers_; }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/IBBSerializer.cpp b/Swiften/Serializer/PayloadSerializers/IBBSerializer.cpp index 7ac4103..f3dad80 100644 --- a/Swiften/Serializer/PayloadSerializers/IBBSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/IBBSerializer.cpp @@ -4,16 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/IBBSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/IBBSerializer.h> #include <boost/shared_ptr.hpp> #include <boost/lexical_cast.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" -#include "Swiften/Serializer/PayloadSerializerCollection.h" -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/StringCodecs/Base64.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/IBBSerializer.h b/Swiften/Serializer/PayloadSerializers/IBBSerializer.h index d750f6f..229f131 100644 --- a/Swiften/Serializer/PayloadSerializers/IBBSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/IBBSerializer.h @@ -6,12 +6,10 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/IBB.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/IBB.h> namespace Swift { - class PayloadSerializerCollection; - class IBBSerializer : public GenericPayloadSerializer<IBB> { public: IBBSerializer(); diff --git a/Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.cpp index e4ae11f..12b1bb5 100644 --- a/Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLRawTextNode.h" -#include "Swiften/Serializer/PayloadSerializers/FormSerializer.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/PayloadSerializers/FormSerializer.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.h index 45d49ea..3b88590 100644 --- a/Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.h @@ -7,12 +7,10 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/InBandRegistrationPayload.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/InBandRegistrationPayload.h> namespace Swift { - class PayloadSerializerCollection; - class InBandRegistrationPayloadSerializer : public GenericPayloadSerializer<InBandRegistrationPayload> { public: InBandRegistrationPayloadSerializer(); diff --git a/Swiften/Serializer/PayloadSerializers/JingleContentPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/JingleContentPayloadSerializer.cpp new file mode 100644 index 0000000..90bd940 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleContentPayloadSerializer.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Serializer/PayloadSerializers/JingleContentPayloadSerializer.h> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/smart_ptr/intrusive_ptr.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLNode.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> + +#include <Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.h> + +#include <Swiften/Serializer/PayloadSerializers/JingleIBBTransportPayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/JingleS5BTransportPayloadSerializer.h> + +#include "Swiften/FileTransfer/JingleTransport.h" + +namespace Swift { + +JingleContentPayloadSerializer::JingleContentPayloadSerializer() { +} + +std::string JingleContentPayloadSerializer::serializePayload(boost::shared_ptr<JingleContentPayload> payload) const { + XMLElement payloadXML("content"); + payloadXML.setAttribute("creator", creatorToString(payload->getCreator())); + payloadXML.setAttribute("name", payload->getName()); + + if (!payload->getDescriptions().empty()) { + // JingleFileTransferDescription + JingleFileTransferDescriptionSerializer ftSerializer; + JingleFileTransferDescription::ref filetransfer; + + foreach(JingleDescription::ref desc, payload->getDescriptions()) { + if ((filetransfer = boost::dynamic_pointer_cast<JingleFileTransferDescription>(desc))) { + payloadXML.addNode(boost::make_shared<XMLRawTextNode>(ftSerializer.serializePayload(filetransfer))); + } + } + } + + if (!payload->getTransports().empty()) { + // JingleIBBTransportPayload + JingleIBBTransportPayloadSerializer ibbSerializer; + JingleIBBTransportPayload::ref ibb; + + // JingleS5BTransportPayload + JingleS5BTransportPayloadSerializer s5bSerializer; + JingleS5BTransportPayload::ref s5b; + + foreach(JingleTransportPayload::ref transport, payload->getTransports()) { + if ((ibb = boost::dynamic_pointer_cast<JingleIBBTransportPayload>(transport))) { + payloadXML.addNode(boost::make_shared<XMLRawTextNode>(ibbSerializer.serializePayload(ibb))); + } else if ((s5b = boost::dynamic_pointer_cast<JingleS5BTransportPayload>(transport))) { + payloadXML.addNode(boost::make_shared<XMLRawTextNode>(s5bSerializer.serializePayload(s5b))); + } + } + } + return payloadXML.serialize(); +} + +std::string JingleContentPayloadSerializer::creatorToString(JingleContentPayload::Creator creator) const { + switch(creator) { + case JingleContentPayload::InitiatorCreator: + return "initiator"; + case JingleContentPayload::ResponderCreator: + return "responder"; + case JingleContentPayload::UnknownCreator: + std::cerr << "Serializing unknown creator value." << std::endl; + return "ERROR ERROR ERROR"; + } + assert(false); +} +} diff --git a/Swiften/Serializer/PayloadSerializers/JingleContentPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/JingleContentPayloadSerializer.h new file mode 100644 index 0000000..2de0064 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleContentPayloadSerializer.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/JingleContentPayload.h> + +namespace Swift { + class PayloadSerializerCollection; + + class JingleContentPayloadSerializer : public GenericPayloadSerializer<JingleContentPayload> { + public: + JingleContentPayloadSerializer(); + + virtual std::string serializePayload(boost::shared_ptr<JingleContentPayload>) const; + + private: + std::string creatorToString(JingleContentPayload::Creator creator) const; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.cpp b/Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.cpp new file mode 100644 index 0000000..16337ff --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.h> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLNode.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> + +#include <Swiften/Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.h> + +namespace Swift { + +JingleFileTransferDescriptionSerializer::JingleFileTransferDescriptionSerializer() { +} + +std::string JingleFileTransferDescriptionSerializer::serializePayload(boost::shared_ptr<JingleFileTransferDescription> payload) const { + XMLElement description("description", "urn:xmpp:jingle:apps:file-transfer:3"); + StreamInitiationFileInfoSerializer fileInfoSerializer; + if (!payload->getOffers().empty()) { + boost::shared_ptr<XMLElement> offers = boost::make_shared<XMLElement>("offer"); + foreach(const StreamInitiationFileInfo &fileInfo, payload->getOffers()) { + boost::shared_ptr<XMLRawTextNode> fileInfoXML = boost::make_shared<XMLRawTextNode>(fileInfoSerializer.serialize(boost::make_shared<StreamInitiationFileInfo>(fileInfo))); + offers->addNode(fileInfoXML); + } + description.addNode(offers); + } + if (!payload->getRequests().empty()) { + boost::shared_ptr<XMLElement> requests = boost::make_shared<XMLElement>("request"); + foreach(const StreamInitiationFileInfo &fileInfo, payload->getRequests()) { + boost::shared_ptr<XMLRawTextNode> fileInfoXML = boost::make_shared<XMLRawTextNode>(fileInfoSerializer.serialize(boost::make_shared<StreamInitiationFileInfo>(fileInfo))); + requests->addNode(fileInfoXML); + } + description.addNode(requests); + } + return description.serialize(); +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.h b/Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.h new file mode 100644 index 0000000..5131435 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/JingleFileTransferDescription.h> + + + +namespace Swift { + class PayloadSerializerCollection; + class XMLElement; + + class JingleFileTransferDescriptionSerializer : public GenericPayloadSerializer<JingleFileTransferDescription> { + public: + JingleFileTransferDescriptionSerializer(); + + virtual std::string serializePayload(boost::shared_ptr<JingleFileTransferDescription>) const; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/JingleFileTransferHashSerializer.cpp b/Swiften/Serializer/PayloadSerializers/JingleFileTransferHashSerializer.cpp new file mode 100644 index 0000000..2bd3afa --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleFileTransferHashSerializer.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Serializer/PayloadSerializers/JingleFileTransferHashSerializer.h> + +#include <string> +#include <map> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLNode.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> + + +namespace Swift { + +JingleFileTransferHashSerializer::JingleFileTransferHashSerializer() { +} + +std::string JingleFileTransferHashSerializer::serializePayload(boost::shared_ptr<JingleFileTransferHash> payload) const { + // code for version urn:xmpp:jingle:apps:file-transfer:2 + //XMLElement hash("hash", "urn:xmpp:jingle:apps:file-transfer:info:2", payload->getHash()); + + // code for version urn:xmpp:jingle:apps:file-transfer:3 + XMLElement checksum("checksum", "urn:xmpp:jingle:apps:file-transfer:3"); + boost::shared_ptr<XMLElement> file = boost::make_shared<XMLElement>("file"); + checksum.addNode(file); + boost::shared_ptr<XMLElement> hashes = boost::make_shared<XMLElement>("hashes", "urn:xmpp:hashes:0"); + file->addNode(hashes); + foreach(const JingleFileTransferHash::HashesMap::value_type& pair, payload->getHashes()) { + boost::shared_ptr<XMLElement> hash = boost::make_shared<XMLElement>("hash", "", pair.second); + hash->setAttribute("algo", pair.first); + hashes->addNode(hash); + } + + return checksum.serialize(); +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/JingleFileTransferHashSerializer.h b/Swiften/Serializer/PayloadSerializers/JingleFileTransferHashSerializer.h new file mode 100644 index 0000000..7fa6ac5 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleFileTransferHashSerializer.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/JingleFileTransferHash.h> + +namespace Swift { + class PayloadSerializerCollection; + class XMLElement; + + class JingleFileTransferHashSerializer : public GenericPayloadSerializer<JingleFileTransferHash> { + public: + JingleFileTransferHashSerializer(); + + virtual std::string serializePayload(boost::shared_ptr<JingleFileTransferHash>) const; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/JingleFileTransferReceivedSerializer.cpp b/Swiften/Serializer/PayloadSerializers/JingleFileTransferReceivedSerializer.cpp new file mode 100644 index 0000000..40be70e --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleFileTransferReceivedSerializer.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Serializer/PayloadSerializers/JingleFileTransferReceivedSerializer.h> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLNode.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> + +#include <Swiften/Serializer/XML/XMLRawTextNode.h> + +namespace Swift { + +JingleFileTransferReceivedSerializer::JingleFileTransferReceivedSerializer() { +} + +std::string JingleFileTransferReceivedSerializer::serializePayload(boost::shared_ptr<JingleFileTransferReceived> payload) const { + XMLElement receivedElement("received", "urn:xmpp:jingle:apps:file-transfer:3"); + XMLElement::ref fileElement = boost::make_shared<XMLElement>("file", "http://jabber.org/protocol/si/profile/file-transfer"); + fileElement->setAttribute("hash", payload->getFileInfo().getHash()); + if (payload->getFileInfo().getAlgo() != "md5") { + fileElement->setAttribute("algo", payload->getFileInfo().getAlgo()); + } + receivedElement.addNode(fileElement); + return receivedElement.serialize(); +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/JingleFileTransferReceivedSerializer.h b/Swiften/Serializer/PayloadSerializers/JingleFileTransferReceivedSerializer.h new file mode 100644 index 0000000..4151dd0 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleFileTransferReceivedSerializer.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/JingleFileTransferReceived.h> + +namespace Swift { + class PayloadSerializerCollection; + class XMLElement; + + class JingleFileTransferReceivedSerializer : public GenericPayloadSerializer<JingleFileTransferReceived> { + public: + JingleFileTransferReceivedSerializer(); + + virtual std::string serializePayload(boost::shared_ptr<JingleFileTransferReceived>) const; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/JingleIBBTransportPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/JingleIBBTransportPayloadSerializer.cpp new file mode 100644 index 0000000..029a5b4 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleIBBTransportPayloadSerializer.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Serializer/PayloadSerializers/JingleIBBTransportPayloadSerializer.h> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/lexical_cast.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLNode.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> + +namespace Swift { + +JingleIBBTransportPayloadSerializer::JingleIBBTransportPayloadSerializer() { +} + +std::string JingleIBBTransportPayloadSerializer::serializePayload(boost::shared_ptr<JingleIBBTransportPayload> payload) const { + XMLElement payloadXML("transport", "urn:xmpp:jingle:transports:ibb:1"); + payloadXML.setAttribute("block-size", boost::lexical_cast<std::string>(payload->getBlockSize())); + payloadXML.setAttribute("sid", payload->getSessionID()); + + return payloadXML.serialize(); +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/JingleIBBTransportPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/JingleIBBTransportPayloadSerializer.h new file mode 100644 index 0000000..ac9cba9 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleIBBTransportPayloadSerializer.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h> + + + +namespace Swift { + class PayloadSerializerCollection; + class XMLElement; + + class JingleIBBTransportPayloadSerializer : public GenericPayloadSerializer<JingleIBBTransportPayload> { + public: + JingleIBBTransportPayloadSerializer(); + + virtual std::string serializePayload(boost::shared_ptr<JingleIBBTransportPayload>) const; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/JinglePayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/JinglePayloadSerializer.cpp new file mode 100644 index 0000000..25d35ff --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JinglePayloadSerializer.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Serializer/PayloadSerializers/JinglePayloadSerializer.h> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/smart_ptr/intrusive_ptr.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLNode.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/PayloadSerializers/JingleContentPayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/JingleFileTransferHashSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/JingleFileTransferReceivedSerializer.h> + +#include <Swiften/Serializer/PayloadSerializerCollection.h> + +#include <Swiften/Elements/JinglePayload.h> +#include <Swiften/Elements/JingleContentPayload.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleFileTransferDescription.h> +#include <Swiften/Elements/JingleFileTransferHash.h> +#include <Swiften/Elements/JingleFileTransferReceived.h> + +namespace Swift { + +JinglePayloadSerializer::JinglePayloadSerializer(PayloadSerializerCollection* serializers) : serializers(serializers) { +} + +std::string JinglePayloadSerializer::serializePayload(boost::shared_ptr<JinglePayload> payload) const { + XMLElement jinglePayload("jingle", "urn:xmpp:jingle:1"); + jinglePayload.setAttribute("action", actionToString(payload->getAction())); + jinglePayload.setAttribute("initiator", payload->getInitiator()); + jinglePayload.setAttribute("sid", payload->getSessionID()); + + if (!payload->getPayloads().empty()) { + foreach(boost::shared_ptr<Payload> subPayload, payload->getPayloads()) { + PayloadSerializer* serializer = serializers->getPayloadSerializer(subPayload); + if (serializer) { + jinglePayload.addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(serializer->serialize(subPayload)))); + } + } + } + + if (payload->getReason().is_initialized()) { + boost::shared_ptr<XMLElement> reason = boost::make_shared<XMLElement>("reason"); + reason->addNode(boost::make_shared<XMLElement>(reasonTypeToString(payload->getReason()->type))); + if (!payload->getReason()->text.empty()) { + reason->addNode(boost::make_shared<XMLElement>("desc", "", payload->getReason()->text)); + } + jinglePayload.addNode(reason); + } + + return jinglePayload.serialize(); +} + +std::string JinglePayloadSerializer::actionToString(JinglePayload::Action action) const { + switch(action) { + case JinglePayload::ContentAccept: + return "content-accept"; + case JinglePayload::ContentAdd: + return "content-add"; + case JinglePayload::ContentModify: + return "content-modify"; + case JinglePayload::ContentReject: + return "content-reject"; + case JinglePayload::ContentRemove: + return "content-remove"; + case JinglePayload::DescriptionInfo: + return "description-info"; + case JinglePayload::SecurityInfo: + return "security-info"; + case JinglePayload::SessionAccept: + return "session-accept"; + case JinglePayload::SessionInfo: + return "session-info"; + case JinglePayload::SessionInitiate: + return "session-initiate"; + case JinglePayload::SessionTerminate: + return "session-terminate"; + case JinglePayload::TransportAccept: + return "transport-accept"; + case JinglePayload::TransportInfo: + return "transport-info"; + case JinglePayload::TransportReject: + return "transport-reject"; + case JinglePayload::TransportReplace: + return "transport-replace"; + case JinglePayload::UnknownAction: + std::cerr << "Serializing unknown action value." << std::endl; + return ""; + } + assert(false); +} + +std::string JinglePayloadSerializer::reasonTypeToString(JinglePayload::Reason::Type type) const { + switch(type) { + case JinglePayload::Reason::UnknownType: + std::cerr << "Unknown jingle reason type!" << std::endl; + return ""; + case JinglePayload::Reason::AlternativeSession: + return "alternative-session"; + case JinglePayload::Reason::Busy: + return "busy"; + case JinglePayload::Reason::Cancel: + return "cancel"; + case JinglePayload::Reason::ConnectivityError: + return "connectivity-error"; + case JinglePayload::Reason::Decline: + return "decline"; + case JinglePayload::Reason::Expired: + return "expired"; + case JinglePayload::Reason::FailedApplication: + return "failed-application"; + case JinglePayload::Reason::FailedTransport: + return "failed-transport"; + case JinglePayload::Reason::GeneralError: + return "general-error"; + case JinglePayload::Reason::Gone: + return "gone"; + case JinglePayload::Reason::IncompatibleParameters: + return "incompatible-parameters"; + case JinglePayload::Reason::MediaError: + return "media-error"; + case JinglePayload::Reason::SecurityError: + return "security-error"; + case JinglePayload::Reason::Success: + return "success"; + case JinglePayload::Reason::Timeout: + return "timeout"; + case JinglePayload::Reason::UnsupportedApplications: + return "unsupported-applications"; + case JinglePayload::Reason::UnsupportedTransports: + return "unsupported-transports"; + } + assert(false); +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/JinglePayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/JinglePayloadSerializer.h new file mode 100644 index 0000000..ccdb6d0 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JinglePayloadSerializer.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/JinglePayload.h> + +namespace Swift { + class PayloadSerializerCollection; + class XMLElement; + + class JinglePayloadSerializer : public GenericPayloadSerializer<JinglePayload> { + public: + JinglePayloadSerializer(PayloadSerializerCollection*); + + virtual std::string serializePayload(boost::shared_ptr<JinglePayload>) const; + + private: + std::string actionToString(JinglePayload::Action action) const; + std::string reasonTypeToString(JinglePayload::Reason::Type type) const; + + private: + PayloadSerializerCollection* serializers; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/JingleS5BTransportPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/JingleS5BTransportPayloadSerializer.cpp new file mode 100644 index 0000000..c5b40d5 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleS5BTransportPayloadSerializer.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Serializer/PayloadSerializers/JingleS5BTransportPayloadSerializer.h> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/lexical_cast.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLNode.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Base/Log.h> + +namespace Swift { + +JingleS5BTransportPayloadSerializer::JingleS5BTransportPayloadSerializer() { +} + +std::string JingleS5BTransportPayloadSerializer::serializePayload(boost::shared_ptr<JingleS5BTransportPayload> payload) const { + XMLElement payloadXML("transport", "urn:xmpp:jingle:transports:s5b:1"); + payloadXML.setAttribute("sid", payload->getSessionID()); + payloadXML.setAttribute("mode", modeToString(payload->getMode())); + + foreach(JingleS5BTransportPayload::Candidate candidate, payload->getCandidates()) { + boost::shared_ptr<XMLElement> candidateXML = boost::make_shared<XMLElement>("candidate"); + candidateXML->setAttribute("cid", candidate.cid); + candidateXML->setAttribute("host", candidate.hostPort.getAddress().toString()); + candidateXML->setAttribute("jid", candidate.jid.toString()); + candidateXML->setAttribute("port", boost::lexical_cast<std::string>(candidate.hostPort.getPort())); + candidateXML->setAttribute("priority", boost::lexical_cast<std::string>(candidate.priority)); + candidateXML->setAttribute("type", typeToString(candidate.type)); + payloadXML.addNode(candidateXML); + } + + if (payload->hasCandidateError()) { + payloadXML.addNode(boost::make_shared<XMLElement>("candidate-error")); + } + if (payload->hasProxyError()) { + payloadXML.addNode(boost::make_shared<XMLElement>("proxy-error")); + } + + if (!payload->getActivated().empty()) { + boost::shared_ptr<XMLElement> activatedXML = boost::make_shared<XMLElement>("activated"); + activatedXML->setAttribute("cid", payload->getActivated()); + payloadXML.addNode(activatedXML); + } + if (!payload->getCandidateUsed().empty()) { + boost::shared_ptr<XMLElement> candusedXML = boost::make_shared<XMLElement>("candidate-used"); + candusedXML->setAttribute("cid", payload->getCandidateUsed()); + payloadXML.addNode(candusedXML); + } + + return payloadXML.serialize(); +} + +std::string JingleS5BTransportPayloadSerializer::modeToString(JingleS5BTransportPayload::Mode mode) const { + switch(mode) { + case JingleS5BTransportPayload::TCPMode: + return "tcp"; + case JingleS5BTransportPayload::UDPMode: + return "udp"; + } + assert(false); +} + +std::string JingleS5BTransportPayloadSerializer::typeToString(JingleS5BTransportPayload::Candidate::Type type) const { + switch(type) { + case JingleS5BTransportPayload::Candidate::AssistedType: + return "assisted"; + case JingleS5BTransportPayload::Candidate::DirectType: + return "direct"; + case JingleS5BTransportPayload::Candidate::ProxyType: + return "proxy"; + case JingleS5BTransportPayload::Candidate::TunnelType: + return "tunnel"; + } + assert(false); +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/JingleS5BTransportPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/JingleS5BTransportPayloadSerializer.h new file mode 100644 index 0000000..210688d --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleS5BTransportPayloadSerializer.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> + +namespace Swift { + class PayloadSerializerCollection; + class XMLElement; + + class JingleS5BTransportPayloadSerializer : public GenericPayloadSerializer<JingleS5BTransportPayload> { + public: + JingleS5BTransportPayloadSerializer(); + + virtual std::string serializePayload(boost::shared_ptr<JingleS5BTransportPayload>) const; + + private: + std::string modeToString(JingleS5BTransportPayload::Mode) const; + std::string typeToString(JingleS5BTransportPayload::Candidate::Type) const; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/LastSerializer.h b/Swiften/Serializer/PayloadSerializers/LastSerializer.h new file mode 100644 index 0000000..e91d702 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/LastSerializer.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/lexical_cast.hpp> + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/Last.h> + +namespace Swift { + class LastSerializer : public GenericPayloadSerializer<Last> { + public: + LastSerializer() : GenericPayloadSerializer<Last>() {} + + virtual std::string serializePayload(boost::shared_ptr<Last> last) const { + return "<query xmlns='jabber:iq:last' seconds='" + boost::lexical_cast<std::string>(last->getSeconds()) + "'/>"; + } + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/MUCAdminPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/MUCAdminPayloadSerializer.cpp new file mode 100644 index 0000000..8758722 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/MUCAdminPayloadSerializer.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Serializer/PayloadSerializers/MUCAdminPayloadSerializer.h> + +#include <sstream> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Serializer/PayloadSerializers/MUCItemSerializer.h> + + +namespace Swift { + +MUCAdminPayloadSerializer::MUCAdminPayloadSerializer() : GenericPayloadSerializer<MUCAdminPayload>() { +} + +std::string MUCAdminPayloadSerializer::serializePayload(boost::shared_ptr<MUCAdminPayload> payload) const { + XMLElement mucElement("query", "http://jabber.org/protocol/muc#admin"); + foreach (const MUCItem& item, payload->getItems()) { + mucElement.addNode(MUCItemSerializer::itemToElement(item)); + } + return mucElement.serialize(); +} + + +} diff --git a/Swiften/Serializer/PayloadSerializers/MUCAdminPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/MUCAdminPayloadSerializer.h new file mode 100644 index 0000000..e288cd7 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/MUCAdminPayloadSerializer.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/MUCAdminPayload.h> + +namespace Swift { + class MUCAdminPayloadSerializer : public GenericPayloadSerializer<MUCAdminPayload> { + public: + MUCAdminPayloadSerializer(); + std::string affiliationToString(MUCOccupant::Affiliation affiliation) const; + std::string roleToString(MUCOccupant::Role role) const; + + virtual std::string serializePayload(boost::shared_ptr<MUCAdminPayload> version) const; + }; +} + diff --git a/Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.cpp new file mode 100644 index 0000000..e78a381 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.h> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> + +namespace Swift { + +MUCDestroyPayloadSerializer::MUCDestroyPayloadSerializer() : GenericPayloadSerializer<MUCDestroyPayload>() { +} + +std::string MUCDestroyPayloadSerializer::serializePayload(boost::shared_ptr<MUCDestroyPayload> payload) const { + XMLElement mucElement("destroy", ""); + if (!payload->getReason().empty()) { + XMLElement::ref reason = boost::make_shared<XMLElement>("reason", ""); + reason->addNode(boost::make_shared<XMLTextNode>(payload->getReason())); + mucElement.addNode(reason); + } + if (payload->getNewVenue().isValid()) { + mucElement.setAttribute("jid", payload->getNewVenue().toString()); + } + return mucElement.serialize(); +} + + + + +} diff --git a/Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.h new file mode 100644 index 0000000..419a683 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/MUCDestroyPayload.h> + +namespace Swift { + class PayloadSerializerCollection; + class MUCDestroyPayloadSerializer : public GenericPayloadSerializer<MUCDestroyPayload> { + public: + MUCDestroyPayloadSerializer(); + virtual std::string serializePayload(boost::shared_ptr<MUCDestroyPayload> version) const; + }; +} + diff --git a/Swiften/Serializer/PayloadSerializers/MUCItemSerializer.h b/Swiften/Serializer/PayloadSerializers/MUCItemSerializer.h new file mode 100644 index 0000000..7cb662c --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/MUCItemSerializer.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/MUCItem.h> +#include <boost/smart_ptr/make_shared.hpp> + +namespace Swift { + class MUCItemSerializer { + public: + static std::string affiliationToString(MUCOccupant::Affiliation affiliation) { + std::string result; + switch (affiliation) { + case MUCOccupant::Owner: result = "owner"; break; + case MUCOccupant::Admin: result = "admin"; break; + case MUCOccupant::Member: result = "member"; break; + case MUCOccupant::Outcast: result = "outcast"; break; + case MUCOccupant::NoAffiliation: result = "none"; break; + default: assert(false); + } + return result; + } + + static std::string roleToString(MUCOccupant::Role role) { + std::string result; + switch (role) { + case MUCOccupant::Moderator: result = "moderator"; break; + case MUCOccupant::NoRole: result = "none"; break; + case MUCOccupant::Participant: result = "participant"; break; + case MUCOccupant::Visitor: result = "visitor"; break; + default: assert(false); + } + return result; + + } + + static boost::shared_ptr<XMLElement> itemToElement(const MUCItem& item) { + boost::shared_ptr<XMLElement> itemElement(new XMLElement("item")); + if (item.affiliation) { + itemElement->setAttribute("affiliation", affiliationToString(item.affiliation.get())); + } + if (item.role) { + itemElement->setAttribute("role", roleToString(item.role.get())); + } + if (item.realJID) { + itemElement->setAttribute("jid", item.realJID.get()); + } + if (item.nick) { + itemElement->setAttribute("nick", item.nick.get()); + } + if (item.actor) { + boost::shared_ptr<XMLElement> actorElement(new XMLElement("actor")); + actorElement->setAttribute("jid", item.actor->toString()); + itemElement->addNode(actorElement); + } + if (item.reason) { + boost::shared_ptr<XMLElement> reasonElement(new XMLElement("reason")); + reasonElement->addNode(boost::make_shared<XMLTextNode>(*item.reason)); + itemElement->addNode(reasonElement); + } + return itemElement; + } + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.cpp index db28514..f86b59e 100644 --- a/Swiften/Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.cpp @@ -4,11 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.h> -#include "Swiften/Serializer/PayloadSerializerCollection.h" -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLRawTextNode.h" +#include <Swiften/Serializer/PayloadSerializerCollection.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.h index 4808744..5e6913a 100644 --- a/Swiften/Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/MUCOwnerPayload.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/MUCOwnerPayload.h> namespace Swift { class PayloadSerializerCollection; diff --git a/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.cpp index d7e1613..7080e14 100644 --- a/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.cpp @@ -4,9 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h> -#include "Swiften/Serializer/XML/XMLElement.h" +#include <boost/lexical_cast.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> + +#include <Swiften/Serializer/XML/XMLElement.h> #include <Swiften/Base/String.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h index 7038e6e..4bf8d22 100644 --- a/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/MUCPayload.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/MUCPayload.h> namespace Swift { class MUCPayloadSerializer : public GenericPayloadSerializer<MUCPayload> { diff --git a/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.cpp index 50746a9..96fba90 100644 --- a/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.cpp @@ -4,24 +4,26 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h> #include <sstream> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" - +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/PayloadSerializers/MUCItemSerializer.h> +#include <Swiften/Serializer/PayloadSerializerCollection.h> namespace Swift { -MUCUserPayloadSerializer::MUCUserPayloadSerializer() : GenericPayloadSerializer<MUCUserPayload>() { +MUCUserPayloadSerializer::MUCUserPayloadSerializer(PayloadSerializerCollection* serializers) : GenericPayloadSerializer<MUCUserPayload>(), serializers(serializers) { } std::string MUCUserPayloadSerializer::serializePayload(boost::shared_ptr<MUCUserPayload> payload) const { - XMLElement mucElement("x", "http://jabber.org/protocol/muc"); + XMLElement mucElement("x", "http://jabber.org/protocol/muc#user"); foreach (const MUCUserPayload::StatusCode statusCode, payload->getStatusCodes()) { boost::shared_ptr<XMLElement> statusElement(new XMLElement("status")); std::ostringstream code; @@ -29,46 +31,20 @@ std::string MUCUserPayloadSerializer::serializePayload(boost::shared_ptr<MUCUser statusElement->setAttribute("code", code.str()); mucElement.addNode(statusElement); } - foreach (const MUCUserPayload::Item item, payload->getItems()) { - boost::shared_ptr<XMLElement> itemElement(new XMLElement("item")); - itemElement->setAttribute("affiliation", affiliationToString(item.affiliation)); - itemElement->setAttribute("role", roleToString(item.role)); - if (item.realJID) { - itemElement->setAttribute("jid", item.realJID.get()); - } - if (item.nick) { - itemElement->setAttribute("nick", item.nick.get()); + foreach (const MUCItem& item, payload->getItems()) { + mucElement.addNode(MUCItemSerializer::itemToElement(item)); + } + boost::shared_ptr<Payload> childPayload = payload->getPayload(); + if (childPayload) { + PayloadSerializer* serializer = serializers->getPayloadSerializer(childPayload); + if (serializer) { + mucElement.addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(serializer->serialize(childPayload)))); } - mucElement.addNode(itemElement); } return mucElement.serialize(); } -std::string MUCUserPayloadSerializer::affiliationToString(MUCOccupant::Affiliation affiliation) const { - std::string result; - switch (affiliation) { - case MUCOccupant::Owner: result = "owner"; break; - case MUCOccupant::Admin: result = "admin"; break; - case MUCOccupant::Member: result = "member"; break; - case MUCOccupant::Outcast: result = "outcast"; break; - case MUCOccupant::NoAffiliation: result = "none"; break; - default: assert(false); - } - return result; -} - -std::string MUCUserPayloadSerializer::roleToString(MUCOccupant::Role role) const { - std::string result; - switch (role) { - case MUCOccupant::Moderator: result = "moderator"; break; - case MUCOccupant::NoRole: result = "none"; break; - case MUCOccupant::Participant: result = "participant"; break; - case MUCOccupant::Visitor: result = "visitor"; break; - default: assert(false); - } - return result; -} } diff --git a/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h index 54e6aff..8c237e0 100644 --- a/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h @@ -6,17 +6,18 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/MUCUserPayload.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/MUCUserPayload.h> namespace Swift { + class PayloadSerializerCollection; class MUCUserPayloadSerializer : public GenericPayloadSerializer<MUCUserPayload> { public: - MUCUserPayloadSerializer(); - std::string affiliationToString(MUCOccupant::Affiliation affiliation) const; - std::string roleToString(MUCOccupant::Role role) const; + MUCUserPayloadSerializer(PayloadSerializerCollection* serializers); virtual std::string serializePayload(boost::shared_ptr<MUCUserPayload> version) const; + private: + PayloadSerializerCollection* serializers; }; } diff --git a/Swiften/Serializer/PayloadSerializers/NicknameSerializer.cpp b/Swiften/Serializer/PayloadSerializers/NicknameSerializer.cpp index 23d2c25..38a5db5 100644 --- a/Swiften/Serializer/PayloadSerializers/NicknameSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/NicknameSerializer.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/NicknameSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/NicknameSerializer.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/NicknameSerializer.h b/Swiften/Serializer/PayloadSerializers/NicknameSerializer.h index e07767b..382ec11 100644 --- a/Swiften/Serializer/PayloadSerializers/NicknameSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/NicknameSerializer.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/Nickname.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/Nickname.h> namespace Swift { class NicknameSerializer : public GenericPayloadSerializer<Nickname> { diff --git a/Swiften/Serializer/PayloadSerializers/PrioritySerializer.h b/Swiften/Serializer/PayloadSerializers/PrioritySerializer.h index cc96ce7..5a2ef27 100644 --- a/Swiften/Serializer/PayloadSerializers/PrioritySerializer.h +++ b/Swiften/Serializer/PayloadSerializers/PrioritySerializer.h @@ -4,13 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_PrioritySerializer_H -#define SWIFTEN_PrioritySerializer_H +#pragma once #include <boost/lexical_cast.hpp> -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/Priority.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/Priority.h> namespace Swift { class PrioritySerializer : public GenericPayloadSerializer<Priority> { @@ -22,5 +21,3 @@ namespace Swift { } }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.cpp b/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.cpp index 6e1d74d..6cb226c 100644 --- a/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.cpp @@ -4,15 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" -#include "Swiften/Serializer/XML/XMLRawTextNode.h" -#include "Swiften/Serializer/PayloadSerializerCollection.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/PayloadSerializerCollection.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h b/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h index 7b46136..3548cac 100644 --- a/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/PrivateStorage.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/PrivateStorage.h> namespace Swift { class PayloadSerializerCollection; diff --git a/Swiften/Serializer/PayloadSerializers/RawXMLPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/RawXMLPayloadSerializer.h index 6874569..02a5564 100644 --- a/Swiften/Serializer/PayloadSerializers/RawXMLPayloadSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/RawXMLPayloadSerializer.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/RawXMLPayload.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/RawXMLPayload.h> namespace Swift { class RawXMLPayloadSerializer : public GenericPayloadSerializer<RawXMLPayload> { diff --git a/Swiften/Serializer/PayloadSerializers/ReplaceSerializer.h b/Swiften/Serializer/PayloadSerializers/ReplaceSerializer.h new file mode 100644 index 0000000..88ad2b3 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/ReplaceSerializer.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2011 Vlad Voicu + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Elements/Replace.h> + +namespace Swift { + class ReplaceSerializer : public GenericPayloadSerializer<Replace> { + public: + ReplaceSerializer() : GenericPayloadSerializer<Replace>() {} + + virtual std::string serializePayload(boost::shared_ptr<Replace> replace) const { + return "<replace id = '" + replace->getID() + "' xmlns='http://swift.im/protocol/replace'/>"; + } + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.cpp b/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.cpp index cfb3a90..af0c609 100644 --- a/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h b/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h index d259555..133e45e 100644 --- a/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_ResourceBindSerializer_H -#define SWIFTEN_ResourceBindSerializer_H +#pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/ResourceBind.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/ResourceBind.h> namespace Swift { class ResourceBindSerializer : public GenericPayloadSerializer<ResourceBind> { @@ -18,5 +17,3 @@ namespace Swift { virtual std::string serializePayload(boost::shared_ptr<ResourceBind>) const; }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/RosterItemExchangeSerializer.cpp b/Swiften/Serializer/PayloadSerializers/RosterItemExchangeSerializer.cpp new file mode 100644 index 0000000..b60db12 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/RosterItemExchangeSerializer.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Serializer/PayloadSerializers/RosterItemExchangeSerializer.h> + +#include <boost/shared_ptr.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/XML/XMLElement.h> + +namespace Swift { + +RosterItemExchangeSerializer::RosterItemExchangeSerializer() : GenericPayloadSerializer<RosterItemExchangePayload>() { +} + +std::string RosterItemExchangeSerializer::serializePayload(boost::shared_ptr<RosterItemExchangePayload> roster) const { + XMLElement queryElement("x", "http://jabber.org/protocol/rosterx"); + foreach(const RosterItemExchangePayload::Item& item, roster->getItems()) { + boost::shared_ptr<XMLElement> itemElement(new XMLElement("item")); + itemElement->setAttribute("jid", item.getJID()); + itemElement->setAttribute("name", item.getName()); + + switch (item.getAction()) { + case RosterItemExchangePayload::Item::Add: itemElement->setAttribute("action", "add"); break; + case RosterItemExchangePayload::Item::Modify: itemElement->setAttribute("action", "modify"); break; + case RosterItemExchangePayload::Item::Delete: itemElement->setAttribute("action", "delete"); break; + } + + foreach(const std::string& group, item.getGroups()) { + boost::shared_ptr<XMLElement> groupElement(new XMLElement("group")); + groupElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(group))); + itemElement->addNode(groupElement); + } + + queryElement.addNode(itemElement); + } + + return queryElement.serialize(); +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/RosterItemExchangeSerializer.h b/Swiften/Serializer/PayloadSerializers/RosterItemExchangeSerializer.h new file mode 100644 index 0000000..f246f9e --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/RosterItemExchangeSerializer.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/RosterItemExchangePayload.h> + +namespace Swift { + class RosterItemExchangeSerializer : public GenericPayloadSerializer<RosterItemExchangePayload> { + public: + RosterItemExchangeSerializer(); + + virtual std::string serializePayload(boost::shared_ptr<RosterItemExchangePayload>) const; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp b/Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp index 40faf73..84f36d2 100644 --- a/Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/RosterSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/RosterSerializer.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" -#include "Swiften/Serializer/XML/XMLRawTextNode.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { @@ -20,6 +20,9 @@ RosterSerializer::RosterSerializer() : GenericPayloadSerializer<RosterPayload>() std::string RosterSerializer::serializePayload(boost::shared_ptr<RosterPayload> roster) const { XMLElement queryElement("query", "jabber:iq:roster"); + if (roster->getVersion()) { + queryElement.setAttribute("ver", *roster->getVersion()); + } foreach(const RosterItemPayload& item, roster->getItems()) { boost::shared_ptr<XMLElement> itemElement(new XMLElement("item")); itemElement->setAttribute("jid", item.getJID()); diff --git a/Swiften/Serializer/PayloadSerializers/RosterSerializer.h b/Swiften/Serializer/PayloadSerializers/RosterSerializer.h index 49e194b..52fdb2a 100644 --- a/Swiften/Serializer/PayloadSerializers/RosterSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/RosterSerializer.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_RosterSerializer_H -#define SWIFTEN_RosterSerializer_H +#pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/RosterPayload.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/RosterPayload.h> namespace Swift { class RosterSerializer : public GenericPayloadSerializer<RosterPayload> { @@ -18,5 +17,3 @@ namespace Swift { virtual std::string serializePayload(boost::shared_ptr<RosterPayload>) const; }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/S5BProxyRequestSerializer.h b/Swiften/Serializer/PayloadSerializers/S5BProxyRequestSerializer.h new file mode 100644 index 0000000..b523588 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/S5BProxyRequestSerializer.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + + +#pragma once + +#include <boost/lexical_cast.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Elements/S5BProxyRequest.h> +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> + +namespace Swift { + class PayloadSerializerCollection; + + class S5BProxyRequestSerializer : public GenericPayloadSerializer<S5BProxyRequest> { + public: + virtual std::string serializePayload(boost::shared_ptr<S5BProxyRequest> s5bProxyRequest) const { + XMLElement queryElement("query", "http://jabber.org/protocol/bytestreams"); + if (s5bProxyRequest && s5bProxyRequest->getStreamHost()) { + boost::shared_ptr<XMLElement> streamHost = boost::make_shared<XMLElement>("streamhost"); + streamHost->setAttribute("host", s5bProxyRequest->getStreamHost().get().addressPort.getAddress().toString()); + streamHost->setAttribute("port", boost::lexical_cast<std::string>(s5bProxyRequest->getStreamHost().get().addressPort.getPort())); + streamHost->setAttribute("jid", s5bProxyRequest->getStreamHost().get().jid.toString()); + queryElement.addNode(streamHost); + } else if (s5bProxyRequest && s5bProxyRequest->getActivate()) { + queryElement.setAttribute("sid", s5bProxyRequest->getSID()); + boost::shared_ptr<XMLElement> activate = boost::make_shared<XMLElement>("activate", "", s5bProxyRequest->getActivate().get().toString()); + queryElement.addNode(activate); + } + return queryElement.serialize(); + } + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.cpp index a7a9fda..a5cd634 100644 --- a/Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLRawTextNode.h" -#include "Swiften/Serializer/PayloadSerializers/FormSerializer.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/PayloadSerializers/FormSerializer.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.h index 2d8ec85..e4dbff8 100644 --- a/Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.h @@ -7,8 +7,8 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/SearchPayload.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/SearchPayload.h> namespace Swift { class PayloadSerializerCollection; diff --git a/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.cpp b/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.cpp index b9ec55e..51079ee 100644 --- a/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.cpp @@ -4,11 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h" -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLRawTextNode.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h b/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h index a02aeb9..a1915c7 100644 --- a/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_SecurityLabelSerializer_H -#define SWIFTEN_SecurityLabelSerializer_H +#pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/SecurityLabel.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/SecurityLabel.h> namespace Swift { class SecurityLabelSerializer : public GenericPayloadSerializer<SecurityLabel> { @@ -18,5 +17,3 @@ namespace Swift { virtual std::string serializePayload(boost::shared_ptr<SecurityLabel> version) const; }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp b/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp index 7424c98..1078292 100644 --- a/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp @@ -4,11 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h" -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLRawTextNode.h" -#include "Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h b/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h index 88a1541..02104df 100644 --- a/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_SecurityLabelsCatalogSerializer_H -#define SWIFTEN_SecurityLabelsCatalogSerializer_H +#pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/SecurityLabelsCatalog.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/SecurityLabelsCatalog.h> namespace Swift { class SecurityLabelsCatalogSerializer : public GenericPayloadSerializer<SecurityLabelsCatalog> { @@ -18,5 +17,3 @@ namespace Swift { virtual std::string serializePayload(boost::shared_ptr<SecurityLabelsCatalog> version) const; }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.cpp b/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.cpp index b2eb1ed..e117167 100644 --- a/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h b/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h index 72f4afd..98fa243 100644 --- a/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_SoftwareVersionSerializer_H -#define SWIFTEN_SoftwareVersionSerializer_H +#pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/SoftwareVersion.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/SoftwareVersion.h> namespace Swift { class SoftwareVersionSerializer : public GenericPayloadSerializer<SoftwareVersion> { @@ -18,5 +17,3 @@ namespace Swift { virtual std::string serializePayload(boost::shared_ptr<SoftwareVersion> version) const; }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/StartSessionSerializer.h b/Swiften/Serializer/PayloadSerializers/StartSessionSerializer.h index dd9ba97..2082f4b 100644 --- a/Swiften/Serializer/PayloadSerializers/StartSessionSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/StartSessionSerializer.h @@ -4,13 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StartSessionSerializer_H -#define SWIFTEN_StartSessionSerializer_H +#pragma once #include <boost/lexical_cast.hpp> -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/StartSession.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/StartSession.h> namespace Swift { class StartSessionSerializer : public GenericPayloadSerializer<StartSession> { @@ -22,5 +21,3 @@ namespace Swift { } }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/StatusSerializer.h b/Swiften/Serializer/PayloadSerializers/StatusSerializer.h index 565d554..a8de26f 100644 --- a/Swiften/Serializer/PayloadSerializers/StatusSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/StatusSerializer.h @@ -4,13 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StatusSerializer_H -#define SWIFTEN_StatusSerializer_H +#pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" -#include "Swiften/Elements/Status.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Elements/Status.h> namespace Swift { class StatusSerializer : public GenericPayloadSerializer<Status> { @@ -24,5 +23,3 @@ namespace Swift { } }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h b/Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h index e797e81..e65c1b6 100644 --- a/Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StatusShowSerializer_H -#define SWIFTEN_StatusShowSerializer_H +#pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/StatusShow.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/StatusShow.h> namespace Swift { class StatusShowSerializer : public GenericPayloadSerializer<StatusShow> { @@ -35,5 +34,3 @@ namespace Swift { } }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/StorageSerializer.cpp b/Swiften/Serializer/PayloadSerializers/StorageSerializer.cpp index 049c797..30adf26 100644 --- a/Swiften/Serializer/PayloadSerializers/StorageSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/StorageSerializer.cpp @@ -4,13 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/StorageSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/StorageSerializer.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/StorageSerializer.h b/Swiften/Serializer/PayloadSerializers/StorageSerializer.h index bc682a6..6f4f03b 100644 --- a/Swiften/Serializer/PayloadSerializers/StorageSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/StorageSerializer.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/Storage.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/Storage.h> namespace Swift { class StorageSerializer : public GenericPayloadSerializer<Storage> { diff --git a/Swiften/Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.cpp b/Swiften/Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.cpp new file mode 100644 index 0000000..7b0cad8 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.h> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/lexical_cast.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/DateTime.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> + + + +namespace Swift { + +StreamInitiationFileInfoSerializer::StreamInitiationFileInfoSerializer() { +} + +std::string StreamInitiationFileInfoSerializer::serializePayload(boost::shared_ptr<StreamInitiationFileInfo> fileInfo) const { + XMLElement fileElement("file", "http://jabber.org/protocol/si/profile/file-transfer"); + + if (fileInfo->getDate() != stringToDateTime("")) { + fileElement.setAttribute("date", dateTimeToString(fileInfo->getDate())); + } + fileElement.setAttribute("hash", fileInfo->getHash()); + if (fileInfo->getAlgo() != "md5") { + fileElement.setAttribute("algo", fileInfo->getAlgo()); + } + if (!fileInfo->getName().empty()) { + fileElement.setAttribute("name", fileInfo->getName()); + } + if (fileInfo->getSize() != 0) { + fileElement.setAttribute("size", boost::lexical_cast<std::string>(fileInfo->getSize())); + } + if (!fileInfo->getDescription().empty()) { + boost::shared_ptr<XMLElement> desc = boost::make_shared<XMLElement>("desc", "", fileInfo->getDescription()); + fileElement.addNode(desc); + } + if (fileInfo->getSupportsRangeRequests()) { + boost::shared_ptr<XMLElement> range = boost::make_shared<XMLElement>("range"); + if (fileInfo->getRangeOffset() != 0) { + range->setAttribute("offset", boost::lexical_cast<std::string>(fileInfo->getRangeOffset())); + } + fileElement.addNode(range); + } + return fileElement.serialize(); +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.h b/Swiften/Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.h new file mode 100644 index 0000000..4ac0a0d --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/StreamInitiationFileInfo.h> + +#include <Swiften/Serializer/XML/XMLElement.h> + +namespace Swift { + class PayloadSerializerCollection; + + class StreamInitiationFileInfoSerializer : public GenericPayloadSerializer<StreamInitiationFileInfo> { + public: + StreamInitiationFileInfoSerializer(); + + virtual std::string serializePayload(boost::shared_ptr<StreamInitiationFileInfo>) const; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.cpp b/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.cpp index 70fb2ac..9ccfab2 100644 --- a/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.cpp @@ -4,17 +4,16 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h> #include <boost/shared_ptr.hpp> #include <boost/lexical_cast.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" -#include "Swiften/Serializer/XML/XMLRawTextNode.h" -#include "Swiften/Serializer/PayloadSerializerCollection.h" -#include "Swiften/Serializer/PayloadSerializers/FormSerializer.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/PayloadSerializers/FormSerializer.h> #define FILE_TRANSFER_NS "http://jabber.org/protocol/si/profile/file-transfer" @@ -37,19 +36,19 @@ std::string StreamInitiationSerializer::serializePayload(boost::shared_ptr<Strea if (streamInitiation->getFileInfo()) { StreamInitiationFileInfo file = *streamInitiation->getFileInfo(); boost::shared_ptr<XMLElement> fileElement(new XMLElement("file", "http://jabber.org/protocol/si/profile/file-transfer")); - fileElement->setAttribute("name", file.name); - if (file.size != -1) { - fileElement->setAttribute("size", boost::lexical_cast<std::string>(file.size)); + fileElement->setAttribute("name", file.getName()); + if (file.getSize() != 0) { + fileElement->setAttribute("size", boost::lexical_cast<std::string>(file.getSize())); } - if (!file.description.empty()) { + if (!file.getDescription().empty()) { boost::shared_ptr<XMLElement> descElement(new XMLElement("desc")); - descElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(file.description))); + descElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(file.getDescription()))); fileElement->addNode(descElement); } siElement.addNode(fileElement); } - boost::shared_ptr<XMLElement> featureElement(new XMLElement("feature", "http://jabber.org/protocol/feature-neg")); + boost::shared_ptr<XMLElement> featureElement(new XMLElement("feature", FEATURE_NEG_NS)); if (streamInitiation->getProvidedMethods().size() > 0) { Form::ref form(new Form(Form::FormType)); ListSingleFormField::ref field = ListSingleFormField::create(); diff --git a/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h b/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h index 0b51519..76f0f45 100644 --- a/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h @@ -6,12 +6,10 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/StreamInitiation.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/StreamInitiation.h> namespace Swift { - class PayloadSerializerCollection; - class StreamInitiationSerializer : public GenericPayloadSerializer<StreamInitiation> { public: StreamInitiationSerializer(); diff --git a/Swiften/Serializer/PayloadSerializers/SubjectSerializer.h b/Swiften/Serializer/PayloadSerializers/SubjectSerializer.h index cf78ddd..fe82499 100644 --- a/Swiften/Serializer/PayloadSerializers/SubjectSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/SubjectSerializer.h @@ -6,9 +6,9 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" -#include "Swiften/Elements/Subject.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Elements/Subject.h> namespace Swift { class SubjectSerializer : public GenericPayloadSerializer<Subject> { diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/CapsInfoSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/CapsInfoSerializerTest.cpp index 2604331..270d165 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/CapsInfoSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/CapsInfoSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/DiscoInfoSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/DiscoInfoSerializerTest.cpp index 3875efd..32f5f49 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/DiscoInfoSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/DiscoInfoSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/ErrorSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/ErrorSerializerTest.cpp index dd06244..27d4ac5 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/ErrorSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/ErrorSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/ErrorSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/ErrorSerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/FormSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/FormSerializerTest.cpp index e4a6661..29e7e59 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/FormSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/FormSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/FormSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/FormSerializer.h> using namespace Swift; @@ -96,13 +96,6 @@ class FormSerializerTest : public CppUnit::TestFixture { field->setDescription("Tell all your friends about your new bot!"); form->addField(field); - std::vector<std::string> values2; - values2.push_back("foo"); - values2.push_back("bar"); - field = UntypedFormField::create(values2); - field->setName("fum"); - form->addField(field); - CPPUNIT_ASSERT_EQUAL(std::string( "<x type=\"form\" xmlns=\"jabber:x:data\">" "<field type=\"hidden\" var=\"FORM_TYPE\">" @@ -139,10 +132,6 @@ class FormSerializerTest : public CppUnit::TestFixture { "<value>foo@bar.com</value>" "<value>baz@fum.org</value>" "</field>" - "<field var=\"fum\">" - "<value>foo</value>" - "<value>bar</value>" - "</field>" "</x>"), testling.serialize(form)); } }; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/InBandRegistrationPayloadSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/InBandRegistrationPayloadSerializerTest.cpp index 7020537..df43e69 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/InBandRegistrationPayloadSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/InBandRegistrationPayloadSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/InBandRegistrationPayloadSerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp new file mode 100644 index 0000000..e3ec8fc --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp @@ -0,0 +1,512 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/JinglePayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h> +#include <Swiften/Elements/JingleFileTransferDescription.h> +#include <Swiften/Elements/StreamInitiationFileInfo.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/Elements/JingleFileTransferHash.h> +#include <Swiften/Elements/JinglePayload.h> +#include <Swiften/Elements/JingleFileTransferReceived.h> +#include <Swiften/Base/DateTime.h> + +using namespace Swift; + +class JingleSerializersTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(JingleSerializersTest); + CPPUNIT_TEST(testSerialize_StreamInitiationFileInfo); + CPPUNIT_TEST(testSerialize_StreamInitiationFileInfoRange); + + CPPUNIT_TEST(testSerialize_Xep0261_Example1); + CPPUNIT_TEST(testSerialize_Xep0261_Example9); + CPPUNIT_TEST(testSerialize_Xep0261_Example13); + + CPPUNIT_TEST(testSerialize_Xep0234_Example1); + CPPUNIT_TEST(testSerialize_Xep0234_Example3); + CPPUNIT_TEST(testSerialize_Xep0234_Example5); + CPPUNIT_TEST(testSerialize_Xep0234_Example8); + CPPUNIT_TEST(testSerialize_Xep0234_Example10); + CPPUNIT_TEST(testSerialize_Xep0234_Example13); + + CPPUNIT_TEST(testSerialize_Xep0260_Example1); + + CPPUNIT_TEST_SUITE_END(); + + boost::shared_ptr<JinglePayloadSerializer> createTestling() { + return boost::make_shared<JinglePayloadSerializer>(&collection); + } + + + public: + void testSerialize_StreamInitiationFileInfo() { + std::string expected = "<file" + " date=\"1969-07-21T02:56:15Z\"" + " hash=\"552da749930852c69ae5d2141d3766b1\"" + " name=\"test.txt\"" + " size=\"1022\"" + " xmlns=\"http://jabber.org/protocol/si/profile/file-transfer\">" + "<desc>This is a test. If this were a real file...</desc>" + "<range/>" + "</file>"; + + StreamInitiationFileInfo::ref fileInfo = boost::make_shared<StreamInitiationFileInfo>(); + fileInfo->setDate(stringToDateTime("1969-07-21T02:56:15Z")); + fileInfo->setHash("552da749930852c69ae5d2141d3766b1"); + fileInfo->setSize(1022); + fileInfo->setName("test.txt"); + fileInfo->setDescription("This is a test. If this were a real file..."); + fileInfo->setSupportsRangeRequests(true); + + boost::shared_ptr<StreamInitiationFileInfoSerializer> serializer = boost::make_shared<StreamInitiationFileInfoSerializer>(); + CPPUNIT_ASSERT_EQUAL(expected, serializer->serializePayload(fileInfo)); + } + + void testSerialize_StreamInitiationFileInfoRange() { + std::string expected = "<file hash=\"552da749930852c69ae5d2141d3766b1\"" + " xmlns=\"http://jabber.org/protocol/si/profile/file-transfer\">" + "<range offset=\"270336\"/>" + "</file>"; + + StreamInitiationFileInfo::ref fileInfo = boost::make_shared<StreamInitiationFileInfo>(); + fileInfo->setHash("552da749930852c69ae5d2141d3766b1"); + fileInfo->setSupportsRangeRequests(true); + fileInfo->setRangeOffset(270336); + + boost::shared_ptr<StreamInitiationFileInfoSerializer> serializer = boost::make_shared<StreamInitiationFileInfoSerializer>(); + CPPUNIT_ASSERT_EQUAL(expected, serializer->serializePayload(fileInfo)); + } + + + // IBB Transport Method Examples + + // http://xmpp.org/extensions/xep-0261.html#example-1 + void testSerialize_Xep0261_Example1() { + std::string expected = + "<jingle action=\"session-initiate\"" + " initiator=\"romeo@montague.lit/orchard\"" + " sid=\"a73sjjvkla37jfea\"" + " xmlns=\"urn:xmpp:jingle:1\">" + "<content creator=\"initiator\" name=\"ex\">" + "<transport block-size=\"4096\"" + " sid=\"ch3d9s71\"" + " xmlns=\"urn:xmpp:jingle:transports:ibb:1\"/>" + "</content>" + "</jingle>"; + + JinglePayload::ref payload = boost::make_shared<JinglePayload>(); + payload->setAction(JinglePayload::SessionInitiate); + payload->setSessionID("a73sjjvkla37jfea"); + payload->setInitiator(JID("romeo@montague.lit/orchard")); + + JingleIBBTransportPayload::ref transport = boost::make_shared<JingleIBBTransportPayload>(); + transport->setBlockSize(4096); + transport->setSessionID("ch3d9s71"); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(JingleContentPayload::InitiatorCreator); + content->setName("ex"); + content->addTransport(transport); + + payload->addPayload(content); + + CPPUNIT_ASSERT_EQUAL(expected, createTestling()->serialize(payload)); + } + + // http://xmpp.org/extensions/xep-0261.html#example-9 + void testSerialize_Xep0261_Example9() { + std::string expected = + "<jingle action=\"transport-info\"" + " initiator=\"romeo@montague.lit/orchard\"" + " sid=\"a73sjjvkla37jfea\"" + " xmlns=\"urn:xmpp:jingle:1\">" + "<content creator=\"initiator\" name=\"ex\">" + "<transport block-size=\"2048\"" + " sid=\"bt8a71h6\"" + " xmlns=\"urn:xmpp:jingle:transports:ibb:1\"/>" + "</content>" + "</jingle>"; + + JinglePayload::ref payload = boost::make_shared<JinglePayload>(); + payload->setAction(JinglePayload::TransportInfo); + payload->setInitiator(JID("romeo@montague.lit/orchard")); + payload->setSessionID("a73sjjvkla37jfea"); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(JingleContentPayload::InitiatorCreator); + content->setName("ex"); + + JingleIBBTransportPayload::ref transport = boost::make_shared<JingleIBBTransportPayload>(); + transport->setBlockSize(2048); + transport->setSessionID("bt8a71h6"); + + content->addTransport(transport); + payload->addPayload(content); + + CPPUNIT_ASSERT_EQUAL(expected, createTestling()->serialize(payload)); + } + + // http://xmpp.org/extensions/xep-0261.html#example-13 + void testSerialize_Xep0261_Example13() { + std::string expected = + "<jingle action=\"session-terminate\"" + " initiator=\"romeo@montague.lit/orchard\"" + " sid=\"a73sjjvkla37jfea\"" + " xmlns=\"urn:xmpp:jingle:1\">" + "<reason><success/></reason>" + "</jingle>"; + + JinglePayload::ref payload = boost::make_shared<JinglePayload>(); + payload->setAction(JinglePayload::SessionTerminate); + payload->setInitiator(JID("romeo@montague.lit/orchard")); + payload->setSessionID("a73sjjvkla37jfea"); + payload->setReason(JinglePayload::Reason(JinglePayload::Reason::Success)); + + CPPUNIT_ASSERT_EQUAL(expected, createTestling()->serialize(payload)); + } + + // http://xmpp.org/extensions/xep-0234.html#example-1 + void testSerialize_Xep0234_Example1() { + std::string expected = "<description xmlns=\"urn:xmpp:jingle:apps:file-transfer:3\">" + "<offer>" + "<file" + " date=\"1969-07-21T02:56:15Z\"" + " hash=\"552da749930852c69ae5d2141d3766b1\"" + " name=\"test.txt\"" + " size=\"1022\"" + " xmlns=\"http://jabber.org/protocol/si/profile/file-transfer\">" + "<desc>This is a test. If this were a real file...</desc>" + "<range/>" + "</file>" + "</offer>" + "</description>"; + JingleFileTransferDescription::ref desc = boost::make_shared<JingleFileTransferDescription>(); + StreamInitiationFileInfo fileInfo; + + fileInfo.setDate(stringToDateTime("1969-07-21T02:56:15Z")); + fileInfo.setHash("552da749930852c69ae5d2141d3766b1"); + fileInfo.setSize(1022); + fileInfo.setName("test.txt"); + fileInfo.setDescription("This is a test. If this were a real file..."); + fileInfo.setSupportsRangeRequests(true); + + desc->addOffer(fileInfo); + + CPPUNIT_ASSERT_EQUAL(expected, boost::make_shared<JingleFileTransferDescriptionSerializer>()->serialize(desc)); + } + + // http://xmpp.org/extensions/xep-0234.html#example-3 + void testSerialize_Xep0234_Example3() { + std::string expected = + "<jingle action=\"session-accept\"" + " initiator=\"romeo@montague.lit/orchard\"" + " sid=\"851ba2\"" + " xmlns=\"urn:xmpp:jingle:1\">" + "<content creator=\"initiator\" name=\"a-file-offer\">" + "<description xmlns=\"urn:xmpp:jingle:apps:file-transfer:3\">" + "<offer>" + "<file" + " date=\"1969-07-21T02:56:15Z\"" + " hash=\"552da749930852c69ae5d2141d3766b1\"" + " name=\"test.txt\"" + " size=\"1022\"" + " xmlns=\"http://jabber.org/protocol/si/profile/file-transfer\">" + "<desc>This is a test. If this were a real file...</desc>" + "<range/>" + "</file>" + "</offer>" + "</description>" + /*"<transport xmlns=\"urn:xmpp:jingle:transports:s5b:1\"" + " mode=\"tcp\"" + " sid=\"vj3hs98y\">" + "<candidate cid=\"ht567dq\"" + " host=\"192.169.1.10\"" + " jid=\"juliet@capulet.lit/balcony\"" + " port=\"6539\"" + " priority=\"8257636\"" + " type=\"direct\"/>" + "<candidate cid=\"hr65dqyd\"" + " host=\"134.102.201.180\"" + " jid=\"juliet@capulet.lit/balcony\"" + " port=\"16453\"" + " priority=\"7929856\"" + " type=\"assisted\"/>" + "<candidate cid=\"grt654q2\"" + " host=\"2001:638:708:30c9:219:d1ff:fea4:a17d\"" + " jid=\"juliet@capulet.lit/balcony\"" + " port=\"6539\"" + " priority=\"8257606\"" + " type=\"direct\"/>" + "</transport>"*/ + "</content>" + "</jingle>"; + + JinglePayload::ref payload = boost::make_shared<JinglePayload>(); + payload->setAction(JinglePayload::SessionAccept); + payload->setInitiator(JID("romeo@montague.lit/orchard")); + payload->setSessionID("851ba2"); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(JingleContentPayload::InitiatorCreator); + content->setName("a-file-offer"); + + JingleFileTransferDescription::ref description = boost::make_shared<JingleFileTransferDescription>(); + StreamInitiationFileInfo fileInfo; + fileInfo.setName("test.txt"); + fileInfo.setSize(1022); + fileInfo.setHash("552da749930852c69ae5d2141d3766b1"); + fileInfo.setDate(stringToDateTime("1969-07-21T02:56:15Z")); + fileInfo.setDescription("This is a test. If this were a real file..."); + fileInfo.setSupportsRangeRequests(true); + + description->addOffer(fileInfo); + content->addDescription(description); + payload->addPayload(content); + + CPPUNIT_ASSERT_EQUAL(expected, createTestling()->serialize(payload)); + } + + // http://xmpp.org/extensions/xep-0234.html#example-5 + void testSerialize_Xep0234_Example5() { + std::string expected = + "<jingle" + " action=\"transport-info\"" + " initiator=\"romeo@montague.lit/orchard\"" + " sid=\"a73sjjvkla37jfea\"" + " xmlns=\"urn:xmpp:jingle:1\">" + "<content creator=\"initiator\" name=\"ex\"/>" + /*"<transport" + " sid=\"vj3hs98y\"" + " xmlns=\"urn:xmpp:jingle:transports:s5b:1\">" + "<candidate-used cid=\"hr65dqyd\"/>" + "</transport>"*/ + //"</content>" + "</jingle>"; + + JinglePayload::ref payload = boost::make_shared<JinglePayload>(); + payload->setAction(JinglePayload::TransportInfo); + payload->setInitiator(JID("romeo@montague.lit/orchard")); + payload->setSessionID("a73sjjvkla37jfea"); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(JingleContentPayload::InitiatorCreator); + content->setName("ex"); + payload->addPayload(content); + + CPPUNIT_ASSERT_EQUAL(expected, createTestling()->serialize(payload)); + } + + // http://xmpp.org/extensions/xep-0234.html#example-8 + void testSerialize_Xep0234_Example8() { + std::string expected = + "<jingle" + " action=\"session-info\"" + " initiator=\"romeo@montague.lit/orchard\"" + " sid=\"a73sjjvkla37jfea\"" + " xmlns=\"urn:xmpp:jingle:1\">" + "<checksum xmlns=\"urn:xmpp:jingle:apps:file-transfer:3\">" + "<file>" + "<hashes xmlns=\"urn:xmpp:hashes:0\">" + "<hash algo=\"sha-1\">552da749930852c69ae5d2141d3766b1</hash>" + "</hashes>" + "</file>" + "</checksum>" + "</jingle>"; + + JinglePayload::ref payload = boost::make_shared<JinglePayload>(); + payload->setAction(JinglePayload::SessionInfo); + payload->setInitiator(JID("romeo@montague.lit/orchard")); + payload->setSessionID("a73sjjvkla37jfea"); + + JingleFileTransferHash::ref hash = boost::make_shared<JingleFileTransferHash>(); + hash->setHash("sha-1", "552da749930852c69ae5d2141d3766b1"); + + payload->addPayload(hash); + + CPPUNIT_ASSERT_EQUAL(expected, createTestling()->serialize(payload)); + } + + // http://xmpp.org/extensions/xep-0234.html#example-10 + void testSerialize_Xep0234_Example10() { + std::string expected = + "<jingle" + " action=\"session-initiate\"" + " initiator=\"romeo@montague.lit/orchard\"" + " sid=\"uj3b2\"" + " xmlns=\"urn:xmpp:jingle:1\">" + "<content creator=\"initiator\" name=\"a-file-request\">" + "<description" + " xmlns=\"urn:xmpp:jingle:apps:file-transfer:3\">" + "<request>" + "<file" + " hash=\"552da749930852c69ae5d2141d3766b1\"" + " xmlns=\"http://jabber.org/protocol/si/profile/file-transfer\">" + "<range offset=\"270336\"/>" + "</file>" + "</request>" + "</description>" + /*"<transport" + " mode=\"tcp\"" + " sid=\"xig361fj\"" + " xmlns=\"urn:xmpp:jingle:transports:s5b:1\">" + "<candidate" + " cid=\"ht567dq\"" + " host=\"192.169.1.10\"" + " jid=\"juliet@capulet.lit/balcony\"" + " port=\"6539\"" + " priority=\"8257636\"" + " type=\"direct\"/>" + "<candidate" + " cid=\"hr65dqyd\"" + " host=\"134.102.201.180\"" + " jid=\"juliet@capulet.lit/balcony\"" + " port=\"16453\"" + " priority=\"7929856\"" + " type=\"assisted\"/>" + "<candidate" + " cid=\"grt654q2\"" + " host=\"2001:638:708:30c9:219:d1ff:fea4:a17d\"" + " jid=\"juliet@capulet.lit/balcony\"" + " port=\"6539\"" + " priority=\"8257606\"" + " type=\"direct\"/>" + "</transport>"*/ + "</content>" + "</jingle>"; + + JinglePayload::ref payload = boost::make_shared<JinglePayload>(); + payload->setAction(JinglePayload::SessionInitiate); + payload->setInitiator(JID("romeo@montague.lit/orchard")); + payload->setSessionID("uj3b2"); + + StreamInitiationFileInfo fileInfo; + fileInfo.setHash("552da749930852c69ae5d2141d3766b1"); + fileInfo.setRangeOffset(270336); + + JingleFileTransferDescription::ref desc = boost::make_shared<JingleFileTransferDescription>(); + desc->addRequest(fileInfo); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(JingleContentPayload::InitiatorCreator); + content->setName("a-file-request"); + content->addDescription(desc); + + payload->addPayload(content); + + CPPUNIT_ASSERT_EQUAL(expected, createTestling()->serialize(payload)); + } + + // http://xmpp.org/extensions/xep-0234.html#example-10 + void testSerialize_Xep0234_Example13() { + std::string expected = + "<jingle" + " action=\"session-info\"" + " initiator=\"romeo@montague.lit/orchard\"" + " sid=\"a73sjjvkla37jfea\"" + " xmlns=\"urn:xmpp:jingle:1\">" + "<received xmlns=\"urn:xmpp:jingle:apps:file-transfer:3\">" + "<file" + " hash=\"a749930852c69ae5d2141d3766b1552d\"" + " xmlns=\"http://jabber.org/protocol/si/profile/file-transfer\"/>" + "</received>" + "</jingle>"; + + JinglePayload::ref payload = boost::make_shared<JinglePayload>(); + payload->setAction(JinglePayload::SessionInfo); + payload->setInitiator(JID("romeo@montague.lit/orchard")); + payload->setSessionID("a73sjjvkla37jfea"); + + JingleFileTransferReceived::ref received = boost::make_shared<JingleFileTransferReceived>(); + + StreamInitiationFileInfo fileInfo; + fileInfo.setHash("a749930852c69ae5d2141d3766b1552d"); + + received->setFileInfo(fileInfo); + payload->addPayload(received); + + CPPUNIT_ASSERT_EQUAL(expected, createTestling()->serialize(payload)); + } + + // http://xmpp.org/extensions/xep-0260.html#example-1 + void testSerialize_Xep0260_Example1() { + std::string expected = + "<jingle" + " action=\"session-initiate\"" + " initiator=\"romeo@montague.lit/orchard\"" + " sid=\"a73sjjvkla37jfea\"" + " xmlns=\"urn:xmpp:jingle:1\">" + "<content creator=\"initiator\" name=\"ex\">" + "<transport" + " mode=\"tcp\"" + " sid=\"vj3hs98y\"" + " xmlns=\"urn:xmpp:jingle:transports:s5b:1\">" + "<candidate cid=\"hft54dqy\"" + " host=\"192.168.4.1\"" + " jid=\"romeo@montague.lit/orchard\"" + " port=\"5086\"" + " priority=\"8257636\"" + " type=\"direct\"/>" + "<candidate cid=\"hutr46fe\"" + " host=\"24.24.24.1\"" + " jid=\"romeo@montague.lit/orchard\"" + " port=\"5087\"" + " priority=\"8258636\"" + " type=\"direct\"/>" + "</transport>" + "</content>" + "</jingle>"; + + JinglePayload::ref payload = boost::make_shared<JinglePayload>(); + payload->setAction(JinglePayload::SessionInitiate); + payload->setInitiator(JID("romeo@montague.lit/orchard")); + payload->setSessionID("a73sjjvkla37jfea"); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(JingleContentPayload::InitiatorCreator); + content->setName("ex"); + + JingleS5BTransportPayload::ref transport = boost::make_shared<JingleS5BTransportPayload>(); + transport->setMode(JingleS5BTransportPayload::TCPMode); + transport->setSessionID("vj3hs98y"); + + JingleS5BTransportPayload::Candidate candidate1; + candidate1.cid = "hft54dqy"; + candidate1.hostPort = HostAddressPort(HostAddress("192.168.4.1"), 5086); + candidate1.jid = JID("romeo@montague.lit/orchard"); + candidate1.priority = 8257636; + candidate1.type = JingleS5BTransportPayload::Candidate::DirectType; + transport->addCandidate(candidate1); + + JingleS5BTransportPayload::Candidate candidate2; + candidate2.cid = "hutr46fe"; + candidate2.hostPort = HostAddressPort(HostAddress("24.24.24.1"), 5087); + candidate2.jid = JID("romeo@montague.lit/orchard"); + candidate2.priority = 8258636; + candidate2.type = JingleS5BTransportPayload::Candidate::DirectType; + transport->addCandidate(candidate2); + + content->addTransport(transport); + + payload->addPayload(content); + + CPPUNIT_ASSERT_EQUAL(expected, createTestling()->serialize(payload)); + } + + private: + FullPayloadSerializerCollection collection; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(JingleSerializersTest); + diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/MUCAdminPayloadSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/MUCAdminPayloadSerializerTest.cpp new file mode 100644 index 0000000..a8acf80 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/MUCAdminPayloadSerializerTest.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Serializer/PayloadSerializers/MUCAdminPayloadSerializer.h> + +using namespace Swift; + +class MUCAdminPayloadSerializerTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(MUCAdminPayloadSerializerTest); + CPPUNIT_TEST(testSerialize); + CPPUNIT_TEST_SUITE_END(); + + public: + MUCAdminPayloadSerializerTest() {} + + void testSerialize() { + MUCAdminPayloadSerializer testling; + boost::shared_ptr<MUCAdminPayload> admin = boost::make_shared<MUCAdminPayload>(); + MUCItem item; + item.affiliation = MUCOccupant::Owner; + item.role = MUCOccupant::Visitor; + item.reason = "malice"; + item.actor = JID("kev@tester.lit"); + admin->addItem(item); + + CPPUNIT_ASSERT_EQUAL(std::string("<query xmlns=\"http://jabber.org/protocol/muc#admin\"><item affiliation=\"owner\" role=\"visitor\"><actor jid=\"kev@tester.lit\"/><reason>malice</reason></item></query>"), testling.serialize(admin)); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(MUCAdminPayloadSerializerTest); diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.cpp index 481d9c2..9eed97e 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.cpp @@ -4,11 +4,11 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.h> #include <cppunit/extensions/HelperMacros.h> -#include "Swiften/Serializer/PayloadSerializer.h" +#include <Swiften/Serializer/PayloadSerializer.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.h b/Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.h index 038b616..01f07e4 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.h @@ -8,9 +8,9 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h> #include <string> -#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h" +#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h> namespace Swift { class PayloadsSerializer { diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/PrioritySerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/PrioritySerializerTest.cpp index c976b12..f5b8bee 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/PrioritySerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/PrioritySerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/PrioritySerializer.h" +#include <Swiften/Serializer/PayloadSerializers/PrioritySerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/PrivateStorageSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/PrivateStorageSerializerTest.cpp index b0f4084..23d71aa 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/PrivateStorageSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/PrivateStorageSerializerTest.cpp @@ -7,9 +7,9 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.h" -#include "Swiften/Elements/PrivateStorage.h" -#include "Swiften/Elements/Storage.h" +#include <Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.h> +#include <Swiften/Elements/PrivateStorage.h> +#include <Swiften/Elements/Storage.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/ReplaceSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/ReplaceSerializerTest.cpp new file mode 100644 index 0000000..3d054cc --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/ReplaceSerializerTest.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Vlad Voicu + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Serializer/PayloadSerializers/ReplaceSerializer.h> + +using namespace Swift; + +class ReplaceSerializerTest: public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(ReplaceSerializerTest); + CPPUNIT_TEST(testSerialize); + CPPUNIT_TEST_SUITE_END(); + + public: + ReplaceSerializerTest() {} + + void testSerialize() { + ReplaceSerializer testling; + boost::shared_ptr<Replace> replace(new Replace()); + replace->setID("bad1"); + CPPUNIT_ASSERT_EQUAL(std::string("<replace id = 'bad1' xmlns='http://swift.im/protocol/replace'/>"), testling.serialize(replace)); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(ReplaceSerializerTest); diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/ResourceBindSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/ResourceBindSerializerTest.cpp index c7872fe..f8d3d30 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/ResourceBindSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/ResourceBindSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/RosterItemExchangeSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/RosterItemExchangeSerializerTest.cpp new file mode 100644 index 0000000..b6a90d9 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/RosterItemExchangeSerializerTest.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Serializer/PayloadSerializers/RosterItemExchangeSerializer.h> + +using namespace Swift; + +class RosterItemExchangeSerializerTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(RosterItemExchangeSerializerTest); + CPPUNIT_TEST(testSerialize); + CPPUNIT_TEST_SUITE_END(); + + public: + RosterItemExchangeSerializerTest() {} + + void testSerialize() { + RosterItemExchangeSerializer testling; + boost::shared_ptr<RosterItemExchangePayload> roster(new RosterItemExchangePayload()); + + RosterItemExchangePayload::Item item1; + item1.setJID("foo@bar.com"); + item1.setName("Foo @ Bar"); + item1.setAction(RosterItemExchangePayload::Item::Add); + item1.addGroup("Group 1"); + item1.addGroup("Group 2"); + roster->addItem(item1); + + RosterItemExchangePayload::Item item2; + item2.setJID("baz@blo.com"); + item2.setName("Baz"); + item2.setAction(RosterItemExchangePayload::Item::Modify); + roster->addItem(item2); + + std::string expectedResult = + "<x xmlns=\"http://jabber.org/protocol/rosterx\">" + "<item action=\"add\" jid=\"foo@bar.com\" name=\"Foo @ Bar\">" + "<group>Group 1</group>" + "<group>Group 2</group>" + "</item>" + "<item action=\"modify\" jid=\"baz@blo.com\" name=\"Baz\"/>" + "</x>"; + + CPPUNIT_ASSERT_EQUAL(expectedResult, testling.serialize(roster)); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(RosterItemExchangeSerializerTest); diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp index b8ceac3..9ecddc3 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp @@ -7,20 +7,19 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/RosterSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/RosterSerializer.h> using namespace Swift; -class RosterSerializerTest : public CppUnit::TestFixture -{ +class RosterSerializerTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(RosterSerializerTest); CPPUNIT_TEST(testSerialize); CPPUNIT_TEST(testSerialize_ItemWithUnknownContent); + CPPUNIT_TEST(testSerialize_WithVersion); + CPPUNIT_TEST(testSerialize_WithEmptyVersion); CPPUNIT_TEST_SUITE_END(); public: - RosterSerializerTest() {} - void testSerialize() { RosterSerializer testling; boost::shared_ptr<RosterPayload> roster(new RosterPayload()); @@ -77,6 +76,26 @@ class RosterSerializerTest : public CppUnit::TestFixture CPPUNIT_ASSERT_EQUAL(expectedResult, testling.serialize(roster)); } + + void testSerialize_WithVersion() { + RosterSerializer testling; + boost::shared_ptr<RosterPayload> roster(new RosterPayload()); + roster->setVersion("ver20"); + + std::string expectedResult = "<query ver=\"ver20\" xmlns=\"jabber:iq:roster\"/>"; + + CPPUNIT_ASSERT_EQUAL(expectedResult, testling.serialize(roster)); + } + + void testSerialize_WithEmptyVersion() { + RosterSerializer testling; + boost::shared_ptr<RosterPayload> roster(new RosterPayload()); + roster->setVersion(""); + + std::string expectedResult = "<query ver=\"\" xmlns=\"jabber:iq:roster\"/>"; + + CPPUNIT_ASSERT_EQUAL(expectedResult, testling.serialize(roster)); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(RosterSerializerTest); diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/SearchPayloadSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/SearchPayloadSerializerTest.cpp index e8328b8..d0dcbef 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/SearchPayloadSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/SearchPayloadSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/SearchPayloadSerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelSerializerTest.cpp index 03bad89..0de509d 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp index a7bf1b9..c060e41 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/SoftwareVersionSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/SoftwareVersionSerializerTest.cpp index 6fac094..ad1e9b4 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/SoftwareVersionSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/SoftwareVersionSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/StatusSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/StatusSerializerTest.cpp index c0b1dc2..af90a0a 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/StatusSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/StatusSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/StatusSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/StatusSerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/StatusShowSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/StatusShowSerializerTest.cpp index 2fee152..898c835 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/StatusShowSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/StatusShowSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/StorageSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/StorageSerializerTest.cpp index 01899a9..b963a9c 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/StorageSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/StorageSerializerTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.h" -#include "Swiften/Elements/Storage.h" +#include <Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.h> +#include <Swiften/Elements/Storage.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/StreamInitiationSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/StreamInitiationSerializerTest.cpp index d05fdba..7b96298 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/StreamInitiationSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/StreamInitiationSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp index 8a9a615..3ac1d77 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/VCardSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/VCardSerializer.h> using namespace Swift; @@ -29,7 +29,7 @@ class VCardSerializerTest : public CppUnit::TestFixture vcard->setFamilyName("Wonderland"); vcard->setSuffix("PhD"); vcard->setNickname("DreamGirl"); - vcard->setPhoto("abcdef"); + vcard->setPhoto(createByteArray("abcdef")); vcard->setPhotoType("image/png"); vcard->addUnknownContent("<BDAY>1234</BDAY><MAILER>mutt</MAILER>"); diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/VCardUpdateSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/VCardUpdateSerializerTest.cpp index 6f37d61..613b465 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/VCardUpdateSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/VCardUpdateSerializerTest.cpp @@ -7,7 +7,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.h> using namespace Swift; diff --git a/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp b/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp index 79e543e..17a6b49 100644 --- a/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp @@ -4,15 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/VCardSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/VCardSerializer.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" -#include "Swiften/Serializer/XML/XMLRawTextNode.h" -#include "Swiften/StringCodecs/Base64.h" -#include "Swiften/Base/foreach.h" +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/StringCodecs/Base64.h> +#include <Swiften/Base/foreach.h> namespace Swift { @@ -87,14 +87,14 @@ std::string VCardSerializer::serializePayload(boost::shared_ptr<VCard> vcard) c nickElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getNickname()))); queryElement.addNode(nickElement); } - if (!vcard->getPhoto().isEmpty() || !vcard->getPhotoType().empty()) { + if (!vcard->getPhoto().empty() || !vcard->getPhotoType().empty()) { XMLElement::ref photoElement(new XMLElement("PHOTO")); if (!vcard->getPhotoType().empty()) { XMLElement::ref typeElement(new XMLElement("TYPE")); typeElement->addNode(XMLTextNode::ref(new XMLTextNode(vcard->getPhotoType()))); photoElement->addNode(typeElement); } - if (!vcard->getPhoto().isEmpty()) { + if (!vcard->getPhoto().empty()) { XMLElement::ref binvalElement(new XMLElement("BINVAL")); binvalElement->addNode(XMLTextNode::ref(new XMLTextNode(Base64::encode(vcard->getPhoto())))); photoElement->addNode(binvalElement); diff --git a/Swiften/Serializer/PayloadSerializers/VCardSerializer.h b/Swiften/Serializer/PayloadSerializers/VCardSerializer.h index 7b9a8a9..c73ff18 100644 --- a/Swiften/Serializer/PayloadSerializers/VCardSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/VCardSerializer.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/VCard.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/VCard.h> namespace Swift { class VCardSerializer : public GenericPayloadSerializer<VCard> { diff --git a/Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.cpp b/Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.cpp index e315bc3..c06262f 100644 --- a/Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.h" +#include <Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> namespace Swift { diff --git a/Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.h b/Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.h index 46ca154..68084f0 100644 --- a/Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.h +++ b/Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Serializer/GenericPayloadSerializer.h" -#include "Swiften/Elements/VCardUpdate.h" +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/VCardUpdate.h> namespace Swift { class VCardUpdateSerializer : public GenericPayloadSerializer<VCardUpdate> { diff --git a/Swiften/Serializer/PresenceSerializer.cpp b/Swiften/Serializer/PresenceSerializer.cpp index 0de6493..20eda4b 100644 --- a/Swiften/Serializer/PresenceSerializer.cpp +++ b/Swiften/Serializer/PresenceSerializer.cpp @@ -4,10 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/PresenceSerializer.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Serializer/PresenceSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> -#include "boost/shared_ptr.hpp" +#include <boost/shared_ptr.hpp> namespace Swift { diff --git a/Swiften/Serializer/PresenceSerializer.h b/Swiften/Serializer/PresenceSerializer.h index 3cb9aab..e5d9f30 100644 --- a/Swiften/Serializer/PresenceSerializer.h +++ b/Swiften/Serializer/PresenceSerializer.h @@ -4,13 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_PresenceSerializer_H -#define SWIFTEN_PresenceSerializer_H +#pragma once -#include <cassert> - -#include "Swiften/Serializer/GenericStanzaSerializer.h" -#include "Swiften/Elements/Presence.h" +#include <Swiften/Serializer/GenericStanzaSerializer.h> +#include <Swiften/Elements/Presence.h> namespace Swift { class PresenceSerializer : public GenericStanzaSerializer<Presence> { @@ -23,5 +20,3 @@ namespace Swift { XMLElement& element) const; }; } - -#endif diff --git a/Swiften/Serializer/StanzaAckRequestSerializer.h b/Swiften/Serializer/StanzaAckRequestSerializer.h index b03a2c2..fff2a83 100644 --- a/Swiften/Serializer/StanzaAckRequestSerializer.h +++ b/Swiften/Serializer/StanzaAckRequestSerializer.h @@ -8,9 +8,9 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/StanzaAckRequest.h" -#include "Swiften/Serializer/GenericElementSerializer.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Elements/StanzaAckRequest.h> +#include <Swiften/Serializer/GenericElementSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { class StanzaAckRequestSerializer : public GenericElementSerializer<StanzaAckRequest> { @@ -18,8 +18,8 @@ namespace Swift { StanzaAckRequestSerializer() : GenericElementSerializer<StanzaAckRequest>() { } - virtual std::string serialize(boost::shared_ptr<Element>) const { - return XMLElement("r", "urn:xmpp:sm:2").serialize(); + virtual SafeByteArray serialize(boost::shared_ptr<Element>) const { + return createSafeByteArray(XMLElement("r", "urn:xmpp:sm:2").serialize()); } }; } diff --git a/Swiften/Serializer/StanzaAckSerializer.h b/Swiften/Serializer/StanzaAckSerializer.h index 984509f..ea1e8ad 100644 --- a/Swiften/Serializer/StanzaAckSerializer.h +++ b/Swiften/Serializer/StanzaAckSerializer.h @@ -9,9 +9,9 @@ #include <boost/shared_ptr.hpp> #include <boost/lexical_cast.hpp> -#include "Swiften/Elements/StanzaAck.h" -#include "Swiften/Serializer/GenericElementSerializer.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Elements/StanzaAck.h> +#include <Swiften/Serializer/GenericElementSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { class StanzaAckSerializer : public GenericElementSerializer<StanzaAck> { @@ -19,12 +19,12 @@ namespace Swift { StanzaAckSerializer() : GenericElementSerializer<StanzaAck>() { } - virtual std::string serialize(boost::shared_ptr<Element> element) const { + virtual SafeByteArray serialize(boost::shared_ptr<Element> element) const { StanzaAck::ref stanzaAck(boost::dynamic_pointer_cast<StanzaAck>(element)); assert(stanzaAck->isValid()); XMLElement result("a", "urn:xmpp:sm:2"); result.setAttribute("h", std::string(boost::lexical_cast<std::string>(stanzaAck->getHandledStanzasCount()))); - return result.serialize(); + return createSafeByteArray(result.serialize()); } }; } diff --git a/Swiften/Serializer/StanzaSerializer.cpp b/Swiften/Serializer/StanzaSerializer.cpp index cfc9a43..9a4fd2c 100644 --- a/Swiften/Serializer/StanzaSerializer.cpp +++ b/Swiften/Serializer/StanzaSerializer.cpp @@ -4,24 +4,25 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/StanzaSerializer.h" +#include <Swiften/Serializer/StanzaSerializer.h> #include <sstream> #include <typeinfo> #include <iostream> -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLRawTextNode.h" -#include "Swiften/Serializer/PayloadSerializer.h" -#include "Swiften/Serializer/PayloadSerializerCollection.h" -#include "Swiften/Elements/Stanza.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/PayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializerCollection.h> +#include <Swiften/Elements/Stanza.h> namespace Swift { StanzaSerializer::StanzaSerializer(const std::string& tag, PayloadSerializerCollection* payloadSerializers) : tag_(tag), payloadSerializers_(payloadSerializers) { } -std::string StanzaSerializer::serialize(boost::shared_ptr<Element> element) const { +SafeByteArray StanzaSerializer::serialize(boost::shared_ptr<Element> element) const { boost::shared_ptr<Stanza> stanza(boost::dynamic_pointer_cast<Stanza>(element)); XMLElement stanzaElement(tag_); @@ -50,7 +51,7 @@ std::string StanzaSerializer::serialize(boost::shared_ptr<Element> element) cons stanzaElement.addNode(boost::shared_ptr<XMLNode>(new XMLRawTextNode(serializedPayloads))); } - return stanzaElement.serialize(); + return createSafeByteArray(stanzaElement.serialize()); } } diff --git a/Swiften/Serializer/StanzaSerializer.h b/Swiften/Serializer/StanzaSerializer.h index 505d320..db18aa2 100644 --- a/Swiften/Serializer/StanzaSerializer.h +++ b/Swiften/Serializer/StanzaSerializer.h @@ -4,11 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_STANZASERIALIZER_H -#define SWIFTEN_STANZASERIALIZER_H +#pragma once -#include "Swiften/Elements/Stanza.h" -#include "Swiften/Serializer/ElementSerializer.h" +#include <Swiften/Elements/Stanza.h> +#include <Swiften/Serializer/ElementSerializer.h> #include <string> namespace Swift { @@ -19,7 +18,7 @@ namespace Swift { public: StanzaSerializer(const std::string& tag, PayloadSerializerCollection* payloadSerializers); - virtual std::string serialize(boost::shared_ptr<Element>) const; + virtual SafeByteArray serialize(boost::shared_ptr<Element>) const; virtual void setStanzaSpecificAttributes(boost::shared_ptr<Element>, XMLElement&) const = 0; private: @@ -27,5 +26,3 @@ namespace Swift { PayloadSerializerCollection* payloadSerializers_; }; } - -#endif diff --git a/Swiften/Serializer/StartTLSFailureSerializer.h b/Swiften/Serializer/StartTLSFailureSerializer.h index 548a24c..779be92 100644 --- a/Swiften/Serializer/StartTLSFailureSerializer.h +++ b/Swiften/Serializer/StartTLSFailureSerializer.h @@ -4,14 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StartTLSFailureSerializer_H -#define SWIFTEN_StartTLSFailureSerializer_H +#pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/StartTLSFailure.h" -#include "Swiften/Serializer/GenericElementSerializer.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Elements/StartTLSFailure.h> +#include <Swiften/Serializer/GenericElementSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { class StartTLSFailureSerializer : public GenericElementSerializer<StartTLSFailure> { @@ -19,10 +18,8 @@ namespace Swift { StartTLSFailureSerializer() : GenericElementSerializer<StartTLSFailure>() { } - virtual std::string serialize(boost::shared_ptr<Element>) const { - return XMLElement("failure", "urn:ietf:params:xml:ns:xmpp-tls").serialize(); + virtual SafeByteArray serialize(boost::shared_ptr<Element>) const { + return createSafeByteArray(XMLElement("failure", "urn:ietf:params:xml:ns:xmpp-tls").serialize()); } }; } - -#endif diff --git a/Swiften/Serializer/StartTLSRequestSerializer.h b/Swiften/Serializer/StartTLSRequestSerializer.h index 2e9ecfa..df914ce 100644 --- a/Swiften/Serializer/StartTLSRequestSerializer.h +++ b/Swiften/Serializer/StartTLSRequestSerializer.h @@ -4,14 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StartTLSRequestSerializer_H -#define SWIFTEN_StartTLSRequestSerializer_H +#pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/StartTLSRequest.h" -#include "Swiften/Serializer/GenericElementSerializer.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Elements/StartTLSRequest.h> +#include <Swiften/Serializer/GenericElementSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { class StartTLSRequestSerializer : public GenericElementSerializer<StartTLSRequest> { @@ -19,10 +18,8 @@ namespace Swift { StartTLSRequestSerializer() : GenericElementSerializer<StartTLSRequest>() { } - virtual std::string serialize(boost::shared_ptr<Element>) const { - return XMLElement("starttls", "urn:ietf:params:xml:ns:xmpp-tls").serialize(); + virtual SafeByteArray serialize(boost::shared_ptr<Element>) const { + return createSafeByteArray(XMLElement("starttls", "urn:ietf:params:xml:ns:xmpp-tls").serialize()); } }; } - -#endif diff --git a/Swiften/Serializer/StreamErrorSerializer.cpp b/Swiften/Serializer/StreamErrorSerializer.cpp index 11f8a30..b3d62a0 100644 --- a/Swiften/Serializer/StreamErrorSerializer.cpp +++ b/Swiften/Serializer/StreamErrorSerializer.cpp @@ -15,7 +15,7 @@ namespace Swift { StreamErrorSerializer::StreamErrorSerializer() : GenericElementSerializer<StreamError>() { } -std::string StreamErrorSerializer::serialize(boost::shared_ptr<Element> element) const { +SafeByteArray StreamErrorSerializer::serialize(boost::shared_ptr<Element> element) const { StreamError::ref error = boost::dynamic_pointer_cast<StreamError>(element); XMLElement errorElement("error", "http://etherx.jabber.org/streams"); @@ -53,7 +53,7 @@ std::string StreamErrorSerializer::serialize(boost::shared_ptr<Element> element) errorElement.addNode(boost::make_shared<XMLElement>("text", "urn:ietf:params:xml:ns:xmpp-streams", error->getText())); } - return errorElement.serialize(); + return createSafeByteArray(errorElement.serialize()); } } diff --git a/Swiften/Serializer/StreamErrorSerializer.h b/Swiften/Serializer/StreamErrorSerializer.h index 9d4f60c..bdaa831 100644 --- a/Swiften/Serializer/StreamErrorSerializer.h +++ b/Swiften/Serializer/StreamErrorSerializer.h @@ -14,6 +14,6 @@ namespace Swift { public: StreamErrorSerializer(); - virtual std::string serialize(boost::shared_ptr<Element> error) const; + virtual SafeByteArray serialize(boost::shared_ptr<Element> error) const; }; } diff --git a/Swiften/Serializer/StreamFeaturesSerializer.cpp b/Swiften/Serializer/StreamFeaturesSerializer.cpp index 915433c..fb7bb8c 100644 --- a/Swiften/Serializer/StreamFeaturesSerializer.cpp +++ b/Swiften/Serializer/StreamFeaturesSerializer.cpp @@ -4,18 +4,20 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/StreamFeaturesSerializer.h" +#include <Swiften/Serializer/StreamFeaturesSerializer.h> -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" -#include "Swiften/Base/foreach.h" +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> +#include <Swiften/Base/foreach.h> namespace Swift { StreamFeaturesSerializer::StreamFeaturesSerializer() { } -std::string StreamFeaturesSerializer::serialize(boost::shared_ptr<Element> element) const { +SafeByteArray StreamFeaturesSerializer::serialize(boost::shared_ptr<Element> element) const { boost::shared_ptr<StreamFeatures> streamFeatures(boost::dynamic_pointer_cast<StreamFeatures>(element)); XMLElement streamFeaturesElement("stream:features"); @@ -49,7 +51,10 @@ std::string StreamFeaturesSerializer::serialize(boost::shared_ptr<Element> eleme if (streamFeatures->hasStreamManagement()) { streamFeaturesElement.addNode(boost::shared_ptr<XMLElement>(new XMLElement("sm", "urn:xmpp:sm:2"))); } - return streamFeaturesElement.serialize(); + if (streamFeatures->hasRosterVersioning()) { + streamFeaturesElement.addNode(boost::make_shared<XMLElement>("ver", "urn:xmpp:features:rosterver")); + } + return createSafeByteArray(streamFeaturesElement.serialize()); } } diff --git a/Swiften/Serializer/StreamFeaturesSerializer.h b/Swiften/Serializer/StreamFeaturesSerializer.h index 3b475e0..5ea3ab1 100644 --- a/Swiften/Serializer/StreamFeaturesSerializer.h +++ b/Swiften/Serializer/StreamFeaturesSerializer.h @@ -4,21 +4,18 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_StreamFeaturesSerializer_H -#define SWIFTEN_StreamFeaturesSerializer_H +#pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/StreamFeatures.h" -#include "Swiften/Serializer/GenericElementSerializer.h" +#include <Swiften/Elements/StreamFeatures.h> +#include <Swiften/Serializer/GenericElementSerializer.h> namespace Swift { class StreamFeaturesSerializer : public GenericElementSerializer<StreamFeatures> { public: StreamFeaturesSerializer(); - virtual std::string serialize(boost::shared_ptr<Element> element) const; + virtual SafeByteArray serialize(boost::shared_ptr<Element> element) const; }; } - -#endif diff --git a/Swiften/Serializer/StreamManagementEnabledSerializer.cpp b/Swiften/Serializer/StreamManagementEnabledSerializer.cpp new file mode 100644 index 0000000..b559721 --- /dev/null +++ b/Swiften/Serializer/StreamManagementEnabledSerializer.cpp @@ -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. + */ + +#include <Swiften/Serializer/StreamManagementEnabledSerializer.h> + +#include <boost/shared_ptr.hpp> + +#include <Swiften/Elements/StreamManagementEnabled.h> +#include <Swiften/Serializer/XML/XMLElement.h> + +using namespace Swift; + +StreamManagementEnabledSerializer::StreamManagementEnabledSerializer() : GenericElementSerializer<StreamManagementEnabled>() { +} + +SafeByteArray StreamManagementEnabledSerializer::serialize(boost::shared_ptr<Element> el) const { + boost::shared_ptr<StreamManagementEnabled> e(boost::dynamic_pointer_cast<StreamManagementEnabled>(el)); + XMLElement element("enabled", "urn:xmpp:sm:2"); + if (!e->getResumeID().empty()) { + element.setAttribute("id", e->getResumeID()); + } + if (e->getResumeSupported()) { + element.setAttribute("resume", "true"); + } + return createSafeByteArray(element.serialize()); +} diff --git a/Swiften/Serializer/StreamManagementEnabledSerializer.h b/Swiften/Serializer/StreamManagementEnabledSerializer.h index fc7bd86..5f28a2b 100644 --- a/Swiften/Serializer/StreamManagementEnabledSerializer.h +++ b/Swiften/Serializer/StreamManagementEnabledSerializer.h @@ -8,18 +8,14 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/StreamManagementEnabled.h" -#include "Swiften/Serializer/GenericElementSerializer.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Elements/StreamManagementEnabled.h> +#include <Swiften/Serializer/GenericElementSerializer.h> namespace Swift { class StreamManagementEnabledSerializer : public GenericElementSerializer<StreamManagementEnabled> { public: - StreamManagementEnabledSerializer() : GenericElementSerializer<StreamManagementEnabled>() { - } + StreamManagementEnabledSerializer(); - virtual std::string serialize(boost::shared_ptr<Element>) const { - return XMLElement("enabled", "urn:xmpp:sm:2").serialize(); - } + virtual SafeByteArray serialize(boost::shared_ptr<Element>) const; }; } diff --git a/Swiften/Serializer/StreamManagementFailedSerializer.h b/Swiften/Serializer/StreamManagementFailedSerializer.h index b22ed0d..f3dcce0 100644 --- a/Swiften/Serializer/StreamManagementFailedSerializer.h +++ b/Swiften/Serializer/StreamManagementFailedSerializer.h @@ -8,9 +8,9 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/StreamManagementFailed.h" -#include "Swiften/Serializer/GenericElementSerializer.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Elements/StreamManagementFailed.h> +#include <Swiften/Serializer/GenericElementSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { class StreamManagementFailedSerializer : public GenericElementSerializer<StreamManagementFailed> { @@ -18,8 +18,8 @@ namespace Swift { StreamManagementFailedSerializer() : GenericElementSerializer<StreamManagementFailed>() { } - virtual std::string serialize(boost::shared_ptr<Element>) const { - return XMLElement("failed", "urn:xmpp:sm:2").serialize(); + virtual SafeByteArray serialize(boost::shared_ptr<Element>) const { + return createSafeByteArray(XMLElement("failed", "urn:xmpp:sm:2").serialize()); } }; } diff --git a/Swiften/Serializer/StreamResumeSerializer.cpp b/Swiften/Serializer/StreamResumeSerializer.cpp new file mode 100644 index 0000000..e9e520d --- /dev/null +++ b/Swiften/Serializer/StreamResumeSerializer.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Serializer/StreamResumeSerializer.h> + +#include <boost/shared_ptr.hpp> +#include <boost/lexical_cast.hpp> + +#include <Swiften/Elements/StreamResume.h> +#include <Swiften/Serializer/XML/XMLElement.h> + +using namespace Swift; + +StreamResumeSerializer::StreamResumeSerializer() : GenericElementSerializer<StreamResume>() { +} + +SafeByteArray StreamResumeSerializer::serialize(boost::shared_ptr<Element> el) const { + boost::shared_ptr<StreamResume> e(boost::dynamic_pointer_cast<StreamResume>(el)); + XMLElement element("resume", "urn:xmpp:sm:2"); + element.setAttribute("previd", e->getResumeID()); + if (e->getHandledStanzasCount()) { + element.setAttribute("h", boost::lexical_cast<std::string>(e->getHandledStanzasCount())); + } + return createSafeByteArray(element.serialize()); +} diff --git a/Swiften/Serializer/StreamResumeSerializer.h b/Swiften/Serializer/StreamResumeSerializer.h new file mode 100644 index 0000000..501d8b6 --- /dev/null +++ b/Swiften/Serializer/StreamResumeSerializer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2011 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/StreamResume.h> +#include <Swiften/Serializer/GenericElementSerializer.h> + +namespace Swift { + class StreamResumeSerializer : public GenericElementSerializer<StreamResume> { + public: + StreamResumeSerializer(); + + virtual SafeByteArray serialize(boost::shared_ptr<Element>) const; + }; +} diff --git a/Swiften/Serializer/StreamResumedSerializer.cpp b/Swiften/Serializer/StreamResumedSerializer.cpp new file mode 100644 index 0000000..7ae82d1 --- /dev/null +++ b/Swiften/Serializer/StreamResumedSerializer.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Serializer/StreamResumedSerializer.h> + +#include <boost/shared_ptr.hpp> +#include <boost/lexical_cast.hpp> + +#include <Swiften/Elements/StreamResumed.h> +#include <Swiften/Serializer/XML/XMLElement.h> + +using namespace Swift; + +StreamResumedSerializer::StreamResumedSerializer() : GenericElementSerializer<StreamResumed>() { +} + +SafeByteArray StreamResumedSerializer::serialize(boost::shared_ptr<Element> el) const { + boost::shared_ptr<StreamResumed> e(boost::dynamic_pointer_cast<StreamResumed>(el)); + XMLElement element("resumed", "urn:xmpp:sm:2"); + element.setAttribute("previd", e->getResumeID()); + if (e->getHandledStanzasCount()) { + element.setAttribute("h", boost::lexical_cast<std::string>(e->getHandledStanzasCount())); + } + return createSafeByteArray(element.serialize()); +} diff --git a/Swiften/Serializer/StreamResumedSerializer.h b/Swiften/Serializer/StreamResumedSerializer.h new file mode 100644 index 0000000..7828694 --- /dev/null +++ b/Swiften/Serializer/StreamResumedSerializer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2011 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/StreamResumed.h> +#include <Swiften/Serializer/GenericElementSerializer.h> + +namespace Swift { + class StreamResumedSerializer : public GenericElementSerializer<StreamResumed> { + public: + StreamResumedSerializer(); + + virtual SafeByteArray serialize(boost::shared_ptr<Element>) const; + }; +} diff --git a/Swiften/Serializer/TLSProceedSerializer.h b/Swiften/Serializer/TLSProceedSerializer.h index 1b08c23..21a8420 100644 --- a/Swiften/Serializer/TLSProceedSerializer.h +++ b/Swiften/Serializer/TLSProceedSerializer.h @@ -4,14 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_TLSProceedSerializer_H -#define SWIFTEN_TLSProceedSerializer_H +#pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/TLSProceed.h" -#include "Swiften/Serializer/GenericElementSerializer.h" -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Elements/TLSProceed.h> +#include <Swiften/Serializer/GenericElementSerializer.h> +#include <Swiften/Serializer/XML/XMLElement.h> namespace Swift { class TLSProceedSerializer : public GenericElementSerializer<TLSProceed> { @@ -19,10 +18,8 @@ namespace Swift { TLSProceedSerializer() : GenericElementSerializer<TLSProceed>() { } - virtual std::string serialize(boost::shared_ptr<Element>) const { - return XMLElement("proceed", "urn:ietf:params:xml:ns:xmpp-tls").serialize(); + virtual SafeByteArray serialize(boost::shared_ptr<Element>) const { + return createSafeByteArray(XMLElement("proceed", "urn:ietf:params:xml:ns:xmpp-tls").serialize()); } }; } - -#endif diff --git a/Swiften/Serializer/UnitTest/AuthChallengeSerializerTest.cpp b/Swiften/Serializer/UnitTest/AuthChallengeSerializerTest.cpp index af857ef..5fb0a4e 100644 --- a/Swiften/Serializer/UnitTest/AuthChallengeSerializerTest.cpp +++ b/Swiften/Serializer/UnitTest/AuthChallengeSerializerTest.cpp @@ -3,12 +3,14 @@ * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/AuthChallengeSerializer.h" -#include "Swiften/Elements/AuthChallenge.h" +#include <Swiften/Serializer/AuthChallengeSerializer.h> +#include <Swiften/Elements/AuthChallenge.h> +#include <Swiften/Base/ByteArray.h> using namespace Swift; @@ -23,9 +25,9 @@ class AuthChallengeSerializerTest : public CppUnit::TestFixture { void testSerialize() { AuthChallengeSerializer testling; boost::shared_ptr<AuthChallenge> authChallenge(new AuthChallenge()); - authChallenge->setValue("foo"); + authChallenge->setValue(createByteArray("foo")); - CPPUNIT_ASSERT_EQUAL(std::string( + CPPUNIT_ASSERT_EQUAL(createSafeByteArray( "<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" "Zm9v" "</challenge>"), testling.serialize(authChallenge)); @@ -35,7 +37,7 @@ class AuthChallengeSerializerTest : public CppUnit::TestFixture { AuthChallengeSerializer testling; boost::shared_ptr<AuthChallenge> authChallenge(new AuthChallenge()); - CPPUNIT_ASSERT_EQUAL(std::string( + CPPUNIT_ASSERT_EQUAL(createSafeByteArray( "<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" "</challenge>"), testling.serialize(authChallenge)); } @@ -43,9 +45,9 @@ class AuthChallengeSerializerTest : public CppUnit::TestFixture { void testSerialize_EmptyMessage() { AuthChallengeSerializer testling; boost::shared_ptr<AuthChallenge> authChallenge(new AuthChallenge()); - authChallenge->setValue(ByteArray()); + authChallenge->setValue(std::vector<unsigned char>()); - CPPUNIT_ASSERT_EQUAL(std::string( + CPPUNIT_ASSERT_EQUAL(createSafeByteArray( "<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" "=" "</challenge>"), testling.serialize(authChallenge)); diff --git a/Swiften/Serializer/UnitTest/AuthRequestSerializerTest.cpp b/Swiften/Serializer/UnitTest/AuthRequestSerializerTest.cpp index 9f9f2fa..db36de7 100644 --- a/Swiften/Serializer/UnitTest/AuthRequestSerializerTest.cpp +++ b/Swiften/Serializer/UnitTest/AuthRequestSerializerTest.cpp @@ -3,12 +3,14 @@ * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/AuthRequestSerializer.h" -#include "Swiften/Elements/AuthRequest.h" +#include <Swiften/Serializer/AuthRequestSerializer.h> +#include <Swiften/Elements/AuthRequest.h> +#include <Swiften/Base/ByteArray.h> using namespace Swift; @@ -23,9 +25,9 @@ class AuthRequestSerializerTest : public CppUnit::TestFixture { void testSerialize() { AuthRequestSerializer testling; boost::shared_ptr<AuthRequest> authRequest(new AuthRequest("PLAIN")); - authRequest->setMessage("foo"); + authRequest->setMessage(createSafeByteArray("foo")); - CPPUNIT_ASSERT_EQUAL(std::string( + CPPUNIT_ASSERT_EQUAL(createSafeByteArray( "<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"PLAIN\">" "Zm9v" "</auth>"), testling.serialize(authRequest)); @@ -35,7 +37,7 @@ class AuthRequestSerializerTest : public CppUnit::TestFixture { AuthRequestSerializer testling; boost::shared_ptr<AuthRequest> authRequest(new AuthRequest("PLAIN")); - CPPUNIT_ASSERT_EQUAL(std::string( + CPPUNIT_ASSERT_EQUAL(createSafeByteArray( "<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"PLAIN\">" "</auth>"), testling.serialize(authRequest)); } @@ -43,9 +45,9 @@ class AuthRequestSerializerTest : public CppUnit::TestFixture { void testSerialize_EmptyMessage() { AuthRequestSerializer testling; boost::shared_ptr<AuthRequest> authRequest(new AuthRequest("PLAIN")); - authRequest->setMessage(ByteArray()); + authRequest->setMessage(SafeByteArray()); - CPPUNIT_ASSERT_EQUAL(std::string( + CPPUNIT_ASSERT_EQUAL(createSafeByteArray( "<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"PLAIN\">" "=" "</auth>"), testling.serialize(authRequest)); diff --git a/Swiften/Serializer/UnitTest/AuthResponseSerializerTest.cpp b/Swiften/Serializer/UnitTest/AuthResponseSerializerTest.cpp index c93810c..4b846d7 100644 --- a/Swiften/Serializer/UnitTest/AuthResponseSerializerTest.cpp +++ b/Swiften/Serializer/UnitTest/AuthResponseSerializerTest.cpp @@ -3,12 +3,14 @@ * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/AuthResponseSerializer.h" -#include "Swiften/Elements/AuthResponse.h" +#include <Swiften/Serializer/AuthResponseSerializer.h> +#include <Swiften/Elements/AuthResponse.h> +#include <Swiften/Base/ByteArray.h> using namespace Swift; @@ -23,9 +25,9 @@ class AuthResponseSerializerTest : public CppUnit::TestFixture { void testSerialize() { AuthResponseSerializer testling; boost::shared_ptr<AuthResponse> authResponse(new AuthResponse()); - authResponse->setValue("foo"); + authResponse->setValue(createSafeByteArray("foo")); - CPPUNIT_ASSERT_EQUAL(std::string( + CPPUNIT_ASSERT_EQUAL(createSafeByteArray( "<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" "Zm9v" "</response>"), testling.serialize(authResponse)); @@ -35,7 +37,7 @@ class AuthResponseSerializerTest : public CppUnit::TestFixture { AuthResponseSerializer testling; boost::shared_ptr<AuthResponse> authResponse(new AuthResponse()); - CPPUNIT_ASSERT_EQUAL(std::string( + CPPUNIT_ASSERT_EQUAL(createSafeByteArray( "<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" "</response>"), testling.serialize(authResponse)); } @@ -43,9 +45,9 @@ class AuthResponseSerializerTest : public CppUnit::TestFixture { void testSerialize_EmptyMessage() { AuthResponseSerializer testling; boost::shared_ptr<AuthResponse> authResponse(new AuthResponse()); - authResponse->setValue(ByteArray()); + authResponse->setValue(SafeByteArray()); - CPPUNIT_ASSERT_EQUAL(std::string( + CPPUNIT_ASSERT_EQUAL(createSafeByteArray( "<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" "=" "</response>"), testling.serialize(authResponse)); diff --git a/Swiften/Serializer/UnitTest/AuthSuccessSerializerTest.cpp b/Swiften/Serializer/UnitTest/AuthSuccessSerializerTest.cpp index 385c1e5..86e01f5 100644 --- a/Swiften/Serializer/UnitTest/AuthSuccessSerializerTest.cpp +++ b/Swiften/Serializer/UnitTest/AuthSuccessSerializerTest.cpp @@ -3,12 +3,14 @@ * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/AuthSuccessSerializer.h" -#include "Swiften/Elements/AuthSuccess.h" +#include <Swiften/Serializer/AuthSuccessSerializer.h> +#include <Swiften/Elements/AuthSuccess.h> +#include <Swiften/Base/ByteArray.h> using namespace Swift; @@ -23,9 +25,9 @@ class AuthSuccessSerializerTest : public CppUnit::TestFixture { void testSerialize() { AuthSuccessSerializer testling; boost::shared_ptr<AuthSuccess> authSuccess(new AuthSuccess()); - authSuccess->setValue("foo"); + authSuccess->setValue(createByteArray("foo")); - CPPUNIT_ASSERT_EQUAL(std::string( + CPPUNIT_ASSERT_EQUAL(createSafeByteArray( "<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" "Zm9v" "</success>"), testling.serialize(authSuccess)); @@ -35,7 +37,7 @@ class AuthSuccessSerializerTest : public CppUnit::TestFixture { AuthSuccessSerializer testling; boost::shared_ptr<AuthSuccess> authSuccess(new AuthSuccess()); - CPPUNIT_ASSERT_EQUAL(std::string( + CPPUNIT_ASSERT_EQUAL(createSafeByteArray( "<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" "</success>"), testling.serialize(authSuccess)); } @@ -43,9 +45,9 @@ class AuthSuccessSerializerTest : public CppUnit::TestFixture { void testSerialize_EmptyMessage() { AuthSuccessSerializer testling; boost::shared_ptr<AuthSuccess> authSuccess(new AuthSuccess()); - authSuccess->setValue(ByteArray()); + authSuccess->setValue(std::vector<unsigned char>()); - CPPUNIT_ASSERT_EQUAL(std::string( + CPPUNIT_ASSERT_EQUAL(createSafeByteArray( "<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" "=" "</success>"), testling.serialize(authSuccess)); diff --git a/Swiften/Serializer/UnitTest/StreamFeaturesSerializerTest.cpp b/Swiften/Serializer/UnitTest/StreamFeaturesSerializerTest.cpp index 65caa81..0abb32c 100644 --- a/Swiften/Serializer/UnitTest/StreamFeaturesSerializerTest.cpp +++ b/Swiften/Serializer/UnitTest/StreamFeaturesSerializerTest.cpp @@ -3,12 +3,14 @@ * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/StreamFeaturesSerializer.h" -#include "Swiften/Elements/StreamFeatures.h" +#include <Swiften/Serializer/StreamFeaturesSerializer.h> +#include <Swiften/Elements/StreamFeatures.h> + using namespace Swift; @@ -32,8 +34,9 @@ class StreamFeaturesSerializerTest : public CppUnit::TestFixture streamFeatures->setHasResourceBind(); streamFeatures->setHasSession(); streamFeatures->setHasStreamManagement(); + streamFeatures->setHasRosterVersioning(); - CPPUNIT_ASSERT_EQUAL(std::string( + CPPUNIT_ASSERT_EQUAL(createSafeByteArray( "<stream:features>" "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>" "<compression xmlns=\"http://jabber.org/features/compress\">" @@ -47,6 +50,7 @@ class StreamFeaturesSerializerTest : public CppUnit::TestFixture "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/>" "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/>" "<sm xmlns=\"urn:xmpp:sm:2\"/>" + "<ver xmlns=\"urn:xmpp:features:rosterver\"/>" "</stream:features>"), testling.serialize(streamFeatures)); } }; diff --git a/Swiften/Serializer/UnitTest/XMPPSerializerTest.cpp b/Swiften/Serializer/UnitTest/XMPPSerializerTest.cpp index 76c1b23..c0ab841 100644 --- a/Swiften/Serializer/UnitTest/XMPPSerializerTest.cpp +++ b/Swiften/Serializer/UnitTest/XMPPSerializerTest.cpp @@ -7,10 +7,10 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/XMPPSerializer.h" -#include "Swiften/Elements/AuthChallenge.h" -#include "Swiften/Serializer/PayloadSerializerCollection.h" -#include "Swiften/Elements/ProtocolHeader.h" +#include <Swiften/Serializer/XMPPSerializer.h> +#include <Swiften/Elements/AuthChallenge.h> +#include <Swiften/Serializer/PayloadSerializerCollection.h> +#include <Swiften/Elements/ProtocolHeader.h> using namespace Swift; @@ -31,7 +31,7 @@ class XMPPSerializerTest : public CppUnit::TestFixture { } void testSerializeHeader_Client() { - std::auto_ptr<XMPPSerializer> testling(createSerializer(ClientStreamType)); + boost::shared_ptr<XMPPSerializer> testling(createSerializer(ClientStreamType)); ProtocolHeader protocolHeader; protocolHeader.setFrom("bla@foo.com"); protocolHeader.setTo("foo.com"); @@ -42,7 +42,7 @@ class XMPPSerializerTest : public CppUnit::TestFixture { } void testSerializeHeader_Component() { - std::auto_ptr<XMPPSerializer> testling(createSerializer(ComponentStreamType)); + boost::shared_ptr<XMPPSerializer> testling(createSerializer(ComponentStreamType)); ProtocolHeader protocolHeader; protocolHeader.setFrom("bla@foo.com"); protocolHeader.setTo("foo.com"); @@ -53,7 +53,7 @@ class XMPPSerializerTest : public CppUnit::TestFixture { } void testSerializeHeader_Server() { - std::auto_ptr<XMPPSerializer> testling(createSerializer(ServerStreamType)); + boost::shared_ptr<XMPPSerializer> testling(createSerializer(ServerStreamType)); ProtocolHeader protocolHeader; protocolHeader.setFrom("bla@foo.com"); protocolHeader.setTo("foo.com"); diff --git a/Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp b/Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp index 8c68f97..897a4f4 100644 --- a/Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp +++ b/Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp @@ -7,8 +7,8 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Serializer/XML/XMLElement.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> using namespace Swift; diff --git a/Swiften/Serializer/XML/XMLElement.cpp b/Swiften/Serializer/XML/XMLElement.cpp index 6c90e0d..d39ec39 100644 --- a/Swiften/Serializer/XML/XMLElement.cpp +++ b/Swiften/Serializer/XML/XMLElement.cpp @@ -4,10 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/XML/XMLElement.h" +#include <Swiften/Serializer/XML/XMLElement.h> -#include "Swiften/Base/foreach.h" -#include "Swiften/Serializer/XML/XMLTextNode.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> namespace Swift { @@ -28,7 +28,7 @@ std::string XMLElement::serialize() { result += " " + p.first + "=\"" + p.second + "\""; } - if (childNodes_.size() > 0) { + if (!childNodes_.empty()) { result += ">"; foreach (boost::shared_ptr<XMLNode> node, childNodes_) { result += node->serialize(); diff --git a/Swiften/Serializer/XML/XMLElement.h b/Swiften/Serializer/XML/XMLElement.h index 65af7ae..6eacb82 100644 --- a/Swiften/Serializer/XML/XMLElement.h +++ b/Swiften/Serializer/XML/XMLElement.h @@ -12,7 +12,7 @@ #include <string> -#include "Swiften/Serializer/XML/XMLNode.h" +#include <Swiften/Serializer/XML/XMLNode.h> namespace Swift { class XMLElement : public XMLNode { diff --git a/Swiften/Serializer/XML/XMLNode.cpp b/Swiften/Serializer/XML/XMLNode.cpp index cd604f5..7eedeff 100644 --- a/Swiften/Serializer/XML/XMLNode.cpp +++ b/Swiften/Serializer/XML/XMLNode.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/XML/XMLNode.h" +#include <Swiften/Serializer/XML/XMLNode.h> namespace Swift { diff --git a/Swiften/Serializer/XML/XMLNode.h b/Swiften/Serializer/XML/XMLNode.h index 5261888..d222faf 100644 --- a/Swiften/Serializer/XML/XMLNode.h +++ b/Swiften/Serializer/XML/XMLNode.h @@ -4,8 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_XMLNode_H -#define SWIFTEN_XMLNode_H +#pragma once #include <string> @@ -17,5 +16,3 @@ namespace Swift { virtual std::string serialize() = 0; }; } - -#endif diff --git a/Swiften/Serializer/XML/XMLRawTextNode.h b/Swiften/Serializer/XML/XMLRawTextNode.h index 9fa8c40..9e222d5 100644 --- a/Swiften/Serializer/XML/XMLRawTextNode.h +++ b/Swiften/Serializer/XML/XMLRawTextNode.h @@ -4,10 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_XMLRawTextNode_H -#define SWIFTEN_XMLRawTextNode_H +#pragma once -#include "Swiften/Serializer/XML/XMLNode.h" +#include <Swiften/Serializer/XML/XMLNode.h> namespace Swift { class XMLRawTextNode : public XMLNode { @@ -23,5 +22,3 @@ namespace Swift { std::string text_; }; } - -#endif diff --git a/Swiften/Serializer/XML/XMLTextNode.h b/Swiften/Serializer/XML/XMLTextNode.h index 4d55f76..648854f 100644 --- a/Swiften/Serializer/XML/XMLTextNode.h +++ b/Swiften/Serializer/XML/XMLTextNode.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Serializer/XML/XMLNode.h" +#include <Swiften/Serializer/XML/XMLNode.h> #include <Swiften/Base/String.h> namespace Swift { diff --git a/Swiften/Serializer/XMPPSerializer.cpp b/Swiften/Serializer/XMPPSerializer.cpp index 06f3558..389f7cc 100644 --- a/Swiften/Serializer/XMPPSerializer.cpp +++ b/Swiften/Serializer/XMPPSerializer.cpp @@ -4,36 +4,38 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Serializer/XMPPSerializer.h" +#include <Swiften/Serializer/XMPPSerializer.h> #include <boost/bind.hpp> #include <boost/smart_ptr/make_shared.hpp> #include <iostream> #include <cassert> -#include "Swiften/Elements/ProtocolHeader.h" -#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" -#include "Swiften/Serializer/AuthSuccessSerializer.h" -#include "Swiften/Serializer/AuthChallengeSerializer.h" -#include "Swiften/Serializer/AuthResponseSerializer.h" -#include "Swiften/Serializer/EnableStreamManagementSerializer.h" -#include "Swiften/Serializer/StreamManagementEnabledSerializer.h" -#include "Swiften/Serializer/StreamManagementFailedSerializer.h" -#include "Swiften/Serializer/StanzaAckSerializer.h" -#include "Swiften/Serializer/StanzaAckRequestSerializer.h" -#include "Swiften/Serializer/StartTLSRequestSerializer.h" -#include "Swiften/Serializer/StartTLSFailureSerializer.h" -#include "Swiften/Serializer/TLSProceedSerializer.h" -#include "Swiften/Serializer/MessageSerializer.h" -#include "Swiften/Serializer/PresenceSerializer.h" -#include "Swiften/Serializer/IQSerializer.h" -#include "Swiften/Serializer/ComponentHandshakeSerializer.h" +#include <Swiften/Elements/ProtocolHeader.h> +#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> +#include <Swiften/Serializer/AuthSuccessSerializer.h> +#include <Swiften/Serializer/AuthChallengeSerializer.h> +#include <Swiften/Serializer/AuthResponseSerializer.h> +#include <Swiften/Serializer/EnableStreamManagementSerializer.h> +#include <Swiften/Serializer/StreamManagementEnabledSerializer.h> +#include <Swiften/Serializer/StreamResumeSerializer.h> +#include <Swiften/Serializer/StreamResumedSerializer.h> +#include <Swiften/Serializer/StreamManagementFailedSerializer.h> +#include <Swiften/Serializer/StanzaAckSerializer.h> +#include <Swiften/Serializer/StanzaAckRequestSerializer.h> +#include <Swiften/Serializer/StartTLSRequestSerializer.h> +#include <Swiften/Serializer/StartTLSFailureSerializer.h> +#include <Swiften/Serializer/TLSProceedSerializer.h> +#include <Swiften/Serializer/MessageSerializer.h> +#include <Swiften/Serializer/PresenceSerializer.h> +#include <Swiften/Serializer/IQSerializer.h> +#include <Swiften/Serializer/ComponentHandshakeSerializer.h> namespace Swift { @@ -56,6 +58,8 @@ XMPPSerializer::XMPPSerializer(PayloadSerializerCollection* payloadSerializers, 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<StreamResumeSerializer>()); + serializers_.push_back(boost::make_shared<StreamResumedSerializer>()); serializers_.push_back(boost::make_shared<StanzaAckSerializer>()); serializers_.push_back(boost::make_shared<StanzaAckRequestSerializer>()); serializers_.push_back(boost::make_shared<ComponentHandshakeSerializer>()); @@ -79,16 +83,14 @@ std::string XMPPSerializer::serializeHeader(const ProtocolHeader& header) const return result; } -std::string XMPPSerializer::serializeElement(boost::shared_ptr<Element> element) const { - std::vector< boost::shared_ptr<ElementSerializer> >::const_iterator i = std::find_if( - serializers_.begin(), serializers_.end(), - boost::bind(&ElementSerializer::canSerialize, _1, element)); +SafeByteArray XMPPSerializer::serializeElement(boost::shared_ptr<Element> element) const { + std::vector< boost::shared_ptr<ElementSerializer> >::const_iterator i = std::find_if(serializers_.begin(), serializers_.end(), boost::bind(&ElementSerializer::canSerialize, _1, element)); if (i != serializers_.end()) { return (*i)->serialize(element); } else { std::cerr << "Could not find serializer for " << typeid(*(element.get())).name() << std::endl; - return ""; + return createSafeByteArray(""); } } diff --git a/Swiften/Serializer/XMPPSerializer.h b/Swiften/Serializer/XMPPSerializer.h index 4f83857..8727f7a 100644 --- a/Swiften/Serializer/XMPPSerializer.h +++ b/Swiften/Serializer/XMPPSerializer.h @@ -9,10 +9,10 @@ #include <boost/shared_ptr.hpp> #include <vector> -#include "Swiften/Elements/Element.h" -#include "Swiften/Elements/StreamType.h" +#include <Swiften/Elements/Element.h> +#include <Swiften/Elements/StreamType.h> #include <string> -#include "Swiften/Serializer/ElementSerializer.h" +#include <Swiften/Serializer/ElementSerializer.h> namespace Swift { class PayloadSerializerCollection; @@ -24,7 +24,7 @@ namespace Swift { XMPPSerializer(PayloadSerializerCollection*, StreamType type); std::string serializeHeader(const ProtocolHeader&) const; - std::string serializeElement(boost::shared_ptr<Element> stanza) const; + SafeByteArray serializeElement(boost::shared_ptr<Element> stanza) const; std::string serializeFooter() const; private: diff --git a/Swiften/Session/BasicSessionStream.cpp b/Swiften/Session/BasicSessionStream.cpp index c783e01..d08be4f 100644 --- a/Swiften/Session/BasicSessionStream.cpp +++ b/Swiften/Session/BasicSessionStream.cpp @@ -4,18 +4,18 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Session/BasicSessionStream.h" +#include <Swiften/Session/BasicSessionStream.h> #include <boost/bind.hpp> -#include "Swiften/StreamStack/XMPPLayer.h" -#include "Swiften/StreamStack/StreamStack.h" -#include "Swiften/StreamStack/ConnectionLayer.h" -#include "Swiften/StreamStack/WhitespacePingLayer.h" -#include "Swiften/StreamStack/CompressionLayer.h" -#include "Swiften/StreamStack/TLSLayer.h" -#include "Swiften/TLS/TLSContextFactory.h" -#include "Swiften/TLS/TLSContext.h" +#include <Swiften/StreamStack/XMPPLayer.h> +#include <Swiften/StreamStack/StreamStack.h> +#include <Swiften/StreamStack/ConnectionLayer.h> +#include <Swiften/StreamStack/WhitespacePingLayer.h> +#include <Swiften/StreamStack/CompressionLayer.h> +#include <Swiften/StreamStack/TLSLayer.h> +#include <Swiften/TLS/TLSContextFactory.h> +#include <Swiften/TLS/TLSContext.h> namespace Swift { @@ -192,12 +192,12 @@ void BasicSessionStream::handleConnectionFinished(const boost::optional<Connecti } } -void BasicSessionStream::handleDataRead(const ByteArray& data) { - onDataRead(data.toString()); +void BasicSessionStream::handleDataRead(const SafeByteArray& data) { + onDataRead(data); } -void BasicSessionStream::handleDataWritten(const ByteArray& data) { - onDataWritten(data.toString()); +void BasicSessionStream::handleDataWritten(const SafeByteArray& data) { + onDataWritten(data); } }; diff --git a/Swiften/Session/BasicSessionStream.h b/Swiften/Session/BasicSessionStream.h index b3f7421..2a1ed8a 100644 --- a/Swiften/Session/BasicSessionStream.h +++ b/Swiften/Session/BasicSessionStream.h @@ -8,9 +8,10 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Network/Connection.h" -#include "Swiften/Session/SessionStream.h" -#include "Swiften/Elements/StreamType.h" +#include <Swiften/Base/SafeByteArray.h> +#include <Swiften/Network/Connection.h> +#include <Swiften/Session/SessionStream.h> +#include <Swiften/Elements/StreamType.h> namespace Swift { class TLSContextFactory; @@ -64,8 +65,8 @@ namespace Swift { void handleTLSError(); void handleStreamStartReceived(const ProtocolHeader&); void handleElementReceived(boost::shared_ptr<Element>); - void handleDataRead(const ByteArray& data); - void handleDataWritten(const ByteArray& data); + void handleDataRead(const SafeByteArray& data); + void handleDataWritten(const SafeByteArray& data); private: bool available; diff --git a/Swiften/Session/Session.cpp b/Swiften/Session/Session.cpp index 0c38f07..e8b8308 100644 --- a/Swiften/Session/Session.cpp +++ b/Swiften/Session/Session.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Session/Session.h" +#include <Swiften/Session/Session.h> #include <boost/bind.hpp> -#include "Swiften/StreamStack/XMPPLayer.h" -#include "Swiften/StreamStack/StreamStack.h" +#include <Swiften/StreamStack/XMPPLayer.h> +#include <Swiften/StreamStack/StreamStack.h> namespace Swift { diff --git a/Swiften/Session/Session.h b/Swiften/Session/Session.h index f8c8f0a..9e954c7 100644 --- a/Swiften/Session/Session.h +++ b/Swiften/Session/Session.h @@ -7,21 +7,21 @@ #pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/optional.hpp> #include <boost/enable_shared_from_this.hpp> -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/Element.h" -#include "Swiften/Network/Connection.h" -#include "Swiften/StreamStack/ConnectionLayer.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/Element.h> +#include <Swiften/Network/Connection.h> +#include <Swiften/StreamStack/ConnectionLayer.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class ProtocolHeader; class StreamStack; class JID; class Element; - class ByteArray; class PayloadParserFactoryCollection; class PayloadSerializerCollection; class XMPPLayer; @@ -63,8 +63,8 @@ namespace Swift { boost::signal<void (boost::shared_ptr<Element>)> onElementReceived; boost::signal<void (const boost::optional<SessionError>&)> onSessionFinished; - boost::signal<void (const ByteArray&)> onDataWritten; - boost::signal<void (const ByteArray&)> onDataRead; + boost::signal<void (const SafeByteArray&)> onDataWritten; + boost::signal<void (const SafeByteArray&)> onDataRead; protected: void setRemoteJID(const JID& j) { diff --git a/Swiften/Session/SessionStream.cpp b/Swiften/Session/SessionStream.cpp index 5bca0aa..0d73b63 100644 --- a/Swiften/Session/SessionStream.cpp +++ b/Swiften/Session/SessionStream.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Session/SessionStream.h" +#include <Swiften/Session/SessionStream.h> namespace Swift { diff --git a/Swiften/Session/SessionStream.h b/Swiften/Session/SessionStream.h index 2753878..e6b9469 100644 --- a/Swiften/Session/SessionStream.h +++ b/Swiften/Session/SessionStream.h @@ -6,16 +6,17 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> #include <boost/optional.hpp> -#include "Swiften/Elements/ProtocolHeader.h" -#include "Swiften/Elements/Element.h" -#include "Swiften/Base/Error.h" -#include "Swiften/TLS/PKCS12Certificate.h" -#include "Swiften/TLS/Certificate.h" -#include "Swiften/TLS/CertificateVerificationError.h" +#include <Swiften/Elements/ProtocolHeader.h> +#include <Swiften/Elements/Element.h> +#include <Swiften/Base/Error.h> +#include <Swiften/Base/SafeByteArray.h> +#include <Swiften/TLS/PKCS12Certificate.h> +#include <Swiften/TLS/Certificate.h> +#include <Swiften/TLS/CertificateVerificationError.h> namespace Swift { class SessionStream { @@ -71,8 +72,8 @@ namespace Swift { boost::signal<void (boost::shared_ptr<Element>)> onElementReceived; boost::signal<void (boost::shared_ptr<Error>)> onClosed; boost::signal<void ()> onTLSEncrypted; - boost::signal<void (const std::string&)> onDataRead; - boost::signal<void (const std::string&)> onDataWritten; + boost::signal<void (const SafeByteArray&)> onDataRead; + boost::signal<void (const SafeByteArray&)> onDataWritten; protected: const PKCS12Certificate& getTLSCertificate() const { diff --git a/Swiften/Session/SessionTracer.cpp b/Swiften/Session/SessionTracer.cpp new file mode 100644 index 0000000..e0a39bf --- /dev/null +++ b/Swiften/Session/SessionTracer.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Session/SessionTracer.h> + +#include <iostream> +#include <boost/bind.hpp> + +namespace Swift { + +SessionTracer::SessionTracer(boost::shared_ptr<Session> session) : session(session) { + session->onDataRead.connect(boost::bind(&SessionTracer::printData, this, '<', _1)); + session->onDataWritten.connect(boost::bind(&SessionTracer::printData, this, '>', _1)); +} + +void SessionTracer::printData(char direction, const SafeByteArray& data) { + std::cerr << direction << direction << " " << session->getLocalJID() << " "; + for (unsigned int i = 0; i < 72 - session->getLocalJID().toString().size() - session->getRemoteJID().toString().size(); ++i) { + std::cerr << direction; + } + std::cerr << " " << session->getRemoteJID()<< " " << direction << direction << std::endl; + std::cerr << byteArrayToString(ByteArray(data.begin(), data.end())) << std::endl; +} + +} diff --git a/Swiften/Session/SessionTracer.h b/Swiften/Session/SessionTracer.h index cce45eb..72c93b4 100644 --- a/Swiften/Session/SessionTracer.h +++ b/Swiften/Session/SessionTracer.h @@ -6,29 +6,18 @@ #pragma once -#include <iostream> - -#include "Swiften/Session/Session.h" #include <string> -#include "Swiften/Base/ByteArray.h" + +#include <Swiften/Session/Session.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class SessionTracer { public: - SessionTracer(boost::shared_ptr<Session> session) : session(session) { - session->onDataRead.connect(boost::bind(&SessionTracer::printData, this, '<', _1)); - session->onDataWritten.connect(boost::bind(&SessionTracer::printData, this, '>', _1)); - } + SessionTracer(boost::shared_ptr<Session> session); private: - void printData(char direction, const ByteArray& data) { - std::cerr << direction << direction << " " << session->getLocalJID() << " "; - for (unsigned int i = 0; i < 72 - session->getLocalJID().toString().size() - session->getRemoteJID().toString().size(); ++i) { - std::cerr << direction; - } - std::cerr << " " << session->getRemoteJID()<< " " << direction << direction << std::endl; - std::cerr << data.toString() << std::endl; - } + void printData(char direction, const SafeByteArray& data); boost::shared_ptr<Session> session; }; diff --git a/Swiften/StreamManagement/StanzaAckRequester.cpp b/Swiften/StreamManagement/StanzaAckRequester.cpp index f7d603b..b60b9b0 100644 --- a/Swiften/StreamManagement/StanzaAckRequester.cpp +++ b/Swiften/StreamManagement/StanzaAckRequester.cpp @@ -4,11 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/StreamManagement/StanzaAckRequester.h" +#include <Swiften/StreamManagement/StanzaAckRequester.h> #include <boost/numeric/conversion/cast.hpp> +#include <iostream> -#include "Swiften/Elements/Message.h" +#include <Swiften/Elements/Message.h> namespace Swift { @@ -28,7 +29,7 @@ void StanzaAckRequester::handleStanzaSent(boost::shared_ptr<Stanza> stanza) { void StanzaAckRequester::handleAckReceived(unsigned int handledStanzasCount) { unsigned int i = lastHandledStanzasCount; while (i != handledStanzasCount) { - if (unackedStanzas.size() == 0) { + if (unackedStanzas.empty()) { std::cerr << "Warning: Server acked more stanzas than we sent" << std::endl; break; } diff --git a/Swiften/StreamManagement/StanzaAckRequester.h b/Swiften/StreamManagement/StanzaAckRequester.h index 89f068e..e8e4997 100644 --- a/Swiften/StreamManagement/StanzaAckRequester.h +++ b/Swiften/StreamManagement/StanzaAckRequester.h @@ -9,8 +9,8 @@ #include <boost/shared_ptr.hpp> #include <deque> -#include "Swiften/Elements/Stanza.h" -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Elements/Stanza.h> +#include <Swiften/Base/boost_bsignals.h> namespace Swift { class StanzaAckRequester { diff --git a/Swiften/StreamManagement/StanzaAckResponder.cpp b/Swiften/StreamManagement/StanzaAckResponder.cpp index 5b71f91..9295924 100644 --- a/Swiften/StreamManagement/StanzaAckResponder.cpp +++ b/Swiften/StreamManagement/StanzaAckResponder.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/StreamManagement/StanzaAckResponder.h" +#include <Swiften/StreamManagement/StanzaAckResponder.h> #include <boost/numeric/conversion/cast.hpp> diff --git a/Swiften/StreamManagement/StanzaAckResponder.h b/Swiften/StreamManagement/StanzaAckResponder.h index bc83aa1..b5888b7 100644 --- a/Swiften/StreamManagement/StanzaAckResponder.h +++ b/Swiften/StreamManagement/StanzaAckResponder.h @@ -8,8 +8,8 @@ #include <boost/shared_ptr.hpp> -#include "Swiften/Elements/Stanza.h" -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Elements/Stanza.h> +#include <Swiften/Base/boost_bsignals.h> namespace Swift { class StanzaAckResponder { diff --git a/Swiften/StreamManagement/UnitTest/StanzaAckRequesterTest.cpp b/Swiften/StreamManagement/UnitTest/StanzaAckRequesterTest.cpp index 1028ae7..baccc41 100644 --- a/Swiften/StreamManagement/UnitTest/StanzaAckRequesterTest.cpp +++ b/Swiften/StreamManagement/UnitTest/StanzaAckRequesterTest.cpp @@ -9,10 +9,10 @@ #include <boost/bind.hpp> #include <boost/numeric/conversion/cast.hpp> -#include "Swiften/StreamManagement/StanzaAckRequester.h" -#include "Swiften/Elements/Message.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/IQ.h" +#include <Swiften/StreamManagement/StanzaAckRequester.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Elements/IQ.h> using namespace Swift; @@ -36,28 +36,28 @@ class StanzaAckRequesterTest : public CppUnit::TestFixture { } void testHandleStanzaSent_MessageRequestsAck() { - std::auto_ptr<StanzaAckRequester> testling(createRequester()); + boost::shared_ptr<StanzaAckRequester> testling(createRequester()); testling->handleStanzaSent(createMessage("m1")); CPPUNIT_ASSERT_EQUAL(1, acksRequested); } void testHandleStanzaSent_IQDoesNotRequestAck() { - std::auto_ptr<StanzaAckRequester> testling(createRequester()); + boost::shared_ptr<StanzaAckRequester> testling(createRequester()); testling->handleStanzaSent(createIQ("iq1")); CPPUNIT_ASSERT_EQUAL(0, acksRequested); } void testHandleStanzaSent_PresenceDoesNotRequestAck() { - std::auto_ptr<StanzaAckRequester> testling(createRequester()); + boost::shared_ptr<StanzaAckRequester> testling(createRequester()); testling->handleStanzaSent(createPresence("p1")); CPPUNIT_ASSERT_EQUAL(0, acksRequested); } void testHandleAckReceived_AcksStanza() { - std::auto_ptr<StanzaAckRequester> testling(createRequester()); + boost::shared_ptr<StanzaAckRequester> testling(createRequester()); testling->handleStanzaSent(createMessage("m1")); testling->handleAckReceived(1); @@ -67,7 +67,7 @@ class StanzaAckRequesterTest : public CppUnit::TestFixture { } void testHandleAckReceived_AcksMultipleMessages() { - std::auto_ptr<StanzaAckRequester> testling(createRequester()); + boost::shared_ptr<StanzaAckRequester> testling(createRequester()); testling->handleStanzaSent(createMessage("m1")); testling->handleStanzaSent(createMessage("m2")); @@ -79,7 +79,7 @@ class StanzaAckRequesterTest : public CppUnit::TestFixture { } void testHandleAckReceived_AcksMultipleStanzas() { - std::auto_ptr<StanzaAckRequester> testling(createRequester()); + boost::shared_ptr<StanzaAckRequester> testling(createRequester()); testling->handleStanzaSent(createIQ("iq1")); testling->handleStanzaSent(createPresence("p1")); testling->handleStanzaSent(createMessage("m1")); @@ -93,7 +93,7 @@ class StanzaAckRequesterTest : public CppUnit::TestFixture { } void testHandleAckReceived_MultipleAcks() { - std::auto_ptr<StanzaAckRequester> testling(createRequester()); + boost::shared_ptr<StanzaAckRequester> testling(createRequester()); testling->handleStanzaSent(createMessage("m1")); testling->handleAckReceived(1); @@ -109,7 +109,7 @@ class StanzaAckRequesterTest : public CppUnit::TestFixture { // Handle stanza ack count wrapping, as per the XEP void testHandleAckReceived_WrapAround() { - std::auto_ptr<StanzaAckRequester> testling(createRequester()); + boost::shared_ptr<StanzaAckRequester> testling(createRequester()); testling->lastHandledStanzasCount = boost::numeric_cast<unsigned int>((1ULL<<32) - 1); testling->handleStanzaSent(createMessage("m1")); testling->handleStanzaSent(createMessage("m2")); diff --git a/Swiften/StreamManagement/UnitTest/StanzaAckResponderTest.cpp b/Swiften/StreamManagement/UnitTest/StanzaAckResponderTest.cpp index b24335f..71a7f94 100644 --- a/Swiften/StreamManagement/UnitTest/StanzaAckResponderTest.cpp +++ b/Swiften/StreamManagement/UnitTest/StanzaAckResponderTest.cpp @@ -9,8 +9,8 @@ #include <boost/bind.hpp> #include <boost/numeric/conversion/cast.hpp> -#include "Swiften/StreamManagement/StanzaAckResponder.h" -#include "Swiften/Elements/Message.h" +#include <Swiften/StreamManagement/StanzaAckResponder.h> +#include <Swiften/Elements/Message.h> using namespace Swift; @@ -26,7 +26,7 @@ class StanzaAckResponderTest : public CppUnit::TestFixture { public: void testHandleAckRequestReceived_AcksStanza() { - std::auto_ptr<StanzaAckResponder> testling(createResponder()); + boost::shared_ptr<StanzaAckResponder> testling(createResponder()); testling->handleStanzaReceived(); testling->handleAckRequestReceived(); @@ -36,7 +36,7 @@ class StanzaAckResponderTest : public CppUnit::TestFixture { } void testHandleAckRequestReceived_AcksMultipleStanzas() { - std::auto_ptr<StanzaAckResponder> testling(createResponder()); + boost::shared_ptr<StanzaAckResponder> testling(createResponder()); testling->handleStanzaReceived(); testling->handleStanzaReceived(); @@ -47,7 +47,7 @@ class StanzaAckResponderTest : public CppUnit::TestFixture { } void testHandleAckRequestReceived_MultipleAcks() { - std::auto_ptr<StanzaAckResponder> testling(createResponder()); + boost::shared_ptr<StanzaAckResponder> testling(createResponder()); testling->handleStanzaReceived(); testling->handleAckRequestReceived(); @@ -61,7 +61,7 @@ class StanzaAckResponderTest : public CppUnit::TestFixture { // Handle stanza ack count wrapping, as per the XEP void testHandleAckRequestReceived_WrapAround() { - std::auto_ptr<StanzaAckResponder> testling(createResponder()); + boost::shared_ptr<StanzaAckResponder> testling(createResponder()); testling->handledStanzasCount = boost::numeric_cast<unsigned int>((1ULL<<32) - 1); testling->handleStanzaReceived(); testling->handleStanzaReceived(); diff --git a/Swiften/StreamStack/CompressionLayer.h b/Swiften/StreamStack/CompressionLayer.h index b8293a8..783cfca 100644 --- a/Swiften/StreamStack/CompressionLayer.h +++ b/Swiften/StreamStack/CompressionLayer.h @@ -7,13 +7,13 @@ #pragma once #include <boost/noncopyable.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/StreamStack/StreamLayer.h" -#include "Swiften/Compress/ZLibException.h" -#include "Swiften/Compress/ZLibCompressor.h" -#include "Swiften/Compress/ZLibDecompressor.h" +#include <Swiften/Base/SafeByteArray.h> +#include <Swiften/StreamStack/StreamLayer.h> +#include <Swiften/Compress/ZLibException.h> +#include <Swiften/Compress/ZLibCompressor.h> +#include <Swiften/Compress/ZLibDecompressor.h> namespace Swift { class ZLibCompressor; @@ -23,20 +23,20 @@ namespace Swift { public: CompressionLayer() {} - virtual void writeData(const ByteArray& data) { + virtual void writeData(const SafeByteArray& data) { try { writeDataToChildLayer(compressor_.process(data)); } - catch (const ZLibException& e) { + catch (const ZLibException&) { onError(); } } - virtual void handleDataRead(const ByteArray& data) { + virtual void handleDataRead(const SafeByteArray& data) { try { writeDataToParentLayer(decompressor_.process(data)); } - catch (const ZLibException& e) { + catch (const ZLibException&) { onError(); } } diff --git a/Swiften/StreamStack/ConnectionLayer.cpp b/Swiften/StreamStack/ConnectionLayer.cpp new file mode 100644 index 0000000..5ea06eb --- /dev/null +++ b/Swiften/StreamStack/ConnectionLayer.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/StreamStack/ConnectionLayer.h> +#include <boost/bind.hpp> + +namespace Swift { + +ConnectionLayer::ConnectionLayer(boost::shared_ptr<Connection> connection) : connection(connection) { + connection->onDataRead.connect(boost::bind(&ConnectionLayer::handleDataRead, this, _1)); +} + +ConnectionLayer::~ConnectionLayer() { + connection->onDataRead.disconnect(boost::bind(&ConnectionLayer::writeDataToParentLayer, this, _1)); +} + +void ConnectionLayer::handleDataRead(boost::shared_ptr<SafeByteArray> data) { + writeDataToParentLayer(*data); +} + + +} diff --git a/Swiften/StreamStack/ConnectionLayer.h b/Swiften/StreamStack/ConnectionLayer.h index 0da0900..6776751 100644 --- a/Swiften/StreamStack/ConnectionLayer.h +++ b/Swiften/StreamStack/ConnectionLayer.h @@ -6,29 +6,25 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" #include <boost/shared_ptr.hpp> -#include <boost/bind.hpp> -#include "Swiften/StreamStack/LowLayer.h" -#include "Swiften/Network/Connection.h" +#include <Swiften/StreamStack/LowLayer.h> +#include <Swiften/Network/Connection.h> namespace Swift { class ConnectionLayer : public LowLayer { public: - ConnectionLayer(boost::shared_ptr<Connection> connection) : connection(connection) { - connection->onDataRead.connect(boost::bind(&ConnectionLayer::writeDataToParentLayer, this, _1)); - } - - ~ConnectionLayer() { - connection->onDataRead.disconnect(boost::bind(&ConnectionLayer::writeDataToParentLayer, this, _1)); - } + ConnectionLayer(boost::shared_ptr<Connection> connection); + ~ConnectionLayer(); - void writeData(const ByteArray& data) { + void writeData(const SafeByteArray& data) { connection->write(data); } private: + void handleDataRead(boost::shared_ptr<SafeByteArray>); + + private: boost::shared_ptr<Connection> connection; }; } diff --git a/Swiften/StreamStack/HighLayer.cpp b/Swiften/StreamStack/HighLayer.cpp index 7203b7f..dc17c2a 100644 --- a/Swiften/StreamStack/HighLayer.cpp +++ b/Swiften/StreamStack/HighLayer.cpp @@ -18,7 +18,7 @@ HighLayer::HighLayer() : childLayer(NULL) { HighLayer::~HighLayer() { } -void HighLayer::writeDataToChildLayer(const ByteArray& data) { +void HighLayer::writeDataToChildLayer(const SafeByteArray& data) { assert(childLayer); childLayer->writeData(data); } diff --git a/Swiften/StreamStack/HighLayer.h b/Swiften/StreamStack/HighLayer.h index ca983f9..06b1d25 100644 --- a/Swiften/StreamStack/HighLayer.h +++ b/Swiften/StreamStack/HighLayer.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class LowLayer; @@ -18,7 +18,7 @@ namespace Swift { HighLayer(); virtual ~HighLayer(); - virtual void handleDataRead(const ByteArray& data) = 0; + virtual void handleDataRead(const SafeByteArray& data) = 0; protected: LowLayer* getChildLayer() { @@ -29,7 +29,7 @@ namespace Swift { this->childLayer = childLayer; } - void writeDataToChildLayer(const ByteArray& data); + void writeDataToChildLayer(const SafeByteArray& data); private: LowLayer* childLayer; diff --git a/Swiften/StreamStack/LowLayer.cpp b/Swiften/StreamStack/LowLayer.cpp index ed93cd2..ff4ca17 100644 --- a/Swiften/StreamStack/LowLayer.cpp +++ b/Swiften/StreamStack/LowLayer.cpp @@ -18,7 +18,7 @@ LowLayer::LowLayer() : parentLayer(NULL) { LowLayer::~LowLayer() { } -void LowLayer::writeDataToParentLayer(const ByteArray& data) { +void LowLayer::writeDataToParentLayer(const SafeByteArray& data) { assert(parentLayer); parentLayer->handleDataRead(data); } diff --git a/Swiften/StreamStack/LowLayer.h b/Swiften/StreamStack/LowLayer.h index 1f9645a..00960ea 100644 --- a/Swiften/StreamStack/LowLayer.h +++ b/Swiften/StreamStack/LowLayer.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class HighLayer; @@ -18,7 +18,7 @@ namespace Swift { LowLayer(); virtual ~LowLayer(); - virtual void writeData(const ByteArray& data) = 0; + virtual void writeData(const SafeByteArray& data) = 0; protected: HighLayer* getParentLayer() { @@ -29,7 +29,7 @@ namespace Swift { this->parentLayer = parentLayer; } - void writeDataToParentLayer(const ByteArray& data); + void writeDataToParentLayer(const SafeByteArray& data); private: HighLayer* parentLayer; diff --git a/Swiften/StreamStack/SConscript b/Swiften/StreamStack/SConscript index 022c695..06fcc03 100644 --- a/Swiften/StreamStack/SConscript +++ b/Swiften/StreamStack/SConscript @@ -6,6 +6,7 @@ sources = [ "HighLayer.cpp", "LowLayer.cpp", "StreamStack.cpp", + "ConnectionLayer.cpp", "TLSLayer.cpp", "WhitespacePingLayer.cpp", "XMPPLayer.cpp", diff --git a/Swiften/StreamStack/StreamLayer.h b/Swiften/StreamStack/StreamLayer.h index bcc5d79..09bb5b3 100644 --- a/Swiften/StreamStack/StreamLayer.h +++ b/Swiften/StreamStack/StreamLayer.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/StreamStack/LowLayer.h" -#include "Swiften/StreamStack/HighLayer.h" +#include <Swiften/StreamStack/LowLayer.h> +#include <Swiften/StreamStack/HighLayer.h> namespace Swift { class StreamLayer : public LowLayer, public HighLayer { diff --git a/Swiften/StreamStack/StreamStack.cpp b/Swiften/StreamStack/StreamStack.cpp index 2a30768..78409f7 100644 --- a/Swiften/StreamStack/StreamStack.cpp +++ b/Swiften/StreamStack/StreamStack.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/StreamStack/StreamStack.h" +#include <Swiften/StreamStack/StreamStack.h> #include <boost/bind.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/StreamStack/XMPPLayer.h" -#include "Swiften/StreamStack/LowLayer.h" -#include "Swiften/StreamStack/StreamLayer.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/StreamStack/XMPPLayer.h> +#include <Swiften/StreamStack/LowLayer.h> +#include <Swiften/StreamStack/StreamLayer.h> namespace Swift { diff --git a/Swiften/StreamStack/StreamStack.h b/Swiften/StreamStack/StreamStack.h index 562245e..30e17ce 100644 --- a/Swiften/StreamStack/StreamStack.h +++ b/Swiften/StreamStack/StreamStack.h @@ -7,11 +7,10 @@ #pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <vector> -#include "Swiften/Elements/Stanza.h" -#include "Swiften/Base/foreach.h" +#include <Swiften/Elements/Stanza.h> namespace Swift { class XMPPLayer; @@ -30,8 +29,8 @@ namespace Swift { } template<typename T> T* getLayer() { - foreach(StreamLayer* streamLayer, layers_) { - T* layer = dynamic_cast<T*>(streamLayer); + for (size_t i = 0; i < layers_.size(); ++i) { + T* layer = dynamic_cast<T*>(layers_[i]); if (layer) { return layer; } diff --git a/Swiften/StreamStack/TLSLayer.cpp b/Swiften/StreamStack/TLSLayer.cpp index 8a6c008..6f2223d 100644 --- a/Swiften/StreamStack/TLSLayer.cpp +++ b/Swiften/StreamStack/TLSLayer.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/StreamStack/TLSLayer.h" +#include <Swiften/StreamStack/TLSLayer.h> #include <boost/bind.hpp> -#include "Swiften/TLS/TLSContextFactory.h" -#include "Swiften/TLS/TLSContext.h" +#include <Swiften/TLS/TLSContextFactory.h> +#include <Swiften/TLS/TLSContext.h> namespace Swift { @@ -29,11 +29,11 @@ void TLSLayer::connect() { context->connect(); } -void TLSLayer::writeData(const ByteArray& data) { +void TLSLayer::writeData(const SafeByteArray& data) { context->handleDataFromApplication(data); } -void TLSLayer::handleDataRead(const ByteArray& data) { +void TLSLayer::handleDataRead(const SafeByteArray& data) { context->handleDataFromNetwork(data); } diff --git a/Swiften/StreamStack/TLSLayer.h b/Swiften/StreamStack/TLSLayer.h index 22e9aef..a8693d5 100644 --- a/Swiften/StreamStack/TLSLayer.h +++ b/Swiften/StreamStack/TLSLayer.h @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/StreamStack/StreamLayer.h" -#include "Swiften/TLS/Certificate.h" -#include "Swiften/TLS/CertificateVerificationError.h" +#include <Swiften/Base/SafeByteArray.h> +#include <Swiften/StreamStack/StreamLayer.h> +#include <Swiften/TLS/Certificate.h> +#include <Swiften/TLS/CertificateVerificationError.h> namespace Swift { class TLSContext; @@ -27,8 +27,8 @@ namespace Swift { Certificate::ref getPeerCertificate() const; boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const; - void writeData(const ByteArray& data); - void handleDataRead(const ByteArray& data); + void writeData(const SafeByteArray& data); + void handleDataRead(const SafeByteArray& data); TLSContext* getContext() const { return context; diff --git a/Swiften/StreamStack/UnitTest/StreamStackTest.cpp b/Swiften/StreamStack/UnitTest/StreamStackTest.cpp index be16baa..d3c0a7c 100644 --- a/Swiften/StreamStack/UnitTest/StreamStackTest.cpp +++ b/Swiften/StreamStack/UnitTest/StreamStackTest.cpp @@ -4,7 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> #include <vector> #include <boost/bind.hpp> @@ -12,13 +13,14 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/StreamStack/StreamStack.h" -#include "Swiften/StreamStack/LowLayer.h" -#include "Swiften/StreamStack/XMPPLayer.h" -#include "Swiften/StreamStack/StreamLayer.h" -#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" -#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/Concat.h> +#include <Swiften/StreamStack/StreamStack.h> +#include <Swiften/StreamStack/LowLayer.h> +#include <Swiften/StreamStack/XMPPLayer.h> +#include <Swiften/StreamStack/StreamLayer.h> +#include <Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h> +#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h> using namespace Swift; @@ -52,38 +54,38 @@ class StreamStackTest : public CppUnit::TestFixture { xmppStream_->writeData("foo"); CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), physicalStream_->data_.size()); - CPPUNIT_ASSERT_EQUAL(ByteArray("foo"), physicalStream_->data_[0]); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("foo"), physicalStream_->data_[0]); } void testWriteData_OneIntermediateStream() { StreamStack testling(xmppStream_, physicalStream_); - std::auto_ptr<MyStreamLayer> xStream(new MyStreamLayer("X")); + boost::shared_ptr<MyStreamLayer> xStream(new MyStreamLayer("X")); testling.addLayer(xStream.get()); xmppStream_->writeData("foo"); CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), physicalStream_->data_.size()); - CPPUNIT_ASSERT_EQUAL(ByteArray("Xfoo"), physicalStream_->data_[0]); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("Xfoo"), physicalStream_->data_[0]); } void testWriteData_TwoIntermediateStreamStack() { StreamStack testling(xmppStream_, physicalStream_); - std::auto_ptr<MyStreamLayer> xStream(new MyStreamLayer("X")); - std::auto_ptr<MyStreamLayer> yStream(new MyStreamLayer("Y")); + boost::shared_ptr<MyStreamLayer> xStream(new MyStreamLayer("X")); + boost::shared_ptr<MyStreamLayer> yStream(new MyStreamLayer("Y")); testling.addLayer(xStream.get()); testling.addLayer(yStream.get()); xmppStream_->writeData("foo"); CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), physicalStream_->data_.size()); - CPPUNIT_ASSERT_EQUAL(ByteArray("XYfoo"), physicalStream_->data_[0]); + CPPUNIT_ASSERT_EQUAL(createSafeByteArray("XYfoo"), physicalStream_->data_[0]); } void testReadData_NoIntermediateStreamStack() { StreamStack testling(xmppStream_, physicalStream_); xmppStream_->onElement.connect(boost::bind(&StreamStackTest::handleElement, this, _1)); - physicalStream_->onDataRead(ByteArray("<stream:stream xmlns:stream='http://etherx.jabber.org/streams'><presence/>")); + physicalStream_->onDataRead(createSafeByteArray("<stream:stream xmlns:stream='http://etherx.jabber.org/streams'><presence/>")); CPPUNIT_ASSERT_EQUAL(1, elementsReceived_); } @@ -91,10 +93,10 @@ class StreamStackTest : public CppUnit::TestFixture { void testReadData_OneIntermediateStream() { StreamStack testling(xmppStream_, physicalStream_); xmppStream_->onElement.connect(boost::bind(&StreamStackTest::handleElement, this, _1)); - std::auto_ptr<MyStreamLayer> xStream(new MyStreamLayer("<")); + boost::shared_ptr<MyStreamLayer> xStream(new MyStreamLayer("<")); testling.addLayer(xStream.get()); - physicalStream_->onDataRead(ByteArray("stream:stream xmlns:stream='http://etherx.jabber.org/streams'><presence/>")); + physicalStream_->onDataRead(createSafeByteArray("stream:stream xmlns:stream='http://etherx.jabber.org/streams'><presence/>")); CPPUNIT_ASSERT_EQUAL(1, elementsReceived_); } @@ -102,12 +104,12 @@ class StreamStackTest : public CppUnit::TestFixture { void testReadData_TwoIntermediateStreamStack() { StreamStack testling(xmppStream_, physicalStream_); xmppStream_->onElement.connect(boost::bind(&StreamStackTest::handleElement, this, _1)); - std::auto_ptr<MyStreamLayer> xStream(new MyStreamLayer("s")); - std::auto_ptr<MyStreamLayer> yStream(new MyStreamLayer("<")); + boost::shared_ptr<MyStreamLayer> xStream(new MyStreamLayer("s")); + boost::shared_ptr<MyStreamLayer> yStream(new MyStreamLayer("<")); testling.addLayer(xStream.get()); testling.addLayer(yStream.get()); - physicalStream_->onDataRead(ByteArray("tream:stream xmlns:stream='http://etherx.jabber.org/streams'><presence/>")); + physicalStream_->onDataRead(createSafeByteArray("tream:stream xmlns:stream='http://etherx.jabber.org/streams'><presence/>")); CPPUNIT_ASSERT_EQUAL(1, elementsReceived_); } @@ -115,7 +117,7 @@ class StreamStackTest : public CppUnit::TestFixture { void testAddLayer_ExistingOnWriteDataSlot() { StreamStack testling(xmppStream_, physicalStream_); xmppStream_->onWriteData.connect(boost::bind(&StreamStackTest::handleWriteData, this, _1)); - std::auto_ptr<MyStreamLayer> xStream(new MyStreamLayer("X")); + boost::shared_ptr<MyStreamLayer> xStream(new MyStreamLayer("X")); testling.addLayer(xStream.get()); xmppStream_->writeData("foo"); @@ -127,7 +129,7 @@ class StreamStackTest : public CppUnit::TestFixture { ++elementsReceived_; } - void handleWriteData(ByteArray) { + void handleWriteData(const SafeByteArray&) { ++dataWriteReceived_; } @@ -137,12 +139,12 @@ class StreamStackTest : public CppUnit::TestFixture { MyStreamLayer(const std::string& prepend) : prepend_(prepend) { } - virtual void writeData(const ByteArray& data) { - writeDataToChildLayer(ByteArray(prepend_) + data); + virtual void writeData(const SafeByteArray& data) { + writeDataToChildLayer(concat(createSafeByteArray(prepend_), data)); } - virtual void handleDataRead(const ByteArray& data) { - writeDataToParentLayer(ByteArray(prepend_) + data); + virtual void handleDataRead(const SafeByteArray& data) { + writeDataToParentLayer(concat(createSafeByteArray(prepend_), data)); } private: @@ -154,15 +156,15 @@ class StreamStackTest : public CppUnit::TestFixture { TestLowLayer() { } - virtual void writeData(const ByteArray& data) { + virtual void writeData(const SafeByteArray& data) { data_.push_back(data); } - void onDataRead(const ByteArray& data) { + void onDataRead(const SafeByteArray& data) { writeDataToParentLayer(data); } - std::vector<ByteArray> data_; + std::vector<SafeByteArray> data_; }; diff --git a/Swiften/StreamStack/UnitTest/XMPPLayerTest.cpp b/Swiften/StreamStack/UnitTest/XMPPLayerTest.cpp index 9d5e745..bb0ce61 100644 --- a/Swiften/StreamStack/UnitTest/XMPPLayerTest.cpp +++ b/Swiften/StreamStack/UnitTest/XMPPLayerTest.cpp @@ -9,13 +9,13 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Elements/ProtocolHeader.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Base/ByteArray.h" -#include "Swiften/StreamStack/XMPPLayer.h" -#include "Swiften/StreamStack/LowLayer.h" -#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" -#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h" +#include <Swiften/Elements/ProtocolHeader.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/StreamStack/XMPPLayer.h> +#include <Swiften/StreamStack/LowLayer.h> +#include <Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h> +#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h> using namespace Swift; @@ -46,7 +46,7 @@ class XMPPLayerTest : public CppUnit::TestFixture { void testParseData_Error() { testling_->onError.connect(boost::bind(&XMPPLayerTest::handleError, this)); - testling_->handleDataRead("<iq>"); + testling_->handleDataRead(createSafeByteArray("<iq>")); CPPUNIT_ASSERT_EQUAL(1, errorReceived_); } @@ -55,10 +55,10 @@ class XMPPLayerTest : public CppUnit::TestFixture { testling_->onElement.connect(boost::bind(&XMPPLayerTest::handleElement, this, _1)); testling_->onError.connect(boost::bind(&XMPPLayerTest::handleError, this)); - testling_->handleDataRead("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" >"); + testling_->handleDataRead(createSafeByteArray("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" >")); testling_->resetParser(); - testling_->handleDataRead("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" >"); - testling_->handleDataRead("<presence/>"); + testling_->handleDataRead(createSafeByteArray("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" >")); + testling_->handleDataRead(createSafeByteArray("<presence/>")); CPPUNIT_ASSERT_EQUAL(1, elementsReceived_); CPPUNIT_ASSERT_EQUAL(0, errorReceived_); @@ -66,8 +66,8 @@ class XMPPLayerTest : public CppUnit::TestFixture { void testResetParser_FromSlot() { testling_->onElement.connect(boost::bind(&XMPPLayerTest::handleElementAndReset, this, _1)); - testling_->handleDataRead("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" ><presence/>"); - testling_->handleDataRead("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" ><presence/>"); + testling_->handleDataRead(createSafeByteArray("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" ><presence/>")); + testling_->handleDataRead(createSafeByteArray("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" ><presence/>")); CPPUNIT_ASSERT_EQUAL(2, elementsReceived_); CPPUNIT_ASSERT_EQUAL(0, errorReceived_); @@ -120,8 +120,8 @@ class XMPPLayerTest : public CppUnit::TestFixture { class DummyLowLayer : public LowLayer { public: - virtual void writeData(const ByteArray& data) { - writtenData += data.toString(); + virtual void writeData(const SafeByteArray& data) { + writtenData += byteArrayToString(ByteArray(data.begin(), data.end())); } std::string writtenData; diff --git a/Swiften/StreamStack/WhitespacePingLayer.cpp b/Swiften/StreamStack/WhitespacePingLayer.cpp index 35efc3c..b14f3a2 100644 --- a/Swiften/StreamStack/WhitespacePingLayer.cpp +++ b/Swiften/StreamStack/WhitespacePingLayer.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/StreamStack/WhitespacePingLayer.h" +#include <Swiften/StreamStack/WhitespacePingLayer.h> #include <boost/bind.hpp> -#include "Swiften/Network/TimerFactory.h" -#include "Swiften/Network/Timer.h" +#include <Swiften/Network/TimerFactory.h> +#include <Swiften/Network/Timer.h> namespace Swift { @@ -20,17 +20,17 @@ WhitespacePingLayer::WhitespacePingLayer(TimerFactory* timerFactory) : isActive( timer->onTick.connect(boost::bind(&WhitespacePingLayer::handleTimerTick, this)); } -void WhitespacePingLayer::writeData(const ByteArray& data) { +void WhitespacePingLayer::writeData(const SafeByteArray& data) { writeDataToChildLayer(data); } -void WhitespacePingLayer::handleDataRead(const ByteArray& data) { +void WhitespacePingLayer::handleDataRead(const SafeByteArray& data) { writeDataToParentLayer(data); } void WhitespacePingLayer::handleTimerTick() { timer->stop(); - writeDataToChildLayer(" "); + writeDataToChildLayer(createSafeByteArray(" ")); timer->start(); } diff --git a/Swiften/StreamStack/WhitespacePingLayer.h b/Swiften/StreamStack/WhitespacePingLayer.h index 0532bbd..1435842 100644 --- a/Swiften/StreamStack/WhitespacePingLayer.h +++ b/Swiften/StreamStack/WhitespacePingLayer.h @@ -9,7 +9,7 @@ #include <boost/noncopyable.hpp> #include <boost/shared_ptr.hpp> -#include "Swiften/StreamStack/StreamLayer.h" +#include <Swiften/StreamStack/StreamLayer.h> namespace Swift { class Timer; @@ -21,8 +21,8 @@ namespace Swift { void setActive(); void setInactive(); - void writeData(const ByteArray& data); - void handleDataRead(const ByteArray& data); + void writeData(const SafeByteArray& data); + void handleDataRead(const SafeByteArray& data); bool getIsActive() const { return isActive; diff --git a/Swiften/StreamStack/XMPPLayer.cpp b/Swiften/StreamStack/XMPPLayer.cpp index 684dfe6..1dcd84f 100644 --- a/Swiften/StreamStack/XMPPLayer.cpp +++ b/Swiften/StreamStack/XMPPLayer.cpp @@ -4,10 +4,10 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/StreamStack/XMPPLayer.h" -#include "Swiften/Parser/XMPPParser.h" -#include "Swiften/Serializer/XMPPSerializer.h" -#include "Swiften/Elements/ProtocolHeader.h" +#include <Swiften/StreamStack/XMPPLayer.h> +#include <Swiften/Parser/XMPPParser.h> +#include <Swiften/Serializer/XMPPSerializer.h> +#include <Swiften/Elements/ProtocolHeader.h> namespace Swift { @@ -29,30 +29,33 @@ XMPPLayer::~XMPPLayer() { } void XMPPLayer::writeHeader(const ProtocolHeader& header) { - writeDataInternal(ByteArray(xmppSerializer_->serializeHeader(header))); + writeDataInternal(createSafeByteArray(xmppSerializer_->serializeHeader(header))); } void XMPPLayer::writeFooter() { - writeDataInternal(ByteArray(xmppSerializer_->serializeFooter())); + writeDataInternal(createSafeByteArray(xmppSerializer_->serializeFooter())); } void XMPPLayer::writeElement(boost::shared_ptr<Element> element) { - writeDataInternal(ByteArray(xmppSerializer_->serializeElement(element))); + writeDataInternal(xmppSerializer_->serializeElement(element)); } void XMPPLayer::writeData(const std::string& data) { - writeDataInternal(ByteArray(data)); + writeDataInternal(createSafeByteArray(data)); } -void XMPPLayer::writeDataInternal(const ByteArray& data) { +void XMPPLayer::writeDataInternal(const SafeByteArray& data) { onWriteData(data); writeDataToChildLayer(data); } -void XMPPLayer::handleDataRead(const ByteArray& data) { +void XMPPLayer::handleDataRead(const SafeByteArray& data) { onDataRead(data); inParser_ = true; - if (!xmppParser_->parse(data.toString())) { + // FIXME: Converting to unsafe string. Should be ok, since we don't take passwords + // from the stream in clients. If servers start using this, and require safe storage, + // we need to fix this. + if (!xmppParser_->parse(byteArrayToString(ByteArray(data.begin(), data.end())))) { inParser_ = false; onError(); return; diff --git a/Swiften/StreamStack/XMPPLayer.h b/Swiften/StreamStack/XMPPLayer.h index 6669cda..54bdd42 100644 --- a/Swiften/StreamStack/XMPPLayer.h +++ b/Swiften/StreamStack/XMPPLayer.h @@ -7,14 +7,14 @@ #pragma once #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/noncopyable.hpp> #include <Swiften/StreamStack/HighLayer.h> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Elements/Element.h" -#include "Swiften/Elements/StreamType.h" -#include "Swiften/Parser/XMPPParserClient.h" +#include <Swiften/Base/SafeByteArray.h> +#include <Swiften/Elements/Element.h> +#include <Swiften/Elements/StreamType.h> +#include <Swiften/Parser/XMPPParserClient.h> namespace Swift { class ProtocolHeader; @@ -39,14 +39,14 @@ namespace Swift { void resetParser(); protected: - void handleDataRead(const ByteArray& data); - void writeDataInternal(const ByteArray& data); + void handleDataRead(const SafeByteArray& data); + void writeDataInternal(const SafeByteArray& data); public: boost::signal<void (const ProtocolHeader&)> onStreamStart; boost::signal<void (boost::shared_ptr<Element>)> onElement; - boost::signal<void (const ByteArray&)> onWriteData; - boost::signal<void (const ByteArray&)> onDataRead; + boost::signal<void (const SafeByteArray&)> onWriteData; + boost::signal<void (const SafeByteArray&)> onDataRead; boost::signal<void ()> onError; private: diff --git a/Swiften/StringCodecs/Base64.cpp b/Swiften/StringCodecs/Base64.cpp index 795d982..e4eaa4e 100644 --- a/Swiften/StringCodecs/Base64.cpp +++ b/Swiften/StringCodecs/Base64.cpp @@ -5,50 +5,63 @@ */ #include <boost/numeric/conversion/cast.hpp> + #include <algorithm> -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/StringCodecs/Base64.h> +#include <Swiften/Base/Algorithm.h> namespace Swift { #pragma GCC diagnostic ignored "-Wold-style-cast" -std::string Base64::encode(const ByteArray &s) { - int i; - int len = s.getSize(); - char tbl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - int a, b, c; - - std::string p; - p.resize((len+2)/3*4); - int at = 0; - for( i = 0; i < len; i += 3 ) { - a = ((unsigned char) (s[i]) & 3) << 4; - if(i + 1 < len) { - a += (unsigned char) (s[i + 1]) >> 4; - b = ((unsigned char) (s[i + 1]) & 0xF) << 2; - if(i + 2 < len) { - b += (unsigned char) (s[i + 2]) >> 6; - c = (unsigned char) (s[i + 2]) & 0x3F; +namespace { + template<typename TargetType, typename SourceType> + TargetType base64Encode(const SourceType& s) { + int i; + int len = s.size(); + char tbl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + int a, b, c; + + TargetType p; + p.resize((len+2)/3*4); + int at = 0; + for( i = 0; i < len; i += 3 ) { + a = ((unsigned char) (s[i]) & 3) << 4; + if(i + 1 < len) { + a += (unsigned char) (s[i + 1]) >> 4; + b = ((unsigned char) (s[i + 1]) & 0xF) << 2; + if(i + 2 < len) { + b += (unsigned char) (s[i + 2]) >> 6; + c = (unsigned char) (s[i + 2]) & 0x3F; + } + else + c = 64; + } + else { + b = c = 64; } - else - c = 64; - } - else { - b = c = 64; - } - p[at++] = tbl[(unsigned char) (s[i]) >> 2]; - p[at++] = tbl[a]; - p[at++] = tbl[b]; - p[at++] = tbl[c]; + p[at++] = tbl[(unsigned char) (s[i]) >> 2]; + p[at++] = tbl[a]; + p[at++] = tbl[b]; + p[at++] = tbl[c]; + } + return p; } - return p; +} + +std::string Base64::encode(const ByteArray &s) { + return base64Encode<std::string, ByteArray>(s); +} + +SafeByteArray Base64::encode(const SafeByteArray &s) { + return base64Encode<SafeByteArray, SafeByteArray>(s); } ByteArray Base64::decode(const std::string& input) { std::string inputWithoutNewlines(input); - inputWithoutNewlines.erase(std::remove(inputWithoutNewlines.begin(), inputWithoutNewlines.end(), '\n'), inputWithoutNewlines.end()); + erase(inputWithoutNewlines, '\n'); const std::string& s = inputWithoutNewlines; ByteArray p; diff --git a/Swiften/StringCodecs/Base64.h b/Swiften/StringCodecs/Base64.h index 4b19a9f..2d67971 100644 --- a/Swiften/StringCodecs/Base64.h +++ b/Swiften/StringCodecs/Base64.h @@ -9,12 +9,15 @@ #include <vector> #include <string> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class Base64 { public: static std::string encode(const ByteArray& s); + static SafeByteArray encode(const SafeByteArray& s); + static ByteArray decode(const std::string &s); }; } diff --git a/Swiften/StringCodecs/HMAC.h b/Swiften/StringCodecs/HMAC.h new file mode 100644 index 0000000..cf0abfe --- /dev/null +++ b/Swiften/StringCodecs/HMAC.h @@ -0,0 +1,66 @@ +/* + * 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/Base/ByteArray.h> +#include <Swiften/Base/Algorithm.h> +#include <cassert> + +namespace Swift { + namespace HMAC_Detail { + template<typename KeyType> struct KeyWrapper; + template<> struct KeyWrapper<ByteArray> { + ByteArray wrap(const ByteArray& hash) const { + return hash; + } + }; + template<> struct KeyWrapper<SafeByteArray> { + SafeByteArray wrap(const ByteArray& hash) const { + return createSafeByteArray(hash); + } + }; + + template<typename Hash, typename KeyType, int BlockSize> + static ByteArray getHMAC(const KeyType& key, const ByteArray& data) { + Hash hash; + + // Create the padded key + KeyType paddedKey(key.size() <= BlockSize ? key : KeyWrapper<KeyType>().wrap(hash(key))); + paddedKey.resize(BlockSize, 0x0); + + // Create the first value + KeyType x(paddedKey); + for (unsigned int i = 0; i < x.size(); ++i) { + x[i] ^= 0x36; + } + append(x, data); + + // Create the second value + KeyType y(paddedKey); + for (unsigned int i = 0; i < y.size(); ++i) { + y[i] ^= 0x5c; + } + append(y, hash(x)); + + return hash(y); + } + }; + + template<typename Hash, int BlockSize> + class HMAC { + private: + + public: + ByteArray operator()(const ByteArray& key, const ByteArray& data) const { + return HMAC_Detail::getHMAC<Hash,ByteArray,BlockSize>(key, data); + } + + ByteArray operator()(const SafeByteArray& key, const ByteArray& data) const { + return HMAC_Detail::getHMAC<Hash,SafeByteArray,BlockSize>(key, data); + } + }; +} diff --git a/Swiften/StringCodecs/HMACSHA1.cpp b/Swiften/StringCodecs/HMACSHA1.cpp deleted file mode 100644 index 6ae5513..0000000 --- a/Swiften/StringCodecs/HMACSHA1.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include "Swiften/StringCodecs/HMACSHA1.h" - -#include <cassert> - -#include "Swiften/StringCodecs/SHA1.h" -#include "Swiften/Base/ByteArray.h" - -namespace Swift { - -static const unsigned int B = 64; - -ByteArray HMACSHA1::getResult(const ByteArray& key, const ByteArray& data) { - assert(key.getSize() <= B); - - // Create the padded key - ByteArray paddedKey(key); - paddedKey.resize(B, 0x0); - - // Create the first value - ByteArray x(paddedKey); - for (unsigned int i = 0; i < x.getSize(); ++i) { - x[i] ^= 0x36; - } - x += data; - - // Create the second value - ByteArray y(paddedKey); - for (unsigned int i = 0; i < y.getSize(); ++i) { - y[i] ^= 0x5c; - } - y += SHA1::getHash(x); - - return SHA1::getHash(y); -} - -#if 0 - -// A tweaked version of HMACSHA1 that is more than twice as fast as the one above. -// After this, more than 80% is spent in SHA1. -// Optimizations: -// - Avoids using ByteArray/std::vector -// - Uses openssl's SHA1, which is slightly faster -// - Does 'xor' on word basis -// - Passes return value as a parameter - -#include <openssl/sha.h> - -void HMACSHA1::getResult(const ByteArray& key, const ByteArray& data, ByteArray& result) { - // Create first value - size_t xSize = B + data.getSize(); - unsigned char* x = (unsigned char*) malloc(xSize * sizeof(unsigned char)); - memset(x, 0, B); - memcpy(x, key.getData(), key.getSize()); - for (unsigned int i = 0; i < (B>>32); ++i) { - x[i<<32] ^= 0x36363636; - } - memcpy(x + B, data.getData(), data.getSize()); - - // Create the second value - unsigned char y[B + 20]; - memset(y, 0, B); - memcpy(y, key.getData(), key.getSize()); - for (unsigned int i = 0; i < (B>>32); ++i) { - y[i<<32] ^= 0x5c5c5c5c; - } - ::SHA1(x, xSize, y + B); - free(x); - - ::SHA1(y, B + 20, (unsigned char*) result.getData()); -} - -#endif - -} diff --git a/Swiften/StringCodecs/HMACSHA1.h b/Swiften/StringCodecs/HMAC_SHA1.h index cc6cb04..8f403c6 100644 --- a/Swiften/StringCodecs/HMACSHA1.h +++ b/Swiften/StringCodecs/HMAC_SHA1.h @@ -6,11 +6,9 @@ #pragma once -namespace Swift { - class ByteArray; +#include <Swiften/StringCodecs/HMAC.h> +#include <Swiften/StringCodecs/SHA1.h> - class HMACSHA1 { - public: - static ByteArray getResult(const ByteArray& key, const ByteArray& data); - }; +namespace Swift { + typedef HMAC<SHA1, 64> HMAC_SHA1; } diff --git a/Swiften/StringCodecs/HMAC_SHA256.h b/Swiften/StringCodecs/HMAC_SHA256.h new file mode 100644 index 0000000..2d856cb --- /dev/null +++ b/Swiften/StringCodecs/HMAC_SHA256.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/StringCodecs/HMAC.h> +#include <Swiften/StringCodecs/SHA256.h> + +namespace Swift { + typedef HMAC<SHA256, 64> HMAC_SHA256; +} diff --git a/Swiften/StringCodecs/Hexify.cpp b/Swiften/StringCodecs/Hexify.cpp index 61732b0..668079b 100644 --- a/Swiften/StringCodecs/Hexify.cpp +++ b/Swiften/StringCodecs/Hexify.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/StringCodecs/Hexify.h" +#include <Swiften/StringCodecs/Hexify.h> #include <sstream> #include <iomanip> #include <boost/numeric/conversion/cast.hpp> #include <string> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> namespace Swift { @@ -25,10 +25,28 @@ std::string Hexify::hexify(const ByteArray& data) { std::ostringstream result; result << std::hex; - for (unsigned int i = 0; i < data.getSize(); ++i) { + for (unsigned int i = 0; i < data.size(); ++i) { result << std::setw(2) << std::setfill('0') << boost::numeric_cast<unsigned int>(static_cast<unsigned char>(data[i])); } return std::string(result.str()); } +ByteArray Hexify::unhexify(const std::string& hexstring) { + if (hexstring.size() % 2) { + return ByteArray(); + } + ByteArray result = ByteArray(hexstring.size() / 2); + for (size_t pos = 0; pos < hexstring.size() - 1; pos += 2) { + char c; + c = hexstring[pos]; + int a = (c>='0'&&c<='9') ? c-'0' : (c>='A'&&c<='Z') ? c-'A' + 10 : (c>='a'&&c<='z') ? c-'a' + 10 : -1; + c = hexstring[pos+1]; + int b = (c>='0'&&c<='9') ? c-'0' : (c>='A'&&c<='Z') ? c-'A' + 10 : (c>='a'&&c<='z') ? c-'a' + 10 : -1; + if (a == -1 || b == -1) return ByteArray(); // fail + result[pos/2] = (a<<4) | b; + + } + return result; +} + } diff --git a/Swiften/StringCodecs/Hexify.h b/Swiften/StringCodecs/Hexify.h index f85db15..c016448 100644 --- a/Swiften/StringCodecs/Hexify.h +++ b/Swiften/StringCodecs/Hexify.h @@ -6,15 +6,13 @@ #pragma once -#include <string> +#include <Swiften/Base/ByteArray.h> namespace Swift { - - class ByteArray; - class Hexify { public: static std::string hexify(unsigned char byte); static std::string hexify(const ByteArray& data); + static ByteArray unhexify(const std::string& hexstring); }; } diff --git a/Swiften/StringCodecs/MD5.cpp b/Swiften/StringCodecs/MD5.cpp index 718f52e..6871f79 100644 --- a/Swiften/StringCodecs/MD5.cpp +++ b/Swiften/StringCodecs/MD5.cpp @@ -33,12 +33,13 @@ #pragma GCC diagnostic ignored "-Wold-style-cast" -#include "Swiften/StringCodecs/MD5.h" +#include <Swiften/StringCodecs/MD5.h> #include <cassert> +#include <string.h> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Base/Platform.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/Platform.h> namespace Swift { @@ -124,13 +125,13 @@ static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) { a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2], d = pms->abcd[3]; md5_word_t t; -#ifdef SWIFTEN_BIG_ENDIAN - /* Define storage only for big-endian CPUs. */ - md5_word_t X[16]; -#else +#ifdef SWIFTEN_LITTLE_ENDIAN /* Define storage for little-endian or both types of CPUs. */ md5_word_t xbuf[16]; const md5_word_t *X; +#else + /* Define storage only for big-endian CPUs. */ + md5_word_t X[16]; #endif { @@ -350,16 +351,48 @@ md5_finish(md5_state_t *pms, md5_byte_t digest[16]) digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); } -ByteArray MD5::getHash(const ByteArray& data) { +namespace { + template<typename SourceType> + ByteArray getMD5Hash(const SourceType& data) { + ByteArray digest; + digest.resize(16); + + md5_state_t state; + md5_init(&state); + md5_append(&state, reinterpret_cast<const md5_byte_t*>(vecptr(data)), data.size()); + md5_finish(&state, reinterpret_cast<md5_byte_t*>(vecptr(digest))); + + return digest; + } +} + +MD5::MD5() { + state = new md5_state_t; + md5_init(state); +} + +MD5::~MD5() { + delete state; +} + +MD5& MD5::update(const std::vector<unsigned char>& input) { + md5_append(state, reinterpret_cast<const md5_byte_t*>(vecptr(input)), input.size()); + return *this; +} + +std::vector<unsigned char> MD5::getHash() { ByteArray digest; digest.resize(16); + md5_finish(state, reinterpret_cast<md5_byte_t*>(vecptr(digest))); + return digest; +} - md5_state_t state; - md5_init(&state); - md5_append(&state, reinterpret_cast<const md5_byte_t*>(data.getData()), data.getSize()); - md5_finish(&state, reinterpret_cast<md5_byte_t*>(digest.getData())); +ByteArray MD5::getHash(const ByteArray& data) { + return getMD5Hash(data); +} - return digest; +ByteArray MD5::getHash(const SafeByteArray& data) { + return getMD5Hash(data); } } diff --git a/Swiften/StringCodecs/MD5.h b/Swiften/StringCodecs/MD5.h index b896529..09473c2 100644 --- a/Swiften/StringCodecs/MD5.h +++ b/Swiften/StringCodecs/MD5.h @@ -6,11 +6,24 @@ #pragma once +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h> + namespace Swift { - class ByteArray; + struct md5_state_s; class MD5 { public: + MD5(); + ~MD5(); + + MD5& update(const std::vector<unsigned char>& data); + std::vector<unsigned char> getHash(); + static ByteArray getHash(const ByteArray& data); + static ByteArray getHash(const SafeByteArray& data); + + private: + md5_state_s* state; }; } diff --git a/Swiften/StringCodecs/PBKDF2.cpp b/Swiften/StringCodecs/PBKDF2.cpp deleted file mode 100644 index a652242..0000000 --- a/Swiften/StringCodecs/PBKDF2.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include "Swiften/StringCodecs/PBKDF2.h" -#include "Swiften/StringCodecs/HMACSHA1.h" - -namespace Swift { - -ByteArray PBKDF2::encode(const ByteArray& password, const ByteArray& salt, int iterations) { - ByteArray u = HMACSHA1::getResult(password, salt + ByteArray("\0\0\0\1", 4)); - ByteArray result = u; - int i = 1; - while (i < iterations) { - u = HMACSHA1::getResult(password, u); - for (unsigned int j = 0; j < u.getSize(); ++j) { - result[j] ^= u[j]; - } - ++i; - } - return result; -} - -} diff --git a/Swiften/StringCodecs/PBKDF2.h b/Swiften/StringCodecs/PBKDF2.h index 7f87af7..0c04145 100644 --- a/Swiften/StringCodecs/PBKDF2.h +++ b/Swiften/StringCodecs/PBKDF2.h @@ -6,11 +6,26 @@ #pragma once -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/SafeByteArray.h> +#include <Swiften/Base/Concat.h> namespace Swift { class PBKDF2 { public: - static ByteArray encode(const ByteArray& password, const ByteArray& salt, int iterations); + template<typename PRF> + static ByteArray encode(const SafeByteArray& password, const ByteArray& salt, int iterations) { + PRF prf; + ByteArray u = prf(password, concat(salt, createByteArray("\0\0\0\1", 4))); + ByteArray result(u); + int i = 1; + while (i < iterations) { + u = prf(password, u); + for (unsigned int j = 0; j < u.size(); ++j) { + result[j] ^= u[j]; + } + ++i; + } + return result; + } }; } diff --git a/Swiften/StringCodecs/SHA1.cpp b/Swiften/StringCodecs/SHA1.cpp index 9882f70..e4081f4 100644 --- a/Swiften/StringCodecs/SHA1.cpp +++ b/Swiften/StringCodecs/SHA1.cpp @@ -4,10 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/Platform.h" +#include <Swiften/StringCodecs/SHA1.h> + +#include <Swiften/Base/Platform.h> #pragma GCC diagnostic ignored "-Wold-style-cast" +using namespace Swift; + /* SHA-1 in C By Steve Reid <steve@edmweb.com> @@ -25,21 +29,9 @@ A million repetitions of "a" /* #define LITTLE_ENDIAN * This should be #define'd if true. */ /* #define SHA1HANDSOFF * Copies data before messing with it. */ -#include <boost/cstdint.hpp> #include <stdio.h> #include <string.h> -typedef struct { - boost::uint32_t state[5]; - boost::uint32_t count[2]; - boost::uint8_t buffer[64]; -} SHA1_CTX; - -void SHA1Transform(boost::uint32_t state[5], boost::uint8_t buffer[64]); -void SHA1Init(SHA1_CTX* context); -void SHA1Update(SHA1_CTX* context, boost::uint8_t* data, unsigned int len); -void SHA1Final(boost::uint8_t digest[20], SHA1_CTX* context); - #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) /* blk0() and blk() perform the initial expand. */ @@ -63,7 +55,7 @@ void SHA1Final(boost::uint8_t digest[20], SHA1_CTX* context); /* Hash a single 512-bit block. This is the core of the algorithm. */ -void SHA1Transform(boost::uint32_t state[5], boost::uint8_t buffer[64]) +void SHA1::Transform(boost::uint32_t state[5], boost::uint8_t buffer[64]) { boost::uint32_t a, b, c, d, e; typedef union { @@ -118,7 +110,7 @@ static boost::uint8_t workspace[64]; /* SHA1Init - Initialize new context */ -void SHA1Init(SHA1_CTX* context) +void SHA1::Init(SHA1::CTX* context) { /* SHA1 initialization constants */ context->state[0] = 0x67452301; @@ -132,7 +124,7 @@ void SHA1Init(SHA1_CTX* context) /* Run your data through this. */ -void SHA1Update(SHA1_CTX* context, boost::uint8_t* data, unsigned int len) +void SHA1::Update(SHA1::CTX* context, boost::uint8_t* data, unsigned int len) { unsigned int i, j; @@ -141,9 +133,9 @@ unsigned int i, j; context->count[1] += (len >> 29); if ((j + len) > 63) { memcpy(&context->buffer[j], data, (i = 64-j)); - SHA1Transform(context->state, context->buffer); + Transform(context->state, context->buffer); for ( ; i + 63 < len; i += 64) { - SHA1Transform(context->state, &data[i]); + Transform(context->state, &data[i]); } j = 0; } @@ -154,7 +146,7 @@ unsigned int i, j; /* Add padding and return the message digest. */ -void SHA1Final(boost::uint8_t digest[20], SHA1_CTX* context) +void SHA1::Final(boost::uint8_t digest[20], SHA1::CTX* context) { boost::uint32_t i, j; boost::uint8_t finalcount[8]; @@ -163,11 +155,11 @@ boost::uint8_t finalcount[8]; finalcount[i] = (boost::uint8_t) ((context->count[(i >= 4 ? 0 : 1)] >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ } - SHA1Update(context, (boost::uint8_t *)("\200"), 1); + Update(context, (boost::uint8_t *)("\200"), 1); while ((context->count[0] & 504) != 448) { - SHA1Update(context, (boost::uint8_t *)("\0"), 1); + Update(context, (boost::uint8_t *)("\0"), 1); } - SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ for (i = 0; i < 20; i++) { digest[i] = (boost::uint8_t) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); @@ -179,25 +171,54 @@ boost::uint8_t finalcount[8]; memset(context->count, 0, 8); memset(&finalcount, 0, 8); #ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ - SHA1Transform(context->state, context->buffer); + Transform(context->state, context->buffer); #endif } // ----------------------------------------------------------------------------- -#include "Swiften/StringCodecs/SHA1.h" - namespace Swift { -ByteArray SHA1::getHash(const ByteArray& input) { - ByteArray inputCopy(input); +SHA1::SHA1() { + Init(&context); +} + +SHA1& SHA1::update(const std::vector<unsigned char>& input) { + std::vector<unsigned char> inputCopy(input); + Update(&context, (boost::uint8_t*) vecptr(inputCopy), inputCopy.size()); + return *this; +} + +std::vector<unsigned char> SHA1::getHash() const { + std::vector<unsigned char> digest; + digest.resize(20); + CTX contextCopy(context); + Final((boost::uint8_t*) vecptr(digest), &contextCopy); + return digest; +} + +template<typename Container> +ByteArray SHA1::getHashInternal(const Container& input) { + CTX context; + Init(&context); + + Container inputCopy(input); + Update(&context, (boost::uint8_t*) vecptr(inputCopy), inputCopy.size()); + ByteArray digest; digest.resize(20); - SHA1_CTX context; - SHA1Init(&context); - SHA1Update(&context, (boost::uint8_t*) inputCopy.getData(), inputCopy.getSize()); - SHA1Final((boost::uint8_t*) digest.getData(), &context); + Final((boost::uint8_t*) vecptr(digest), &context); + return digest; } +ByteArray SHA1::getHash(const ByteArray& input) { + return getHashInternal(input); +} + +ByteArray SHA1::getHash(const SafeByteArray& input) { + return getHashInternal(input); +} + + } diff --git a/Swiften/StringCodecs/SHA1.h b/Swiften/StringCodecs/SHA1.h index fc5ba0e..19488cb 100644 --- a/Swiften/StringCodecs/SHA1.h +++ b/Swiften/StringCodecs/SHA1.h @@ -6,11 +6,50 @@ #pragma once -#include "Swiften/Base/ByteArray.h" +#include <vector> +#include <boost/cstdint.hpp> + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class SHA1 { public: + SHA1(); + + SHA1& update(const std::vector<unsigned char>& data); + std::vector<unsigned char> getHash() const; + + /** + * Equivalent of: + * SHA1().update(data),getHash(), but slightly more efficient and + * convenient. + */ static ByteArray getHash(const ByteArray& data); + static ByteArray getHash(const SafeByteArray& data); + + ByteArray operator()(const SafeByteArray& data) { + return getHash(data); + } + + ByteArray operator()(const ByteArray& data) { + return getHash(data); + } + + private: + typedef struct { + boost::uint32_t state[5]; + boost::uint32_t count[2]; + boost::uint8_t buffer[64]; + } CTX; + static void Init(CTX* context); + static void Transform(boost::uint32_t state[5], boost::uint8_t buffer[64]); + static void Update(CTX* context, boost::uint8_t* data, unsigned int len); + static void Final(boost::uint8_t digest[20], CTX* context); + + template<typename Container> static ByteArray getHashInternal(const Container& input); + + private: + CTX context; }; } diff --git a/Swiften/StringCodecs/SHA256.cpp b/Swiften/StringCodecs/SHA256.cpp new file mode 100644 index 0000000..f92e7af --- /dev/null +++ b/Swiften/StringCodecs/SHA256.cpp @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/StringCodecs/SHA256.h> + +#include <cassert> +#include <algorithm> +#include <string.h> + +#pragma GCC diagnostic ignored "-Wold-style-cast" + +using namespace Swift; + +// Copied & adapted from LibTomCrypt, by Tom St Denis, tomstdenis@gmail.com, http://libtom.org +// Substituted some macros by the platform-independent (slower) variants + +#include <stdlib.h> + +#define CRYPT_OK 0 +#define CRYPT_INVALID_ARG -1 +#define LTC_ARGCHK assert + +#define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +/* a simple macro for making hash "process" functions */ +#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \ +int func_name (State * md, const unsigned char *in, unsigned int inlen) \ +{ \ + unsigned long n; \ + int err; \ + LTC_ARGCHK(md != NULL); \ + LTC_ARGCHK(in != NULL || inlen == 0); \ + if (md-> curlen > sizeof(md->buf)) { \ + return CRYPT_INVALID_ARG; \ + } \ + while (inlen > 0) { \ + if (md->curlen == 0 && inlen >= block_size) { \ + if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \ + return err; \ + } \ + md-> length += block_size * 8; \ + in += block_size; \ + inlen -= block_size; \ + } else { \ + n = std::min(inlen, (block_size - md-> curlen)); \ + memcpy(md-> buf + md-> curlen, in, (size_t)n); \ + md-> curlen += n; \ + in += n; \ + inlen -= n; \ + if (md-> curlen == block_size) { \ + if ((err = compress_name (md, md-> buf)) != CRYPT_OK) { \ + return err; \ + } \ + md-> length += 8*block_size; \ + md-> curlen = 0; \ + } \ + } \ + } \ + return CRYPT_OK; \ +} + +#ifdef LTC_SMALL_CODE +/* the K array */ +static const boost::uint32_t K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; +#endif + +/* Various logical functions */ +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x),(n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) + +#ifdef LTC_CLEAN_STACK +int SHA256::_compress(State * md, unsigned char *buf) +#else +int SHA256::compress(State * md, unsigned char *buf) +#endif +{ + boost::uint32_t S[8], W[64], t0, t1; +#ifdef LTC_SMALL_CODE + boost::uint32_t t; +#endif + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->state[i]; + } + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32H(W[i], buf + (4*i)); + } + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + + /* Compress */ +#ifdef LTC_SMALL_CODE +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 64; ++i) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i); + t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; + S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; + } +#else +#define RND(a,b,c,d,e,f,g,h,i,ki) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); + +#undef RND + +#endif + + /* feedback */ + for (i = 0; i < 8; i++) { + md->state[i] = md->state[i] + S[i]; + } + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int SHA256::compress(State * md, unsigned char *buf) +{ + int err; + err = SHA256::_compress(md, buf); + burn_stack(sizeof(boost::uint32_t) * 74); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int SHA256::init(State * md) +{ + LTC_ARGCHK(md != NULL); + + md->curlen = 0; + md->length = 0; + md->state[0] = 0x6A09E667UL; + md->state[1] = 0xBB67AE85UL; + md->state[2] = 0x3C6EF372UL; + md->state[3] = 0xA54FF53AUL; + md->state[4] = 0x510E527FUL; + md->state[5] = 0x9B05688CUL; + md->state[6] = 0x1F83D9ABUL; + md->state[7] = 0x5BE0CD19UL; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(SHA256::process, SHA256::compress, sha256, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful +*/ +int SHA256::done(State * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->curlen >= sizeof(md->buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->length += md->curlen * 8; + + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->curlen > 56) { + while (md->curlen < 64) { + md->buf[md->curlen++] = (unsigned char)0; + } + SHA256::compress(md, md->buf); + md->curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->curlen < 56) { + md->buf[md->curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->length, md->buf+56); + SHA256::compress(md, md->buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE32H(md->state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(State)); +#endif + return CRYPT_OK; +} + +// End copied code + +namespace Swift { + +SHA256::SHA256() { + init(&state); +} + +SHA256& SHA256::update(const std::vector<unsigned char>& input) { + std::vector<unsigned char> inputCopy(input); + process(&state, (boost::uint8_t*) vecptr(inputCopy), inputCopy.size()); + return *this; +} + +std::vector<unsigned char> SHA256::getHash() const { + std::vector<unsigned char> digest; + digest.resize(256/8); + State contextCopy(state); + done(&contextCopy, (boost::uint8_t*) vecptr(digest)); + return digest; +} + +template<typename Container> +ByteArray SHA256::getHashInternal(const Container& input) { + State context; + init(&context); + + Container inputCopy(input); + process(&context, (boost::uint8_t*) vecptr(inputCopy), inputCopy.size()); + + ByteArray digest; + digest.resize(256/8); + done(&context, (boost::uint8_t*) vecptr(digest)); + + return digest; +} + +ByteArray SHA256::getHash(const ByteArray& input) { + return getHashInternal(input); +} + +ByteArray SHA256::getHash(const SafeByteArray& input) { + return getHashInternal(input); +} + +} diff --git a/Swiften/StringCodecs/SHA256.h b/Swiften/StringCodecs/SHA256.h new file mode 100644 index 0000000..28a0e05 --- /dev/null +++ b/Swiften/StringCodecs/SHA256.h @@ -0,0 +1,56 @@ +/* + * 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 <vector> +#include <boost/cstdint.hpp> + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h> + +namespace Swift { + class SHA256 { + public: + SHA256(); + + SHA256& update(const std::vector<unsigned char>& data); + std::vector<unsigned char> getHash() const; + + /** + * Equivalent of: + * SHA256().update(data),getHash(), but slightly more efficient and + * convenient. + */ + static ByteArray getHash(const ByteArray& data); + static ByteArray getHash(const SafeByteArray& data); + + ByteArray operator()(const SafeByteArray& data) { + return getHash(data); + } + + ByteArray operator()(const ByteArray& data) { + return getHash(data); + } + + private: + struct State { + boost::uint64_t length; + boost::uint32_t state[8], curlen; + unsigned char buf[64]; + }; + + static int init(State *md); + static int process(State * md, const unsigned char *in, unsigned int inlen); + static int compress(State *md, unsigned char *buf); + static int done(State * md, unsigned char *out); + + template<typename Container> static ByteArray getHashInternal(const Container& input); + + private: + State state; + }; +} diff --git a/Swiften/StringCodecs/UnitTest/Base64Test.cpp b/Swiften/StringCodecs/UnitTest/Base64Test.cpp index b263050..f6a424b 100644 --- a/Swiften/StringCodecs/UnitTest/Base64Test.cpp +++ b/Swiften/StringCodecs/UnitTest/Base64Test.cpp @@ -4,12 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/StringCodecs/Base64.h> using namespace Swift; @@ -24,12 +25,12 @@ class Base64Test : public CppUnit::TestFixture { public: void testEncode() { - std::string result(Base64::encode("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890")); + std::string result(Base64::encode(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"))); CPPUNIT_ASSERT_EQUAL(std::string("QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejEyMzQ1Njc4OTA="), result); } void testEncode_NonAscii() { - std::string result(Base64::encode(ByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"))); + std::string result(Base64::encode(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"))); CPPUNIT_ASSERT_EQUAL(std::string("QgayPKawpkPSDYmwT/WM94uAlu0="), result); } @@ -40,7 +41,7 @@ class Base64Test : public CppUnit::TestFixture { void testDecode() { ByteArray result(Base64::decode("QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejEyMzQ1Njc4OTA=")); - CPPUNIT_ASSERT_EQUAL(ByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"), result); + CPPUNIT_ASSERT_EQUAL(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"), result); } void testDecode_NoData() { diff --git a/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp b/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp deleted file mode 100644 index 44bd5b7..0000000 --- a/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include "Swiften/Base/ByteArray.h" - -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/extensions/TestFactoryRegistry.h> - -#include "Swiften/Base/ByteArray.h" -#include "Swiften/StringCodecs/HMACSHA1.h" - -using namespace Swift; - -class HMACSHA1Test : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(HMACSHA1Test); - CPPUNIT_TEST(testGetResult); - CPPUNIT_TEST_SUITE_END(); - - public: - void testGetResult() { - ByteArray result(HMACSHA1::getResult("foo", "foobar")); - CPPUNIT_ASSERT_EQUAL(ByteArray("\xa4\xee\xba\x8e\x63\x3d\x77\x88\x69\xf5\x68\xd0\x5a\x1b\x3d\xc7\x2b\xfd\x4\xdd"), result); - } -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(HMACSHA1Test); diff --git a/Swiften/StringCodecs/UnitTest/HMACTest.cpp b/Swiften/StringCodecs/UnitTest/HMACTest.cpp new file mode 100644 index 0000000..50b1330 --- /dev/null +++ b/Swiften/StringCodecs/UnitTest/HMACTest.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/StringCodecs/HMAC_SHA1.h> +#include <Swiften/StringCodecs/HMAC_SHA256.h> + +using namespace Swift; + +class HMACTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(HMACTest); + CPPUNIT_TEST(testGetResult); + CPPUNIT_TEST(testGetResult_KeyLongerThanBlockSize); + CPPUNIT_TEST(testGetResult_RFC4231_1); + CPPUNIT_TEST(testGetResult_RFC4231_7); + CPPUNIT_TEST_SUITE_END(); + + public: + void testGetResult() { + ByteArray result(HMAC_SHA1()(createSafeByteArray("foo"), createByteArray("foobar"))); + CPPUNIT_ASSERT_EQUAL(createByteArray("\xa4\xee\xba\x8e\x63\x3d\x77\x88\x69\xf5\x68\xd0\x5a\x1b\x3d\xc7\x2b\xfd\x4\xdd"), result); + } + + void testGetResult_KeyLongerThanBlockSize() { + ByteArray result(HMAC_SHA1()(createSafeByteArray("---------|---------|---------|---------|---------|----------|---------|"), createByteArray("foobar"))); + CPPUNIT_ASSERT_EQUAL(createByteArray("\xd6""n""\x8f""P|1""\xd3"",""\x6"" ""\xb9\xe3""gg""\x8e\xcf"" ]+""\xa"), result); + } + + void testGetResult_RFC4231_1() { + ByteArray result(HMAC_SHA256()(createSafeByteArray("\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20), createByteArray("Hi There"))); + CPPUNIT_ASSERT_EQUAL(createByteArray("\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7", 32), result); + } + + void testGetResult_RFC4231_7() { + ByteArray result(HMAC_SHA256()(createSafeByteArray("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131), createByteArray("This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm."))); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2", 32), result); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(HMACTest); diff --git a/Swiften/StringCodecs/UnitTest/HexifyTest.cpp b/Swiften/StringCodecs/UnitTest/HexifyTest.cpp index 0f267bf..38233f9 100644 --- a/Swiften/StringCodecs/UnitTest/HexifyTest.cpp +++ b/Swiften/StringCodecs/UnitTest/HexifyTest.cpp @@ -7,9 +7,9 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/StringCodecs/Hexify.h" +#include <Swiften/StringCodecs/Hexify.h> #include <string> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> using namespace Swift; @@ -17,16 +17,22 @@ class HexifyTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(HexifyTest); CPPUNIT_TEST(testHexify); CPPUNIT_TEST(testHexify_Byte); + CPPUNIT_TEST(testUnhexify); CPPUNIT_TEST_SUITE_END(); public: void testHexify() { - CPPUNIT_ASSERT_EQUAL(std::string("4206b23ca6b0a643d20d89b04ff58cf78b8096ed"), Hexify::hexify(ByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"))); + CPPUNIT_ASSERT_EQUAL(std::string("4206b23ca6b0a643d20d89b04ff58cf78b8096ed"), Hexify::hexify(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"))); } void testHexify_Byte() { CPPUNIT_ASSERT_EQUAL(std::string("b2"), Hexify::hexify(0xb2)); } + + void testUnhexify() { + CPPUNIT_ASSERT_EQUAL(std::string("ffaf02"), Hexify::hexify(Hexify::unhexify("ffaf02"))); + CPPUNIT_ASSERT(createByteArray("\x01\x23\xf2", 3) == Hexify::unhexify("0123f2")); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(HexifyTest); diff --git a/Swiften/StringCodecs/UnitTest/MD5Test.cpp b/Swiften/StringCodecs/UnitTest/MD5Test.cpp index b76af48..c62c46a 100644 --- a/Swiften/StringCodecs/UnitTest/MD5Test.cpp +++ b/Swiften/StringCodecs/UnitTest/MD5Test.cpp @@ -4,13 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/StringCodecs/MD5.h" -#include "Swiften/Base/ByteArray.h" +#include <Swiften/StringCodecs/MD5.h> +#include <Swiften/Base/ByteArray.h> using namespace Swift; @@ -18,19 +19,30 @@ class MD5Test : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(MD5Test); CPPUNIT_TEST(testGetHash_Empty); CPPUNIT_TEST(testGetHash_Alphabet); + CPPUNIT_TEST(testIncrementalTest); CPPUNIT_TEST_SUITE_END(); public: void testGetHash_Empty() { - ByteArray result(MD5::getHash("")); + ByteArray result(MD5::getHash(createByteArray(""))); - CPPUNIT_ASSERT_EQUAL(ByteArray("\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e", 16), result); + CPPUNIT_ASSERT_EQUAL(createByteArray("\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e", 16), result); } void testGetHash_Alphabet() { - ByteArray result(MD5::getHash("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")); + ByteArray result(MD5::getHash(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"))); - CPPUNIT_ASSERT_EQUAL(ByteArray("\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f", 16), result); + CPPUNIT_ASSERT_EQUAL(createByteArray("\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f", 16), result); + } + + void testIncrementalTest() { + MD5 testling; + testling.update(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZ")); + testling.update(createByteArray("abcdefghijklmnopqrstuvwxyz0123456789")); + + ByteArray result = testling.getHash(); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f", 16), result); } }; diff --git a/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp b/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp index 092fe31..608ca62 100644 --- a/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp +++ b/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp @@ -4,13 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/StringCodecs/PBKDF2.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/StringCodecs/PBKDF2.h> +#include <Swiften/StringCodecs/HMAC_SHA1.h> using namespace Swift; @@ -23,21 +25,21 @@ class PBKDF2Test : public CppUnit::TestFixture { public: void testGetResult_I1() { - ByteArray result(PBKDF2::encode("password", "salt", 1)); + ByteArray result(PBKDF2::encode<HMAC_SHA1 >(createSafeByteArray("password"), createByteArray("salt"), 1)); - CPPUNIT_ASSERT_EQUAL(ByteArray("\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6"), result); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6"), result); } void testGetResult_I2() { - ByteArray result(PBKDF2::encode("password", "salt", 2)); + ByteArray result(PBKDF2::encode<HMAC_SHA1 >(createSafeByteArray("password"), createByteArray("salt"), 2)); - CPPUNIT_ASSERT_EQUAL(ByteArray("\xea\x6c\x1\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57"), result); + CPPUNIT_ASSERT_EQUAL(createByteArray("\xea\x6c\x1\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57"), result); } void testGetResult_I4096() { - ByteArray result(PBKDF2::encode("password", "salt", 4096)); + ByteArray result(PBKDF2::encode<HMAC_SHA1 >(createSafeByteArray("password"), createByteArray("salt"), 4096)); - CPPUNIT_ASSERT_EQUAL(ByteArray("\x4b\x00\x79\x1\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1", 20), result); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x4b\x00\x79\x1\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1", 20), result); } }; diff --git a/Swiften/StringCodecs/UnitTest/SHA1Test.cpp b/Swiften/StringCodecs/UnitTest/SHA1Test.cpp index 9434235..bdccb1c 100644 --- a/Swiften/StringCodecs/UnitTest/SHA1Test.cpp +++ b/Swiften/StringCodecs/UnitTest/SHA1Test.cpp @@ -4,41 +4,89 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/StringCodecs/SHA1.h" +#include <Swiften/StringCodecs/SHA1.h> using namespace Swift; class SHA1Test : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(SHA1Test); CPPUNIT_TEST(testGetHash); - CPPUNIT_TEST(testGetHash_Twice); + CPPUNIT_TEST(testGetHash_TwoUpdates); + CPPUNIT_TEST(testGetHash_TwoGetHash); CPPUNIT_TEST(testGetHash_NoData); + CPPUNIT_TEST(testGetHash_InterleavedUpdate); + CPPUNIT_TEST(testGetHashStatic); + CPPUNIT_TEST(testGetHashStatic_Twice); + CPPUNIT_TEST(testGetHashStatic_NoData); CPPUNIT_TEST_SUITE_END(); public: void testGetHash() { - ByteArray result(SHA1::getHash("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); - CPPUNIT_ASSERT_EQUAL(ByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), result); + SHA1 sha; + sha.update(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), sha.getHash()); + } + + void testGetHash_TwoUpdates() { + SHA1 sha; + sha.update(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<")); + sha.update(createByteArray("http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), sha.getHash()); + } + + void testGetHash_TwoGetHash() { + SHA1 sha; + sha.update(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); + + sha.getHash(); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), sha.getHash()); + } + + void testGetHash_InterleavedUpdate() { + SHA1 sha; + + sha.update(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<")); + sha.getHash(); + sha.update(createByteArray("http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), sha.getHash()); + } + + + void testGetHash_NoData() { + SHA1 sha; + sha.update(std::vector<unsigned char>()); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09"), sha.getHash()); } + void testGetHashStatic() { + ByteArray result(SHA1::getHash(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<"))); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), result); + } - void testGetHash_Twice() { - ByteArray input("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<"); + + void testGetHashStatic_Twice() { + ByteArray input(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); SHA1::getHash(input); ByteArray result(SHA1::getHash(input)); - CPPUNIT_ASSERT_EQUAL(ByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), result); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), result); } - void testGetHash_NoData() { + void testGetHashStatic_NoData() { ByteArray result(SHA1::getHash(ByteArray())); - CPPUNIT_ASSERT_EQUAL(ByteArray("\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09"), result); + CPPUNIT_ASSERT_EQUAL(createByteArray("\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09"), result); } }; diff --git a/Swiften/StringCodecs/UnitTest/SHA256Test.cpp b/Swiften/StringCodecs/UnitTest/SHA256Test.cpp new file mode 100644 index 0000000..5bcdd11 --- /dev/null +++ b/Swiften/StringCodecs/UnitTest/SHA256Test.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/StringCodecs/SHA256.h> + +using namespace Swift; + +class SHA256Test : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(SHA256Test); + CPPUNIT_TEST(testGetHashStatic_Empty); + CPPUNIT_TEST(testGetHashStatic_Small); + CPPUNIT_TEST(testGetHashStatic_Large); + CPPUNIT_TEST_SUITE_END(); + + public: + void testGetHashStatic_Empty() { + ByteArray result(SHA256::getHash(createByteArray(""))); + CPPUNIT_ASSERT_EQUAL(createByteArray("\xe3\xb0\xc4" "B" "\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99" "o" "\xb9" "$'" "\xae" "A" "\xe4" "d" "\x9b\x93" "L" "\xa4\x95\x99\x1b" "xR" "\xb8" "U", 32), result); + } + + void testGetHashStatic_Small() { + ByteArray result(SHA256::getHash(createByteArray("abc"))); + CPPUNIT_ASSERT_EQUAL(createByteArray("\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad", 32), result); + } + + void testGetHashStatic_Large() { + ByteArray result(SHA256::getHash(createByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"))); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1", 32), result); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(SHA256Test); diff --git a/Swiften/TLS/BlindCertificateTrustChecker.h b/Swiften/TLS/BlindCertificateTrustChecker.h index d9db14c..3177322 100644 --- a/Swiften/TLS/BlindCertificateTrustChecker.h +++ b/Swiften/TLS/BlindCertificateTrustChecker.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/TLS/CertificateTrustChecker.h" +#include <Swiften/TLS/CertificateTrustChecker.h> namespace Swift { /** diff --git a/Swiften/TLS/Certificate.cpp b/Swiften/TLS/Certificate.cpp index ecd7d5e..a796463 100644 --- a/Swiften/TLS/Certificate.cpp +++ b/Swiften/TLS/Certificate.cpp @@ -22,7 +22,7 @@ Certificate::~Certificate() { std::string Certificate::getSHA1Fingerprint() const { ByteArray hash = SHA1::getHash(toDER()); std::ostringstream s; - for (size_t i = 0; i < hash.getSize(); ++i) { + for (size_t i = 0; i < hash.size(); ++i) { if (i > 0) { s << ":"; } diff --git a/Swiften/TLS/Certificate.h b/Swiften/TLS/Certificate.h index dc93a2d..ec59a39 100644 --- a/Swiften/TLS/Certificate.h +++ b/Swiften/TLS/Certificate.h @@ -9,7 +9,7 @@ #include <boost/shared_ptr.hpp> #include <string> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> namespace Swift { class Certificate { diff --git a/Swiften/TLS/CertificateFactory.cpp b/Swiften/TLS/CertificateFactory.cpp index b2edaf4..df01090 100644 --- a/Swiften/TLS/CertificateFactory.cpp +++ b/Swiften/TLS/CertificateFactory.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/TLS/CertificateFactory.h" +#include <Swiften/TLS/CertificateFactory.h> namespace Swift { diff --git a/Swiften/TLS/CertificateFactory.h b/Swiften/TLS/CertificateFactory.h index 90eca58..3e94082 100644 --- a/Swiften/TLS/CertificateFactory.h +++ b/Swiften/TLS/CertificateFactory.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/TLS/Certificate.h" +#include <Swiften/TLS/Certificate.h> namespace Swift { class CertificateFactory { diff --git a/Swiften/TLS/CertificateTrustChecker.cpp b/Swiften/TLS/CertificateTrustChecker.cpp index f4f921d..42e24a1 100644 --- a/Swiften/TLS/CertificateTrustChecker.cpp +++ b/Swiften/TLS/CertificateTrustChecker.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/TLS/CertificateTrustChecker.h" +#include <Swiften/TLS/CertificateTrustChecker.h> namespace Swift { diff --git a/Swiften/TLS/CertificateTrustChecker.h b/Swiften/TLS/CertificateTrustChecker.h index aec03e3..06c0c32 100644 --- a/Swiften/TLS/CertificateTrustChecker.h +++ b/Swiften/TLS/CertificateTrustChecker.h @@ -9,7 +9,7 @@ #include <boost/shared_ptr.hpp> #include <string> -#include "Swiften/TLS/Certificate.h" +#include <Swiften/TLS/Certificate.h> namespace Swift { /** diff --git a/Swiften/TLS/CertificateVerificationError.h b/Swiften/TLS/CertificateVerificationError.h index 554fd3b..2815fdb 100644 --- a/Swiften/TLS/CertificateVerificationError.h +++ b/Swiften/TLS/CertificateVerificationError.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/Base/Error.h" +#include <Swiften/Base/Error.h> namespace Swift { class CertificateVerificationError : public Error { diff --git a/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp b/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp index 0b2df5b..06ce360 100644 --- a/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp +++ b/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp @@ -23,11 +23,11 @@ OpenSSLCertificate::OpenSSLCertificate(boost::shared_ptr<X509> cert) : cert(cert OpenSSLCertificate::OpenSSLCertificate(const ByteArray& der) { #if OPENSSL_VERSION_NUMBER <= 0x009070cfL - unsigned char* p = const_cast<unsigned char*>(der.getData()); + unsigned char* p = const_cast<unsigned char*>(vecptr(der)); #else - const unsigned char* p = der.getData(); + const unsigned char* p = vecptr(der); #endif - cert = boost::shared_ptr<X509>(d2i_X509(NULL, &p, der.getSize()), X509_free); + cert = boost::shared_ptr<X509>(d2i_X509(NULL, &p, der.size()), X509_free); if (!cert) { SWIFT_LOG(warning) << "Error creating certificate from DER data" << std::endl; } @@ -41,7 +41,7 @@ ByteArray OpenSSLCertificate::toDER() const { ByteArray result; result.resize(i2d_X509(cert.get(), NULL)); - unsigned char* p = reinterpret_cast<unsigned char*>(result.getData()); + unsigned char* p = vecptr(result); i2d_X509(cert.get(), &p); return result; } @@ -57,15 +57,15 @@ void OpenSSLCertificate::parse() { // Subject name ByteArray subjectNameData; subjectNameData.resize(256); - X509_NAME_oneline(X509_get_subject_name(cert.get()), reinterpret_cast<char*>(subjectNameData.getData()), subjectNameData.getSize()); - this->subjectName = std::string(reinterpret_cast<const char*>(subjectNameData.getData())); + X509_NAME_oneline(X509_get_subject_name(cert.get()), reinterpret_cast<char*>(vecptr(subjectNameData)), subjectNameData.size()); + this->subjectName = byteArrayToString(subjectNameData); // Common name int cnLoc = X509_NAME_get_index_by_NID(subjectName, NID_commonName, -1); while (cnLoc != -1) { X509_NAME_ENTRY* cnEntry = X509_NAME_get_entry(subjectName, cnLoc); ASN1_STRING* cnData = X509_NAME_ENTRY_get_data(cnEntry); - commonNames.push_back(ByteArray(cnData->data, cnData->length).toString()); + commonNames.push_back(byteArrayToString(createByteArray(reinterpret_cast<const char*>(cnData->data), cnData->length))); cnLoc = X509_NAME_get_index_by_NID(subjectName, NID_commonName, cnLoc); } } @@ -87,7 +87,7 @@ void OpenSSLCertificate::parse() { continue; } ASN1_UTF8STRING* xmppAddrValue = otherName->value->value.utf8string; - addXMPPAddress(ByteArray(ASN1_STRING_data(xmppAddrValue), ASN1_STRING_length(xmppAddrValue)).toString()); + addXMPPAddress(byteArrayToString(createByteArray(reinterpret_cast<const char*>(ASN1_STRING_data(xmppAddrValue)), ASN1_STRING_length(xmppAddrValue)))); } else if (OBJ_cmp(otherName->type_id, dnsSRVObject.get()) == 0) { // SRVName @@ -95,12 +95,12 @@ void OpenSSLCertificate::parse() { continue; } ASN1_IA5STRING* srvNameValue = otherName->value->value.ia5string; - addSRVName(ByteArray(ASN1_STRING_data(srvNameValue), ASN1_STRING_length(srvNameValue)).toString()); + addSRVName(byteArrayToString(createByteArray(reinterpret_cast<const char*>(ASN1_STRING_data(srvNameValue)), ASN1_STRING_length(srvNameValue)))); } } else if (generalName->type == GEN_DNS) { // DNSName - addDNSName(ByteArray(ASN1_STRING_data(generalName->d.dNSName), ASN1_STRING_length(generalName->d.dNSName)).toString()); + addDNSName(byteArrayToString(createByteArray(ASN1_STRING_data(generalName->d.dNSName), ASN1_STRING_length(generalName->d.dNSName)))); } } } diff --git a/Swiften/TLS/OpenSSL/OpenSSLCertificate.h b/Swiften/TLS/OpenSSL/OpenSSLCertificate.h index b900170..897b432 100644 --- a/Swiften/TLS/OpenSSL/OpenSSLCertificate.h +++ b/Swiften/TLS/OpenSSL/OpenSSLCertificate.h @@ -10,7 +10,7 @@ #include <openssl/ssl.h> #include <string> -#include "Swiften/TLS/Certificate.h" +#include <Swiften/TLS/Certificate.h> namespace Swift { class OpenSSLCertificate : public Certificate { diff --git a/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h b/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h index cd4982e..52f134c 100644 --- a/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h +++ b/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/TLS/CertificateFactory.h" -#include "Swiften/TLS/OpenSSL/OpenSSLCertificate.h" +#include <Swiften/TLS/CertificateFactory.h> +#include <Swiften/TLS/OpenSSL/OpenSSLCertificate.h> namespace Swift { class OpenSSLCertificateFactory : public CertificateFactory { diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp index 378b6aa..220e7f9 100644 --- a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp +++ b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp @@ -3,7 +3,7 @@ * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/Platform.h" +#include <Swiften/Base/Platform.h> #ifdef SWIFTEN_PLATFORM_WINDOWS #include <windows.h> @@ -13,14 +13,15 @@ #include <vector> #include <openssl/err.h> #include <openssl/pkcs12.h> +#include <boost/smart_ptr/make_shared.hpp> #if defined(SWIFTEN_PLATFORM_MACOSX) && OPENSSL_VERSION_NUMBER < 0x00908000 #include <Security/Security.h> #endif -#include "Swiften/TLS/OpenSSL/OpenSSLContext.h" -#include "Swiften/TLS/OpenSSL/OpenSSLCertificate.h" -#include "Swiften/TLS/PKCS12Certificate.h" +#include <Swiften/TLS/OpenSSL/OpenSSLContext.h> +#include <Swiften/TLS/OpenSSL/OpenSSLCertificate.h> +#include <Swiften/TLS/PKCS12Certificate.h> #pragma GCC diagnostic ignored "-Wold-style-cast" @@ -48,8 +49,7 @@ OpenSSLContext::OpenSSLContext() : state_(Start), context_(0), handle_(0), readB if (!certContext) { break; } - ByteArray certData(certContext->pbCertEncoded, certContext->cbCertEncoded); - OpenSSLCertificate cert(certData); + OpenSSLCertificate cert(createByteArray(certContext->pbCertEncoded, certContext->cbCertEncoded)); if (store && cert.getInternalX509()) { X509_STORE_add_cert(store, cert.getInternalX509().get()); } @@ -138,15 +138,15 @@ void OpenSSLContext::doConnect() { void OpenSSLContext::sendPendingDataToNetwork() { int size = BIO_pending(writeBIO_); if (size > 0) { - ByteArray data; + SafeByteArray data; data.resize(size); - BIO_read(writeBIO_, data.getData(), size); + BIO_read(writeBIO_, vecptr(data), size); onDataForNetwork(data); } } -void OpenSSLContext::handleDataFromNetwork(const ByteArray& data) { - BIO_write(readBIO_, data.getData(), data.getSize()); +void OpenSSLContext::handleDataFromNetwork(const SafeByteArray& data) { + BIO_write(readBIO_, vecptr(data), data.size()); switch (state_) { case Connecting: doConnect(); @@ -159,8 +159,8 @@ void OpenSSLContext::handleDataFromNetwork(const ByteArray& data) { } } -void OpenSSLContext::handleDataFromApplication(const ByteArray& data) { - if (SSL_write(handle_, data.getData(), data.getSize()) >= 0) { +void OpenSSLContext::handleDataFromApplication(const SafeByteArray& data) { + if (SSL_write(handle_, vecptr(data), data.size()) >= 0) { sendPendingDataToNetwork(); } else { @@ -170,14 +170,14 @@ void OpenSSLContext::handleDataFromApplication(const ByteArray& data) { } void OpenSSLContext::sendPendingDataToApplication() { - ByteArray data; + SafeByteArray data; data.resize(SSL_READ_BUFFERSIZE); - int ret = SSL_read(handle_, data.getData(), data.getSize()); + int ret = SSL_read(handle_, vecptr(data), data.size()); while (ret > 0) { data.resize(ret); onDataForApplication(data); data.resize(SSL_READ_BUFFERSIZE); - ret = SSL_read(handle_, data.getData(), data.getSize()); + ret = SSL_read(handle_, vecptr(data), data.size()); } if (ret < 0 && SSL_get_error(handle_, ret) != SSL_ERROR_WANT_READ) { state_ = Error; @@ -192,7 +192,7 @@ bool OpenSSLContext::setClientCertificate(const PKCS12Certificate& certificate) // Create a PKCS12 structure BIO* bio = BIO_new(BIO_s_mem()); - BIO_write(bio, certificate.getData().getData(), certificate.getData().getSize()); + BIO_write(bio, vecptr(certificate.getData()), certificate.getData().size()); boost::shared_ptr<PKCS12> pkcs12(d2i_PKCS12_bio(bio, NULL), PKCS12_free); BIO_free(bio); if (!pkcs12) { @@ -203,7 +203,7 @@ bool OpenSSLContext::setClientCertificate(const PKCS12Certificate& certificate) X509 *certPtr = 0; EVP_PKEY* privateKeyPtr = 0; STACK_OF(X509)* caCertsPtr = 0; - int result = PKCS12_parse(pkcs12.get(), certificate.getPassword().c_str(), &privateKeyPtr, &certPtr, &caCertsPtr); + int result = PKCS12_parse(pkcs12.get(), reinterpret_cast<const char*>(vecptr(certificate.getPassword())), &privateKeyPtr, &certPtr, &caCertsPtr); if (result != 1) { return false; } @@ -227,7 +227,7 @@ bool OpenSSLContext::setClientCertificate(const PKCS12Certificate& certificate) Certificate::ref OpenSSLContext::getPeerCertificate() const { boost::shared_ptr<X509> x509Cert(SSL_get_peer_certificate(handle_), X509_free); if (x509Cert) { - return Certificate::ref(new OpenSSLCertificate(x509Cert)); + return boost::make_shared<OpenSSLCertificate>(x509Cert); } else { return Certificate::ref(); @@ -237,7 +237,7 @@ Certificate::ref OpenSSLContext::getPeerCertificate() const { boost::shared_ptr<CertificateVerificationError> OpenSSLContext::getPeerCertificateVerificationError() const { int verifyResult = SSL_get_verify_result(handle_); if (verifyResult != X509_V_OK) { - return boost::shared_ptr<CertificateVerificationError>(new CertificateVerificationError(getVerificationErrorTypeForResult(verifyResult))); + return boost::make_shared<CertificateVerificationError>(getVerificationErrorTypeForResult(verifyResult)); } else { return boost::shared_ptr<CertificateVerificationError>(); @@ -247,7 +247,7 @@ boost::shared_ptr<CertificateVerificationError> OpenSSLContext::getPeerCertifica ByteArray OpenSSLContext::getFinishMessage() const { ByteArray data; data.resize(MAX_FINISHED_SIZE); - size_t size = SSL_get_finished(handle_, data.getData(), data.getSize()); + size_t size = SSL_get_finished(handle_, vecptr(data), data.size()); data.resize(size); return data; } diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.h b/Swiften/TLS/OpenSSL/OpenSSLContext.h index 40e5483..04693a3 100644 --- a/Swiften/TLS/OpenSSL/OpenSSLContext.h +++ b/Swiften/TLS/OpenSSL/OpenSSLContext.h @@ -7,11 +7,11 @@ #pragma once #include <openssl/ssl.h> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/noncopyable.hpp> -#include "Swiften/TLS/TLSContext.h" -#include "Swiften/Base/ByteArray.h" +#include <Swiften/TLS/TLSContext.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { class PKCS12Certificate; @@ -24,8 +24,8 @@ namespace Swift { void connect(); bool setClientCertificate(const PKCS12Certificate& cert); - void handleDataFromNetwork(const ByteArray&); - void handleDataFromApplication(const ByteArray&); + void handleDataFromNetwork(const SafeByteArray&); + void handleDataFromApplication(const SafeByteArray&); Certificate::ref getPeerCertificate() const; boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const; diff --git a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp index f975df7..516482d 100644 --- a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp +++ b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp @@ -4,8 +4,8 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/TLS/OpenSSL/OpenSSLContextFactory.h" -#include "Swiften/TLS/OpenSSL/OpenSSLContext.h" +#include <Swiften/TLS/OpenSSL/OpenSSLContextFactory.h> +#include <Swiften/TLS/OpenSSL/OpenSSLContext.h> namespace Swift { diff --git a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h index cf982c0..4e39cd6 100644 --- a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h +++ b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/TLS/TLSContextFactory.h" +#include <Swiften/TLS/TLSContextFactory.h> namespace Swift { class OpenSSLContextFactory : public TLSContextFactory { diff --git a/Swiften/TLS/PKCS12Certificate.h b/Swiften/TLS/PKCS12Certificate.h index 1c8c38f..c0e01d0 100644 --- a/Swiften/TLS/PKCS12Certificate.h +++ b/Swiften/TLS/PKCS12Certificate.h @@ -4,22 +4,21 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_PKCS12Certificate_H -#define SWIFTEN_PKCS12Certificate_H +#pragma once -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class PKCS12Certificate { public: PKCS12Certificate() {} - PKCS12Certificate(const std::string& filename, const std::string& password) : password_(password) { - data_.readFromFile(filename); + PKCS12Certificate(const std::string& filename, const SafeByteArray& password) : password_(password) { + readByteArrayFromFile(data_, filename); } bool isNull() const { - return data_.isEmpty(); + return data_.empty(); } const ByteArray& getData() const { @@ -30,14 +29,12 @@ namespace Swift { data_ = data; } - const std::string& getPassword() const { + const SafeByteArray& getPassword() const { return password_; } private: ByteArray data_; - std::string password_; + SafeByteArray password_; }; } - -#endif diff --git a/Swiften/TLS/PlatformTLSFactories.cpp b/Swiften/TLS/PlatformTLSFactories.cpp index e642758..dec8788 100644 --- a/Swiften/TLS/PlatformTLSFactories.cpp +++ b/Swiften/TLS/PlatformTLSFactories.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/TLS/PlatformTLSFactories.h" +#include <Swiften/TLS/PlatformTLSFactories.h> #include <cstring> #include <cassert> #ifdef HAVE_OPENSSL -#include "Swiften/TLS/OpenSSL/OpenSSLContextFactory.h" -#include "Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h" +#include <Swiften/TLS/OpenSSL/OpenSSLContextFactory.h> +#include <Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h> #endif namespace Swift { diff --git a/Swiften/TLS/ServerIdentityVerifier.cpp b/Swiften/TLS/ServerIdentityVerifier.cpp index d7b0580..a908ad0 100644 --- a/Swiften/TLS/ServerIdentityVerifier.cpp +++ b/Swiften/TLS/ServerIdentityVerifier.cpp @@ -4,12 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/TLS/ServerIdentityVerifier.h" +#include <Swiften/TLS/ServerIdentityVerifier.h> #include <boost/algorithm/string.hpp> -#include "Swiften/Base/foreach.h" -#include "Swiften/IDN/IDNA.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/IDN/IDNA.h> namespace Swift { @@ -63,7 +63,7 @@ bool ServerIdentityVerifier::certificateVerifies(Certificate::ref certificate) { return false; } -bool ServerIdentityVerifier::matchesDomain(const std::string& s) { +bool ServerIdentityVerifier::matchesDomain(const std::string& s) const { if (boost::starts_with(s, "*.")) { std::string matchString(s.substr(2, s.npos)); std::string matchDomain = encodedDomain; @@ -78,7 +78,7 @@ bool ServerIdentityVerifier::matchesDomain(const std::string& s) { } } -bool ServerIdentityVerifier::matchesAddress(const std::string& s) { +bool ServerIdentityVerifier::matchesAddress(const std::string& s) const { return s == domain; } diff --git a/Swiften/TLS/ServerIdentityVerifier.h b/Swiften/TLS/ServerIdentityVerifier.h index 05bb5f0..b09abd9 100644 --- a/Swiften/TLS/ServerIdentityVerifier.h +++ b/Swiften/TLS/ServerIdentityVerifier.h @@ -9,8 +9,8 @@ #include <boost/shared_ptr.hpp> #include <string> -#include "Swiften/JID/JID.h" -#include "Swiften/TLS/Certificate.h" +#include <Swiften/JID/JID.h> +#include <Swiften/TLS/Certificate.h> namespace Swift { class ServerIdentityVerifier { @@ -20,8 +20,8 @@ namespace Swift { bool certificateVerifies(Certificate::ref); private: - bool matchesDomain(const std::string&); - bool matchesAddress(const std::string&); + bool matchesDomain(const std::string&) const ; + bool matchesAddress(const std::string&) const; private: std::string domain; diff --git a/Swiften/TLS/SimpleCertificate.h b/Swiften/TLS/SimpleCertificate.h index a81a23e..4cf0cc2 100644 --- a/Swiften/TLS/SimpleCertificate.h +++ b/Swiften/TLS/SimpleCertificate.h @@ -7,7 +7,7 @@ #pragma once #include <string> -#include "Swiften/TLS/Certificate.h" +#include <Swiften/TLS/Certificate.h> namespace Swift { class SimpleCertificate : public Certificate { diff --git a/Swiften/TLS/TLSContext.cpp b/Swiften/TLS/TLSContext.cpp index 008bfc0..026ae70 100644 --- a/Swiften/TLS/TLSContext.cpp +++ b/Swiften/TLS/TLSContext.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/TLS/TLSContext.h" +#include <Swiften/TLS/TLSContext.h> namespace Swift { diff --git a/Swiften/TLS/TLSContext.h b/Swiften/TLS/TLSContext.h index 1279eeb..1538863 100644 --- a/Swiften/TLS/TLSContext.h +++ b/Swiften/TLS/TLSContext.h @@ -6,12 +6,12 @@ #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/TLS/Certificate.h" -#include "Swiften/TLS/CertificateVerificationError.h" +#include <Swiften/Base/SafeByteArray.h> +#include <Swiften/TLS/Certificate.h> +#include <Swiften/TLS/CertificateVerificationError.h> namespace Swift { class PKCS12Certificate; @@ -24,8 +24,8 @@ namespace Swift { virtual bool setClientCertificate(const PKCS12Certificate& cert) = 0; - virtual void handleDataFromNetwork(const ByteArray&) = 0; - virtual void handleDataFromApplication(const ByteArray&) = 0; + virtual void handleDataFromNetwork(const SafeByteArray&) = 0; + virtual void handleDataFromApplication(const SafeByteArray&) = 0; virtual Certificate::ref getPeerCertificate() const = 0; virtual CertificateVerificationError::ref getPeerCertificateVerificationError() const = 0; @@ -33,8 +33,8 @@ namespace Swift { virtual ByteArray getFinishMessage() const = 0; public: - boost::signal<void (const ByteArray&)> onDataForNetwork; - boost::signal<void (const ByteArray&)> onDataForApplication; + boost::signal<void (const SafeByteArray&)> onDataForNetwork; + boost::signal<void (const SafeByteArray&)> onDataForApplication; boost::signal<void ()> onError; boost::signal<void ()> onConnected; }; diff --git a/Swiften/TLS/TLSContextFactory.cpp b/Swiften/TLS/TLSContextFactory.cpp index 47b529f..eb02f0c 100644 --- a/Swiften/TLS/TLSContextFactory.cpp +++ b/Swiften/TLS/TLSContextFactory.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/TLS/TLSContextFactory.h" +#include <Swiften/TLS/TLSContextFactory.h> namespace Swift { diff --git a/Swiften/TLS/UnitTest/CertificateTest.cpp b/Swiften/TLS/UnitTest/CertificateTest.cpp index 216aaae..5df5639 100644 --- a/Swiften/TLS/UnitTest/CertificateTest.cpp +++ b/Swiften/TLS/UnitTest/CertificateTest.cpp @@ -23,7 +23,7 @@ class CertificateTest : public CppUnit::TestFixture { public: void testGetSHA1Fingerprint() { SimpleCertificate::ref testling = boost::make_shared<SimpleCertificate>(); - testling->setDER(ByteArray("abcdefg")); + testling->setDER(createByteArray("abcdefg")); CPPUNIT_ASSERT_EQUAL(std::string("2f:b5:e1:34:19:fc:89:24:68:65:e7:a3:24:f4:76:ec:62:4e:87:40"), testling->getSHA1Fingerprint()); } diff --git a/Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp b/Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp index 5234445..bd68c84 100644 --- a/Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp +++ b/Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp @@ -4,14 +4,14 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <vector> -#include "Swiften/TLS/ServerIdentityVerifier.h" -#include "Swiften/TLS/SimpleCertificate.h" +#include <Swiften/TLS/ServerIdentityVerifier.h> +#include <Swiften/TLS/SimpleCertificate.h> using namespace Swift; diff --git a/Swiften/VCards/GetVCardRequest.h b/Swiften/VCards/GetVCardRequest.h index 93e4871..dc65773 100644 --- a/Swiften/VCards/GetVCardRequest.h +++ b/Swiften/VCards/GetVCardRequest.h @@ -6,8 +6,8 @@ #pragma once -#include "Swiften/Queries/GenericRequest.h" -#include "Swiften/Elements/VCard.h" +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Elements/VCard.h> namespace Swift { diff --git a/Swiften/VCards/SConscript b/Swiften/VCards/SConscript index e980ba3..c20c17d 100644 --- a/Swiften/VCards/SConscript +++ b/Swiften/VCards/SConscript @@ -3,6 +3,5 @@ Import("swiften_env") objects = swiften_env.SwiftenObject([ "VCardManager.cpp", "VCardStorage.cpp", - "VCardFileStorage.cpp", ]) swiften_env.Append(SWIFTEN_OBJECTS = [objects]) diff --git a/Swiften/VCards/UnitTest/VCardManagerTest.cpp b/Swiften/VCards/UnitTest/VCardManagerTest.cpp index fa46306..eecec7b 100644 --- a/Swiften/VCards/UnitTest/VCardManagerTest.cpp +++ b/Swiften/VCards/UnitTest/VCardManagerTest.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> @@ -12,10 +12,10 @@ #include <boost/bind.hpp> #include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/VCards/VCardManager.h" -#include "Swiften/VCards/VCardMemoryStorage.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Client/DummyStanzaChannel.h" +#include <Swiften/VCards/VCardManager.h> +#include <Swiften/VCards/VCardMemoryStorage.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Client/DummyStanzaChannel.h> using namespace Swift; @@ -48,7 +48,7 @@ class VCardManagerTest : public CppUnit::TestFixture { } void testGet_NewVCardRequestsVCard() { - std::auto_ptr<VCardManager> testling = createManager(); + boost::shared_ptr<VCardManager> testling = createManager(); VCard::ref result = testling->getVCardAndRequestWhenNeeded(JID("foo@bar.com/baz")); CPPUNIT_ASSERT(!result); @@ -57,7 +57,7 @@ class VCardManagerTest : public CppUnit::TestFixture { } void testGet_ExistingVCard() { - std::auto_ptr<VCardManager> testling = createManager(); + boost::shared_ptr<VCardManager> testling = createManager(); VCard::ref vcard(new VCard()); vcard->setFullName("Foo Bar"); vcardStorage->setVCard(JID("foo@bar.com/baz"), vcard); @@ -69,7 +69,7 @@ class VCardManagerTest : public CppUnit::TestFixture { } void testRequest_RequestsVCard() { - std::auto_ptr<VCardManager> testling = createManager(); + boost::shared_ptr<VCardManager> testling = createManager(); testling->requestVCard(JID("foo@bar.com/baz")); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(stanzaChannel->sentStanzas.size())); @@ -77,7 +77,7 @@ class VCardManagerTest : public CppUnit::TestFixture { } void testRequest_ReceiveEmitsNotification() { - std::auto_ptr<VCardManager> testling = createManager(); + boost::shared_ptr<VCardManager> testling = createManager(); testling->requestVCard(JID("foo@bar.com/baz")); stanzaChannel->onIQReceived(createVCardResult()); @@ -90,7 +90,7 @@ class VCardManagerTest : public CppUnit::TestFixture { } void testRequest_Error() { - std::auto_ptr<VCardManager> testling = createManager(); + boost::shared_ptr<VCardManager> testling = createManager(); testling->requestVCard(JID("foo@bar.com/baz")); stanzaChannel->onIQReceived(IQ::createError(JID("baz@fum.com/foo"), stanzaChannel->sentStanzas[0]->getTo(), stanzaChannel->sentStanzas[0]->getID())); @@ -101,7 +101,7 @@ class VCardManagerTest : public CppUnit::TestFixture { } void testRequest_VCardAlreadyRequested() { - std::auto_ptr<VCardManager> testling = createManager(); + boost::shared_ptr<VCardManager> testling = createManager(); testling->requestVCard(JID("foo@bar.com/baz")); VCard::ref result = testling->getVCardAndRequestWhenNeeded(JID("foo@bar.com/baz")); @@ -110,7 +110,7 @@ class VCardManagerTest : public CppUnit::TestFixture { } void testRequest_AfterPreviousRequest() { - std::auto_ptr<VCardManager> testling = createManager(); + boost::shared_ptr<VCardManager> testling = createManager(); testling->requestVCard(JID("foo@bar.com/baz")); stanzaChannel->onIQReceived(createVCardResult()); testling->requestVCard(JID("foo@bar.com/baz")); @@ -120,7 +120,7 @@ class VCardManagerTest : public CppUnit::TestFixture { } void testRequestOwnVCard() { - std::auto_ptr<VCardManager> testling = createManager(); + boost::shared_ptr<VCardManager> testling = createManager(); testling->requestVCard(ownJID); stanzaChannel->onIQReceived(createOwnVCardResult()); @@ -136,7 +136,7 @@ class VCardManagerTest : public CppUnit::TestFixture { } void testCreateSetVCardRequest() { - std::auto_ptr<VCardManager> testling = createManager(); + boost::shared_ptr<VCardManager> testling = createManager(); VCard::ref vcard = boost::make_shared<VCard>(); vcard->setFullName("New Name"); SetVCardRequest::ref request = testling->createSetVCardRequest(vcard); @@ -150,7 +150,7 @@ class VCardManagerTest : public CppUnit::TestFixture { } void testCreateSetVCardRequest_Error() { - std::auto_ptr<VCardManager> testling = createManager(); + boost::shared_ptr<VCardManager> testling = createManager(); VCard::ref vcard = boost::make_shared<VCard>(); vcard->setFullName("New Name"); SetVCardRequest::ref request = testling->createSetVCardRequest(vcard); @@ -162,8 +162,8 @@ class VCardManagerTest : public CppUnit::TestFixture { } private: - std::auto_ptr<VCardManager> createManager() { - std::auto_ptr<VCardManager> manager(new VCardManager(ownJID, iqRouter, vcardStorage)); + boost::shared_ptr<VCardManager> createManager() { + boost::shared_ptr<VCardManager> manager(new VCardManager(ownJID, iqRouter, vcardStorage)); manager->onVCardChanged.connect(boost::bind(&VCardManagerTest::handleVCardChanged, this, _1, _2)); manager->onOwnVCardChanged.connect(boost::bind(&VCardManagerTest::handleOwnVCardChanged, this, _1)); return manager; diff --git a/Swiften/VCards/VCardFileStorage.cpp b/Swiften/VCards/VCardFileStorage.cpp deleted file mode 100644 index 476fde1..0000000 --- a/Swiften/VCards/VCardFileStorage.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include "Swiften/VCards/VCardFileStorage.h" - -#include <boost/filesystem/fstream.hpp> - -#include <Swiften/Base/String.h> -#include <Swiften/StringCodecs/Hexify.h> -#include <Swiften/StringCodecs/SHA1.h> -#include <Swiften/Base/foreach.h> -#include "Swiften/JID/JID.h" -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Elements/VCard.h" -#include "Swiften/Serializer/PayloadSerializers/VCardSerializer.h" -#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h" -#include "Swiften/Parser/PayloadParsers/VCardParser.h" - -namespace Swift { - -VCardFileStorage::VCardFileStorage(boost::filesystem::path dir) : vcardsPath(dir) { - cacheFile = vcardsPath / "phashes"; - if (boost::filesystem::exists(cacheFile)) { - try { - boost::filesystem::ifstream file(cacheFile); - std::string line; - if (file.is_open()) { - while (!file.eof()) { - getline(file, line); - std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' '); - JID jid(r.second); - if (jid.isValid()) { - photoHashes.insert(std::make_pair(jid, r.first)); - } - else if (!r.first.empty() || !r.second.empty()) { - std::cerr << "Invalid entry in phashes file" << std::endl; - } - } - } - } - catch (...) { - std::cerr << "Error reading phashes file" << std::endl; - } - } -} - -boost::shared_ptr<VCard> VCardFileStorage::getVCard(const JID& jid) const { - boost::shared_ptr<VCard> result; - try { - boost::filesystem::path vcardPath(getVCardPath(jid)); - if (boost::filesystem::exists(vcardPath)) { - ByteArray data; - data.readFromFile(vcardPath.string()); - - VCardParser parser; - PayloadParserTester tester(&parser); - tester.parse(data.toString()); - result = boost::dynamic_pointer_cast<VCard>(parser.getPayload()); - } - } - catch (const boost::filesystem::filesystem_error& e) { - std::cerr << "ERROR: " << e.what() << std::endl; - } - getAndUpdatePhotoHash(jid, result); - return result; -} - -void VCardFileStorage::setVCard(const JID& jid, VCard::ref v) { - try { - boost::filesystem::path vcardPath(getVCardPath(jid)); - if (!boost::filesystem::exists(vcardPath.parent_path())) { - boost::filesystem::create_directories(vcardPath.parent_path()); - } - boost::filesystem::ofstream file(getVCardPath(jid)); - file << VCardSerializer().serializePayload(v); - file.close(); - getAndUpdatePhotoHash(jid, v); - } - catch (const boost::filesystem::filesystem_error& e) { - std::cerr << "ERROR: " << e.what() << std::endl; - } -} - -boost::filesystem::path VCardFileStorage::getVCardPath(const JID& jid) const { - try { - std::string file(jid.toString()); - String::replaceAll(file, '/', "%2f"); - return boost::filesystem::path(vcardsPath / (file + ".xml")); - } - catch (const boost::filesystem::filesystem_error& e) { - std::cerr << "ERROR: " << e.what() << std::endl; - return boost::filesystem::path(); - } -} - -std::string VCardFileStorage::getPhotoHash(const JID& jid) const { - PhotoHashMap::const_iterator i = photoHashes.find(jid); - if (i != photoHashes.end()) { - return i->second; - } - else { - VCard::ref vCard = getVCard(jid); - return getAndUpdatePhotoHash(jid, vCard); - } -} - -std::string VCardFileStorage::getAndUpdatePhotoHash(const JID& jid, VCard::ref vCard) const { - std::string hash; - if (vCard && !vCard->getPhoto().isEmpty()) { - hash = Hexify::hexify(SHA1::getHash(vCard->getPhoto())); - } - std::pair<PhotoHashMap::iterator, bool> r = photoHashes.insert(std::make_pair(jid, hash)); - if (r.second) { - savePhotoHashes(); - } - else if (r.first->second != hash) { - r.first->second = hash; - savePhotoHashes(); - } - return hash; -} - -void VCardFileStorage::savePhotoHashes() const { - try { - boost::filesystem::ofstream file(cacheFile); - for (PhotoHashMap::const_iterator i = photoHashes.begin(); i != photoHashes.end(); ++i) { - file << i->second << " " << i->first.toString() << std::endl; - } - file.close(); - } - catch (...) { - std::cerr << "Error writing vcards file" << std::endl; - } -} - - -} diff --git a/Swiften/VCards/VCardFileStorage.h b/Swiften/VCards/VCardFileStorage.h deleted file mode 100644 index 26bf4b2..0000000 --- a/Swiften/VCards/VCardFileStorage.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 <boost/filesystem.hpp> -#include <string> -#include <map> - -#include "Swiften/VCards/VCardStorage.h" - -namespace Swift { - class VCardFileStorage : public VCardStorage { - public: - VCardFileStorage(boost::filesystem::path dir); - - virtual VCard::ref getVCard(const JID& jid) const; - virtual void setVCard(const JID& jid, VCard::ref v); - - virtual std::string getPhotoHash(const JID&) const; - - private: - boost::filesystem::path getVCardPath(const JID&) const; - - std::string getAndUpdatePhotoHash(const JID& jid, VCard::ref vcard) const; - void savePhotoHashes() const; - - private: - boost::filesystem::path vcardsPath; - boost::filesystem::path cacheFile; - typedef std::map<JID, std::string> PhotoHashMap; - mutable PhotoHashMap photoHashes; - }; -} diff --git a/Swiften/VCards/VCardManager.cpp b/Swiften/VCards/VCardManager.cpp index b9602ab..52447a1 100644 --- a/Swiften/VCards/VCardManager.cpp +++ b/Swiften/VCards/VCardManager.cpp @@ -4,13 +4,13 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/VCards/VCardManager.h" +#include <Swiften/VCards/VCardManager.h> #include <boost/bind.hpp> -#include "Swiften/JID/JID.h" -#include "Swiften/VCards/VCardStorage.h" -#include "Swiften/VCards/GetVCardRequest.h" +#include <Swiften/JID/JID.h> +#include <Swiften/VCards/VCardStorage.h> +#include <Swiften/VCards/GetVCardRequest.h> namespace Swift { diff --git a/Swiften/VCards/VCardManager.h b/Swiften/VCards/VCardManager.h index 1dd16ae..29fe32c 100644 --- a/Swiften/VCards/VCardManager.h +++ b/Swiften/VCards/VCardManager.h @@ -8,9 +8,9 @@ #include <set> -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/VCard.h" -#include "Swiften/Elements/ErrorPayload.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/VCard.h> +#include <Swiften/Elements/ErrorPayload.h> #include <Swiften/VCards/SetVCardRequest.h> #include <Swiften/Base/boost_bsignals.h> diff --git a/Swiften/VCards/VCardMemoryStorage.h b/Swiften/VCards/VCardMemoryStorage.h index b2e99c6..ade9c89 100644 --- a/Swiften/VCards/VCardMemoryStorage.h +++ b/Swiften/VCards/VCardMemoryStorage.h @@ -9,8 +9,8 @@ #include <boost/shared_ptr.hpp> #include <map> -#include "Swiften/JID/JID.h" -#include "Swiften/VCards/VCardStorage.h" +#include <Swiften/JID/JID.h> +#include <Swiften/VCards/VCardStorage.h> namespace Swift { class VCardMemoryStorage : public VCardStorage { diff --git a/Swiften/VCards/VCardStorage.cpp b/Swiften/VCards/VCardStorage.cpp index b14ee60..900f1e5 100644 --- a/Swiften/VCards/VCardStorage.cpp +++ b/Swiften/VCards/VCardStorage.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/VCards/VCardStorage.h" +#include <Swiften/VCards/VCardStorage.h> #include <Swiften/StringCodecs/Hexify.h> #include <Swiften/StringCodecs/SHA1.h> @@ -16,7 +16,7 @@ VCardStorage::~VCardStorage() { std::string VCardStorage::getPhotoHash(const JID& jid) const { VCard::ref vCard = getVCard(jid); - if (vCard && !vCard->getPhoto().isEmpty()) { + if (vCard && !vCard->getPhoto().empty()) { return Hexify::hexify(SHA1::getHash(vCard->getPhoto())); } else { |