diff options
Diffstat (limited to 'kopete/protocols/jabber/libiris/iris/xmpp-core/jid.cpp')
-rw-r--r-- | kopete/protocols/jabber/libiris/iris/xmpp-core/jid.cpp | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/kopete/protocols/jabber/libiris/iris/xmpp-core/jid.cpp b/kopete/protocols/jabber/libiris/iris/xmpp-core/jid.cpp new file mode 100644 index 00000000..29932513 --- /dev/null +++ b/kopete/protocols/jabber/libiris/iris/xmpp-core/jid.cpp @@ -0,0 +1,409 @@ +/* + * jid.cpp - class for verifying and manipulating Jabber IDs + * Copyright (C) 2003 Justin Karneges + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include"xmpp.h" + +#include<qdict.h> +#include<stringprep.h> + +using namespace XMPP; + +//---------------------------------------------------------------------------- +// StringPrepCache +//---------------------------------------------------------------------------- +class StringPrepCache +{ +public: + static bool nameprep(const QString &in, int maxbytes, QString *out) + { + if(in.isEmpty()) + { + if(out) + *out = QString(); + return true; + } + + StringPrepCache *that = get_instance(); + + Result *r = that->nameprep_table.find(in); + if(r) + { + if(!r->norm) + return false; + if(out) + *out = *(r->norm); + return true; + } + + QCString cs = in.utf8(); + cs.resize(maxbytes); + if(stringprep(cs.data(), maxbytes, (Stringprep_profile_flags)0, stringprep_nameprep) != 0) + { + that->nameprep_table.insert(in, new Result); + return false; + } + + QString norm = QString::fromUtf8(cs); + that->nameprep_table.insert(in, new Result(norm)); + if(out) + *out = norm; + return true; + } + + static bool nodeprep(const QString &in, int maxbytes, QString *out) + { + if(in.isEmpty()) + { + if(out) + *out = QString(); + return true; + } + + StringPrepCache *that = get_instance(); + + Result *r = that->nodeprep_table.find(in); + if(r) + { + if(!r->norm) + return false; + if(out) + *out = *(r->norm); + return true; + } + + QCString cs = in.utf8(); + cs.resize(maxbytes); + if(stringprep(cs.data(), maxbytes, (Stringprep_profile_flags)0, stringprep_xmpp_nodeprep) != 0) + { + that->nodeprep_table.insert(in, new Result); + return false; + } + + QString norm = QString::fromUtf8(cs); + that->nodeprep_table.insert(in, new Result(norm)); + if(out) + *out = norm; + return true; + } + + static bool resourceprep(const QString &in, int maxbytes, QString *out) + { + if(in.isEmpty()) + { + if(out) + *out = QString(); + return true; + } + + StringPrepCache *that = get_instance(); + + Result *r = that->resourceprep_table.find(in); + if(r) + { + if(!r->norm) + return false; + if(out) + *out = *(r->norm); + return true; + } + + QCString cs = in.utf8(); + cs.resize(maxbytes); + if(stringprep(cs.data(), maxbytes, (Stringprep_profile_flags)0, stringprep_xmpp_resourceprep) != 0) + { + that->resourceprep_table.insert(in, new Result); + return false; + } + + QString norm = QString::fromUtf8(cs); + that->resourceprep_table.insert(in, new Result(norm)); + if(out) + *out = norm; + return true; + } + +private: + class Result + { + public: + QString *norm; + + Result() : norm(0) + { + } + + Result(const QString &s) : norm(new QString(s)) + { + } + + ~Result() + { + delete norm; + } + }; + + QDict<Result> nameprep_table; + QDict<Result> nodeprep_table; + QDict<Result> resourceprep_table; + + static StringPrepCache *instance; + + static StringPrepCache *get_instance() + { + if(!instance) + instance = new StringPrepCache; + return instance; + } + + StringPrepCache() + { + nameprep_table.setAutoDelete(true); + nodeprep_table.setAutoDelete(true); + resourceprep_table.setAutoDelete(true); + } +}; + +StringPrepCache *StringPrepCache::instance = 0; + +//---------------------------------------------------------------------------- +// Jid +//---------------------------------------------------------------------------- +Jid::Jid() +{ + valid = false; +} + +Jid::~Jid() +{ +} + +Jid::Jid(const QString &s) +{ + set(s); +} + +Jid::Jid(const char *s) +{ + set(QString(s)); +} + +Jid & Jid::operator=(const QString &s) +{ + set(s); + return *this; +} + +Jid & Jid::operator=(const char *s) +{ + set(QString(s)); + return *this; +} + +void Jid::reset() +{ + f = QString(); + b = QString(); + d = QString(); + n = QString(); + r = QString(); + valid = false; +} + +void Jid::update() +{ + // build 'bare' and 'full' jids + if(n.isEmpty()) + b = d; + else + b = n + '@' + d; + + b=b.lower(); // JID are not case sensitive + + if(r.isEmpty()) + f = b; + else + f = b + '/' + r; + if(f.isEmpty()) + valid = false; +} + +void Jid::set(const QString &s) +{ + QString rest, domain, node, resource; + QString norm_domain, norm_node, norm_resource; + int x = s.find('/'); + if(x != -1) { + rest = s.mid(0, x); + resource = s.mid(x+1); + } + else { + rest = s; + resource = QString(); + } + if(!validResource(resource, &norm_resource)) { + reset(); + return; + } + + x = rest.find('@'); + if(x != -1) { + node = rest.mid(0, x); + domain = rest.mid(x+1); + } + else { + node = QString(); + domain = rest; + } + if(!validDomain(domain, &norm_domain) || !validNode(node, &norm_node)) { + reset(); + return; + } + + valid = true; + d = norm_domain; + n = norm_node; + r = norm_resource; + update(); +} + +void Jid::set(const QString &domain, const QString &node, const QString &resource) +{ + QString norm_domain, norm_node, norm_resource; + if(!validDomain(domain, &norm_domain) || !validNode(node, &norm_node) || !validResource(resource, &norm_resource)) { + reset(); + return; + } + valid = true; + d = norm_domain; + n = norm_node; + r = norm_resource; + update(); +} + +void Jid::setDomain(const QString &s) +{ + if(!valid) + return; + QString norm; + if(!validDomain(s, &norm)) { + reset(); + return; + } + d = norm; + update(); +} + +void Jid::setNode(const QString &s) +{ + if(!valid) + return; + QString norm; + if(!validNode(s, &norm)) { + reset(); + return; + } + n = norm; + update(); +} + +void Jid::setResource(const QString &s) +{ + if(!valid) + return; + QString norm; + if(!validResource(s, &norm)) { + reset(); + return; + } + r = norm; + update(); +} + +Jid Jid::withNode(const QString &s) const +{ + Jid j = *this; + j.setNode(s); + return j; +} + +Jid Jid::withResource(const QString &s) const +{ + Jid j = *this; + j.setResource(s); + return j; +} + +bool Jid::isValid() const +{ + return valid; +} + +bool Jid::isEmpty() const +{ + return f.isEmpty(); +} + +bool Jid::compare(const Jid &a, bool compareRes) const +{ + // only compare valid jids + if(!valid || !a.valid) + return false; + + if(compareRes ? (f != a.f) : (b != a.b)) + return false; + + return true; +} + +bool Jid::validDomain(const QString &s, QString *norm) +{ + /*QCString cs = s.utf8(); + cs.resize(1024); + if(stringprep(cs.data(), 1024, (Stringprep_profile_flags)0, stringprep_nameprep) != 0) + return false; + if(norm) + *norm = QString::fromUtf8(cs); + return true;*/ + return StringPrepCache::nameprep(s, 1024, norm); +} + +bool Jid::validNode(const QString &s, QString *norm) +{ + /*QCString cs = s.utf8(); + cs.resize(1024); + if(stringprep(cs.data(), 1024, (Stringprep_profile_flags)0, stringprep_xmpp_nodeprep) != 0) + return false; + if(norm) + *norm = QString::fromUtf8(cs); + return true;*/ + return StringPrepCache::nodeprep(s, 1024, norm); +} + +bool Jid::validResource(const QString &s, QString *norm) +{ + /*QCString cs = s.utf8(); + cs.resize(1024); + if(stringprep(cs.data(), 1024, (Stringprep_profile_flags)0, stringprep_xmpp_resourceprep) != 0) + return false; + if(norm) + *norm = QString::fromUtf8(cs); + return true;*/ + return StringPrepCache::resourceprep(s, 1024, norm); +} |