diff options
Diffstat (limited to 'Swiften/Disco/FeatureOracle.cpp')
-rw-r--r-- | Swiften/Disco/FeatureOracle.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
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; + } +} + +} + + |