summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/JID')
-rw-r--r--Swiften/JID/JID.cpp419
-rw-r--r--Swiften/JID/JID.h370
-rw-r--r--Swiften/JID/SConscript4
-rw-r--r--Swiften/JID/UnitTest/JIDTest.cpp724
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);