/* * Copyright (C) 2008-2010 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 #include #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::identities() const { return m_identities; } void QXmppDiscoveryIq::setIdentities(const QList &identities) { m_identities = identities; } QList QXmppDiscoveryIq::items() const { return m_items; } void QXmppDiscoveryIq::setItems(const QList &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 sortedIdentities = m_identities; qSort(sortedIdentities.begin(), sortedIdentities.end(), identityLessThan); QStringList sortedFeatures = m_features; qSort(sortedFeatures); 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("<"); QCryptographicHash hasher(QCryptographicHash::Sha1); hasher.addData(S.toUtf8()); return hasher.result(); } 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")); 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"); helperToXmlAddAttribute(writer, "xmlns", m_queryType == InfoQuery ? ns_disco_info : ns_disco_items); helperToXmlAddAttribute(writer, "node", m_queryNode); foreach (const QString &feature, m_features) { writer->writeStartElement("feature"); helperToXmlAddAttribute(writer, "var", feature); writer->writeEndElement(); } 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 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(); }