diff options
Diffstat (limited to 'Swiften/JID/JID.cpp')
-rw-r--r-- | Swiften/JID/JID.cpp | 95 |
1 files changed, 71 insertions, 24 deletions
diff --git a/Swiften/JID/JID.cpp b/Swiften/JID/JID.cpp index 0822595..7b51867 100644 --- a/Swiften/JID/JID.cpp +++ b/Swiften/JID/JID.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -18,11 +18,16 @@ #include <boost/assign/list_of.hpp> #include <boost/algorithm/string/find_format.hpp> #include <boost/algorithm/string/finder.hpp> +#include <iostream> #include <sstream> #include <Swiften/Base/String.h> #include <Swiften/JID/JID.h> -#include <Swiften/IDN/StringPrep.h> +#include <Swiften/IDN/IDNConverter.h> +#ifndef SWIFTEN_JID_NO_DEFAULT_IDN_CONVERTER +#include <boost/shared_ptr.hpp> +#include <Swiften/IDN/PlatformIDNConverter.h> +#endif using namespace Swift; @@ -37,6 +42,19 @@ static PrepCache resourcePrepCache; static const std::list<char> escapedChars = boost::assign::list_of(' ')('"')('&')('\'')('/')('<')('>')('@')(':'); +static IDNConverter* idnConverter = NULL; + +#ifndef SWIFTEN_JID_NO_DEFAULT_IDN_CONVERTER +namespace { + struct IDNInitializer { + IDNInitializer() : defaultIDNConverter(PlatformIDNConverter::create()) { + idnConverter = defaultIDNConverter.get(); + } + boost::shared_ptr<IDNConverter> defaultIDNConverter; + } initializer; +} +#endif + static std::string getEscaped(char c) { return makeString() << '\\' << std::hex << static_cast<int>(c); } @@ -111,6 +129,8 @@ struct EscapedCharacterFormatter { }; #endif +namespace Swift { + JID::JID(const char* jid) : valid_(true) { initializeFromString(std::string(jid)); } @@ -159,42 +179,58 @@ void JID::nameprepAndSetComponents(const std::string& node, const std::string& d valid_ = false; return; } - try { #ifndef SWIFTEN_CACHE_JID_PREP - node_ = StringPrep::getPrepared(node, StringPrep::NamePrep); - domain_ = StringPrep::getPrepared(domain, StringPrep::XMPPNodePrep); - resource_ = StringPrep::getPrepared(resource, StringPrep::XMPPResourcePrep); + node_ = idnConverter->getStringPrepared(node, IDNConverter::XMPPNodePrep); + domain_ = idnConverter->getStringPrepared(domain, IDNConverter::NamePrep); + resource_ = idnConverter->getStringPrepared(resource, IDNConverter::XMPPResourcePrep); #else - boost::mutex::scoped_lock lock(namePrepCacheMutex); + boost::mutex::scoped_lock lock(namePrepCacheMutex); - std::pair<PrepCache::iterator, bool> r; + std::pair<PrepCache::iterator, bool> r; - r = nodePrepCache.insert(std::make_pair(node, std::string())); - if (r.second) { - r.first->second = StringPrep::getPrepared(node, StringPrep::NamePrep); + r = nodePrepCache.insert(std::make_pair(node, std::string())); + if (r.second) { + try { + r.first->second = idnConverter->getStringPrepared(node, IDNConverter::XMPPNodePrep); } - node_ = r.first->second; - - r = domainPrepCache.insert(std::make_pair(domain, std::string())); - if (r.second) { - r.first->second = StringPrep::getPrepared(domain, StringPrep::XMPPNodePrep); + catch (...) { + nodePrepCache.erase(r.first); + valid_ = false; + return; } - domain_ = r.first->second; + } + node_ = r.first->second; - r = resourcePrepCache.insert(std::make_pair(resource, std::string())); - if (r.second) { - r.first->second = StringPrep::getPrepared(resource, StringPrep::XMPPResourcePrep); + r = domainPrepCache.insert(std::make_pair(domain, std::string())); + if (r.second) { + try { + r.first->second = idnConverter->getStringPrepared(domain, IDNConverter::NamePrep); } - resource_ = r.first->second; -#endif + catch (...) { + domainPrepCache.erase(r.first); + valid_ = false; + return; + } + } + domain_ = r.first->second; - if (domain_.empty()) { + r = resourcePrepCache.insert(std::make_pair(resource, std::string())); + if (r.second) { + try { + r.first->second = idnConverter->getStringPrepared(resource, IDNConverter::XMPPResourcePrep); + } + catch (...) { + resourcePrepCache.erase(r.first); valid_ = false; return; } } - catch (const std::exception&) { + resource_ = r.first->second; +#endif + + if (domain_.empty()) { valid_ = false; + return; } } @@ -270,3 +306,14 @@ std::string JID::getUnescapedNode() const { return result; //return boost::find_format_all_copy(node_, EscapedCharacterFinder(), EscapedCharacterFormatter()); } + +void JID::setIDNConverter(IDNConverter* converter) { + idnConverter = converter; +} + +std::ostream& operator<<(std::ostream& os, const JID& j) { + os << j.toString(); + return os; +} + +} |