2 * jid.cpp - class for verifying and manipulating Jabber IDs
3 * Copyright (C) 2003 Justin Karneges
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 //#undef IRIS_XMPP_JID_DEPRECATED
22 #include "xmpp/jid/jid.h"
24 #include <QCoreApplication>
27 #include <libidn/stringprep.h>
30 #include "irisnetglobal_p.h"
36 //----------------------------------------------------------------------------
38 //----------------------------------------------------------------------------
39 class StringPrepCache
: public QObject
42 static bool nameprep(const QString
&in
, int maxbytes
, QString
& out
)
49 StringPrepCache
*that
= get_instance();
51 Result
*r
= that
->nameprep_table
[in
];
60 QByteArray cs
= in
.toUtf8();
62 if(stringprep(cs
.data(), maxbytes
, (Stringprep_profile_flags
)0, stringprep_nameprep
) != 0)
64 that
->nameprep_table
.insert(in
, new Result
);
68 QString norm
= QString::fromUtf8(cs
);
69 that
->nameprep_table
.insert(in
, new Result(norm
));
74 static bool nodeprep(const QString
&in
, int maxbytes
, QString
& out
)
81 StringPrepCache
*that
= get_instance();
83 Result
*r
= that
->nodeprep_table
[in
];
92 QByteArray cs
= in
.toUtf8();
94 if(stringprep(cs
.data(), maxbytes
, (Stringprep_profile_flags
)0, stringprep_xmpp_nodeprep
) != 0) {
95 that
->nodeprep_table
.insert(in
, new Result
);
99 QString norm
= QString::fromUtf8(cs
);
100 that
->nodeprep_table
.insert(in
, new Result(norm
));
105 static bool resourceprep(const QString
&in
, int maxbytes
, QString
& out
)
112 StringPrepCache
*that
= get_instance();
114 Result
*r
= that
->resourceprep_table
[in
];
123 QByteArray cs
= in
.toUtf8();
125 if(stringprep(cs
.data(), maxbytes
, (Stringprep_profile_flags
)0, stringprep_xmpp_resourceprep
) != 0) {
126 that
->resourceprep_table
.insert(in
, new Result
);
130 QString norm
= QString::fromUtf8(cs
);
131 that
->resourceprep_table
.insert(in
, new Result(norm
));
136 static void cleanup()
152 Result(const QString
&s
) : norm(new QString(s
))
162 QHash
<QString
,Result
*> nameprep_table
;
163 QHash
<QString
,Result
*> nodeprep_table
;
164 QHash
<QString
,Result
*> resourceprep_table
;
166 static StringPrepCache
*instance
;
168 static StringPrepCache
*get_instance()
172 instance
= new StringPrepCache
;
174 irisNetAddPostRoutine(cleanup
);
186 foreach(Result
* r
, nameprep_table
) {
189 nameprep_table
.clear();
190 foreach(Result
* r
, nodeprep_table
) {
193 nodeprep_table
.clear();
194 foreach(Result
* r
, resourceprep_table
) {
197 resourceprep_table
.clear();
201 StringPrepCache
*StringPrepCache::instance
= 0;
203 //----------------------------------------------------------------------------
205 //----------------------------------------------------------------------------
207 static inline bool validDomain(const QString
&s
, QString
& norm
)
209 return StringPrepCache::nameprep(s
, 1024, norm
);
212 static inline bool validNode(const QString
&s
, QString
& norm
)
214 return StringPrepCache::nodeprep(s
, 1024, norm
);
217 static inline bool validResource(const QString
&s
, QString
& norm
)
219 return StringPrepCache::resourceprep(s
, 1024, norm
);
232 Jid::Jid(const QString
&s
)
237 Jid::Jid(const QString
&node
, const QString
& domain
, const QString
& resource
)
239 set(domain
, node
, resource
);
242 Jid::Jid(const char *s
)
247 Jid
& Jid::operator=(const QString
&s
)
253 Jid
& Jid::operator=(const char *s
)
272 // build 'bare' and 'full' jids
283 null
= f
.isEmpty() && r
.isEmpty();
286 void Jid::set(const QString
&s
)
288 QString rest
, domain
, node
, resource
;
289 QString norm_domain
, norm_node
, norm_resource
;
290 int x
= s
.indexOf('/');
293 resource
= s
.mid(x
+1);
297 resource
= QString();
299 if(!validResource(resource
, norm_resource
)) {
304 x
= rest
.indexOf('@');
306 node
= rest
.mid(0, x
);
307 domain
= rest
.mid(x
+1);
313 if(!validDomain(domain
, norm_domain
) || !validNode(node
, norm_node
)) {
326 void Jid::set(const QString
&domain
, const QString
&node
, const QString
&resource
)
328 QString norm_domain
, norm_node
, norm_resource
;
329 if(!validDomain(domain
, norm_domain
) || !validNode(node
, norm_node
) || !validResource(resource
, norm_resource
)) {
341 void Jid::setDomain(const QString
&s
)
346 if(!validDomain(s
, norm
)) {
354 void Jid::setNode(const QString
&s
)
359 if(!validNode(s
, norm
)) {
367 void Jid::setResource(const QString
&s
)
372 if(!validResource(s
, norm
)) {
380 Jid
Jid::withNode(const QString
&s
) const
387 Jid
Jid::withDomain(const QString
&s
) const
394 Jid
Jid::withResource(const QString
&s
) const
401 bool Jid::isValid() const
406 bool Jid::isEmpty() const
411 bool Jid::compare(const Jid
&a
, bool compareRes
) const
416 // only compare valid jids
417 if(!valid
|| !a
.valid
)
420 if(compareRes
? (f
!= a
.f
) : (b
!= a
.b
))