diff options
Diffstat (limited to 'Swiften/JID')
-rw-r--r-- | Swiften/JID/JID.cpp | 419 | ||||
-rw-r--r-- | Swiften/JID/JID.h | 370 | ||||
-rw-r--r-- | Swiften/JID/SConscript | 4 | ||||
-rw-r--r-- | Swiften/JID/UnitTest/JIDTest.cpp | 724 |
4 files changed, 739 insertions, 778 deletions
diff --git a/Swiften/JID/JID.cpp b/Swiften/JID/JID.cpp index a0f18d5..c82674d 100644 --- a/Swiften/JID/JID.cpp +++ b/Swiften/JID/JID.cpp @@ -1,326 +1,267 @@ /* - * Copyright (c) 2010-2013 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #define SWIFTEN_CACHE_JID_PREP +#include <sstream> +#include <string> #include <vector> -#include <list> -#include <iostream> -#include <string> #ifdef SWIFTEN_CACHE_JID_PREP -#include <boost/thread/mutex.hpp> -#include <boost/unordered_map.hpp> +#include <mutex> +#include <unordered_map> #endif -#include <boost/assign/list_of.hpp> -#include <boost/algorithm/string/find_format.hpp> -#include <boost/algorithm/string/finder.hpp> + #include <boost/optional.hpp> -#include <iostream> -#include <sstream> #include <Swiften/Base/String.h> -#include <Swiften/JID/JID.h> #include <Swiften/IDN/IDNConverter.h> +#include <Swiften/JID/JID.h> + #ifndef SWIFTEN_JID_NO_DEFAULT_IDN_CONVERTER -#include <boost/shared_ptr.hpp> +#include <memory> #include <Swiften/IDN/PlatformIDNConverter.h> #endif using namespace Swift; #ifdef SWIFTEN_CACHE_JID_PREP -typedef boost::unordered_map<std::string, std::string> PrepCache; +typedef std::unordered_map<std::string, std::string> PrepCache; -static boost::mutex namePrepCacheMutex; +static std::mutex namePrepCacheMutex; static PrepCache nodePrepCache; static PrepCache domainPrepCache; static PrepCache resourcePrepCache; #endif -static const std::list<char> escapedChars = boost::assign::list_of(' ')('"')('&')('\'')('/')('<')('>')('@')(':'); +static const std::vector<char> escapedChars = {' ', '"', '&', '\'', '/', '<', '>', '@', ':'}; -static IDNConverter* idnConverter = NULL; +static IDNConverter* idnConverter = nullptr; #ifndef SWIFTEN_JID_NO_DEFAULT_IDN_CONVERTER namespace { - struct IDNInitializer { - IDNInitializer() : defaultIDNConverter(PlatformIDNConverter::create()) { - idnConverter = defaultIDNConverter.get(); - } - boost::shared_ptr<IDNConverter> defaultIDNConverter; - } initializer; + struct IDNInitializer { + IDNInitializer() : defaultIDNConverter(PlatformIDNConverter::create()) { + idnConverter = defaultIDNConverter.get(); + } + std::shared_ptr<IDNConverter> defaultIDNConverter; + } initializer; } #endif static std::string getEscaped(char c) { - return makeString() << '\\' << std::hex << static_cast<int>(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())); + 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 - namespace Swift { JID::JID(const char* jid) : valid_(true) { - assert(jid); - initializeFromString(std::string(jid)); + assert(jid); + initializeFromString(std::string(jid)); } JID::JID(const std::string& jid) : valid_(true) { - initializeFromString(jid); + initializeFromString(jid); } JID::JID(const std::string& node, const std::string& domain) : valid_(true), hasResource_(false) { - nameprepAndSetComponents(node, domain, ""); + nameprepAndSetComponents(node, domain, ""); } JID::JID(const std::string& node, const std::string& domain, const std::string& resource) : valid_(true), hasResource_(true) { - nameprepAndSetComponents(node, domain, resource); + if (resource.empty()) { + valid_ = false; + } + nameprepAndSetComponents(node, domain, resource); } void JID::initializeFromString(const std::string& jid) { - if (String::beginsWith(jid, '@')) { - valid_ = false; - return; - } - - std::string bare, resource; - size_t slashIndex = jid.find('/'); - if (slashIndex != jid.npos) { - hasResource_ = true; - bare = jid.substr(0, slashIndex); - resource = jid.substr(slashIndex + 1, jid.npos); - } - else { - hasResource_ = false; - bare = jid; - } - std::pair<std::string,std::string> nodeAndDomain = String::getSplittedAtFirst(bare, '@'); - if (nodeAndDomain.second.empty()) { - nameprepAndSetComponents("", nodeAndDomain.first, resource); - } - else { - nameprepAndSetComponents(nodeAndDomain.first, nodeAndDomain.second, resource); - } + if (String::beginsWith(jid, '@')) { + valid_ = false; + return; + } + + std::string bare, resource; + size_t slashIndex = jid.find('/'); + if (slashIndex != jid.npos) { + hasResource_ = true; + bare = jid.substr(0, slashIndex); + resource = jid.substr(slashIndex + 1, jid.npos); + } + else { + hasResource_ = false; + bare = jid; + } + std::pair<std::string,std::string> nodeAndDomain = String::getSplittedAtFirst(bare, '@'); + if (nodeAndDomain.second.empty()) { + nameprepAndSetComponents("", nodeAndDomain.first, resource); + } + else { + nameprepAndSetComponents(nodeAndDomain.first, nodeAndDomain.second, resource); + } } void JID::nameprepAndSetComponents(const std::string& node, const std::string& domain, const std::string& resource) { - if (domain.empty() || !idnConverter->getIDNAEncoded(domain)) { - valid_ = false; - return; - } + if (domain.empty() || !idnConverter->getIDNAEncoded(domain)) { + valid_ = false; + return; + } + + if (hasResource_ && resource.empty()) { + valid_ = false; + return; + } #ifndef SWIFTEN_CACHE_JID_PREP - node_ = idnConverter->getStringPrepared(node, IDNConverter::XMPPNodePrep); - domain_ = idnConverter->getStringPrepared(domain, IDNConverter::NamePrep); - resource_ = idnConverter->getStringPrepared(resource, IDNConverter::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); - - std::pair<PrepCache::iterator, bool> r; - - r = nodePrepCache.insert(std::make_pair(node, std::string())); - if (r.second) { - try { - r.first->second = idnConverter->getStringPrepared(node, IDNConverter::XMPPNodePrep); - } - catch (...) { - nodePrepCache.erase(r.first); - valid_ = false; - return; - } - } - node_ = r.first->second; - - r = domainPrepCache.insert(std::make_pair(domain, std::string())); - if (r.second) { - try { - r.first->second = idnConverter->getStringPrepared(domain, IDNConverter::NamePrep); - } - catch (...) { - domainPrepCache.erase(r.first); - valid_ = false; - return; - } - } - domain_ = r.first->second; - - 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; - } - } - resource_ = r.first->second; + std::unique_lock<std::mutex> lock(namePrepCacheMutex); + + std::pair<PrepCache::iterator, bool> r; + + r = nodePrepCache.insert(std::make_pair(node, std::string())); + if (r.second) { + try { + r.first->second = idnConverter->getStringPrepared(node, IDNConverter::XMPPNodePrep); + } + catch (...) { + nodePrepCache.erase(r.first); + valid_ = false; + return; + } + } + node_ = r.first->second; + + r = domainPrepCache.insert(std::make_pair(domain, std::string())); + if (r.second) { + try { + r.first->second = idnConverter->getStringPrepared(domain, IDNConverter::NamePrep); + } + catch (...) { + domainPrepCache.erase(r.first); + valid_ = false; + return; + } + } + domain_ = r.first->second; + + 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; + } + } + resource_ = r.first->second; #endif - if (domain_.empty()) { - valid_ = false; - return; - } + if (domain_.empty()) { + valid_ = false; + return; + } } std::string JID::toString() const { - std::string string; - if (!node_.empty()) { - string += node_ + "@"; - } - string += domain_; - if (!isBare()) { - string += "/" + resource_; - } - return string; + std::string string; + if (!node_.empty()) { + string += node_ + "@"; + } + string += domain_; + if (!isBare()) { + string += "/" + resource_; + } + return string; } int JID::compare(const Swift::JID& o, CompareType compareType) const { - if (node_ < o.node_) { return -1; } - if (node_ > o.node_) { return 1; } - if (domain_ < o.domain_) { return -1; } - if (domain_ > o.domain_) { return 1; } - if (compareType == WithResource) { - if (hasResource_ != o.hasResource_) { - return hasResource_ ? 1 : -1; - } - if (resource_ < o.resource_) { return -1; } - if (resource_ > o.resource_) { return 1; } - } - return 0; + if (node_ < o.node_) { return -1; } + if (node_ > o.node_) { return 1; } + if (domain_ < o.domain_) { return -1; } + if (domain_ > o.domain_) { return 1; } + if (compareType == WithResource) { + if (hasResource_ != o.hasResource_) { + return hasResource_ ? 1 : -1; + } + if (resource_ < o.resource_) { return -1; } + if (resource_ > o.resource_) { return 1; } + } + return 0; } 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 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; } - + 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()); + 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; } void JID::setIDNConverter(IDNConverter* converter) { - idnConverter = converter; + idnConverter = converter; } std::ostream& operator<<(std::ostream& os, const JID& j) { - os << j.toString(); - return os; + os << j.toString(); + return os; } boost::optional<JID> JID::parse(const std::string& s) { - JID jid(s); - return jid.isValid() ? jid : boost::optional<JID>(); + JID jid(s); + return jid.isValid() ? jid : boost::optional<JID>(); } } diff --git a/Swiften/JID/JID.h b/Swiften/JID/JID.h index 9bcc7d5..dc92f53 100644 --- a/Swiften/JID/JID.h +++ b/Swiften/JID/JID.h @@ -1,198 +1,198 @@ /* - * Copyright (c) 2010-2013 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once -#include <string> #include <iosfwd> +#include <string> -#include <Swiften/Base/API.h> #include <boost/optional/optional.hpp> +#include <Swiften/Base/API.h> + namespace Swift { - class IDNConverter; - - /** - * 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 SWIFTEN_API JID { - public: - enum CompareType { - WithResource, WithoutResource - }; - - /** - * 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. - * - * Must not be NULL. - */ - 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; - result.resource_ = ""; - return result; - } - - /** - * Get the full JID with the supplied resource. - */ - JID withResource(const std::string& resource) const { - JID result(this->getNode(), this->getDomain(), resource); - return result; - } - - std::string toString() const; - - bool equals(const JID& o, CompareType compareType) const { - return compare(o, compareType) == 0; - } - - int compare(const JID& o, CompareType compareType) const; - - operator std::string() const { - return toString(); - } - - bool operator<(const Swift::JID& b) const { - return compare(b, Swift::JID::WithResource) < 0; - } - - SWIFTEN_API friend std::ostream& operator<<(std::ostream& os, const Swift::JID& j); - - friend bool operator==(const Swift::JID& a, const Swift::JID& b) { - return a.compare(b, Swift::JID::WithResource) == 0; - } - - friend bool operator!=(const Swift::JID& a, const Swift::JID& b) { - return a.compare(b, Swift::JID::WithResource) != 0; - } - - /** - * Returns an empty optional if the JID is invalid, and an - * optional with a value if the JID is valid. - */ - static boost::optional<JID> parse(const std::string&); - - /** - * If Swiften was compiled with SWIFTEN_JID_NO_DEFAULT_IDN_CONVERTER (not default), use this method at - * the beginning of the program to set an IDN converter to use for JID IDN conversions. - * By default, this method shouldn't be used. - */ - static void setIDNConverter(IDNConverter*); - - private: - void nameprepAndSetComponents(const std::string& node, const std::string& domain, const std::string& resource); - void initializeFromString(const std::string&); - - private: - bool valid_; - std::string node_; - std::string domain_; - bool hasResource_; - std::string resource_; - }; - - SWIFTEN_API std::ostream& operator<<(std::ostream& os, const Swift::JID& j); + class IDNConverter; + + /** + * 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 SWIFTEN_API JID { + public: + enum CompareType { + WithResource, WithoutResource + }; + + /** + * 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. + * + * Must not be NULL. + */ + 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; + result.resource_ = ""; + return result; + } + + /** + * Get the full JID with the supplied resource. + */ + JID withResource(const std::string& resource) const { + JID result(this->getNode(), this->getDomain(), resource); + return result; + } + + std::string toString() const; + + bool equals(const JID& o, CompareType compareType) const { + return compare(o, compareType) == 0; + } + + int compare(const JID& o, CompareType compareType) const; + + operator std::string() const { + return toString(); + } + + bool operator<(const Swift::JID& b) const { + return compare(b, Swift::JID::WithResource) < 0; + } + + SWIFTEN_API friend std::ostream& operator<<(std::ostream& os, const Swift::JID& j); + + friend bool operator==(const Swift::JID& a, const Swift::JID& b) { + return a.compare(b, Swift::JID::WithResource) == 0; + } + + friend bool operator!=(const Swift::JID& a, const Swift::JID& b) { + return a.compare(b, Swift::JID::WithResource) != 0; + } + + /** + * Returns an empty optional if the JID is invalid, and an + * optional with a value if the JID is valid. + */ + static boost::optional<JID> parse(const std::string&); + + /** + * If Swiften was compiled with SWIFTEN_JID_NO_DEFAULT_IDN_CONVERTER (not default), use this method at + * the beginning of the program to set an IDN converter to use for JID IDN conversions. + * By default, this method shouldn't be used. + */ + static void setIDNConverter(IDNConverter*); + + private: + void nameprepAndSetComponents(const std::string& node, const std::string& domain, const std::string& resource); + void initializeFromString(const std::string&); + + private: + bool valid_; + std::string node_; + std::string domain_; + bool hasResource_; + std::string resource_; + }; + + SWIFTEN_API std::ostream& operator<<(std::ostream& os, const Swift::JID& j); } - diff --git a/Swiften/JID/SConscript b/Swiften/JID/SConscript index 12565fc..122388e 100644 --- a/Swiften/JID/SConscript +++ b/Swiften/JID/SConscript @@ -2,6 +2,6 @@ Import("swiften_env") myenv = swiften_env.Clone() objects = myenv.SwiftenObject([ - "JID.cpp", - ]) + "JID.cpp", + ]) swiften_env.Append(SWIFTEN_OBJECTS = [objects]) diff --git a/Swiften/JID/UnitTest/JIDTest.cpp b/Swiften/JID/UnitTest/JIDTest.cpp index 307243a..ca3e5ae 100644 --- a/Swiften/JID/UnitTest/JIDTest.cpp +++ b/Swiften/JID/UnitTest/JIDTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -13,398 +13,418 @@ using namespace Swift; class JIDTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(JIDTest); - CPPUNIT_TEST(testConstructorWithString); - CPPUNIT_TEST(testConstructorWithString_NoResource); - CPPUNIT_TEST(testConstructorWithString_NoNode); - CPPUNIT_TEST(testConstructorWithString_EmptyResource); - CPPUNIT_TEST(testConstructorWithString_OnlyDomain); - CPPUNIT_TEST(testConstructorWithString_InvalidDomain); - CPPUNIT_TEST(testConstructorWithString_UpperCaseNode); - CPPUNIT_TEST(testConstructorWithString_UpperCaseDomain); - CPPUNIT_TEST(testConstructorWithString_UpperCaseResource); - CPPUNIT_TEST(testConstructorWithString_EmptyNode); - CPPUNIT_TEST(testConstructorWithString_IllegalResource); - CPPUNIT_TEST(testConstructorWithString_SpacesInNode); - CPPUNIT_TEST(testConstructorWithStrings); - CPPUNIT_TEST(testConstructorWithStrings_EmptyDomain); - CPPUNIT_TEST(testIsBare); - CPPUNIT_TEST(testIsBare_NotBare); - CPPUNIT_TEST(testToBare); - CPPUNIT_TEST(testToBare_EmptyNode); - CPPUNIT_TEST(testToBare_EmptyResource); - CPPUNIT_TEST(testToString); - CPPUNIT_TEST(testToString_EmptyNode); - CPPUNIT_TEST(testToString_EmptyResource); - CPPUNIT_TEST(testToString_NoResource); - CPPUNIT_TEST(testCompare_SmallerNode); - CPPUNIT_TEST(testCompare_LargerNode); - CPPUNIT_TEST(testCompare_SmallerDomain); - CPPUNIT_TEST(testCompare_LargerDomain); - CPPUNIT_TEST(testCompare_SmallerResource); - CPPUNIT_TEST(testCompare_LargerResource); - CPPUNIT_TEST(testCompare_Equal); - CPPUNIT_TEST(testCompare_EqualWithoutResource); - CPPUNIT_TEST(testCompare_NoResourceAndEmptyResource); - CPPUNIT_TEST(testCompare_EmptyResourceAndNoResource); - CPPUNIT_TEST(testEquals); - CPPUNIT_TEST(testEquals_NotEqual); - CPPUNIT_TEST(testEquals_WithoutResource); - CPPUNIT_TEST(testSmallerThan); - CPPUNIT_TEST(testSmallerThan_Equal); - 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: - JIDTest() {} - - void testConstructorWithString() { - JID testling("foo@bar/baz"); - - CPPUNIT_ASSERT_EQUAL(std::string("foo"), testling.getNode()); - CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain()); - CPPUNIT_ASSERT_EQUAL(std::string("baz"), testling.getResource()); - CPPUNIT_ASSERT(!testling.isBare()); - CPPUNIT_ASSERT(testling.isValid()); - } - - void testConstructorWithString_NoResource() { - JID testling("foo@bar"); - - CPPUNIT_ASSERT_EQUAL(std::string("foo"), testling.getNode()); - CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain()); - CPPUNIT_ASSERT_EQUAL(std::string(""), testling.getResource()); - CPPUNIT_ASSERT(testling.isBare()); - CPPUNIT_ASSERT(testling.isValid()); - } - - void testConstructorWithString_EmptyResource() { - JID testling("bar/"); - - CPPUNIT_ASSERT(testling.isValid()); - CPPUNIT_ASSERT(!testling.isBare()); - } - - void testConstructorWithString_NoNode() { - JID testling("bar/baz"); - - CPPUNIT_ASSERT_EQUAL(std::string(""), testling.getNode()); - CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain()); - CPPUNIT_ASSERT_EQUAL(std::string("baz"), testling.getResource()); - CPPUNIT_ASSERT(!testling.isBare()); - CPPUNIT_ASSERT(testling.isValid()); - } - - void testConstructorWithString_OnlyDomain() { - JID testling("bar"); - - CPPUNIT_ASSERT_EQUAL(std::string(""), testling.getNode()); - CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain()); - CPPUNIT_ASSERT_EQUAL(std::string(""), testling.getResource()); - CPPUNIT_ASSERT(testling.isBare()); - CPPUNIT_ASSERT(testling.isValid()); - } - - void testConstructorWithString_InvalidDomain() { - CPPUNIT_ASSERT(!JID("foo@bar,baz").isValid()); - } - - void testConstructorWithString_UpperCaseNode() { - JID testling("Fo\xCE\xA9@bar"); - - CPPUNIT_ASSERT_EQUAL(std::string("fo\xCF\x89"), testling.getNode()); - CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain()); - CPPUNIT_ASSERT(testling.isValid()); - } - - void testConstructorWithString_UpperCaseDomain() { - JID testling("Fo\xCE\xA9"); - - CPPUNIT_ASSERT_EQUAL(std::string("fo\xCF\x89"), testling.getDomain()); - CPPUNIT_ASSERT(testling.isValid()); - } - - void testConstructorWithString_UpperCaseResource() { - JID testling("bar/Fo\xCE\xA9"); - - CPPUNIT_ASSERT_EQUAL(testling.getResource(), std::string("Fo\xCE\xA9")); - CPPUNIT_ASSERT(testling.isValid()); - } - - void testConstructorWithString_EmptyNode() { - JID testling("@bar"); - - CPPUNIT_ASSERT(!testling.isValid()); - } - - void testConstructorWithString_IllegalResource() { - JID testling("foo@bar.com/\xd8\xb1\xd9\x85\xd9\x82\xd9\x87\x20\xd8\xaa\xd8\xb1\xd9\x86\xd8\xb3\x20"); - - CPPUNIT_ASSERT(!testling.isValid()); - } - - void testConstructorWithString_SpacesInNode() { - CPPUNIT_ASSERT(!JID(" alice@wonderland.lit").isValid()); - CPPUNIT_ASSERT(!JID("alice @wonderland.lit").isValid()); - } - - void testConstructorWithStrings() { - JID testling("foo", "bar", "baz"); + CPPUNIT_TEST_SUITE(JIDTest); + CPPUNIT_TEST(testConstructorWithString); + CPPUNIT_TEST(testConstructorWithString_Empty); + CPPUNIT_TEST(testConstructorWithString_NoResource); + CPPUNIT_TEST(testConstructorWithString_NoNode); + CPPUNIT_TEST(testConstructorWithString_EmptyResource); + CPPUNIT_TEST(testConstructorWithString_OnlyDomain); + CPPUNIT_TEST(testConstructorWithString_InvalidDomain); + CPPUNIT_TEST(testConstructorWithString_UpperCaseNode); + CPPUNIT_TEST(testConstructorWithString_UpperCaseDomain); + CPPUNIT_TEST(testConstructorWithString_UpperCaseResource); + CPPUNIT_TEST(testConstructorWithString_EmptyNode); + CPPUNIT_TEST(testConstructorWithString_IllegalResource); + CPPUNIT_TEST(testConstructorWithString_SpacesInNode); + CPPUNIT_TEST(testConstructorWithStrings); + CPPUNIT_TEST(testConstructorWithStrings_EmptyDomain); + CPPUNIT_TEST(testConstructorWithStrings_EmptyResource); + CPPUNIT_TEST(testIsBare); + CPPUNIT_TEST(testIsBare_NotBare); + CPPUNIT_TEST(testToBare); + CPPUNIT_TEST(testToBare_EmptyNode); + CPPUNIT_TEST(testToBare_EmptyResource); + CPPUNIT_TEST(testToString); + CPPUNIT_TEST(testToString_EmptyNode); + CPPUNIT_TEST(testToString_EmptyResource); + CPPUNIT_TEST(testToString_NoResource); + CPPUNIT_TEST(testCompare_SmallerNode); + CPPUNIT_TEST(testCompare_LargerNode); + CPPUNIT_TEST(testCompare_SmallerDomain); + CPPUNIT_TEST(testCompare_LargerDomain); + CPPUNIT_TEST(testCompare_SmallerResource); + CPPUNIT_TEST(testCompare_LargerResource); + CPPUNIT_TEST(testCompare_Equal); + CPPUNIT_TEST(testCompare_EqualWithoutResource); + CPPUNIT_TEST(testCompare_NoResourceAndEmptyResource); + CPPUNIT_TEST(testCompare_EmptyResourceAndNoResource); + CPPUNIT_TEST(testEquals); + CPPUNIT_TEST(testEquals_NotEqual); + CPPUNIT_TEST(testEquals_WithoutResource); + CPPUNIT_TEST(testSmallerThan); + CPPUNIT_TEST(testSmallerThan_Equal); + 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: + JIDTest() {} + + void testConstructorWithString() { + JID testling("foo@bar/baz"); + + CPPUNIT_ASSERT_EQUAL(std::string("foo"), testling.getNode()); + CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain()); + CPPUNIT_ASSERT_EQUAL(std::string("baz"), testling.getResource()); + CPPUNIT_ASSERT(!testling.isBare()); + CPPUNIT_ASSERT(testling.isValid()); + } + + void testConstructorWithString_Empty() { + JID testling(""); + CPPUNIT_ASSERT_EQUAL(false, testling.isValid()); + } + + void testConstructorWithString_NoResource() { + JID testling("foo@bar"); + + CPPUNIT_ASSERT_EQUAL(std::string("foo"), testling.getNode()); + CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain()); + CPPUNIT_ASSERT_EQUAL(std::string(""), testling.getResource()); + CPPUNIT_ASSERT(testling.isBare()); + CPPUNIT_ASSERT(testling.isValid()); + } + + void testConstructorWithString_EmptyResource() { + JID testling("bar/"); + + CPPUNIT_ASSERT(!testling.isValid()); + CPPUNIT_ASSERT(!testling.isBare()); + } + + void testConstructorWithString_NoNode() { + JID testling("bar/baz"); + + CPPUNIT_ASSERT_EQUAL(std::string(""), testling.getNode()); + CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain()); + CPPUNIT_ASSERT_EQUAL(std::string("baz"), testling.getResource()); + CPPUNIT_ASSERT(!testling.isBare()); + CPPUNIT_ASSERT(testling.isValid()); + } + + void testConstructorWithString_OnlyDomain() { + JID testling("bar"); + + CPPUNIT_ASSERT_EQUAL(std::string(""), testling.getNode()); + CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain()); + CPPUNIT_ASSERT_EQUAL(std::string(""), testling.getResource()); + CPPUNIT_ASSERT(testling.isBare()); + CPPUNIT_ASSERT(testling.isValid()); + } + + void testConstructorWithString_InvalidDomain() { + CPPUNIT_ASSERT(!JID("foo@bar,baz").isValid()); + } + + void testConstructorWithString_UpperCaseNode() { + JID testling("Fo\xCE\xA9@bar"); + + CPPUNIT_ASSERT_EQUAL(std::string("fo\xCF\x89"), testling.getNode()); + CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain()); + CPPUNIT_ASSERT(testling.isValid()); + } + + void testConstructorWithString_UpperCaseDomain() { + JID testling("Fo\xCE\xA9"); + + CPPUNIT_ASSERT_EQUAL(std::string("fo\xCF\x89"), testling.getDomain()); + CPPUNIT_ASSERT(testling.isValid()); + } + + void testConstructorWithString_UpperCaseResource() { + JID testling("bar/Fo\xCE\xA9"); + + CPPUNIT_ASSERT_EQUAL(testling.getResource(), std::string("Fo\xCE\xA9")); + CPPUNIT_ASSERT(testling.isValid()); + } + + void testConstructorWithString_EmptyNode() { + JID testling("@bar"); + + CPPUNIT_ASSERT(!testling.isValid()); + } - CPPUNIT_ASSERT_EQUAL(std::string("foo"), testling.getNode()); - CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain()); - CPPUNIT_ASSERT_EQUAL(std::string("baz"), testling.getResource()); - CPPUNIT_ASSERT(testling.isValid()); - } + void testConstructorWithString_IllegalResource() { + JID testling("foo@bar.com/\xd8\xb1\xd9\x85\xd9\x82\xd9\x87\x20\xd8\xaa\xd8\xb1\xd9\x86\xd8\xb3\x20"); - void testConstructorWithStrings_EmptyDomain() { - JID testling("foo", "", "baz"); + CPPUNIT_ASSERT(!testling.isValid()); + } - CPPUNIT_ASSERT(!testling.isValid()); - } + void testConstructorWithString_SpacesInNode() { + CPPUNIT_ASSERT(!JID(" alice@wonderland.lit").isValid()); + CPPUNIT_ASSERT(!JID("alice @wonderland.lit").isValid()); + } - void testIsBare() { - CPPUNIT_ASSERT(JID("foo@bar").isBare()); - } + void testConstructorWithStrings() { + JID testling("foo", "bar", "baz"); - void testIsBare_NotBare() { - CPPUNIT_ASSERT(!JID("foo@bar/baz").isBare()); - } + CPPUNIT_ASSERT_EQUAL(std::string("foo"), testling.getNode()); + CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain()); + CPPUNIT_ASSERT_EQUAL(std::string("baz"), testling.getResource()); + CPPUNIT_ASSERT(testling.isValid()); + } - void testToBare() { - JID testling("foo@bar/baz"); + void testConstructorWithStrings_EmptyDomain() { + JID testling("foo", "", "baz"); - CPPUNIT_ASSERT_EQUAL(std::string("foo"), testling.toBare().getNode()); - CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.toBare().getDomain()); - CPPUNIT_ASSERT(testling.toBare().isBare()); - } + CPPUNIT_ASSERT(!testling.isValid()); + } - void testToBare_EmptyNode() { - JID testling("bar/baz"); + void testConstructorWithStrings_EmptyResource() { + JID testling("foo", "bar", ""); - CPPUNIT_ASSERT_EQUAL(std::string(""), testling.toBare().getNode()); - CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.toBare().getDomain()); - CPPUNIT_ASSERT(testling.toBare().isBare()); - CPPUNIT_ASSERT(testling.isValid()); - } + CPPUNIT_ASSERT(!testling.isValid()); + } - void testToBare_EmptyResource() { - JID testling("bar/"); + void testIsBare() { + CPPUNIT_ASSERT(JID("foo@bar").isBare()); + } - CPPUNIT_ASSERT_EQUAL(std::string(""), testling.toBare().getNode()); - CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.toBare().getDomain()); - CPPUNIT_ASSERT(testling.toBare().isBare()); - } + void testIsBare_NotBare() { + CPPUNIT_ASSERT(!JID("foo@bar/baz").isBare()); + } - void testToString() { - JID testling("foo@bar/baz"); + void testToBare() { + JID testling("foo@bar/baz"); - CPPUNIT_ASSERT_EQUAL(std::string("foo@bar/baz"), testling.toString()); - } + CPPUNIT_ASSERT_EQUAL(std::string("foo"), testling.toBare().getNode()); + CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.toBare().getDomain()); + CPPUNIT_ASSERT(testling.toBare().isBare()); + } - void testToString_EmptyNode() { - JID testling("bar/baz"); + void testToBare_EmptyNode() { + JID testling("bar/baz"); - CPPUNIT_ASSERT_EQUAL(std::string("bar/baz"), testling.toString()); - } + CPPUNIT_ASSERT_EQUAL(std::string(""), testling.toBare().getNode()); + CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.toBare().getDomain()); + CPPUNIT_ASSERT(testling.toBare().isBare()); + CPPUNIT_ASSERT(testling.isValid()); + } - void testToString_NoResource() { - JID testling("foo@bar"); + void testToBare_EmptyResource() { + JID testling("bar/"); - CPPUNIT_ASSERT_EQUAL(std::string("foo@bar"), testling.toString()); - } + CPPUNIT_ASSERT_EQUAL(std::string(""), testling.toBare().getNode()); + CPPUNIT_ASSERT(!testling.isValid()); + } - void testToString_EmptyResource() { - JID testling("foo@bar/"); + void testToString() { + JID testling("foo@bar/baz"); - CPPUNIT_ASSERT_EQUAL(std::string("foo@bar/"), testling.toString()); - } + CPPUNIT_ASSERT_EQUAL(std::string("foo@bar/baz"), testling.toString()); + } - void testCompare_SmallerNode() { - JID testling1("a@c"); - JID testling2("b@b"); + void testToString_EmptyNode() { + JID testling("bar/baz"); - CPPUNIT_ASSERT_EQUAL(-1, testling1.compare(testling2, JID::WithResource)); - } + CPPUNIT_ASSERT_EQUAL(std::string("bar/baz"), testling.toString()); + } - void testCompare_LargerNode() { - JID testling1("c@a"); - JID testling2("b@b"); + void testToString_NoResource() { + JID testling("foo@bar"); - CPPUNIT_ASSERT_EQUAL(1, testling1.compare(testling2, JID::WithResource)); - } + CPPUNIT_ASSERT_EQUAL(std::string("foo@bar"), testling.toString()); + } - void testCompare_SmallerDomain() { - JID testling1("x@a/c"); - JID testling2("x@b/b"); + void testToString_EmptyResource() { + JID testling("foo@bar/"); - CPPUNIT_ASSERT_EQUAL(-1, testling1.compare(testling2, JID::WithResource)); - } + CPPUNIT_ASSERT_EQUAL(false, testling.isValid()); + } - void testCompare_LargerDomain() { - JID testling1("x@b/b"); - JID testling2("x@a/c"); + void testCompare_SmallerNode() { + JID testling1("a@c"); + JID testling2("b@b"); - CPPUNIT_ASSERT_EQUAL(1, testling1.compare(testling2, JID::WithResource)); - } + CPPUNIT_ASSERT_EQUAL(-1, testling1.compare(testling2, JID::WithResource)); + } - void testCompare_SmallerResource() { - JID testling1("x@y/a"); - JID testling2("x@y/b"); + void testCompare_LargerNode() { + JID testling1("c@a"); + JID testling2("b@b"); - CPPUNIT_ASSERT_EQUAL(-1, testling1.compare(testling2, JID::WithResource)); - } + CPPUNIT_ASSERT_EQUAL(1, testling1.compare(testling2, JID::WithResource)); + } - void testCompare_LargerResource() { - JID testling1("x@y/b"); - JID testling2("x@y/a"); + void testCompare_SmallerDomain() { + JID testling1("x@a/c"); + JID testling2("x@b/b"); - CPPUNIT_ASSERT_EQUAL(1, testling1.compare(testling2, JID::WithResource)); - } + CPPUNIT_ASSERT_EQUAL(-1, testling1.compare(testling2, JID::WithResource)); + } - void testCompare_Equal() { - JID testling1("x@y/z"); - JID testling2("x@y/z"); + void testCompare_LargerDomain() { + JID testling1("x@b/b"); + JID testling2("x@a/c"); - CPPUNIT_ASSERT_EQUAL(0, testling1.compare(testling2, JID::WithResource)); - } + CPPUNIT_ASSERT_EQUAL(1, testling1.compare(testling2, JID::WithResource)); + } - void testCompare_EqualWithoutResource() { - JID testling1("x@y/a"); - JID testling2("x@y/b"); + void testCompare_SmallerResource() { + JID testling1("x@y/a"); + JID testling2("x@y/b"); - CPPUNIT_ASSERT_EQUAL(0, testling1.compare(testling2, JID::WithoutResource)); - } + CPPUNIT_ASSERT_EQUAL(-1, testling1.compare(testling2, JID::WithResource)); + } - void testCompare_NoResourceAndEmptyResource() { - JID testling1("x@y/"); - JID testling2("x@y"); + void testCompare_LargerResource() { + JID testling1("x@y/b"); + JID testling2("x@y/a"); - CPPUNIT_ASSERT_EQUAL(1, testling1.compare(testling2, JID::WithResource)); - } + CPPUNIT_ASSERT_EQUAL(1, testling1.compare(testling2, JID::WithResource)); + } - void testCompare_EmptyResourceAndNoResource() { - JID testling1("x@y"); - JID testling2("x@y/"); + void testCompare_Equal() { + JID testling1("x@y/z"); + JID testling2("x@y/z"); - CPPUNIT_ASSERT_EQUAL(-1, testling1.compare(testling2, JID::WithResource)); - } + CPPUNIT_ASSERT_EQUAL(0, testling1.compare(testling2, JID::WithResource)); + } - void testEquals() { - JID testling1("x@y/c"); - JID testling2("x@y/c"); + void testCompare_EqualWithoutResource() { + JID testling1("x@y/a"); + JID testling2("x@y/b"); - CPPUNIT_ASSERT(testling1.equals(testling2, JID::WithResource)); - } - - void testEquals_NotEqual() { - JID testling1("x@y/c"); - JID testling2("x@y/d"); - - CPPUNIT_ASSERT(!testling1.equals(testling2, JID::WithResource)); - } - - void testEquals_WithoutResource() { - JID testling1("x@y/c"); - JID testling2("x@y/d"); - - CPPUNIT_ASSERT(testling1.equals(testling2, JID::WithoutResource)); - } - - void testSmallerThan() { - JID testling1("x@y/c"); - JID testling2("x@y/d"); - - CPPUNIT_ASSERT(testling1 < testling2); - } - - void testSmallerThan_Equal() { - JID testling1("x@y/d"); - JID testling2("x@y/d"); - - CPPUNIT_ASSERT(!(testling1 < testling2)); - } - - void testSmallerThan_Larger() { - JID testling1("x@y/d"); - JID testling2("x@y/c"); - - CPPUNIT_ASSERT(!(testling1 < testling2)); - } - - void testHasResource() { - JID testling("x@y/d"); - - CPPUNIT_ASSERT(!testling.isBare()); - } - - void testHasResource_NoResource() { - JID testling("x@y"); - - 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_ASSERT_EQUAL(0, testling1.compare(testling2, JID::WithoutResource)); + } + + void testCompare_NoResourceAndEmptyResource() { + JID testling1("x@y/"); + JID testling2("x@y"); + + CPPUNIT_ASSERT_EQUAL(-1, testling1.compare(testling2, JID::WithResource)); + } + + void testCompare_EmptyResourceAndNoResource() { + JID testling1("x@y"); + JID testling2("x@y/"); + + CPPUNIT_ASSERT_EQUAL(1, testling1.compare(testling2, JID::WithResource)); + } + + void testEquals() { + JID testling1("x@y/c"); + JID testling2("x@y/c"); + + CPPUNIT_ASSERT(testling1.equals(testling2, JID::WithResource)); + } + + void testEquals_NotEqual() { + JID testling1("x@y/c"); + JID testling2("x@y/d"); + + CPPUNIT_ASSERT(!testling1.equals(testling2, JID::WithResource)); + } + + void testEquals_WithoutResource() { + JID testling1("x@y/c"); + JID testling2("x@y/d"); + + CPPUNIT_ASSERT(testling1.equals(testling2, JID::WithoutResource)); + } + + void testSmallerThan() { + JID testling1("x@y/c"); + JID testling2("x@y/d"); + + CPPUNIT_ASSERT(testling1 < testling2); + } + + void testSmallerThan_Equal() { + JID testling1("x@y/d"); + JID testling2("x@y/d"); + + CPPUNIT_ASSERT(!(testling1 < testling2)); + } + + void testSmallerThan_Larger() { + JID testling1("x@y/d"); + JID testling2("x@y/c"); + + CPPUNIT_ASSERT(!(testling1 < testling2)); + } + + void testHasResource() { + JID testling("x@y/d"); + + CPPUNIT_ASSERT(!testling.isBare()); + } + + void testHasResource_NoResource() { + { + JID testling("x@y"); + + CPPUNIT_ASSERT(testling.isBare()); + CPPUNIT_ASSERT_EQUAL(true, testling.isValid()); + } + + { + JID testling("node@domain/"); + CPPUNIT_ASSERT_EQUAL(false, testling.isValid()); + } + } + + 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); |