123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- /*
- * Copyright (C) 2008-2012 The QXmpp developers
- *
- * Author:
- * Jeremy Lainé
- *
- * Source:
- * http://code.google.com/p/qxmpp
- *
- * This file is a part of QXmpp library.
- *
- * 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.
- *
- */
- #include <QCryptographicHash>
- #include <QDomElement>
- #include "QXmppConstants.h"
- #include "QXmppDiscoveryIq.h"
- #include "QXmppUtils.h"
- static bool identityLessThan(const QXmppDiscoveryIq::Identity &i1, const QXmppDiscoveryIq::Identity &i2)
- {
- if (i1.category() < i2.category())
- return true;
- else if (i1.category() > i2.category())
- return false;
- if (i1.type() < i2.type())
- return true;
- else if (i1.type() > i2.type())
- return false;
- if (i1.language() < i2.language())
- return true;
- else if (i1.language() > i2.language())
- return false;
- if (i1.name() < i2.name())
- return true;
- else if (i1.name() > i2.name())
- return false;
- return false;
- }
- QString QXmppDiscoveryIq::Identity::category() const
- {
- return m_category;
- }
- void QXmppDiscoveryIq::Identity::setCategory(const QString &category)
- {
- m_category = category;
- }
- QString QXmppDiscoveryIq::Identity::language() const
- {
- return m_language;
- }
- void QXmppDiscoveryIq::Identity::setLanguage(const QString &language)
- {
- m_language = language;
- }
- QString QXmppDiscoveryIq::Identity::name() const
- {
- return m_name;
- }
- void QXmppDiscoveryIq::Identity::setName(const QString &name)
- {
- m_name = name;
- }
- QString QXmppDiscoveryIq::Identity::type() const
- {
- return m_type;
- }
- void QXmppDiscoveryIq::Identity::setType(const QString &type)
- {
- m_type = type;
- }
- QString QXmppDiscoveryIq::Item::jid() const
- {
- return m_jid;
- }
- void QXmppDiscoveryIq::Item::setJid(const QString &jid)
- {
- m_jid = jid;
- }
- QString QXmppDiscoveryIq::Item::name() const
- {
- return m_name;
- }
- void QXmppDiscoveryIq::Item::setName(const QString &name)
- {
- m_name = name;
- }
- QString QXmppDiscoveryIq::Item::node() const
- {
- return m_node;
- }
- void QXmppDiscoveryIq::Item::setNode(const QString &node)
- {
- m_node = node;
- }
- QStringList QXmppDiscoveryIq::features() const
- {
- return m_features;
- }
- void QXmppDiscoveryIq::setFeatures(const QStringList &features)
- {
- m_features = features;
- }
- QList<QXmppDiscoveryIq::Identity> QXmppDiscoveryIq::identities() const
- {
- return m_identities;
- }
- void QXmppDiscoveryIq::setIdentities(const QList<QXmppDiscoveryIq::Identity> &identities)
- {
- m_identities = identities;
- }
- QList<QXmppDiscoveryIq::Item> QXmppDiscoveryIq::items() const
- {
- return m_items;
- }
- void QXmppDiscoveryIq::setItems(const QList<QXmppDiscoveryIq::Item> &items)
- {
- m_items = items;
- }
- /// Returns the QXmppDataForm for this IQ, as defined by
- /// XEP-0128: Service Discovery Extensions.
- ///
- QXmppDataForm QXmppDiscoveryIq::form() const
- {
- return m_form;
- }
- /// Sets the QXmppDataForm for this IQ, as define by
- /// XEP-0128: Service Discovery Extensions.
- ///
- /// \param form
- ///
- void QXmppDiscoveryIq::setForm(const QXmppDataForm &form)
- {
- m_form = form;
- }
- QString QXmppDiscoveryIq::queryNode() const
- {
- return m_queryNode;
- }
- void QXmppDiscoveryIq::setQueryNode(const QString &node)
- {
- m_queryNode = node;
- }
- enum QXmppDiscoveryIq::QueryType QXmppDiscoveryIq::queryType() const
- {
- return m_queryType;
- }
- void QXmppDiscoveryIq::setQueryType(enum QXmppDiscoveryIq::QueryType type)
- {
- m_queryType = type;
- }
- /// Calculate the verification string for XEP-0115 : Entity Capabilities
- QByteArray QXmppDiscoveryIq::verificationString() const
- {
- QString S;
- QList<QXmppDiscoveryIq::Identity> sortedIdentities = m_identities;
- qSort(sortedIdentities.begin(), sortedIdentities.end(), identityLessThan);
- QStringList sortedFeatures = m_features;
- qSort(sortedFeatures);
- sortedFeatures.removeDuplicates();
- foreach (const QXmppDiscoveryIq::Identity &identity, sortedIdentities)
- S += QString("%1/%2/%3/%4<").arg(identity.category(), identity.type(), identity.language(), identity.name());
- foreach (const QString &feature, sortedFeatures)
- S += feature + QLatin1String("<");
- if (!m_form.isNull()) {
- QMap<QString, QXmppDataForm::Field> fieldMap;
- foreach (const QXmppDataForm::Field &field, m_form.fields()) {
- fieldMap.insert(field.key(), field);
- }
- if (fieldMap.contains("FORM_TYPE")) {
- const QXmppDataForm::Field field = fieldMap.take("FORM_TYPE");
- S += field.value().toString() + QLatin1String("<");
- QStringList keys = fieldMap.keys();
- qSort(keys);
- foreach (const QString &key, keys) {
- const QXmppDataForm::Field field = fieldMap.value(key);
- S += key + QLatin1String("<");
- if (field.value().canConvert<QStringList>()) {
- QStringList list = field.value().toStringList();
- list.sort();
- S += list.join(QLatin1String("<"));
- } else {
- S += field.value().toString();
- }
- S += QLatin1String("<");
- }
- } else {
- qWarning("QXmppDiscoveryIq form does not contain FORM_TYPE");
- }
- }
- QCryptographicHash hasher(QCryptographicHash::Sha1);
- hasher.addData(S.toUtf8());
- return hasher.result();
- }
- /// \cond
- bool QXmppDiscoveryIq::isDiscoveryIq(const QDomElement &element)
- {
- QDomElement queryElement = element.firstChildElement("query");
- return (queryElement.namespaceURI() == ns_disco_info ||
- queryElement.namespaceURI() == ns_disco_items);
- }
- void QXmppDiscoveryIq::parseElementFromChild(const QDomElement &element)
- {
- QDomElement queryElement = element.firstChildElement("query");
- m_queryNode = queryElement.attribute("node");
- if (queryElement.namespaceURI() == ns_disco_items)
- m_queryType = ItemsQuery;
- else
- m_queryType = InfoQuery;
- QDomElement itemElement = queryElement.firstChildElement();
- while (!itemElement.isNull())
- {
- if (itemElement.tagName() == "feature")
- {
- m_features.append(itemElement.attribute("var"));
- }
- else if (itemElement.tagName() == "identity")
- {
- QXmppDiscoveryIq::Identity identity;
- identity.setLanguage(itemElement.attribute("xml:lang"));
- identity.setCategory(itemElement.attribute("category"));
- identity.setName(itemElement.attribute("name"));
- identity.setType(itemElement.attribute("type"));
- // FIXME: for some reason the language does not found,
- // so we are forced to use QDomNamedNodeMap
- QDomNamedNodeMap m(itemElement.attributes());
- for (int i = 0; i < m.size(); ++i) {
- if (m.item(i).nodeName() == "xml:lang") {
- identity.setLanguage(m.item(i).nodeValue());
- break;
- }
- }
- m_identities.append(identity);
- }
- else if (itemElement.tagName() == "item")
- {
- QXmppDiscoveryIq::Item item;
- item.setJid(itemElement.attribute("jid"));
- item.setName(itemElement.attribute("name"));
- item.setNode(itemElement.attribute("node"));
- m_items.append(item);
- }
- else if (itemElement.tagName() == "x" &&
- itemElement.namespaceURI() == ns_data)
- {
- m_form.parse(itemElement);
- }
- itemElement = itemElement.nextSiblingElement();
- }
- }
- void QXmppDiscoveryIq::toXmlElementFromChild(QXmlStreamWriter *writer) const
- {
- writer->writeStartElement("query");
- writer->writeAttribute("xmlns",
- m_queryType == InfoQuery ? ns_disco_info : ns_disco_items);
- helperToXmlAddAttribute(writer, "node", m_queryNode);
- if (m_queryType == InfoQuery) {
- foreach (const QXmppDiscoveryIq::Identity& identity, m_identities) {
- writer->writeStartElement("identity");
- helperToXmlAddAttribute(writer, "xml:lang", identity.language());
- helperToXmlAddAttribute(writer, "category", identity.category());
- helperToXmlAddAttribute(writer, "name", identity.name());
- helperToXmlAddAttribute(writer, "type", identity.type());
- writer->writeEndElement();
- }
- foreach (const QString &feature, m_features) {
- writer->writeStartElement("feature");
- helperToXmlAddAttribute(writer, "var", feature);
- writer->writeEndElement();
- }
- } else {
- foreach (const QXmppDiscoveryIq::Item& item, m_items) {
- writer->writeStartElement("item");
- helperToXmlAddAttribute(writer, "jid", item.jid());
- helperToXmlAddAttribute(writer, "name", item.name());
- helperToXmlAddAttribute(writer, "node", item.node());
- writer->writeEndElement();
- }
- }
- m_form.toXml(writer);
- writer->writeEndElement();
- }
- /// \endcond
|