diff options
Diffstat (limited to 'Swiften')
-rw-r--r-- | Swiften/Base/Tristate.h | 13 | ||||
-rw-r--r-- | Swiften/Disco/FeatureOracle.cpp | 99 | ||||
-rw-r--r-- | Swiften/Disco/FeatureOracle.h | 47 | ||||
-rw-r--r-- | Swiften/Disco/SConscript | 1 |
4 files changed, 160 insertions, 0 deletions
diff --git a/Swiften/Base/Tristate.h b/Swiften/Base/Tristate.h new file mode 100644 index 0000000..edb7444 --- /dev/null +++ b/Swiften/Base/Tristate.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#pragma once + +namespace Swift { + +enum Tristate {Yes, No, Maybe}; + +} diff --git a/Swiften/Disco/FeatureOracle.cpp b/Swiften/Disco/FeatureOracle.cpp new file mode 100644 index 0000000..4e61aa9 --- /dev/null +++ b/Swiften/Disco/FeatureOracle.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swiften/Disco/FeatureOracle.h> + +#include <algorithm> +#include <iterator> +#include <vector> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Disco/EntityCapsProvider.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/FileTransfer/FileTransferManager.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Presence/PresenceOracle.h> + +namespace Swift { + +FeatureOracle::FeatureOracle(EntityCapsProvider* capsProvider, PresenceOracle* presenceOracle) : capsProvider_(capsProvider), presenceOracle_(presenceOracle) { + +} + +Tristate FeatureOracle::isFileTransferSupported(const JID& jid) { + DiscoInfo::ref discoInfo = getDiscoResultForJID(jid); + if (discoInfo) { + return FileTransferManager::isSupportedBy(discoInfo) ? Yes : No; + } + else { + return Maybe; + } +} + +Tristate FeatureOracle::isMessageReceiptsSupported(const JID& jid) { + return isFeatureSupported(jid, DiscoInfo::MessageDeliveryReceiptsFeature); +} + +Tristate FeatureOracle::isMessageCorrectionSupported(const JID& jid) { + return isFeatureSupported(jid, DiscoInfo::MessageCorrectionFeature); +} + +DiscoInfo::ref FeatureOracle::getDiscoResultForJID(const JID& jid) { + DiscoInfo::ref discoInfo; + if (jid.isBare()) { + // Calculate the common subset of disco features of all available results and return that. + std::vector<Presence::ref> availablePresences = presenceOracle_->getAllPresence(jid); + + bool commonFeaturesInitialized = false; + std::vector<std::string> commonFeatures; + foreach(Presence::ref presence, availablePresences) { + DiscoInfo::ref presenceDiscoInfo = capsProvider_->getCaps(presence->getFrom()); + if (presenceDiscoInfo) { + std::vector<std::string> features = presenceDiscoInfo->getFeatures(); + if (!commonFeaturesInitialized) { + commonFeatures = features; + commonFeaturesInitialized = true; + } + else { + std::vector<std::string> featuresToRemove; + foreach(const std::string& feature, commonFeatures) { + if (std::find(features.begin(), features.end(), feature) == features.end()) { + featuresToRemove.push_back(feature); + } + } + foreach(const std::string& featureToRemove, featuresToRemove) { + commonFeatures.erase(std::remove(commonFeatures.begin(), commonFeatures.end(), featureToRemove), commonFeatures.end()); + } + } + } + } + discoInfo = boost::make_shared<DiscoInfo>(); + + foreach(const std::string& commonFeature, commonFeatures) { + discoInfo->addFeature(commonFeature); + } + } + else { + // Return the disco result of the full JID. + discoInfo = capsProvider_->getCaps(jid); + } + + return discoInfo; +} + +Tristate FeatureOracle::isFeatureSupported(const JID& jid, const std::string& feature) { + DiscoInfo::ref discoInfo = getDiscoResultForJID(jid); + if (discoInfo) { + return discoInfo->hasFeature(feature) ? Yes : No; + } + else { + return Maybe; + } +} + +} + + diff --git a/Swiften/Disco/FeatureOracle.h b/Swiften/Disco/FeatureOracle.h new file mode 100644 index 0000000..d579e5a --- /dev/null +++ b/Swiften/Disco/FeatureOracle.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#pragma once + +#include <Swiften/Base/API.h> +#include <Swiften/Base/Tristate.h> +#include <Swiften/Elements/DiscoInfo.h> + +namespace Swift { + +class EntityCapsProvider; +class JID; +class PresenceOracle; + +/** + * @brief The FeatureOracle class enables direct feature support lookup for client features supported by Swiften. + */ +class SWIFTEN_API FeatureOracle { + public: + FeatureOracle(EntityCapsProvider* capsProvider, PresenceOracle* presenceOracle); + + public: + Tristate isFileTransferSupported(const JID& jid); + Tristate isMessageReceiptsSupported(const JID& jid); + Tristate isMessageCorrectionSupported(const JID& jid); + + private: + /** + * @brief getDiscoResultForJID returns a shared reference to a DiscoInfo representing features supported by the jid. + * @param jid The JID to return the DiscoInfo::ref for. + * @return DiscoResult::ref + */ + DiscoInfo::ref getDiscoResultForJID(const JID& jid); + + Tristate isFeatureSupported(const JID& jid, const std::string& feature); + + private: + EntityCapsProvider* capsProvider_; + PresenceOracle* presenceOracle_; +}; + +} + diff --git a/Swiften/Disco/SConscript b/Swiften/Disco/SConscript index c821b42..1779e26 100644 --- a/Swiften/Disco/SConscript +++ b/Swiften/Disco/SConscript @@ -11,5 +11,6 @@ objects = swiften_env.SwiftenObject([ "DiscoInfoResponder.cpp", "JIDDiscoInfoResponder.cpp", "DiscoServiceWalker.cpp", + "FeatureOracle.cpp", ]) swiften_env.Append(SWIFTEN_OBJECTS = [objects]) |