initial commit

This commit is contained in:
mikhail "synzr" 2025-12-25 01:37:49 +05:00
commit 9d20827c46
2469 changed files with 470994 additions and 0 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,180 @@
/*
* Copyright (C) 2001, 2002 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 <QDomElement>
#include <QString>
#include "xmpp_task.h"
#include "xmpp_jid.h"
#include "xmpp_discoitem.h"
#include "xmpp_discoinfotask.h"
#include "xmpp_xmlcommon.h"
using namespace XMPP;
class DiscoInfoTask::Private
{
public:
Private() { }
QDomElement iq;
Jid jid;
QString node;
DiscoItem item;
XData xdata;
};
DiscoInfoTask::DiscoInfoTask(Task *parent)
: Task(parent)
{
d = new Private;
}
DiscoInfoTask::~DiscoInfoTask()
{
delete d;
}
void DiscoInfoTask::get(const DiscoItem &item)
{
DiscoItem::Identity id;
if ( item.identities().count() == 1 )
id = item.identities().first();
get(item.jid(), item.node(), id);
}
void DiscoInfoTask::get (const Jid &j, const QString &node, DiscoItem::Identity ident)
{
d->item = DiscoItem(); // clear item
d->jid = j;
d->node = node;
d->iq = createIQ(doc(), "get", d->jid.full(), id());
QDomElement query = doc()->createElement("query");
query.setAttribute("xmlns", "http://jabber.org/protocol/disco#info");
if ( !node.isEmpty() )
query.setAttribute("node", node);
if ( !ident.category.isEmpty() && !ident.type.isEmpty() ) {
QDomElement i = doc()->createElement("item");
i.setAttribute("category", ident.category);
i.setAttribute("type", ident.type);
if ( !ident.name.isEmpty() )
i.setAttribute("name", ident.name);
query.appendChild( i );
}
d->iq.appendChild(query);
}
/**
* Original requested jid.
* Is here because sometimes the responder does not include this information
* in the reply.
*/
const Jid& DiscoInfoTask::jid() const
{
return d->jid;
}
/**
* Original requested node.
* Is here because sometimes the responder does not include this information
* in the reply.
*/
const QString& DiscoInfoTask::node() const
{
return d->node;
}
const DiscoItem &DiscoInfoTask::item() const
{
return d->item;
}
const XData &DiscoInfoTask::xdata() const
{
return d->xdata;
}
void DiscoInfoTask::onGo ()
{
send(d->iq);
}
bool DiscoInfoTask::take(const QDomElement &x)
{
if(!iqVerify(x, d->jid, id()))
return false;
if(x.attribute("type") == "result") {
QDomElement q = queryTag(x);
DiscoItem item;
item.setJid( d->jid );
item.setNode( q.attribute("node") );
QStringList features;
DiscoItem::Identities identities;
for(QDomNode n = q.firstChild(); !n.isNull(); n = n.nextSibling()) {
QDomElement e = n.toElement();
if( e.isNull() )
continue;
if ( e.tagName() == "feature" ) {
features << e.attribute("var");
}
else if ( e.tagName() == "identity" ) {
DiscoItem::Identity id;
id.category = e.attribute("category");
id.name = e.attribute("name");
id.type = e.attribute("type");
identities.append( id );
}
else if ( e.tagName() == "x" && e.attribute("xmlns") =="jabber:x:data" ) {
d->xdata.fromXml(e);
}
}
item.setFeatures( features );
item.setIdentities( identities );
d->item = item;
setSuccess(true);
}
else {
setError(x);
}
return true;
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (C) 2001, 2002 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
*
*/
#ifndef XMPP_DISCOINFOTASK_H
#define XMPP_DISCOINFOTASK_H
#include "xmpp_task.h"
#include "xmpp_discoitem.h"
#include "xmpp_xdata.h"
namespace XMPP {
class Jid;
}
class QString;
class QDomElement;
namespace XMPP
{
class DiscoInfoTask : public Task
{
Q_OBJECT
public:
DiscoInfoTask(Task *);
~DiscoInfoTask();
void get(const Jid &, const QString &node = QString::null, const DiscoItem::Identity = DiscoItem::Identity());
void get(const DiscoItem &);
const DiscoItem &item() const;
const Jid& jid() const;
const QString& node() const;
const XData &xdata() const;
void onGo();
bool take(const QDomElement &);
private:
class Private;
Private *d;
};
// Deprecated name
typedef DiscoInfoTask JT_DiscoInfo;
}
#endif

View file

@ -0,0 +1,199 @@
/*
* xmpp_discoitem.cpp
* 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_discoitem.h"
using namespace XMPP;
class DiscoItem::Private
{
public:
Private()
{
action = None;
}
Jid jid;
QString name;
QString node;
Action action;
Features features;
Identities identities;
};
DiscoItem::DiscoItem()
{
d = new Private;
}
DiscoItem::DiscoItem(const DiscoItem &from)
{
d = new Private;
*this = from;
}
DiscoItem & DiscoItem::operator= (const DiscoItem &from)
{
d->jid = from.d->jid;
d->name = from.d->name;
d->node = from.d->node;
d->action = from.d->action;
d->features = from.d->features;
d->identities = from.d->identities;
return *this;
}
DiscoItem::~DiscoItem()
{
delete d;
}
AgentItem DiscoItem::toAgentItem() const
{
AgentItem ai;
ai.setJid( jid() );
ai.setName( name() );
Identity id;
if ( !identities().isEmpty() )
id = identities().first();
ai.setCategory( id.category );
ai.setType( id.type );
ai.setFeatures( d->features );
return ai;
}
void DiscoItem::fromAgentItem(const AgentItem &ai)
{
setJid( ai.jid() );
setName( ai.name() );
Identity id;
id.category = ai.category();
id.type = ai.type();
id.name = ai.name();
Identities idList;
idList << id;
setIdentities( idList );
setFeatures( ai.features() );
}
const Jid &DiscoItem::jid() const
{
return d->jid;
}
void DiscoItem::setJid(const Jid &j)
{
d->jid = j;
}
const QString &DiscoItem::name() const
{
return d->name;
}
void DiscoItem::setName(const QString &n)
{
d->name = n;
}
const QString &DiscoItem::node() const
{
return d->node;
}
void DiscoItem::setNode(const QString &n)
{
d->node = n;
}
DiscoItem::Action DiscoItem::action() const
{
return d->action;
}
void DiscoItem::setAction(Action a)
{
d->action = a;
}
const Features &DiscoItem::features() const
{
return d->features;
}
void DiscoItem::setFeatures(const Features &f)
{
d->features = f;
}
const DiscoItem::Identities &DiscoItem::identities() const
{
return d->identities;
}
void DiscoItem::setIdentities(const Identities &i)
{
d->identities = i;
if ( name().isEmpty() && i.count() )
setName( i.first().name );
}
DiscoItem::Action DiscoItem::string2action(QString s)
{
Action a;
if ( s == "update" )
a = Update;
else if ( s == "remove" )
a = Remove;
else
a = None;
return a;
}
QString DiscoItem::action2string(Action a)
{
QString s;
if ( a == Update )
s = "update";
else if ( a == Remove )
s = "remove";
else
s = QString::null;
return s;
}

View file

@ -0,0 +1,289 @@
/*
* xmpp_features.cpp - XMPP entity features
* 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 <QApplication>
#include <QString>
#include <QMap>
#include <QStringList>
#include "xmpp_features.h"
using namespace XMPP;
Features::Features()
{
}
Features::Features(const QStringList &l)
{
setList(l);
}
Features::Features(const QString &str)
{
QStringList l;
l << str;
setList(l);
}
Features::~Features()
{
}
QStringList Features::list() const
{
return _list;
}
void Features::setList(const QStringList &l)
{
_list = l;
}
void Features::addFeature(const QString& s)
{
_list += s;
}
bool Features::test(const QString &ns) const
{
return _list.contains(ns);
}
bool Features::test(const QStringList &ns) const
{
QStringList::ConstIterator it = ns.begin();
for ( ; it != ns.end(); ++it) {
if ( _list.contains( *it )) {
return true;
}
}
return false;
}
#define FID_MULTICAST "http://jabber.org/protocol/address"
bool Features::canMulticast() const
{
QStringList ns;
ns << FID_MULTICAST;
return test(ns);
}
#define FID_AHCOMMAND "http://jabber.org/protocol/commands"
bool Features::canCommand() const
{
QStringList ns;
ns << FID_AHCOMMAND;
return test(ns);
}
#define FID_REGISTER "jabber:iq:register"
bool Features::canRegister() const
{
QStringList ns;
ns << FID_REGISTER;
return test(ns);
}
#define FID_SEARCH "jabber:iq:search"
bool Features::canSearch() const
{
QStringList ns;
ns << FID_SEARCH;
return test(ns);
}
#define FID_GROUPCHAT "jabber:iq:conference"
bool Features::canGroupchat() const
{
QStringList ns;
ns << "http://jabber.org/protocol/muc";
ns << FID_GROUPCHAT;
return test(ns);
}
#define FID_VOICE "http://www.google.com/xmpp/protocol/voice/v1"
bool Features::canVoice() const
{
QStringList ns;
ns << FID_VOICE;
return test(ns);
}
#define FID_GATEWAY "jabber:iq:gateway"
bool Features::isGateway() const
{
QStringList ns;
ns << FID_GATEWAY;
return test(ns);
}
#define FID_DISCO "http://jabber.org/protocol/disco"
bool Features::canDisco() const
{
QStringList ns;
ns << FID_DISCO;
ns << "http://jabber.org/protocol/disco#info";
ns << "http://jabber.org/protocol/disco#items";
return test(ns);
}
#define FID_CHATSTATE "http://jabber.org/protocol/chatstates"
bool Features::canChatState() const
{
QStringList ns;
ns << FID_CHATSTATE;
return test(ns);
}
#define FID_VCARD "vcard-temp"
bool Features::haveVCard() const
{
QStringList ns;
ns << FID_VCARD;
return test(ns);
}
#define FID_MESSAGE_RECEIPTS "urn:xmpp:receipts"
bool Features::canMessageReceipts() const
{
QStringList ns;
ns << FID_MESSAGE_RECEIPTS;
return test(ns);
}
// custom Psi acitons
#define FID_ADD "psi:add"
class Features::FeatureName : public QObject
{
Q_OBJECT
public:
FeatureName()
: QObject(qApp)
{
id2s[FID_Invalid] = tr("ERROR: Incorrect usage of Features class");
id2s[FID_None] = tr("None");
id2s[FID_Register] = tr("Register");
id2s[FID_Search] = tr("Search");
id2s[FID_Groupchat] = tr("Groupchat");
id2s[FID_Gateway] = tr("Gateway");
id2s[FID_Disco] = tr("Service Discovery");
id2s[FID_VCard] = tr("VCard");
id2s[FID_AHCommand] = tr("Execute command");
// custom Psi actions
id2s[FID_Add] = tr("Add to roster");
// compute reverse map
//QMap<QString, long>::Iterator it = id2s.begin();
//for ( ; it != id2s.end(); ++it)
// s2id[it.data()] = it.key();
id2f[FID_Register] = FID_REGISTER;
id2f[FID_Search] = FID_SEARCH;
id2f[FID_Groupchat] = FID_GROUPCHAT;
id2f[FID_Gateway] = FID_GATEWAY;
id2f[FID_Disco] = FID_DISCO;
id2f[FID_VCard] = FID_VCARD;
id2f[FID_AHCommand] = FID_AHCOMMAND;
// custom Psi actions
id2f[FID_Add] = FID_ADD;
}
//QMap<QString, long> s2id;
QMap<long, QString> id2s;
QMap<long, QString> id2f;
};
static Features::FeatureName *featureName = 0;
long Features::id() const
{
if ( _list.count() > 1 )
return FID_Invalid;
else if ( canRegister() )
return FID_Register;
else if ( canSearch() )
return FID_Search;
else if ( canGroupchat() )
return FID_Groupchat;
else if ( isGateway() )
return FID_Gateway;
else if ( canDisco() )
return FID_Disco;
else if ( haveVCard() )
return FID_VCard;
else if ( canCommand() )
return FID_AHCommand;
else if ( test(QStringList(FID_ADD)) )
return FID_Add;
return FID_None;
}
long Features::id(const QString &feature)
{
Features f(feature);
return f.id();
}
QString Features::feature(long id)
{
if ( !featureName )
featureName = new FeatureName();
return featureName->id2f[id];
}
QString Features::name(long id)
{
if ( !featureName )
featureName = new FeatureName();
return featureName->id2s[id];
}
QString Features::name() const
{
return name(id());
}
QString Features::name(const QString &feature)
{
Features f(feature);
return f.name(f.id());
}
#include "xmpp_features.moc"

View file

@ -0,0 +1,301 @@
/*
* 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 <QTimer>
#include <qplatformdefs.h>
#include "safedelete.h"
#include "xmpp_task.h"
#include "xmpp_client.h"
#include "xmpp_xmlcommon.h"
using namespace XMPP;
class Task::TaskPrivate
{
public:
TaskPrivate() {}
QString id;
bool success;
int statusCode;
QString statusString;
Client *client;
bool insig, deleteme, autoDelete;
bool done;
};
Task::Task(Task *parent)
:QObject(parent)
{
init();
d->client = parent->client();
d->id = client()->genUniqueId();
connect(d->client, SIGNAL(disconnected()), SLOT(clientDisconnected()));
}
Task::Task(Client *parent, bool)
:QObject(0)
{
init();
d->client = parent;
connect(d->client, SIGNAL(disconnected()), SLOT(clientDisconnected()));
}
Task::~Task()
{
delete d;
}
void Task::init()
{
d = new TaskPrivate;
d->success = false;
d->insig = false;
d->deleteme = false;
d->autoDelete = false;
d->done = false;
}
Task *Task::parent() const
{
return (Task *)QObject::parent();
}
Client *Task::client() const
{
return d->client;
}
QDomDocument *Task::doc() const
{
return client()->doc();
}
QString Task::id() const
{
return d->id;
}
bool Task::success() const
{
return d->success;
}
int Task::statusCode() const
{
return d->statusCode;
}
const QString & Task::statusString() const
{
return d->statusString;
}
void Task::go(bool autoDelete)
{
d->autoDelete = autoDelete;
if (!client() || !&client()->stream()) {
qWarning("Task::go(): attempted to send a task over the broken connection.");
if (autoDelete) {
deleteLater();
}
}
else {
onGo();
}
}
bool Task::take(const QDomElement &x)
{
const QObjectList p = children();
// pass along the xml
Task *t;
for(QObjectList::ConstIterator it = p.begin(); it != p.end(); ++it) {
QObject *obj = *it;
if(!obj->inherits("XMPP::Task"))
continue;
t = static_cast<Task*>(obj);
if(t->take(x))
return true;
}
return false;
}
void Task::safeDelete()
{
if(d->deleteme)
return;
d->deleteme = true;
if(!d->insig)
SafeDelete::deleteSingle(this);
}
void Task::onGo()
{
}
void Task::onDisconnect()
{
if(!d->done) {
d->success = false;
d->statusCode = ErrDisc;
d->statusString = tr("Disconnected");
// delay this so that tasks that react don't block the shutdown
QTimer::singleShot(0, this, SLOT(done()));
}
}
void Task::send(const QDomElement &x)
{
client()->send(x);
}
void Task::setSuccess(int code, const QString &str)
{
if(!d->done) {
d->success = true;
d->statusCode = code;
d->statusString = str;
done();
}
}
void Task::setError(const QDomElement &e)
{
if(!d->done) {
d->success = false;
getErrorFromElement(e, d->client->streamBaseNS(), &d->statusCode, &d->statusString);
done();
}
}
void Task::setError(int code, const QString &str)
{
if(!d->done) {
d->success = false;
d->statusCode = code;
d->statusString = str;
done();
}
}
void Task::done()
{
if(d->done || d->insig)
return;
d->done = true;
if(d->deleteme || d->autoDelete)
d->deleteme = true;
d->insig = true;
finished();
d->insig = false;
if(d->deleteme)
SafeDelete::deleteSingle(this);
}
void Task::clientDisconnected()
{
onDisconnect();
}
void Task::debug(const char *fmt, ...)
{
Q_UNUSED(fmt);
#if 0
char *buf;
QString str;
int size = 1024;
int r;
do {
buf = new char[size];
va_list ap;
va_start(ap, fmt);
r = QT_VSNPRINTF(buf, size, fmt, ap);
va_end(ap);
if(r != -1)
str = QString(buf);
delete [] buf;
size *= 2;
} while(r == -1);
debug(str);
#endif
}
void Task::debug(const QString &str)
{
client()->debug(QString("%1: ").arg(metaObject()->className()) + str);
}
bool Task::iqVerify(const QDomElement &x, const Jid &to, const QString &id, const QString &xmlns)
{
if(x.tagName() != "iq")
return false;
Jid from(x.attribute("from"));
Jid local = client()->jid();
Jid server = client()->host();
// empty 'from' ?
if(from.isEmpty()) {
// allowed if we are querying the server
if(!to.isEmpty() && !to.compare(server))
return false;
}
// from ourself?
else if(from.compare(local, false) || from.compare(local.domain(),false)) {
// allowed if we are querying ourself or the server
if(!to.isEmpty() && !to.compare(local, false) && !to.compare(server))
return false;
}
// from anywhere else?
else {
if(!from.compare(to))
return false;
}
if(!id.isEmpty()) {
if(x.attribute("id") != id)
return false;
}
if(!xmlns.isEmpty()) {
if(queryNS(x) != xmlns)
return false;
}
return true;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,530 @@
/*
* tasks.h - basic tasks
* Copyright (C) 2001, 2002 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
*
*/
#ifndef JABBER_TASKS_H
#define JABBER_TASKS_H
#include <qstring.h>
#include <qdom.h>
//Added by qt3to4:
#include <QList>
#include "im.h"
#include "xmpp_vcard.h"
#include "xmpp_discoinfotask.h"
#ifdef YAPSI
#include "xmpp_yadatetime.h"
#endif
namespace XMPP
{
class Roster;
class Status;
class JT_Register : public Task
{
Q_OBJECT
public:
JT_Register(Task *parent);
~JT_Register();
// OLd style registration
void reg(const QString &user, const QString &pass);
void changepw(const QString &pass);
void unreg(const Jid &j="");
const Form & form() const;
bool hasXData() const;
const XData& xdata() const;
void getForm(const Jid &);
void setForm(const Form &);
void setForm(const Jid&, const XData &);
void onGo();
bool take(const QDomElement &);
private:
QDomElement iq;
Jid to;
class Private;
Private *d;
};
class JT_UnRegister : public Task
{
Q_OBJECT
public:
JT_UnRegister(Task *parent);
~JT_UnRegister();
void unreg(const Jid &);
void onGo();
private slots:
void getFormFinished();
void unregFinished();
private:
class Private;
Private *d;
};
class JT_Roster : public Task
{
Q_OBJECT
public:
JT_Roster(Task *parent);
~JT_Roster();
void get();
void set(const Jid &, const QString &name, const QStringList &groups);
void remove(const Jid &);
const Roster & roster() const;
QString toString() const;
bool fromString(const QString &);
void onGo();
bool take(const QDomElement &x);
private:
int type;
QDomElement iq;
Jid to;
class Private;
Private *d;
};
class JT_PushRoster : public Task
{
Q_OBJECT
public:
JT_PushRoster(Task *parent);
~JT_PushRoster();
bool take(const QDomElement &);
signals:
void roster(const Roster &);
};
class JT_Presence : public Task
{
Q_OBJECT
public:
JT_Presence(Task *parent);
~JT_Presence();
void pres(const Status &);
void pres(const Jid &, const Status &);
void sub(const Jid &, const QString &subType, const QString& nick = QString());
void probe(const Jid &);
void onGo();
private:
QDomElement tag;
int type;
};
class JT_PushPresence : public Task
{
Q_OBJECT
public:
JT_PushPresence(Task *parent);
~JT_PushPresence();
bool take(const QDomElement &);
signals:
void presence(const Jid &, const Status &);
void subscription(const Jid &, const QString &, const QString&);
};
class JT_Session : public Task
{
public:
JT_Session(Task *parent);
void onGo();
bool take(const QDomElement&);
};
class JT_Message : public Task
{
Q_OBJECT
public:
JT_Message(Task *parent, const Message &);
~JT_Message();
void onGo();
private:
Message m;
};
class JT_PushMessage : public Task
{
Q_OBJECT
public:
JT_PushMessage(Task *parent);
~JT_PushMessage();
bool take(const QDomElement &);
signals:
void message(const Message &);
};
class JT_GetServices : public Task
{
Q_OBJECT
public:
JT_GetServices(Task *);
void get(const Jid &);
const AgentList & agents() const;
void onGo();
bool take(const QDomElement &x);
private:
QDomElement iq;
Jid jid;
AgentList agentList;
};
class JT_VCard : public Task
{
Q_OBJECT
public:
JT_VCard(Task *parent);
~JT_VCard();
void get(const Jid &);
void set(const Jid &, const VCard &);
const Jid & jid() const;
const VCard & vcard() const;
void onGo();
bool take(const QDomElement &x);
private:
int type;
class Private;
Private *d;
};
class JT_Search : public Task
{
Q_OBJECT
public:
JT_Search(Task *parent);
~JT_Search();
const Form & form() const;
const QList<SearchResult> & results() const;
void get(const Jid &);
void set(const Form &);
void onGo();
bool take(const QDomElement &x);
private:
QDomElement iq;
int type;
class Private;
Private *d;
};
class JT_ClientVersion : public Task
{
Q_OBJECT
public:
JT_ClientVersion(Task *);
void get(const Jid &);
void onGo();
bool take(const QDomElement &);
const Jid & jid() const;
const QString & name() const;
const QString & version() const;
const QString & os() const;
private:
QDomElement iq;
Jid j;
QString v_name, v_ver, v_os;
};
/*
class JT_ClientTime : public Task
{
Q_OBJECT
public:
JT_ClientTime(Task *, const Jid &);
void go();
bool take(const QDomElement &);
Jid j;
QDateTime utc;
QString timezone, display;
private:
QDomElement iq;
};
*/
class JT_ServInfo : public Task
{
Q_OBJECT
public:
JT_ServInfo(Task *);
~JT_ServInfo();
bool take(const QDomElement &);
};
class JT_Gateway : public Task
{
Q_OBJECT
public:
JT_Gateway(Task *);
void get(const Jid &);
void set(const Jid &, const QString &prompt);
void onGo();
bool take(const QDomElement &);
Jid jid() const;
QString desc() const;
QString prompt() const;
private:
QDomElement iq;
int type;
Jid v_jid;
QString v_prompt, v_desc;
};
class JT_Browse : public Task
{
Q_OBJECT
public:
JT_Browse(Task *);
~JT_Browse();
void get(const Jid &);
const AgentList & agents() const;
const AgentItem & root() const;
void onGo();
bool take(const QDomElement &);
private:
class Private;
Private *d;
AgentItem browseHelper (const QDomElement &i);
};
class JT_DiscoItems : public Task
{
Q_OBJECT
public:
JT_DiscoItems(Task *);
~JT_DiscoItems();
void get(const Jid &, const QString &node = QString::null);
void get(const DiscoItem &);
const Jid & jid() const;
const DiscoList &items() const;
void onGo();
bool take(const QDomElement &);
private:
class Private;
Private *d;
};
class JT_DiscoPublish : public Task
{
Q_OBJECT
public:
JT_DiscoPublish(Task *);
~JT_DiscoPublish();
void set(const Jid &, const DiscoList &);
void onGo();
bool take(const QDomElement &);
private:
class Private;
Private *d;
};
#ifdef YAPSI
class JT_YaLogMessage : public Task
{
Q_OBJECT
public:
JT_YaLogMessage(Task *parent);
~JT_YaLogMessage();
void log(bool originLocal, const YaDateTime& timeStamp, const XMPP::Jid& accountJid, const Message &message);
void onGo();
bool take(const QDomElement &);
private:
Message m_;
XMPP::Jid selfJid_;
bool originLocal_;
YaDateTime timeStamp_;
};
class JT_YaRemoveHistory : public Task
{
Q_OBJECT
public:
JT_YaRemoveHistory(Task *parent);
~JT_YaRemoveHistory();
void remove(const XMPP::Jid& owner);
void remove(const XMPP::Jid& owner, const XMPP::Jid& twin);
void remove(const XMPP::Jid& owner, const XMPP::Jid& twin, const XMPP::Jid& contact);
void onGo();
bool take(const QDomElement &);
private:
XMPP::Jid selfJid_;
XMPP::Jid twin_;
XMPP::Jid contact_;
};
class JT_YaRetrieveHistory : public Task
{
Q_OBJECT
public:
JT_YaRetrieveHistory(Task *parent);
~JT_YaRetrieveHistory();
struct Chat {
YaDateTime timeStamp;
QString body;
bool originLocal;
XMPP::Jid jid;
};
void retrieve(const XMPP::Jid& contact, int messageCount, YaDateTime startTime = YaDateTime());
void checkUnread(YaDateTime startTime = YaDateTime());
const XMPP::Jid& contact() const;
const QList<Chat>& messages() const;
void onGo();
bool take(const QDomElement &);
private:
XMPP::Jid contact_;
int messageCount_;
bool checkUnread_;
YaDateTime startTime_;
QList<Chat> messages_;
};
class JT_YaMessageRead : public Task
{
Q_OBJECT
public:
JT_YaMessageRead(Task* parent);
~JT_YaMessageRead();
void messageRead(const XMPP::Jid& contact, const YaDateTime& timeStamp);
void setTo(const XMPP::Jid& to);
void onGo();
bool take(const QDomElement &);
private:
XMPP::Jid to_;
XMPP::Jid contact_;
YaDateTime timeStamp_;
};
class JT_YaMoodSwitch : public Task
{
Q_OBJECT
public:
JT_YaMoodSwitch(Task* parent);
~JT_YaMoodSwitch();
void get();
void set(bool enabled_);
bool enabled() const;
void onGo();
bool take(const QDomElement &);
private:
bool isGet_;
bool enabled_;
};
class JT_YaMaxLast : public Task
{
Q_OBJECT
public:
JT_YaMaxLast(Task* parent);
~JT_YaMaxLast();
void get();
void set(int maxLast);
int maxLast() const;
void onGo();
bool take(const QDomElement &);
private:
bool isGet_;
int maxLast_;
};
#endif
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,311 @@
/*
* xmpp_vcard.h - classes for handling vCards
* Copyright (C) 2003 Michail Pishchagin
*
* 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
*
*/
#ifndef JABBER_VCARD_H
#define JABBER_VCARD_H
#include <QList>
#include <QString>
#include <QStringList>
class QDate;
class QDomElement;
class QDomDocument;
class QByteArray;
class QDate;
class QImage;
namespace XMPP
{
class VCard
{
public:
VCard();
VCard(const VCard &);
VCard & operator=(const VCard &);
~VCard();
QDomElement toXml(QDomDocument *) const;
bool fromXml(const QDomElement &);
bool isEmpty() const;
const QString &version() const;
void setVersion(const QString &);
const QString &fullName() const;
void setFullName(const QString &);
const QString &familyName() const;
void setFamilyName(const QString &);
const QString &givenName() const;
void setGivenName(const QString &);
const QString &middleName() const;
void setMiddleName(const QString &);
const QString &prefixName() const;
void setPrefixName(const QString &);
const QString &suffixName() const;
void setSuffixName(const QString &);
const QString &nickName() const;
void setNickName(const QString &);
const QByteArray &photo() const;
void setPhoto(const QByteArray &);
void setPhoto(const QImage &);
const QString &photoURI() const;
void setPhotoURI(const QString &);
const QDate bday() const;
void setBday(const QDate &);
const QString &bdayStr() const;
void setBdayStr(const QString &);
class Address {
public:
Address();
bool isNull() const;
bool home;
bool work;
bool postal;
bool parcel;
bool dom;
bool intl;
bool pref;
QString pobox;
QString extaddr;
QString street;
QString locality;
QString region;
QString pcode;
QString country;
};
typedef QList<Address> AddressList;
const AddressList &addressList() const;
void setAddressList(const AddressList &);
Address address() const;
QString locality() const;
QString addressString() const;
class Label {
public:
Label();
bool home;
bool work;
bool postal;
bool parcel;
bool dom;
bool intl;
bool pref;
QStringList lines;
};
typedef QList<Label> LabelList;
const LabelList &labelList() const;
void setLabelList(const LabelList &);
class Phone {
public:
Phone();
bool home;
bool work;
bool voice;
bool fax;
bool pager;
bool msg;
bool cell;
bool video;
bool bbs;
bool modem;
bool isdn;
bool pcs;
bool pref;
QString number;
};
typedef QList<Phone> PhoneList;
const PhoneList &phoneList() const;
void setPhoneList(const PhoneList &);
class Email {
public:
Email();
bool home;
bool work;
bool internet;
bool x400;
QString userid;
};
typedef QList<Email> EmailList;
const EmailList &emailList() const;
void setEmailList(const EmailList &);
QString email() const;
const QString &jid() const;
void setJid(const QString &);
const QString &mailer() const;
void setMailer(const QString &);
const QString &timezone() const;
void setTimezone(const QString &);
class Geo {
public:
Geo();
QString lat;
QString lon;
};
const Geo &geo() const;
void setGeo(const Geo &);
const QString &title() const;
void setTitle(const QString &);
const QString &role() const;
void setRole(const QString &);
const QByteArray &logo() const;
void setLogo(const QByteArray &);
const QString &logoURI() const;
void setLogoURI(const QString &);
const VCard *agent() const;
void setAgent(const VCard &);
const QString agentURI() const;
void setAgentURI(const QString &);
class Org {
public:
Org();
QString name;
QStringList unit;
};
const Org &org() const;
void setOrg(const Org &);
const QStringList &categories() const;
void setCategories(const QStringList &);
const QString &note() const;
void setNote(const QString &);
const QString &prodId() const; // it must equal to "Psi" ;-)
void setProdId(const QString &);
const QString &rev() const;
void setRev(const QString &);
const QString &sortString() const;
void setSortString(const QString &);
const QByteArray &sound() const;
void setSound(const QByteArray &);
const QString &soundURI() const;
void setSoundURI(const QString &);
const QString &soundPhonetic() const;
void setSoundPhonetic(const QString &);
const QString &uid() const;
void setUid(const QString &);
const QString &url() const;
void setUrl(const QString &);
const QString &desc() const;
void setDesc(const QString &);
enum PrivacyClass {
pcNone = 0,
pcPublic = 1,
pcPrivate,
pcConfidential
};
const PrivacyClass &privacyClass() const;
void setPrivacyClass(const PrivacyClass &);
const QByteArray &key() const;
void setKey(const QByteArray &);
int age() const;
enum Gender {
UnknownGender = 0,
Male,
Female
#ifdef YAPSI
, MultipleGender
#endif
};
Gender gender() const;
void setGender(Gender);
QString mood() const;
void setMood(const QString&);
private:
class Private;
Private *d;
};
}
QString image2type(const QByteArray &ba);
#endif

View file

@ -0,0 +1,473 @@
/*
* xmpp_xdata.cpp - a class for jabber:x:data forms
* Copyright (C) 2003-2004 Michail Pishchagin
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU 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_xdata.h"
#include "xmpp_xmlcommon.h"
#include "xmpp_jid.h"
#include <QList>
#include <QSharedDataPointer>
using namespace XMPP;
using namespace XMLHelper;
// TODO: report, item
XData::Private::Private()
: QSharedData()
{
type = Data_Form;
}
//----------------------------------------------------------------------------
// XData::Field
//----------------------------------------------------------------------------
XData::Field::Field()
{
}
XData::Field::~Field()
{
}
QString XData::Field::desc() const
{
return _desc;
}
void XData::Field::setDesc(const QString &d)
{
_desc = d;
}
XData::Field::OptionList XData::Field::options() const
{
return _options;
}
void XData::Field::setOptions(XData::Field::OptionList o)
{
_options = o;
}
bool XData::Field::required() const
{
return _required;
}
void XData::Field::setRequired(bool r)
{
_required = r;
}
QString XData::Field::label() const
{
return _label;
}
void XData::Field::setLabel(const QString &l)
{
_label = l;
}
QString XData::Field::var() const
{
return _var;
}
void XData::Field::setVar(const QString &v)
{
_var = v;
}
QStringList XData::Field::value() const
{
return _value;
}
void XData::Field::setValue(const QStringList &v)
{
_value = v;
}
XData::Field::Type XData::Field::type() const
{
return _type;
}
void XData::Field::setType(XData::Field::Type t)
{
_type = t;
}
bool XData::Field::isValid() const
{
if ( _required && _value.isEmpty() )
return false;
if ( _type == Field_Hidden || _type == Field_Fixed) {
return true;
}
if ( _type == Field_Boolean ) {
if ( _value.count() != 1 )
return false;
QString str = _value.first();
if ( str == "0" || str == "1" || str == "true" || str == "false" || str == "yes" || str == "no" )
return true;
}
if ( _type == Field_TextSingle || _type == Field_TextPrivate ) {
if ( _value.count() == 1 )
return true;
}
if ( _type == Field_TextMulti ) {
//no particular test. empty/required case already caught (see above)
return true;
}
if ( _type == Field_ListSingle || _type == Field_ListMulti ) {
//no particular test. empty/required case already caught (see above)
return true;
}
if ( _type == Field_JidSingle ) {
if ( _value.count() != 1 )
return false;
Jid j( _value.first() );
return j.isValid();
}
if ( _type == Field_JidMulti ) {
QStringList::ConstIterator it = _value.begin();
bool allValid = true;
for ( ; it != _value.end(); ++it) {
Jid j(*it);
if ( !j.isValid() ) {
allValid = false;
break;
}
}
return allValid;
}
return false;
}
void XData::Field::fromXml(const QDomElement &e)
{
if ( e.tagName() != "field" )
return;
_var = e.attribute("var");
_label = e.attribute("label");
QString type = e.attribute("type");
if ( type == "boolean" )
_type = Field_Boolean;
else if ( type == "fixed" )
_type = Field_Fixed;
else if ( type == "hidden" )
_type = Field_Hidden;
else if ( type == "jid-multi" )
_type = Field_JidMulti;
else if ( type == "jid-single" )
_type = Field_JidSingle;
else if ( type == "list-multi" )
_type = Field_ListMulti;
else if ( type == "list-single" )
_type = Field_ListSingle;
else if ( type == "text-multi" )
_type = Field_TextMulti;
else if ( type == "text-private" )
_type = Field_TextPrivate;
else
_type = Field_TextSingle;
_required = false;
_desc = QString::null;
_options.clear();
_value.clear();
QDomNode n = e.firstChild();
for ( ; !n.isNull(); n = n.nextSibling() ) {
QDomElement i = n.toElement();
if ( i.isNull() )
continue;
QString tag = i.tagName();
if ( tag == "required" )
_required = true;
else if ( tag == "desc" )
_desc = i.text().simplifyWhiteSpace();
else if ( tag == "option" ) {
Option o;
bool found;
o.label = i.attribute("label");
QDomElement e = findSubTag( i, "value", &found );
o.value = ( found ? e.text() : QString("") );
_options.append(o);
}
else if ( tag == "value" ) {
_value.append(i.text());
}
}
}
QDomElement XData::Field::toXml(QDomDocument *doc, bool submitForm) const
{
QDomElement f = doc->createElement("field");
// setting attributes...
if ( !_var.isEmpty() )
f.setAttribute("var", _var);
if ( !submitForm && !_label.isEmpty() )
f.setAttribute("label", _label);
// now we're gonna get the 'type'
QString type = "text-single";
if ( _type == Field_Boolean )
type = "boolean";
else if ( _type == Field_Fixed )
type = "fixed";
else if ( _type == Field_Hidden )
type = "hidden";
else if ( _type == Field_JidMulti )
type = "jid-multi";
else if ( _type == Field_JidSingle )
type = "jid-single";
else if ( _type == Field_ListMulti )
type = "list-multi";
else if ( _type == Field_ListSingle )
type = "list-single";
else if ( _type == Field_TextMulti )
type = "text-multi";
else if ( _type == Field_TextPrivate )
type = "text-private";
f.setAttribute("type", type);
// now, setting nested tags...
if ( !submitForm && _required )
f.appendChild( emptyTag(doc, "required") );
if ( !submitForm && !_desc.isEmpty() )
f.appendChild( textTag(doc, "desc", _desc) );
if ( !submitForm && !_options.isEmpty() ) {
OptionList::ConstIterator it = _options.begin();
for ( ; it != _options.end(); ++it) {
QDomElement o = doc->createElement("option");
o.appendChild(textTag(doc, "value", (*it).value));
if ( !(*it).label.isEmpty() )
o.setAttribute("label", (*it).label);
f.appendChild(o);
}
}
if ( !_value.isEmpty() ) {
QStringList::ConstIterator it = _value.begin();
for ( ; it != _value.end(); ++it)
f.appendChild( textTag(doc, "value", *it) );
}
return f;
}
//----------------------------------------------------------------------------
// XData
//----------------------------------------------------------------------------
XData::XData()
{
d = new Private;
}
QString XData::title() const
{
return d->title;
}
void XData::setTitle(const QString &t)
{
d->title = t;
}
QString XData::instructions() const
{
return d->instructions;
}
void XData::setInstructions(const QString &i)
{
d->instructions = i;
}
XData::Type XData::type() const
{
return d->type;
}
void XData::setType(Type t)
{
d->type = t;
}
XData::FieldList XData::fields() const
{
return d->fields;
}
void XData::setFields(const FieldList &f)
{
d->fields = f;
}
void XData::fromXml(const QDomElement &e)
{
if ( (e.attribute("xmlns") != "jabber:x:data") && (e.namespaceURI() != "jabber:x:data") )
return;
QString type = e.attribute("type");
if ( type == "result" )
d->type = Data_Result;
else if ( type == "submit" )
d->type = Data_Submit;
else if ( type == "cancel" )
d->type = Data_Cancel;
else
d->type = Data_Form;
d->title = subTagText(e, "title");
d->instructions = subTagText(e, "instructions");
d->fields.clear();
QDomNode n = e.firstChild();
for ( ; !n.isNull(); n = n.nextSibling() ) {
QDomElement i = n.toElement();
if ( i.isNull() )
continue;
if ( i.tagName() == "field" ) {
Field f;
f.fromXml(i);
d->fields.append(f);
}
else if ( i.tagName() == "reported" ) {
d->report.clear();
d->reportItems.clear();
QDomNode nn = i.firstChild();
for ( ; !nn.isNull(); nn = nn.nextSibling() ) {
QDomElement ii = nn.toElement();
if ( ii.isNull() )
continue;
if ( ii.tagName() == "field" ) {
d->report.append( ReportField( ii.attribute("label"), ii.attribute("var") ) );
}
}
}
else if ( i.tagName() == "item" ) {
ReportItem item;
QDomNode nn = i.firstChild();
for ( ; !nn.isNull(); nn = nn.nextSibling() ) {
QDomElement ii = nn.toElement();
if ( ii.isNull() )
continue;
if ( ii.tagName() == "field" ) {
QString name = ii.attribute("var");
QString value;
bool found;
QDomElement e = findSubTag( ii, "value", &found );
if ( found )
value = e.text();
item[name] = value;
}
}
d->reportItems.append( item );
}
}
}
QDomElement XData::toXml(QDomDocument *doc, bool submitForm) const
{
QDomElement x = doc->createElementNS("jabber:x:data", "x");
x.setAttribute("xmlns", "jabber:x:data");
QString type = "form";
if ( d->type == Data_Result )
type = "result";
else if ( d->type == Data_Submit )
type = "submit";
else if ( d->type == Data_Cancel )
type = "cancel";
x.setAttribute("type", type);
if ( !submitForm && !d->title.isEmpty() )
x.appendChild( textTag(doc, "title", d->title) );
if ( !submitForm && !d->instructions.isEmpty() )
x.appendChild( textTag(doc, "instructions", d->instructions) );
if ( !d->fields.isEmpty() ) {
FieldList::ConstIterator it = d->fields.begin();
for ( ; it != d->fields.end(); ++it) {
Field f = *it;
if ( !(submitForm && f.var().isEmpty()) )
x.appendChild( f.toXml(doc, submitForm) );
}
}
return x;
}
const QList<XData::ReportField> &XData::report() const
{
return d->report;
}
const QList<XData::ReportItem> &XData::reportItems() const
{
return d->reportItems;
}
bool XData::isValid() const
{
foreach(Field f, d->fields) {
if (!f.isValid())
return false;
}
return true;
}
void XData::addField(XMPP::XData::Field::Type type, const QString& var, const QString& value)
{
XMPP::XData::Field field;
field.setVar(var);
field.setType(type);
field.setValue(QStringList() << value);
d->fields << field;
}

View file

@ -0,0 +1,500 @@
/*
* xmlcommon.cpp - helper functions for dealing with XML
* Copyright (C) 2001, 2002 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_xmlcommon.h"
#include "xmpp_stanza.h"
#include <qstring.h>
#include <qdom.h>
#include <qdatetime.h>
#include <qsize.h>
#include <qrect.h>
#include <qstringlist.h>
#include <qcolor.h>
QDateTime stamp2TS(const QString &ts)
{
if(ts.length() != 17)
return QDateTime();
int year = ts.mid(0,4).toInt();
int month = ts.mid(4,2).toInt();
int day = ts.mid(6,2).toInt();
int hour = ts.mid(9,2).toInt();
int min = ts.mid(12,2).toInt();
int sec = ts.mid(15,2).toInt();
QDate xd;
xd.setYMD(year, month, day);
if(!xd.isValid())
return QDateTime();
QTime xt;
xt.setHMS(hour, min, sec);
if(!xt.isValid())
return QDateTime();
return QDateTime(xd, xt);
}
bool stamp2TS(const QString &ts, QDateTime *d)
{
QDateTime dateTime = stamp2TS(ts);
if (dateTime.isNull())
return false;
*d = dateTime;
return true;
}
QString TS2stamp(const QDateTime &d)
{
QString str;
str.sprintf("%04d%02d%02dT%02d:%02d:%02d",
d.date().year(),
d.date().month(),
d.date().day(),
d.time().hour(),
d.time().minute(),
d.time().second());
return str;
}
QDomElement textTag(QDomDocument *doc, const QString &name, const QString &content)
{
QDomElement tag = doc->createElement(name);
QDomText text = doc->createTextNode(content);
tag.appendChild(text);
return tag;
}
QString tagContent(const QDomElement &e)
{
// look for some tag content
for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
QDomText i = n.toText();
if(i.isNull())
continue;
return i.data();
}
return "";
}
/**
* \brief find an direct child element by name
* \param e parent element
* \param name name of element to find
* \param found (optional/out) found?
* \return the element (or a null QDomElemnt if not found)
*/
QDomElement findSubTag(const QDomElement &e, const QString &name, bool *found)
{
if(found)
*found = false;
for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
QDomElement i = n.toElement();
if(i.isNull())
continue;
if(i.tagName() == name) {
if(found)
*found = true;
return i;
}
}
QDomElement tmp;
return tmp;
}
QDomElement createIQ(QDomDocument *doc, const QString &type, const QString &to, const QString &id)
{
QDomElement iq = doc->createElement("iq");
if(!type.isEmpty())
iq.setAttribute("type", type);
if(!to.isEmpty())
iq.setAttribute("to", to);
if(!id.isEmpty())
iq.setAttribute("id", id);
return iq;
}
/** \brief returns direct child element named "query"
* \return the element (or a null QDomElemnt if not found)
*/
QDomElement queryTag(const QDomElement &e)
{
bool found;
QDomElement q = findSubTag(e, "query", &found);
return q;
}
QString queryNS(const QDomElement &e)
{
bool found;
QDomElement q = findSubTag(e, "query", &found);
if(found)
return q.attribute("xmlns");
return "";
}
/**
\brief Extracts the error code and description from the stanza element.
This function finds the error element in the given stanza element \a e.
You need to provide the base namespace of the stream to which this stanza belongs to
(probably by using stream.baseNS() function).
The error description is either error text extracted from XML
or - if no text is found - the error name and description (separated by '\n') taken from RFC-3920
or - if the error is not defined in the RFC - the empty string.
Note: This function uses the Stanza::Error class,
so it may guess missing values as defined in JEP-0086.
\param e the element representing stanza
\param baseNS the base namespace of the stream
\param code if not NULL, will be filled with numeric error code
\param str if not NULL, will be filled with human readable error description
*/
void getErrorFromElement(const QDomElement &e, const QString &baseNS, int *code, QString *str)
{
bool found;
QDomElement tag = findSubTag(e, "error", &found);
if(!found)
return;
XMPP::Stanza::Error err;
err.fromXml(tag, baseNS);
if(code)
*code = err.code();
if(str) {
QPair<QString, QString> desc = err.description();
#ifdef YAPSI
*str = desc.first;
#else
if (err.text.isEmpty())
*str = desc.first + ".\n" + desc.second;
else
*str = desc.first + ".\n" + desc.second + "\n" + err.text;
#endif
}
}
QDomElement addCorrectNS(const QDomElement &e)
{
int x;
// grab child nodes
/*QDomDocumentFragment frag = e.ownerDocument().createDocumentFragment();
QDomNodeList nl = e.childNodes();
for(x = 0; x < nl.count(); ++x)
frag.appendChild(nl.item(x).cloneNode());*/
// find closest xmlns
QDomNode n = e;
while(!n.isNull() && !n.toElement().hasAttribute("xmlns"))
n = n.parentNode();
QString ns;
if(n.isNull() || !n.toElement().hasAttribute("xmlns"))
ns = "jabber:client";
else
ns = n.toElement().attribute("xmlns");
// make a new node
QDomElement i = e.ownerDocument().createElementNS(ns, e.tagName());
// copy attributes
QDomNamedNodeMap al = e.attributes();
for(x = 0; x < al.count(); ++x) {
QDomAttr a = al.item(x).toAttr();
if(a.name() != "xmlns")
i.setAttributeNodeNS(a.cloneNode().toAttr());
}
// copy children
QDomNodeList nl = e.childNodes();
for(x = 0; x < nl.count(); ++x) {
QDomNode n = nl.item(x);
if(n.isElement())
i.appendChild(addCorrectNS(n.toElement()));
else
i.appendChild(n.cloneNode());
}
//i.appendChild(frag);
return i;
}
//----------------------------------------------------------------------------
// XMLHelper
//----------------------------------------------------------------------------
namespace XMLHelper {
QDomElement emptyTag(QDomDocument *doc, const QString &name)
{
QDomElement tag = doc->createElement(name);
return tag;
}
bool hasSubTag(const QDomElement &e, const QString &name)
{
bool found;
findSubTag(e, name, &found);
return found;
}
QString subTagText(const QDomElement &e, const QString &name)
{
bool found;
QDomElement i = findSubTag(e, name, &found);
if ( found )
return i.text();
return QString::null;
}
QDomElement textTag(QDomDocument &doc, const QString &name, const QString &content)
{
QDomElement tag = doc.createElement(name);
QDomText text = doc.createTextNode(content);
tag.appendChild(text);
return tag;
}
QDomElement textTag(QDomDocument &doc, const QString &name, int content)
{
QDomElement tag = doc.createElement(name);
QDomText text = doc.createTextNode(QString::number(content));
tag.appendChild(text);
return tag;
}
QDomElement textTag(QDomDocument &doc, const QString &name, bool content)
{
QDomElement tag = doc.createElement(name);
QDomText text = doc.createTextNode(content ? "true" : "false");
tag.appendChild(text);
return tag;
}
QDomElement textTag(QDomDocument &doc, const QString &name, QSize &s)
{
QString str;
str.sprintf("%d,%d", s.width(), s.height());
QDomElement tag = doc.createElement(name);
QDomText text = doc.createTextNode(str);
tag.appendChild(text);
return tag;
}
QDomElement textTag(QDomDocument &doc, const QString &name, QRect &r)
{
QString str;
str.sprintf("%d,%d,%d,%d", r.x(), r.y(), r.width(), r.height());
QDomElement tag = doc.createElement(name);
QDomText text = doc.createTextNode(str);
tag.appendChild(text);
return tag;
}
QDomElement stringListToXml(QDomDocument &doc, const QString &name, const QStringList &l)
{
QDomElement tag = doc.createElement(name);
for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it)
tag.appendChild(textTag(doc, "item", *it));
return tag;
}
/*QString tagContent(const QDomElement &e)
{
// look for some tag content
for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
QDomText i = n.toText();
if(i.isNull())
continue;
return i.data();
}
return "";
}*/
/*QDomElement findSubTag(const QDomElement &e, const QString &name, bool *found)
{
if(found)
*found = FALSE;
for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
QDomElement i = n.toElement();
if(i.isNull())
continue;
if(i.tagName() == name) {
if(found)
*found = TRUE;
return i;
}
}
QDomElement tmp;
return tmp;
}*/
void readEntry(const QDomElement &e, const QString &name, QString *v)
{
bool found = FALSE;
QDomElement tag = findSubTag(e, name, &found);
if(!found)
return;
*v = tagContent(tag);
}
void readNumEntry(const QDomElement &e, const QString &name, int *v)
{
bool found = FALSE;
QDomElement tag = findSubTag(e, name, &found);
if(!found)
return;
*v = tagContent(tag).toInt();
}
void readBoolEntry(const QDomElement &e, const QString &name, bool *v)
{
bool found = FALSE;
QDomElement tag = findSubTag(e, name, &found);
if(!found)
return;
*v = (tagContent(tag) == "true") ? TRUE: FALSE;
}
void readSizeEntry(const QDomElement &e, const QString &name, QSize *v)
{
bool found = FALSE;
QDomElement tag = findSubTag(e, name, &found);
if(!found)
return;
QStringList list = tagContent(tag).split(',');
if(list.count() != 2)
return;
QSize s;
s.setWidth(list[0].toInt());
s.setHeight(list[1].toInt());
*v = s;
}
void readRectEntry(const QDomElement &e, const QString &name, QRect *v)
{
bool found = FALSE;
QDomElement tag = findSubTag(e, name, &found);
if(!found)
return;
QStringList list = tagContent(tag).split(',');
if(list.count() != 4)
return;
QRect r;
r.setX(list[0].toInt());
r.setY(list[1].toInt());
r.setWidth(list[2].toInt());
r.setHeight(list[3].toInt());
*v = r;
}
void readColorEntry(const QDomElement &e, const QString &name, QColor *v)
{
bool found = FALSE;
QDomElement tag = findSubTag(e, name, &found);
if(!found)
return;
QColor c;
c.setNamedColor(tagContent(tag));
if(c.isValid())
*v = c;
}
void xmlToStringList(const QDomElement &e, const QString &name, QStringList *v)
{
bool found = false;
QDomElement tag = findSubTag(e, name, &found);
if(!found)
return;
QStringList list;
for(QDomNode n = tag.firstChild(); !n.isNull(); n = n.nextSibling()) {
QDomElement i = n.toElement();
if(i.isNull())
continue;
if(i.tagName() == "item")
list += tagContent(i);
}
*v = list;
}
void setBoolAttribute(QDomElement e, const QString &name, bool b)
{
e.setAttribute(name, b ? "true" : "false");
}
void readBoolAttribute(QDomElement e, const QString &name, bool *v)
{
if(e.hasAttribute(name)) {
QString s = e.attribute(name);
*v = (s == "true") ? TRUE: FALSE;
}
}
void removeNodes(QDomElement& root, const QDomNodeList& nl)
{
for (int i = 0; i < nl.count(); ++i) {
QDomElement e = nl.item(i).toElement();
if (e.isNull())
continue;
root.removeChild(e);
}
}
void removeNodes(QDomElement& root, const QDomElement& n)
{
if (n.isNull())
return;
root.removeChild(n);
}
};

View file

@ -0,0 +1,76 @@
/*
* xmlcommon.h - helper functions for dealing with XML
* Copyright (C) 2001, 2002 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
*
*/
#ifndef JABBER_XMLCOMMON_H
#define JABBER_XMLCOMMON_H
#include <QDomElement>
class QDateTime;
class QRect;
class QSize;
class QColor;
class QStringList;
QDateTime stamp2TS(const QString &ts);
bool stamp2TS(const QString &ts, QDateTime *d);
QString TS2stamp(const QDateTime &d);
QDomElement textTag(QDomDocument *doc, const QString &name, const QString &content);
QString tagContent(const QDomElement &e);
QDomElement findSubTag(const QDomElement &e, const QString &name, bool *found);
QDomElement createIQ(QDomDocument *doc, const QString &type, const QString &to, const QString &id);
QDomElement queryTag(const QDomElement &e);
QString queryNS(const QDomElement &e);
void getErrorFromElement(const QDomElement &e, const QString &baseNS, int *code, QString *str);
QDomElement addCorrectNS(const QDomElement &e);
namespace XMLHelper {
//QDomElement findSubTag(const QDomElement &e, const QString &name, bool *found);
bool hasSubTag(const QDomElement &e, const QString &name);
QDomElement emptyTag(QDomDocument *doc, const QString &name);
QString subTagText(const QDomElement &e, const QString &name);
QDomElement textTag(QDomDocument &doc, const QString &name, const QString &content);
QDomElement textTag(QDomDocument &doc, const QString &name, int content);
QDomElement textTag(QDomDocument &doc, const QString &name, bool content);
QDomElement textTag(QDomDocument &doc, const QString &name, QSize &s);
QDomElement textTag(QDomDocument &doc, const QString &name, QRect &r);
QDomElement stringListToXml(QDomDocument &doc, const QString &name, const QStringList &l);
void readEntry(const QDomElement &e, const QString &name, QString *v);
void readNumEntry(const QDomElement &e, const QString &name, int *v);
void readBoolEntry(const QDomElement &e, const QString &name, bool *v);
void readSizeEntry(const QDomElement &e, const QString &name, QSize *v);
void readRectEntry(const QDomElement &e, const QString &name, QRect *v);
void readColorEntry(const QDomElement &e, const QString &name, QColor *v);
void xmlToStringList(const QDomElement &e, const QString &name, QStringList *v);
void setBoolAttribute(QDomElement e, const QString &name, bool b);
void readBoolAttribute(QDomElement e, const QString &name, bool *v);
//QString tagContent(const QDomElement &e); // obsolete;
void removeNodes(QDomElement& root, const QDomNodeList& nl);
void removeNodes(QDomElement& root, const QDomElement& n);
};
#endif