~ubuntu-branches/ubuntu/quantal/psi/quantal

« back to all changes in this revision

Viewing changes to iris/xmpp-im/xmpp_xmlcommon.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2009-09-25 17:49:51 UTC
  • mfrom: (6.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090925174951-lvm7kdap82o8xhn3
Tags: 0.13-1
* Updated to upstream version 0.13
* Set Standards-Version to 3.8.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * xmlcommon.cpp - helper functions for dealing with XML
3
 
 * Copyright (C) 2001, 2002  Justin Karneges
4
 
 *
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.
9
 
 *
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.
14
 
 *
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
18
 
 *
19
 
 */
20
 
 
21
 
#include "xmpp_xmlcommon.h"
22
 
#include "xmpp_stanza.h"
23
 
 
24
 
#include <qstring.h>
25
 
#include <qdom.h>
26
 
#include <qdatetime.h>
27
 
#include <qsize.h>
28
 
#include <qrect.h>
29
 
#include <qstringlist.h>
30
 
#include <qcolor.h>
31
 
 
32
 
//----------------------------------------------------------------------------
33
 
// XDomNodeList
34
 
//----------------------------------------------------------------------------
35
 
XDomNodeList::XDomNodeList()
36
 
{
37
 
}
38
 
 
39
 
XDomNodeList::XDomNodeList(const XDomNodeList &from) :
40
 
        list(from.list)
41
 
{
42
 
}
43
 
 
44
 
XDomNodeList::XDomNodeList(const QDomNodeList &from)
45
 
{
46
 
        for(int n = 0; n < from.count(); ++n)
47
 
                list += from.item(n);
48
 
}
49
 
 
50
 
XDomNodeList::~XDomNodeList()
51
 
{
52
 
}
53
 
 
54
 
XDomNodeList & XDomNodeList::operator=(const XDomNodeList &from)
55
 
{
56
 
        list = from.list;
57
 
        return *this;
58
 
}
59
 
 
60
 
bool XDomNodeList::isEmpty() const
61
 
{
62
 
        return list.isEmpty();
63
 
}
64
 
 
65
 
QDomNode XDomNodeList::item(int index) const
66
 
{
67
 
        return list.value(index);
68
 
}
69
 
 
70
 
uint XDomNodeList::length() const
71
 
{
72
 
        return (uint)list.count();
73
 
}
74
 
 
75
 
bool XDomNodeList::operator==(const XDomNodeList &a) const
76
 
{
77
 
        return (list == a.list);
78
 
}
79
 
 
80
 
void XDomNodeList::append(const QDomNode &i)
81
 
{
82
 
        list += i;
83
 
}
84
 
 
85
 
 
86
 
QDateTime stamp2TS(const QString &ts)
87
 
{
88
 
        if(ts.length() != 17)
89
 
                return QDateTime();
90
 
 
91
 
        int year  = ts.mid(0,4).toInt();
92
 
        int month = ts.mid(4,2).toInt();
93
 
        int day   = ts.mid(6,2).toInt();
94
 
 
95
 
        int hour  = ts.mid(9,2).toInt();
96
 
        int min   = ts.mid(12,2).toInt();
97
 
        int sec   = ts.mid(15,2).toInt();
98
 
 
99
 
        QDate xd;
100
 
        xd.setYMD(year, month, day);
101
 
        if(!xd.isValid())
102
 
                return QDateTime();
103
 
 
104
 
        QTime xt;
105
 
        xt.setHMS(hour, min, sec);
106
 
        if(!xt.isValid())
107
 
                return QDateTime();
108
 
 
109
 
        return QDateTime(xd, xt);
110
 
}
111
 
 
112
 
bool stamp2TS(const QString &ts, QDateTime *d)
113
 
{
114
 
        QDateTime dateTime = stamp2TS(ts);
115
 
        if (dateTime.isNull())
116
 
                return false;
117
 
 
118
 
        *d = dateTime;
119
 
 
120
 
        return true;
121
 
}
122
 
 
123
 
QString TS2stamp(const QDateTime &d)
124
 
{
125
 
        QString str;
126
 
 
127
 
        str.sprintf("%04d%02d%02dT%02d:%02d:%02d",
128
 
                d.date().year(),
129
 
                d.date().month(),
130
 
                d.date().day(),
131
 
                d.time().hour(),
132
 
                d.time().minute(),
133
 
                d.time().second());
134
 
 
135
 
        return str;
136
 
}
137
 
 
138
 
QDomElement textTag(QDomDocument *doc, const QString &name, const QString &content)
139
 
{
140
 
        QDomElement tag = doc->createElement(name);
141
 
        QDomText text = doc->createTextNode(content);
142
 
        tag.appendChild(text);
143
 
 
144
 
        return tag;
145
 
}
146
 
 
147
 
QString tagContent(const QDomElement &e)
148
 
{
149
 
        // look for some tag content
150
 
        for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
151
 
                QDomText i = n.toText();
152
 
                if(i.isNull())
153
 
                        continue;
154
 
                return i.data();
155
 
        }
156
 
 
157
 
        return "";
158
 
}
159
 
 
160
 
 
161
 
/**
162
 
 * \brief find an direct child element by name
163
 
 * \param e parent element
164
 
 * \param name name of element to find
165
 
 * \param found (optional/out) found?
166
 
 * \return the element (or a null QDomElemnt if not found)
167
 
 */
168
 
QDomElement findSubTag(const QDomElement &e, const QString &name, bool *found)
169
 
{
170
 
        if(found)
171
 
                *found = false;
172
 
 
173
 
        for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
174
 
                QDomElement i = n.toElement();
175
 
                if(i.isNull())
176
 
                        continue;
177
 
                if(i.tagName() == name) {
178
 
                        if(found)
179
 
                                *found = true;
180
 
                        return i;
181
 
                }
182
 
        }
183
 
 
184
 
        QDomElement tmp;
185
 
        return tmp;
186
 
}
187
 
 
188
 
 
189
 
/**
190
 
 * \brief obtain direct child elements of a certain kind.  unlike
191
 
 *        elementsByTagNameNS, this function does not descend beyond the first
192
 
 *        level of children.
193
 
 * \param e parent element
194
 
 * \param nsURI namespace of the elements to find
195
 
 * \param localName local name of the elements to find
196
 
 * \return the node list of found elements (empty list if none are found)
197
 
 */
198
 
XDomNodeList childElementsByTagNameNS(const QDomElement &e, const QString &nsURI, const QString &localName)
199
 
{
200
 
        XDomNodeList out;
201
 
        for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
202
 
                if(!n.isElement())
203
 
                        continue;
204
 
                QDomElement i = n.toElement();
205
 
                if(i.namespaceURI() == nsURI && i.localName() == localName)
206
 
                        out.append(i);
207
 
        }
208
 
        return out;
209
 
}
210
 
 
211
 
 
212
 
/**
213
 
 * \brief create a new IQ stanza
214
 
 * \param doc 
215
 
 * \param type 
216
 
 * \param to destination jid
217
 
 * \param id stanza id
218
 
 * \return the created stanza
219
 
*/
220
 
QDomElement createIQ(QDomDocument *doc, const QString &type, const QString &to, const QString &id)
221
 
{
222
 
        QDomElement iq = doc->createElement("iq");
223
 
        if(!type.isEmpty())
224
 
                iq.setAttribute("type", type);
225
 
        if(!to.isEmpty())
226
 
                iq.setAttribute("to", to);
227
 
        if(!id.isEmpty())
228
 
                iq.setAttribute("id", id);
229
 
 
230
 
        return iq;
231
 
}
232
 
 
233
 
/** \brief returns direct child element named "query"
234
 
 * \return the element (or a null QDomElemnt if not found)
235
 
*/
236
 
QDomElement queryTag(const QDomElement &e)
237
 
{
238
 
        bool found;
239
 
        QDomElement q = findSubTag(e, "query", &found);
240
 
        return q;
241
 
}
242
 
 
243
 
QString queryNS(const QDomElement &e)
244
 
{
245
 
        bool found;
246
 
        QDomElement q = findSubTag(e, "query", &found);
247
 
        if(found)
248
 
                return q.attribute("xmlns");
249
 
 
250
 
        return "";
251
 
}
252
 
 
253
 
/**
254
 
        \brief Extracts the error code and description from the stanza element.
255
 
 
256
 
        This function finds the error element in the given stanza element \a e.
257
 
 
258
 
        You need to provide the base namespace of the stream to which this stanza belongs to
259
 
        (probably by using stream.baseNS() function).
260
 
 
261
 
        The error description is either error text extracted from XML
262
 
        or - if no text is found - the error name and description (separated by '\n') taken from RFC-3920
263
 
        or - if the error is not defined in the RFC - the empty string.
264
 
 
265
 
        Note: This function uses the Stanza::Error class,
266
 
        so it may guess missing values as defined in JEP-0086.
267
 
 
268
 
        \param e        the element representing stanza
269
 
        \param baseNS   the base namespace of the stream
270
 
        \param code     if not NULL, will be filled with numeric error code
271
 
        \param str      if not NULL, will be filled with human readable error description
272
 
*/
273
 
 
274
 
void getErrorFromElement(const QDomElement &e, const QString &baseNS, int *code, QString *str)
275
 
{
276
 
        bool found;
277
 
        QDomElement tag = findSubTag(e, "error", &found);
278
 
        if(!found)
279
 
                return;
280
 
 
281
 
        XMPP::Stanza::Error err;
282
 
        err.fromXml(tag, baseNS);
283
 
 
284
 
        if(code)
285
 
                *code = err.code();
286
 
        if(str) {
287
 
                QPair<QString, QString> desc = err.description();
288
 
                if (err.text.isEmpty())
289
 
                        *str = desc.first + ".\n" + desc.second;
290
 
                else
291
 
                        *str = desc.first + ".\n" + desc.second + "\n" + err.text;
292
 
        }
293
 
 
294
 
}
295
 
 
296
 
QDomElement addCorrectNS(const QDomElement &e)
297
 
{
298
 
        int x;
299
 
 
300
 
        // grab child nodes
301
 
        /*QDomDocumentFragment frag = e.ownerDocument().createDocumentFragment();
302
 
        QDomNodeList nl = e.childNodes();
303
 
        for(x = 0; x < nl.count(); ++x)
304
 
                frag.appendChild(nl.item(x).cloneNode());*/
305
 
 
306
 
        // find closest xmlns
307
 
        QDomNode n = e;
308
 
        while(!n.isNull() && !n.toElement().hasAttribute("xmlns"))
309
 
                n = n.parentNode();
310
 
        QString ns;
311
 
        if(n.isNull() || !n.toElement().hasAttribute("xmlns"))
312
 
                ns = "jabber:client";
313
 
        else
314
 
                ns = n.toElement().attribute("xmlns");
315
 
 
316
 
        // make a new node
317
 
        QDomElement i = e.ownerDocument().createElementNS(ns, e.tagName());
318
 
 
319
 
        // copy attributes
320
 
        QDomNamedNodeMap al = e.attributes();
321
 
        for(x = 0; x < al.count(); ++x) {
322
 
                QDomAttr a = al.item(x).toAttr();
323
 
                if(a.name() != "xmlns")
324
 
                        i.setAttributeNodeNS(a.cloneNode().toAttr());
325
 
        }
326
 
 
327
 
        // copy children
328
 
        QDomNodeList nl = e.childNodes();
329
 
        for(x = 0; x < nl.count(); ++x) {
330
 
                QDomNode n = nl.item(x);
331
 
                if(n.isElement())
332
 
                        i.appendChild(addCorrectNS(n.toElement()));
333
 
                else
334
 
                        i.appendChild(n.cloneNode());
335
 
        }
336
 
 
337
 
        //i.appendChild(frag);
338
 
        return i;
339
 
}
340
 
 
341
 
//----------------------------------------------------------------------------
342
 
// XMLHelper
343
 
//----------------------------------------------------------------------------
344
 
 
345
 
namespace XMLHelper {
346
 
 
347
 
QDomElement emptyTag(QDomDocument *doc, const QString &name)
348
 
{
349
 
        QDomElement tag = doc->createElement(name);
350
 
 
351
 
        return tag;
352
 
}
353
 
 
354
 
bool hasSubTag(const QDomElement &e, const QString &name)
355
 
{
356
 
        bool found;
357
 
        findSubTag(e, name, &found);
358
 
        return found;
359
 
}
360
 
 
361
 
QString subTagText(const QDomElement &e, const QString &name)
362
 
{
363
 
        bool found;
364
 
        QDomElement i = findSubTag(e, name, &found);
365
 
        if ( found )
366
 
                return i.text();
367
 
        return QString::null;
368
 
}
369
 
 
370
 
QDomElement textTag(QDomDocument &doc, const QString &name, const QString &content)
371
 
{
372
 
        QDomElement tag = doc.createElement(name);
373
 
        QDomText text = doc.createTextNode(content);
374
 
        tag.appendChild(text);
375
 
 
376
 
        return tag;
377
 
}
378
 
 
379
 
QDomElement textTag(QDomDocument &doc, const QString &name, int content)
380
 
{
381
 
        QDomElement tag = doc.createElement(name);
382
 
        QDomText text = doc.createTextNode(QString::number(content));
383
 
        tag.appendChild(text);
384
 
 
385
 
        return tag;
386
 
}
387
 
 
388
 
QDomElement textTag(QDomDocument &doc, const QString &name, bool content)
389
 
{
390
 
        QDomElement tag = doc.createElement(name);
391
 
        QDomText text = doc.createTextNode(content ? "true" : "false");
392
 
        tag.appendChild(text);
393
 
 
394
 
        return tag;
395
 
}
396
 
 
397
 
QDomElement textTag(QDomDocument &doc, const QString &name, QSize &s)
398
 
{
399
 
        QString str;
400
 
        str.sprintf("%d,%d", s.width(), s.height());
401
 
 
402
 
        QDomElement tag = doc.createElement(name);
403
 
        QDomText text = doc.createTextNode(str);
404
 
        tag.appendChild(text);
405
 
 
406
 
        return tag;
407
 
}
408
 
 
409
 
QDomElement textTag(QDomDocument &doc, const QString &name, QRect &r)
410
 
{
411
 
        QString str;
412
 
        str.sprintf("%d,%d,%d,%d", r.x(), r.y(), r.width(), r.height());
413
 
 
414
 
        QDomElement tag = doc.createElement(name);
415
 
        QDomText text = doc.createTextNode(str);
416
 
        tag.appendChild(text);
417
 
 
418
 
        return tag;
419
 
}
420
 
 
421
 
QDomElement stringListToXml(QDomDocument &doc, const QString &name, const QStringList &l)
422
 
{
423
 
        QDomElement tag = doc.createElement(name);
424
 
        for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it)
425
 
                tag.appendChild(textTag(doc, "item", *it));
426
 
 
427
 
        return tag;
428
 
}
429
 
 
430
 
/*QString tagContent(const QDomElement &e)
431
 
{
432
 
        // look for some tag content
433
 
        for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
434
 
                QDomText i = n.toText();
435
 
                if(i.isNull())
436
 
                        continue;
437
 
                return i.data();
438
 
        }
439
 
 
440
 
        return "";
441
 
}*/
442
 
 
443
 
/*QDomElement findSubTag(const QDomElement &e, const QString &name, bool *found)
444
 
{
445
 
        if(found)
446
 
                *found = FALSE;
447
 
 
448
 
        for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
449
 
                QDomElement i = n.toElement();
450
 
                if(i.isNull())
451
 
                        continue;
452
 
                if(i.tagName() == name) {
453
 
                        if(found)
454
 
                                *found = TRUE;
455
 
                        return i;
456
 
                }
457
 
        }
458
 
 
459
 
        QDomElement tmp;
460
 
        return tmp;
461
 
}*/
462
 
 
463
 
void readEntry(const QDomElement &e, const QString &name, QString *v)
464
 
{
465
 
        bool found = FALSE;
466
 
        QDomElement tag = findSubTag(e, name, &found);
467
 
        if(!found)
468
 
                return;
469
 
        *v = tagContent(tag);
470
 
}
471
 
 
472
 
void readNumEntry(const QDomElement &e, const QString &name, int *v)
473
 
{
474
 
        bool found = FALSE;
475
 
        QDomElement tag = findSubTag(e, name, &found);
476
 
        if(!found)
477
 
                return;
478
 
        *v = tagContent(tag).toInt();
479
 
}
480
 
 
481
 
void readBoolEntry(const QDomElement &e, const QString &name, bool *v)
482
 
{
483
 
        bool found = FALSE;
484
 
        QDomElement tag = findSubTag(e, name, &found);
485
 
        if(!found)
486
 
                return;
487
 
        *v = (tagContent(tag) == "true") ? TRUE: FALSE;
488
 
}
489
 
 
490
 
void readSizeEntry(const QDomElement &e, const QString &name, QSize *v)
491
 
{
492
 
        bool found = FALSE;
493
 
        QDomElement tag = findSubTag(e, name, &found);
494
 
        if(!found)
495
 
                return;
496
 
        QStringList list = tagContent(tag).split(',');
497
 
        if(list.count() != 2)
498
 
                return;
499
 
        QSize s;
500
 
        s.setWidth(list[0].toInt());
501
 
        s.setHeight(list[1].toInt());
502
 
        *v = s;
503
 
}
504
 
 
505
 
void readRectEntry(const QDomElement &e, const QString &name, QRect *v)
506
 
{
507
 
        bool found = FALSE;
508
 
        QDomElement tag = findSubTag(e, name, &found);
509
 
        if(!found)
510
 
                return;
511
 
        QStringList list = tagContent(tag).split(',');
512
 
        if(list.count() != 4)
513
 
                return;
514
 
        QRect r;
515
 
        r.setX(list[0].toInt());
516
 
        r.setY(list[1].toInt());
517
 
        r.setWidth(list[2].toInt());
518
 
        r.setHeight(list[3].toInt());
519
 
        *v = r;
520
 
}
521
 
 
522
 
void readColorEntry(const QDomElement &e, const QString &name, QColor *v)
523
 
{
524
 
        bool found = FALSE;
525
 
        QDomElement tag = findSubTag(e, name, &found);
526
 
        if(!found)
527
 
                return;
528
 
        QColor c;
529
 
        c.setNamedColor(tagContent(tag));
530
 
        if(c.isValid())
531
 
                *v = c;
532
 
}
533
 
 
534
 
void xmlToStringList(const QDomElement &e, const QString &name, QStringList *v)
535
 
{
536
 
        bool found = false;
537
 
        QDomElement tag = findSubTag(e, name, &found);
538
 
        if(!found)
539
 
                return;
540
 
        QStringList list;
541
 
        for(QDomNode n = tag.firstChild(); !n.isNull(); n = n.nextSibling()) {
542
 
                QDomElement i = n.toElement();
543
 
                if(i.isNull())
544
 
                        continue;
545
 
                if(i.tagName() == "item")
546
 
                        list += tagContent(i);
547
 
        }
548
 
        *v = list;
549
 
}
550
 
 
551
 
void setBoolAttribute(QDomElement e, const QString &name, bool b)
552
 
{
553
 
        e.setAttribute(name, b ? "true" : "false");
554
 
}
555
 
 
556
 
void readBoolAttribute(QDomElement e, const QString &name, bool *v)
557
 
{
558
 
        if(e.hasAttribute(name)) {
559
 
                QString s = e.attribute(name);
560
 
                *v = (s == "true") ? TRUE: FALSE;
561
 
        }
562
 
}
563
 
 
564
 
};
565