summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Fernengel <harald.fernengel@nokia.com>2012-01-18 21:28:31 +0100
committerQt by Nokia <qt-info@nokia.com>2012-01-22 22:10:02 +0100
commit0696071316b3dacb8d1ca15a269e4f4215642b9d (patch)
tree26f4dbad16ec36a1243a8676d929269ace74b7f1
parent7c247d3e70788fd601cdc4d45649d2c7ca1004f3 (diff)
Remove dependency of QtDBus onto QtXml
Replace the QDom based code in qdbusxmlparser with code using QXmlStreamReader. Task-number: QTBUG-20856 Change-Id: I294e3ebd6faa813c20806be3ae225ac00befb622 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/dbus/dbus.pro6
-rw-r--r--src/dbus/qdbusintrospection.cpp17
-rw-r--r--src/dbus/qdbusintrospection_p.h12
-rw-r--r--src/dbus/qdbusxmlparser.cpp514
-rw-r--r--src/dbus/qdbusxmlparser_p.h11
-rw-r--r--src/modules/qt_dbus.pri2
-rw-r--r--src/src.pro2
-rw-r--r--tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp2
-rw-r--r--tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp138
9 files changed, 292 insertions, 412 deletions
diff --git a/src/dbus/dbus.pro b/src/dbus/dbus.pro
index 8669bb003a..6fd48de48d 100644
--- a/src/dbus/dbus.pro
+++ b/src/dbus/dbus.pro
@@ -2,8 +2,7 @@ load(qt_module)
TARGET = QtDBus
QPRO_PWD = $$PWD
-QT = core-private \
- xml
+QT = core-private
CONFIG += link_pkgconfig module
MODULE_PRI = ../modules/qt_dbus.pri
@@ -21,8 +20,7 @@ unix|win32-g++* {
QMAKE_PKGCONFIG_DESCRIPTION = Qt \
DBus \
module
- QMAKE_PKGCONFIG_REQUIRES = QtCore \
- QtXml
+ QMAKE_PKGCONFIG_REQUIRES = QtCore
}
win32 {
wince*:LIBS_PRIVATE += -lws2
diff --git a/src/dbus/qdbusintrospection.cpp b/src/dbus/qdbusintrospection.cpp
index 23eda78e5a..60e3bb9ac9 100644
--- a/src/dbus/qdbusintrospection.cpp
+++ b/src/dbus/qdbusintrospection.cpp
@@ -407,23 +407,6 @@ QDBusIntrospection::parseObject(const QString &xml, const QString &service, cons
return *retval;
}
-/*!
- Parses the XML document fragment (given by \a xml) containing one object node and returns all
- the information about the interfaces and sub-objects, found at the service \a service and path
- \a path.
-
- The Objects map returned will contain the absolute path names in the key.
-*/
-QDBusIntrospection::ObjectTree
-QDBusIntrospection::parseObjectTree(const QString &xml, const QString &service, const QString &path)
-{
- QDBusXmlParser parser(service, path, xml);
- QSharedDataPointer<QDBusIntrospection::ObjectTree> retval = parser.objectTree();
- if (!retval)
- return QDBusIntrospection::ObjectTree();
- return *retval;
-}
-
QT_END_NAMESPACE
#endif // QT_NO_DBUS
diff --git a/src/dbus/qdbusintrospection_p.h b/src/dbus/qdbusintrospection_p.h
index 025cf63fe3..780e706498 100644
--- a/src/dbus/qdbusintrospection_p.h
+++ b/src/dbus/qdbusintrospection_p.h
@@ -59,7 +59,7 @@
#include <QtCore/qmap.h>
#include <QtCore/qpair.h>
#include <QtCore/qshareddata.h>
-#include <qdbusmacros.h>
+#include "qdbusmacros.h"
QT_BEGIN_NAMESPACE
@@ -150,26 +150,16 @@ public:
{
QString service;
QString path;
- QString introspection;
QStringList interfaces;
QStringList childObjects;
};
- struct ObjectTree: public Object
- {
- Interfaces interfaceData;
- Objects childObjectData;
- };
-
public:
static Interface parseInterface(const QString &xml);
static Interfaces parseInterfaces(const QString &xml);
static Object parseObject(const QString &xml, const QString &service = QString(),
const QString &path = QString());
- static ObjectTree parseObjectTree(const QString &xml,
- const QString &service,
- const QString &path);
private:
QDBusIntrospection();
diff --git a/src/dbus/qdbusxmlparser.cpp b/src/dbus/qdbusxmlparser.cpp
index b1d0b78c96..b563fa934b 100644
--- a/src/dbus/qdbusxmlparser.cpp
+++ b/src/dbus/qdbusxmlparser.cpp
@@ -40,337 +40,319 @@
****************************************************************************/
#include "qdbusxmlparser_p.h"
-#include "qdbusinterface.h"
-#include "qdbusinterface_p.h"
-#include "qdbusconnection_p.h"
#include "qdbusutil_p.h"
-#include <QtXml/qdom.h>
#include <QtCore/qmap.h>
#include <QtCore/qvariant.h>
#include <QtCore/qtextstream.h>
+#include <QtCore/qxmlstream.h>
+#include <QtCore/qdebug.h>
#ifndef QT_NO_DBUS
//#define QDBUS_PARSER_DEBUG
#ifdef QDBUS_PARSER_DEBUG
-# define qDBusParserError qWarning
+# define qDBusParserError qDebug
#else
# define qDBusParserError if (true) {} else qDebug
#endif
QT_BEGIN_NAMESPACE
-static QDBusIntrospection::Annotations
-parseAnnotations(const QDomElement& elem)
+static bool parseArg(const QXmlStreamAttributes &attributes, QDBusIntrospection::Argument &argData)
{
- QDBusIntrospection::Annotations retval;
- QDomNodeList list = elem.elementsByTagName(QLatin1String("annotation"));
- for (int i = 0; i < list.count(); ++i)
- {
- QDomElement ann = list.item(i).toElement();
- if (ann.isNull())
- continue;
-
- QString name = ann.attribute(QLatin1String("name")),
- value = ann.attribute(QLatin1String("value"));
-
- if (!QDBusUtil::isValidInterfaceName(name)) {
- qDBusParserError("Invalid D-BUS annotation '%s' found while parsing introspection",
- qPrintable(name));
- continue;
- }
+ const QString argType = attributes.value(QLatin1String("type")).toString();
- retval.insert(name, value);
+ bool ok = QDBusUtil::isValidSingleSignature(argType);
+ if (!ok) {
+ qDBusParserError("Invalid D-BUS type signature '%s' found while parsing introspection",
+ qPrintable(argType));
}
- return retval;
+ argData.name = attributes.value(QLatin1String("name")).toString();
+ argData.type = argType;
+
+ return ok;
}
-static QDBusIntrospection::Arguments
-parseArgs(const QDomElement& elem, const QLatin1String& direction, bool acceptEmpty)
+static bool parseAnnotation(const QXmlStreamReader &xml, QDBusIntrospection::Annotations &annotations)
{
- QDBusIntrospection::Arguments retval;
- QDomNodeList list = elem.elementsByTagName(QLatin1String("arg"));
- for (int i = 0; i < list.count(); ++i)
- {
- QDomElement arg = list.item(i).toElement();
- if (arg.isNull())
- continue;
-
- if ((acceptEmpty && !arg.hasAttribute(QLatin1String("direction"))) ||
- arg.attribute(QLatin1String("direction")) == direction) {
-
- QDBusIntrospection::Argument argData;
- if (arg.hasAttribute(QLatin1String("name")))
- argData.name = arg.attribute(QLatin1String("name")); // can be empty
- argData.type = arg.attribute(QLatin1String("type"));
- if (!QDBusUtil::isValidSingleSignature(argData.type)) {
- qDBusParserError("Invalid D-BUS type signature '%s' found while parsing introspection",
- qPrintable(argData.type));
- }
+ Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String("annotation"));
- retval << argData;
- }
+ const QXmlStreamAttributes attributes = xml.attributes();
+ const QString name = attributes.value(QLatin1String("name")).toString();
+
+ if (!QDBusUtil::isValidInterfaceName(name)) {
+ qDBusParserError("Invalid D-BUS annotation '%s' found while parsing introspection",
+ qPrintable(name));
+ return false;
}
- return retval;
+ annotations.insert(name, attributes.value(QLatin1String("value")).toString());
+ return true;
}
-QDBusXmlParser::QDBusXmlParser(const QString& service, const QString& path,
- const QString& xmlData)
- : m_service(service), m_path(path)
+static bool parseProperty(QXmlStreamReader &xml, QDBusIntrospection::Property &propertyData,
+ const QString &ifaceName)
{
- QDomDocument doc;
- doc.setContent(xmlData);
- m_node = doc.firstChildElement(QLatin1String("node"));
-}
+ Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String("property"));
+
+ QXmlStreamAttributes attributes = xml.attributes();
+ const QString propertyName = attributes.value(QLatin1String("name")).toString();
+ if (!QDBusUtil::isValidMemberName(propertyName)) {
+ qDBusParserError("Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection",
+ qPrintable(propertyName), qPrintable(ifaceName));
+ xml.skipCurrentElement();
+ return false;
+ }
-QDBusXmlParser::QDBusXmlParser(const QString& service, const QString& path,
- const QDomElement& node)
- : m_service(service), m_path(path), m_node(node)
-{
-}
+ // parse data
+ propertyData.name = propertyName;
+ propertyData.type = attributes.value(QLatin1String("type")).toString();
-QDBusIntrospection::Interfaces
-QDBusXmlParser::interfaces() const
-{
- QDBusIntrospection::Interfaces retval;
-
- if (m_node.isNull())
- return retval;
-
- QDomNodeList interfaceList = m_node.elementsByTagName(QLatin1String("interface"));
- for (int i = 0; i < interfaceList.count(); ++i)
- {
- QDomElement iface = interfaceList.item(i).toElement();
- QString ifaceName = iface.attribute(QLatin1String("name"));
- if (iface.isNull())
- continue; // for whatever reason
- if (!QDBusUtil::isValidInterfaceName(ifaceName)) {
- qDBusParserError("Invalid D-BUS interface name '%s' found while parsing introspection",
- qPrintable(ifaceName));
- continue;
- }
+ if (!QDBusUtil::isValidSingleSignature(propertyData.type)) {
+ // cannot be!
+ qDBusParserError("Invalid D-BUS type signature '%s' found in property '%s.%s' while parsing introspection",
+ qPrintable(propertyData.type), qPrintable(ifaceName),
+ qPrintable(propertyName));
+ }
+
+ const QString access = attributes.value(QLatin1String("access")).toString();
+ if (access == QLatin1String("read"))
+ propertyData.access = QDBusIntrospection::Property::Read;
+ else if (access == QLatin1String("write"))
+ propertyData.access = QDBusIntrospection::Property::Write;
+ else if (access == QLatin1String("readwrite"))
+ propertyData.access = QDBusIntrospection::Property::ReadWrite;
+ else {
+ qDBusParserError("Invalid D-BUS property access '%s' found in property '%s.%s' while parsing introspection",
+ qPrintable(access), qPrintable(ifaceName),
+ qPrintable(propertyName));
+ return false; // invalid one!
+ }
- QDBusIntrospection::Interface *ifaceData = new QDBusIntrospection::Interface;
- ifaceData->name = ifaceName;
- {
- // save the data
- QTextStream ts(&ifaceData->introspection);
- iface.save(ts,2);
+ while (xml.readNextStartElement()) {
+ if (xml.name() == QLatin1String("annotation")) {
+ parseAnnotation(xml, propertyData.annotations);
+ } else if (xml.prefix().isEmpty()) {
+ qDBusParserError() << "Unknown element" << xml.name() << "while checking for annotations";
}
+ xml.skipCurrentElement();
+ }
- // parse annotations
- ifaceData->annotations = parseAnnotations(iface);
-
- // parse methods
- QDomNodeList list = iface.elementsByTagName(QLatin1String("method"));
- for (int j = 0; j < list.count(); ++j)
- {
- QDomElement method = list.item(j).toElement();
- QString methodName = method.attribute(QLatin1String("name"));
- if (method.isNull())
- continue;
- if (!QDBusUtil::isValidMemberName(methodName)) {
- qDBusParserError("Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection",
- qPrintable(methodName), qPrintable(ifaceName));
- continue;
- }
+ if (!xml.isEndElement() || xml.name() != QLatin1String("property")) {
+ qDBusParserError() << "Invalid property specification" << xml.tokenString() << xml.name();
+ return false;
+ }
- QDBusIntrospection::Method methodData;
- methodData.name = methodName;
+ return true;
+}
- // parse arguments
- methodData.inputArgs = parseArgs(method, QLatin1String("in"), true);
- methodData.outputArgs = parseArgs(method, QLatin1String("out"), false);
- methodData.annotations = parseAnnotations(method);
+static bool parseMethod(QXmlStreamReader &xml, QDBusIntrospection::Method &methodData,
+ const QString &ifaceName)
+{
+ Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String("method"));
+
+ const QXmlStreamAttributes attributes = xml.attributes();
+ const QString methodName = attributes.value(QLatin1String("name")).toString();
+ if (!QDBusUtil::isValidMemberName(methodName)) {
+ qDBusParserError("Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection",
+ qPrintable(methodName), qPrintable(ifaceName));
+ return false;
+ }
- // add it
- ifaceData->methods.insert(methodName, methodData);
+ methodData.name = methodName;
+
+ QDBusIntrospection::Arguments outArguments;
+ QDBusIntrospection::Arguments inArguments;
+ QDBusIntrospection::Annotations annotations;
+
+ while (xml.readNextStartElement()) {
+ if (xml.name() == QLatin1String("annotation")) {
+ parseAnnotation(xml, annotations);
+ } else if (xml.name() == QLatin1String("arg")) {
+ const QXmlStreamAttributes attributes = xml.attributes();
+ const QString direction = attributes.value(QLatin1String("direction")).toString();
+ QDBusIntrospection::Argument argument;
+ if (!attributes.hasAttribute(QLatin1String("direction"))
+ || direction == QLatin1String("in")) {
+ parseArg(attributes, argument);
+ inArguments << argument;
+ } else if (direction == QLatin1String("out")) {
+ parseArg(attributes, argument);
+ outArguments << argument;
+ }
+ } else if (xml.prefix().isEmpty()) {
+ qDBusParserError() << "Unknown element" << xml.name() << "while checking for method arguments";
}
+ xml.skipCurrentElement();
+ }
- // parse signals
- list = iface.elementsByTagName(QLatin1String("signal"));
- for (int j = 0; j < list.count(); ++j)
- {
- QDomElement signal = list.item(j).toElement();
- QString signalName = signal.attribute(QLatin1String("name"));
- if (signal.isNull())
- continue;
- if (!QDBusUtil::isValidMemberName(signalName)) {
- qDBusParserError("Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection",
- qPrintable(signalName), qPrintable(ifaceName));
- continue;
- }
+ methodData.inputArgs = inArguments;
+ methodData.outputArgs = outArguments;
+ methodData.annotations = annotations;
- QDBusIntrospection::Signal signalData;
- signalData.name = signalName;
+ return true;
+}
- // parse data
- signalData.outputArgs = parseArgs(signal, QLatin1String("out"), true);
- signalData.annotations = parseAnnotations(signal);
- // add it
- ifaceData->signals_.insert(signalName, signalData);
- }
+static bool parseSignal(QXmlStreamReader &xml, QDBusIntrospection::Signal &signalData,
+ const QString &ifaceName)
+{
+ Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String("signal"));
- // parse properties
- list = iface.elementsByTagName(QLatin1String("property"));
- for (int j = 0; j < list.count(); ++j)
- {
- QDomElement property = list.item(j).toElement();
- QString propertyName = property.attribute(QLatin1String("name"));
- if (property.isNull())
- continue;
- if (!QDBusUtil::isValidMemberName(propertyName)) {
- qDBusParserError("Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection",
- qPrintable(propertyName), qPrintable(ifaceName));
- continue;
- }
+ const QXmlStreamAttributes attributes = xml.attributes();
+ const QString signalName = attributes.value(QLatin1String("name")).toString();
- QDBusIntrospection::Property propertyData;
+ if (!QDBusUtil::isValidMemberName(signalName)) {
+ qDBusParserError("Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection",
+ qPrintable(signalName), qPrintable(ifaceName));
+ return false;
+ }
- // parse data
- propertyData.name = propertyName;
- propertyData.type = property.attribute(QLatin1String("type"));
- propertyData.annotations = parseAnnotations(property);
+ signalData.name = signalName;
- if (!QDBusUtil::isValidSingleSignature(propertyData.type)) {
- // cannot be!
- qDBusParserError("Invalid D-BUS type signature '%s' found in property '%s.%s' while parsing introspection",
- qPrintable(propertyData.type), qPrintable(ifaceName),
- qPrintable(propertyName));
- }
- QString access = property.attribute(QLatin1String("access"));
- if (access == QLatin1String("read"))
- propertyData.access = QDBusIntrospection::Property::Read;
- else if (access == QLatin1String("write"))
- propertyData.access = QDBusIntrospection::Property::Write;
- else if (access == QLatin1String("readwrite"))
- propertyData.access = QDBusIntrospection::Property::ReadWrite;
- else {
- qDBusParserError("Invalid D-BUS property access '%s' found in property '%s.%s' while parsing introspection",
- qPrintable(access), qPrintable(ifaceName),
- qPrintable(propertyName));
- continue; // invalid one!
- }
+ QDBusIntrospection::Arguments arguments;
+ QDBusIntrospection::Annotations annotations;
- // add it
- ifaceData->properties.insert(propertyName, propertyData);
+ while (xml.readNextStartElement()) {
+ if (xml.name() == QLatin1String("annotation")) {
+ parseAnnotation(xml, annotations);
+ } else if (xml.name() == QLatin1String("arg")) {
+ const QXmlStreamAttributes attributes = xml.attributes();
+ QDBusIntrospection::Argument argument;
+ if (!attributes.hasAttribute(QLatin1String("direction")) ||
+ attributes.value(QLatin1String("direction")) == QLatin1String("out")) {
+ parseArg(attributes, argument);
+ arguments << argument;
+ }
+ } else {
+ qDBusParserError() << "Unknown element" << xml.name() << "while checking for signal arguments";
}
-
- // add it
- retval.insert(ifaceName, QSharedDataPointer<QDBusIntrospection::Interface>(ifaceData));
+ xml.skipCurrentElement();
}
- return retval;
+ signalData.outputArgs = arguments;
+ signalData.annotations = annotations;
+
+ return true;
}
-QSharedDataPointer<QDBusIntrospection::Object>
-QDBusXmlParser::object() const
+static void readInterface(QXmlStreamReader &xml, QDBusIntrospection::Object *objData,
+ QDBusIntrospection::Interfaces *interfaces)
{
- if (m_node.isNull())
- return QSharedDataPointer<QDBusIntrospection::Object>();
-
- QDBusIntrospection::Object* objData;
- objData = new QDBusIntrospection::Object;
- objData->service = m_service;
- objData->path = m_path;
-
- // check if we have anything to process
- if (objData->introspection.isNull() && !m_node.firstChild().isNull()) {
- // yes, introspect this object
- QTextStream ts(&objData->introspection);
- m_node.save(ts,2);
-
- QDomNodeList objects = m_node.elementsByTagName(QLatin1String("node"));
- for (int i = 0; i < objects.count(); ++i) {
- QDomElement obj = objects.item(i).toElement();
- QString objName = obj.attribute(QLatin1String("name"));
- if (obj.isNull())
- continue; // for whatever reason
- if (!QDBusUtil::isValidObjectPath(m_path + QLatin1Char('/') + objName)) {
- qDBusParserError("Invalid D-BUS object path '%s/%s' found while parsing introspection",
- qPrintable(m_path), qPrintable(objName));
- continue;
- }
+ const QString ifaceName = xml.attributes().value(QLatin1String("name")).toString();
+ if (!QDBusUtil::isValidInterfaceName(ifaceName)) {
+ qDBusParserError("Invalid D-BUS interface name '%s' found while parsing introspection",
+ qPrintable(ifaceName));
+ return;
+ }
- objData->childObjects.append(objName);
- }
+ objData->interfaces.append(ifaceName);
- QDomNodeList interfaceList = m_node.elementsByTagName(QLatin1String("interface"));
- for (int i = 0; i < interfaceList.count(); ++i) {
- QDomElement iface = interfaceList.item(i).toElement();
- QString ifaceName = iface.attribute(QLatin1String("name"));
- if (iface.isNull())
- continue;
- if (!QDBusUtil::isValidInterfaceName(ifaceName)) {
- qDBusParserError("Invalid D-BUS interface name '%s' found while parsing introspection",
- qPrintable(ifaceName));
- continue;
- }
+ QDBusIntrospection::Interface *ifaceData = new QDBusIntrospection::Interface;
+ ifaceData->name = ifaceName;
- objData->interfaces.append(ifaceName);
+ while (xml.readNextStartElement()) {
+ if (xml.name() == QLatin1String("method")) {
+ QDBusIntrospection::Method methodData;
+ if (parseMethod(xml, methodData, ifaceName))
+ ifaceData->methods.insert(methodData.name, methodData);
+ } else if (xml.name() == QLatin1String("signal")) {
+ QDBusIntrospection::Signal signalData;
+ if (parseSignal(xml, signalData, ifaceName))
+ ifaceData->signals_.insert(signalData.name, signalData);
+ } else if (xml.name() == QLatin1String("property")) {
+ QDBusIntrospection::Property propertyData;
+ if (parseProperty(xml, propertyData, ifaceName))
+ ifaceData->properties.insert(propertyData.name, propertyData);
+ } else if (xml.name() == QLatin1String("annotation")) {
+ parseAnnotation(xml, ifaceData->annotations);
+ xml.skipCurrentElement(); // skip over annotation object
+ } else {
+ if (xml.prefix().isEmpty()) {
+ qDBusParserError() << "Unknown element while parsing interface" << xml.name();
+ }
+ xml.skipCurrentElement();
}
- } else {
- objData->introspection = QLatin1String("<node/>\n");
}
- QSharedDataPointer<QDBusIntrospection::Object> retval;
- retval = objData;
- return retval;
+ interfaces->insert(ifaceName, QSharedDataPointer<QDBusIntrospection::Interface>(ifaceData));
+
+ if (!xml.isEndElement() || xml.name() != QLatin1String("interface")) {
+ qDBusParserError() << "Invalid Interface specification";
+ }
+}
+
+static void readNode(const QXmlStreamReader &xml, QDBusIntrospection::Object *objData, int nodeLevel)
+{
+ const QString objName = xml.attributes().value(QLatin1String("name")).toString();
+ const QString fullName = objData->path.endsWith(QLatin1Char('/'))
+ ? (objData->path + objName)
+ : QString(objData->path + QLatin1Char('/') + objName);
+ if (!QDBusUtil::isValidObjectPath(fullName)) {
+ qDBusParserError("Invalid D-BUS object path '%s' found while parsing introspection",
+ qPrintable(fullName));
+ return;
+ }
+
+ if (nodeLevel > 0)
+ objData->childObjects.append(objName);
}
-QSharedDataPointer<QDBusIntrospection::ObjectTree>
-QDBusXmlParser::objectTree() const
+QDBusXmlParser::QDBusXmlParser(const QString& service, const QString& path,
+ const QString& xmlData)
+ : m_service(service), m_path(path), m_object(new QDBusIntrospection::Object)
{
- QSharedDataPointer<QDBusIntrospection::ObjectTree> retval;
-
- if (m_node.isNull())
- return retval;
-
- retval = new QDBusIntrospection::ObjectTree;
-
- retval->service = m_service;
- retval->path = m_path;
-
- QTextStream ts(&retval->introspection);
- m_node.save(ts,2);
-
- // interfaces are easy:
- retval->interfaceData = interfaces();
- retval->interfaces = retval->interfaceData.keys();
-
- // sub-objects are slightly more difficult:
- QDomNodeList objects = m_node.elementsByTagName(QLatin1String("node"));
- for (int i = 0; i < objects.count(); ++i) {
- QDomElement obj = objects.item(i).toElement();
- QString objName = obj.attribute(QLatin1String("name"));
- if (obj.isNull() || objName.isEmpty())
- continue; // for whatever reason
-
- // check if we have anything to process
- if (!obj.firstChild().isNull()) {
- // yes, introspect this object
- QString xml;
- QTextStream ts2(&xml);
- obj.save(ts2,0);
-
- // parse it
- QString objAbsName = m_path;
- if (!objAbsName.endsWith(QLatin1Char('/')))
- objAbsName.append(QLatin1Char('/'));
- objAbsName += objName;
-
- QDBusXmlParser parser(m_service, objAbsName, obj);
- retval->childObjectData.insert(objName, parser.objectTree());
- }
+// qDBusParserError() << "parsing" << xmlData;
- retval->childObjects << objName;
+ m_object->service = m_service;
+ m_object->path = m_path;
+
+ QXmlStreamReader xml(xmlData);
+
+ int nodeLevel = -1;
+
+ while (!xml.atEnd()) {
+ xml.readNext();
+
+ switch (xml.tokenType()) {
+ case QXmlStreamReader::StartElement:
+ if (xml.name() == QLatin1String("node")) {
+ readNode(xml, m_object, ++nodeLevel);
+ } else if (xml.name() == QLatin1String("interface")) {
+ readInterface(xml, m_object, &m_interfaces);
+ } else {
+ if (xml.prefix().isEmpty()) {
+ qDBusParserError() << "skipping unknown element" << xml.name();
+ }
+ xml.skipCurrentElement();
+ }
+ break;
+ case QXmlStreamReader::EndElement:
+ if (xml.name() == QLatin1String("node")) {
+ --nodeLevel;
+ } else {
+ qDBusParserError() << "Invalid Node declaration" << xml.name();
+ }
+ break;
+ case QXmlStreamReader::StartDocument:
+ case QXmlStreamReader::EndDocument:
+ case QXmlStreamReader::DTD:
+ // not interested
+ break;
+ case QXmlStreamReader::Comment:
+ // ignore comments and processing instructions
+ break;
+ default:
+ qDBusParserError() << "unknown token" << xml.name() << xml.tokenString();
+ break;
+ }
}
- return QSharedDataPointer<QDBusIntrospection::ObjectTree>( retval );
+ if (xml.hasError()) {
+ qDBusParserError() << "xml error" << xml.errorString() << "doc" << xmlData;
+ }
}
QT_END_NAMESPACE
diff --git a/src/dbus/qdbusxmlparser_p.h b/src/dbus/qdbusxmlparser_p.h
index f7677e0ae4..bd063e759b 100644
--- a/src/dbus/qdbusxmlparser_p.h
+++ b/src/dbus/qdbusxmlparser_p.h
@@ -54,7 +54,6 @@
//
#include <QtCore/qmap.h>
-#include <QtXml/qdom.h>
#include <qdbusmacros.h>
#include "qdbusintrospection_p.h"
@@ -69,17 +68,15 @@ class QDBusXmlParser
{
QString m_service;
QString m_path;
- QDomElement m_node;
+ QSharedDataPointer<QDBusIntrospection::Object> m_object;
+ QDBusIntrospection::Interfaces m_interfaces;
public:
QDBusXmlParser(const QString& service, const QString& path,
const QString& xmlData);
- QDBusXmlParser(const QString& service, const QString& path,
- const QDomElement& node);
- QDBusIntrospection::Interfaces interfaces() const;
- QSharedDataPointer<QDBusIntrospection::Object> object() const;
- QSharedDataPointer<QDBusIntrospection::ObjectTree> objectTree() const;
+ inline QDBusIntrospection::Interfaces interfaces() const { return m_interfaces; }
+ inline QSharedDataPointer<QDBusIntrospection::Object> object() const { return m_object; }
};
QT_END_NAMESPACE
diff --git a/src/modules/qt_dbus.pri b/src/modules/qt_dbus.pri
index d57160eb77..8514265f8c 100644
--- a/src/modules/qt_dbus.pri
+++ b/src/modules/qt_dbus.pri
@@ -11,6 +11,6 @@ QT.dbus.sources = $$QT_MODULE_BASE/src/dbus
QT.dbus.libs = $$QT_MODULE_LIB_BASE
QT.dbus.plugins = $$QT_MODULE_PLUGIN_BASE
QT.dbus.imports = $$QT_MODULE_IMPORT_BASE
-QT.dbus.depends = core xml
+QT.dbus.depends = core
QT.dbus.CONFIG = dbusadaptors dbusinterfaces
QT.dbus.DEFINES = QT_DBUS_LIB
diff --git a/src/src.pro b/src/src.pro
index 80d1c4e3bd..8d750bab76 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -50,7 +50,7 @@ src_platformsupport.target = sub-platformsupport
src_platformsupport.depends = src_corelib src_gui src_network
src_widgets.depends = src_corelib src_gui src_tools_uic
src_xml.depends = src_corelib
- src_dbus.depends = src_corelib src_xml
+ src_dbus.depends = src_corelib
src_network.depends = src_corelib
src_opengl.depends = src_gui src_widgets
src_sql.depends = src_corelib
diff --git a/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
index dc8363db42..44f1b1cfa7 100644
--- a/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+++ b/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
@@ -46,7 +46,7 @@
#include <QtTest/QtTest>
#include <QtCore/qvariant.h>
#include <QtDBus/QtDBus>
-
+#include <qdebug.h>
#include "../qdbusmarshall/common.h"
#include "myobject.h"
diff --git a/tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp b/tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp
index 42a3fd19cc..dad8c6d577 100644
--- a/tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp
+++ b/tests/auto/dbus/qdbusxmlparser/tst_qdbusxmlparser.cpp
@@ -61,9 +61,6 @@ private slots:
void parsingWithDoctype_data();
void parsingWithDoctype();
- void objectWithContent_data();
- void objectWithContent();
-
void methods_data();
void methods();
void signals__data();
@@ -77,40 +74,49 @@ void tst_QDBusXmlParser::parsing_data()
QTest::addColumn<QString>("xmlData");
QTest::addColumn<int>("interfaceCount");
QTest::addColumn<int>("objectCount");
+ QTest::addColumn<int>("annotationCount");
- QTest::newRow("null") << QString() << 0 << 0;
- QTest::newRow("empty") << QString("") << 0 << 0;
+ QTest::newRow("null") << QString() << 0 << 0 << 0;
+ QTest::newRow("empty") << QString("") << 0 << 0 << 0;
- QTest::newRow("junk") << "<junk/>" << 0 << 0;
+ QTest::newRow("junk") << "<junk/>" << 0 << 0 << 0;
QTest::newRow("interface-inside-junk") << "<junk><interface name=\"iface.iface1\" /></junk>"
- << 0 << 0;
+ << 0 << 0 << 0;
QTest::newRow("object-inside-junk") << "<junk><node name=\"obj1\" /></junk>"
- << 0 << 0;
+ << 0 << 0 << 0;
- QTest::newRow("zero-interfaces") << "<node/>" << 0 << 0;
- QTest::newRow("one-interface") << "<node><interface name=\"iface.iface1\" /></node>" << 1 << 0;
+ QTest::newRow("zero-interfaces") << "<node/>" << 0 << 0 << 0;
+ QTest::newRow("one-interface") << "<node><interface name=\"iface.iface1\" /></node>" << 1 << 0 << 0;
QTest::newRow("two-interfaces") << "<node><interface name=\"iface.iface1\" />"
- "<interface name=\"iface.iface2\"></node>"
- << 2 << 0;
+ "<interface name=\"iface.iface2\" /></node>"
+ << 2 << 0 << 0;
- QTest::newRow("one-object") << "<node><node name=\"obj1\"/></node>" << 0 << 1;
- QTest::newRow("two-objects") << "<node><node name=\"obj1\"/><node name=\"obj2\"></node>" << 0 << 2;
+ QTest::newRow("one-object") << "<node><node name=\"obj1\"/></node>" << 0 << 1 << 0;
+ QTest::newRow("two-objects") << "<node><node name=\"obj1\"/><node name=\"obj2\"/></node>" << 0 << 2 << 0;
- QTest::newRow("i1o1") << "<node><interface name=\"iface.iface1\"><node name=\"obj1\"></node>" << 1 << 1;
+ QTest::newRow("i1o1") << "<node><interface name=\"iface.iface1\"/><node name=\"obj1\"/></node>" << 1 << 1 << 0;
+ QTest::newRow("one-interface-annotated") << "<node><interface name=\"iface.iface1\">"
+ "<annotation name=\"foo.testing\" value=\"nothing to see here\" />"
+ "</interface></node>" << 1 << 0 << 1;
+ QTest::newRow("one-interface-docnamespace") << "<?xml version=\"1.0\" xmlns:doc=\"foo\" ?><node>"
+ "<interface name=\"iface.iface1\"><doc:something />"
+ "</interface></node>" << 1 << 0 << 0;
}
void tst_QDBusXmlParser::parsing_common(const QString &xmlData)
{
- QDBusIntrospection::ObjectTree obj =
- QDBusIntrospection::parseObjectTree(xmlData, "local.testing", "/");
+ QDBusIntrospection::Object obj =
+ QDBusIntrospection::parseObject(xmlData, "local.testing", "/");
QFETCH(int, interfaceCount);
QFETCH(int, objectCount);
+ QFETCH(int, annotationCount);
QCOMPARE(obj.interfaces.count(), interfaceCount);
QCOMPARE(obj.childObjects.count(), objectCount);
+ QCOMPARE(QDBusIntrospection::parseInterface(xmlData).annotations.count(), annotationCount);
// also verify the naming
int i = 0;
@@ -140,92 +146,14 @@ void tst_QDBusXmlParser::parsingWithDoctype()
"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n";
QFETCH(QString, xmlData);
- parsing_common(docType + xmlData);
-}
-
-void tst_QDBusXmlParser::objectWithContent_data()
-{
- QTest::addColumn<QString>("xmlData");
- QTest::addColumn<QString>("probedObject");
- QTest::addColumn<int>("interfaceCount");
- QTest::addColumn<int>("objectCount");
-
- QTest::newRow("zero") << "<node><node name=\"obj\"/></node>" << "obj" << 0 << 0;
-
- QString xmlData = "<node><node name=\"obj\">"
- "<interface name=\"iface.iface1\" />"
- "</node></node>";
- QTest::newRow("one-interface") << xmlData << "obj" << 1 << 0;
- QTest::newRow("one-interface2") << xmlData << "obj2" << 0 << 0;
-
- xmlData = "<node><node name=\"obj\">"
- "<interface name=\"iface.iface1\" />"
- "<interface name=\"iface.iface2\" />"
- "</node></node>";
- QTest::newRow("two-interfaces") << xmlData << "obj" << 2 << 0;
- QTest::newRow("two-interfaces2") << xmlData << "obj2" << 0 << 0;
-
- xmlData = "<node><node name=\"obj\">"
- "<interface name=\"iface.iface1\" />"
- "<interface name=\"iface.iface2\" />"
- "</node><node name=\"obj2\">"
- "<interface name=\"iface.iface1\" />"
- "</node></node>";
- QTest::newRow("two-nodes-two-interfaces") << xmlData << "obj" << 2 << 0;
- QTest::newRow("two-nodes-one-interface") << xmlData << "obj2" << 1 << 0;
-
- xmlData = "<node><node name=\"obj\">"
- "<node name=\"obj1\" />"
- "</node></node>";
- QTest::newRow("one-object") << xmlData << "obj" << 0 << 1;
- QTest::newRow("one-object2") << xmlData << "obj2" << 0 << 0;
-
- xmlData = "<node><node name=\"obj\">"
- "<node name=\"obj1\" />"
- "<node name=\"obj2\" />"
- "</node></node>";
- QTest::newRow("two-objects") << xmlData << "obj" << 0 << 2;
- QTest::newRow("two-objects2") << xmlData << "obj2" << 0 << 0;
-
- xmlData = "<node><node name=\"obj\">"
- "<node name=\"obj1\" />"
- "<node name=\"obj2\" />"
- "</node><node name=\"obj2\">"
- "<node name=\"obj1\" />"
- "</node></node>";
- QTest::newRow("two-nodes-two-objects") << xmlData << "obj" << 0 << 2;
- QTest::newRow("two-nodes-one-object") << xmlData << "obj2" << 0 << 1;
-}
-
-void tst_QDBusXmlParser::objectWithContent()
-{
- QFETCH(QString, xmlData);
- QFETCH(QString, probedObject);
-
- QDBusIntrospection::ObjectTree tree =
- QDBusIntrospection::parseObjectTree(xmlData, "local.testing", "/");
-
- const ObjectMap &om = tree.childObjectData;
-
- if (om.contains(probedObject)) {
- const QSharedDataPointer<QDBusIntrospection::ObjectTree>& obj = om.value(probedObject);
- QVERIFY(obj != 0);
-
- QFETCH(int, interfaceCount);
- QFETCH(int, objectCount);
-
- QCOMPARE(obj->interfaces.count(), interfaceCount);
- QCOMPARE(obj->childObjects.count(), objectCount);
-
- // verify the object names
- int i = 0;
- foreach (QString name, obj->interfaces)
- QCOMPARE(name, QString("iface.iface%1").arg(++i));
-
- i = 0;
- foreach (QString name, obj->childObjects)
- QCOMPARE(name, QString("obj%1").arg(++i));
+ QString toParse;
+ if (xmlData.startsWith(QLatin1String("<?xml"))) {
+ int split = xmlData.indexOf(QLatin1Char('>')) + 1;
+ toParse = xmlData.left(split) + docType + xmlData.mid(split);
+ } else {
+ toParse = docType + xmlData;
}
+ parsing_common(toParse);
}
void tst_QDBusXmlParser::methods_data()
@@ -261,7 +189,7 @@ void tst_QDBusXmlParser::methods_data()
QTest::newRow("method-with-annotation") <<
"<method name=\"Foo\"/>"
"<method name=\"Bar\"/>"
- "<method name=\"Baz\"><annotation name=\"foo.testing\" value=\"nothing to see here\"></method>"
+ "<method name=\"Baz\"><annotation name=\"foo.testing\" value=\"nothing to see here\" /></method>"
<< map;
// arguments
@@ -428,7 +356,7 @@ void tst_QDBusXmlParser::signals__data()
QTest::newRow("signal-with-annotation") <<
"<signal name=\"Foo\"/>"
"<signal name=\"Bar\"/>"
- "<signal name=\"Baz\"><annotation name=\"foo.testing\" value=\"nothing to see here\"></signal>"
+ "<signal name=\"Baz\"><annotation name=\"foo.testing\" value=\"nothing to see here\" /></signal>"
<< map;
// one out argument
@@ -563,6 +491,7 @@ void tst_QDBusXmlParser::properties_data()
"<property name=\"baz\" type=\"as\" access=\"write\">"
"<annotation name=\"foo.annotation\" value=\"Hello, World\" />"
"<annotation name=\"foo.annotation2\" value=\"Goodbye, World\" />"
+ "</property>"
"<property name=\"foo\" type=\"s\" access=\"readwrite\"/>" << map;
// and now change the order
@@ -570,6 +499,7 @@ void tst_QDBusXmlParser::properties_data()
"<property name=\"baz\" type=\"as\" access=\"write\">"
"<annotation name=\"foo.annotation2\" value=\"Goodbye, World\" />"
"<annotation name=\"foo.annotation\" value=\"Hello, World\" />"
+ "</property>"
"<property name=\"bar\" type=\"i\" access=\"read\"/>"
"<property name=\"foo\" type=\"s\" access=\"readwrite\"/>" << map;
}