| 1 | /**************************************************************************** | 
|---|
| 2 | ** | 
|---|
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | 
|---|
| 4 | ** Contact: https://www.qt.io/licensing/ | 
|---|
| 5 | ** | 
|---|
| 6 | ** This file is part of the QtDBus module of the Qt Toolkit. | 
|---|
| 7 | ** | 
|---|
| 8 | ** $QT_BEGIN_LICENSE:LGPL$ | 
|---|
| 9 | ** Commercial License Usage | 
|---|
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
|---|
| 11 | ** accordance with the commercial license agreement provided with the | 
|---|
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
|---|
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
|---|
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
|---|
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
|---|
| 16 | ** | 
|---|
| 17 | ** GNU Lesser General Public License Usage | 
|---|
| 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
|---|
| 19 | ** General Public License version 3 as published by the Free Software | 
|---|
| 20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | 
|---|
| 21 | ** packaging of this file. Please review the following information to | 
|---|
| 22 | ** ensure the GNU Lesser General Public License version 3 requirements | 
|---|
| 23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | 
|---|
| 24 | ** | 
|---|
| 25 | ** GNU General Public License Usage | 
|---|
| 26 | ** Alternatively, this file may be used under the terms of the GNU | 
|---|
| 27 | ** General Public License version 2.0 or (at your option) the GNU General | 
|---|
| 28 | ** Public license version 3 or any later version approved by the KDE Free | 
|---|
| 29 | ** Qt Foundation. The licenses are as published by the Free Software | 
|---|
| 30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | 
|---|
| 31 | ** included in the packaging of this file. Please review the following | 
|---|
| 32 | ** information to ensure the GNU General Public License requirements will | 
|---|
| 33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | 
|---|
| 34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | 
|---|
| 35 | ** | 
|---|
| 36 | ** $QT_END_LICENSE$ | 
|---|
| 37 | ** | 
|---|
| 38 | ****************************************************************************/ | 
|---|
| 39 |  | 
|---|
| 40 | #include "qdbusxmlparser_p.h" | 
|---|
| 41 | #include "qdbusutil_p.h" | 
|---|
| 42 |  | 
|---|
| 43 | #include <QtCore/qmap.h> | 
|---|
| 44 | #include <QtCore/qvariant.h> | 
|---|
| 45 | #include <QtCore/qtextstream.h> | 
|---|
| 46 | #include <QtCore/qxmlstream.h> | 
|---|
| 47 | #include <QtCore/qdebug.h> | 
|---|
| 48 |  | 
|---|
| 49 | #ifndef QT_NO_DBUS | 
|---|
| 50 |  | 
|---|
| 51 | QT_BEGIN_NAMESPACE | 
|---|
| 52 |  | 
|---|
| 53 | Q_LOGGING_CATEGORY(dbusParser, "dbus.parser", QtWarningMsg) | 
|---|
| 54 |  | 
|---|
| 55 | #define qDBusParserError(...) qCDebug(dbusParser, ##__VA_ARGS__) | 
|---|
| 56 |  | 
|---|
| 57 | static bool parseArg(const QXmlStreamAttributes &attributes, QDBusIntrospection::Argument &argData, | 
|---|
| 58 | QDBusIntrospection::Interface *ifaceData) | 
|---|
| 59 | { | 
|---|
| 60 | const QString argType = attributes.value(QLatin1String( "type")).toString(); | 
|---|
| 61 |  | 
|---|
| 62 | bool ok = QDBusUtil::isValidSingleSignature(argType); | 
|---|
| 63 | if (!ok) { | 
|---|
| 64 | qDBusParserError( "Invalid D-BUS type signature '%s' found while parsing introspection", | 
|---|
| 65 | qPrintable(argType)); | 
|---|
| 66 | } | 
|---|
| 67 |  | 
|---|
| 68 | argData.name = attributes.value(QLatin1String( "name")).toString(); | 
|---|
| 69 | argData.type = argType; | 
|---|
| 70 |  | 
|---|
| 71 | ifaceData->introspection += QLatin1String( "      <arg"); | 
|---|
| 72 | if (attributes.hasAttribute(QLatin1String( "direction"))) { | 
|---|
| 73 | const QString direction = attributes.value(QLatin1String( "direction")).toString(); | 
|---|
| 74 | ifaceData->introspection += QLatin1String( " direction=\"") + direction + QLatin1String( "\""); | 
|---|
| 75 | } | 
|---|
| 76 | ifaceData->introspection += QLatin1String( " type=\"") + argData.type + QLatin1String( "\""); | 
|---|
| 77 | if (!argData.name.isEmpty()) | 
|---|
| 78 | ifaceData->introspection += QLatin1String( " name=\"") + argData.name + QLatin1String( "\""); | 
|---|
| 79 | ifaceData->introspection += QLatin1String( "/>\n"); | 
|---|
| 80 |  | 
|---|
| 81 | return ok; | 
|---|
| 82 | } | 
|---|
| 83 |  | 
|---|
| 84 | static bool parseAnnotation(const QXmlStreamReader &xml, QDBusIntrospection::Annotations &annotations, | 
|---|
| 85 | QDBusIntrospection::Interface *ifaceData, bool interfaceAnnotation = false) | 
|---|
| 86 | { | 
|---|
| 87 | Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String( "annotation")); | 
|---|
| 88 |  | 
|---|
| 89 | const QXmlStreamAttributes attributes = xml.attributes(); | 
|---|
| 90 | const QString name = attributes.value(QLatin1String( "name")).toString(); | 
|---|
| 91 |  | 
|---|
| 92 | if (!QDBusUtil::isValidInterfaceName(name)) { | 
|---|
| 93 | qDBusParserError( "Invalid D-BUS annotation '%s' found while parsing introspection", | 
|---|
| 94 | qPrintable(name)); | 
|---|
| 95 | return false; | 
|---|
| 96 | } | 
|---|
| 97 | const QString value = attributes.value(QLatin1String( "value")).toString(); | 
|---|
| 98 | annotations.insert(name, value); | 
|---|
| 99 | if (!interfaceAnnotation) | 
|---|
| 100 | ifaceData->introspection += QLatin1String( "  "); | 
|---|
| 101 | ifaceData->introspection += QLatin1String( "    <annotation value=\"") + value.toHtmlEscaped() + QLatin1String( "\" name=\"") + name + QLatin1String( "\"/>\n"); | 
|---|
| 102 | return true; | 
|---|
| 103 | } | 
|---|
| 104 |  | 
|---|
| 105 | static bool parseProperty(QXmlStreamReader &xml, QDBusIntrospection::Property &propertyData, | 
|---|
| 106 | QDBusIntrospection::Interface *ifaceData) | 
|---|
| 107 | { | 
|---|
| 108 | Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String( "property")); | 
|---|
| 109 |  | 
|---|
| 110 | QXmlStreamAttributes attributes = xml.attributes(); | 
|---|
| 111 | const QString propertyName = attributes.value(QLatin1String( "name")).toString(); | 
|---|
| 112 | if (!QDBusUtil::isValidMemberName(propertyName)) { | 
|---|
| 113 | qDBusParserError( "Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection", | 
|---|
| 114 | qPrintable(propertyName), qPrintable(ifaceData->name)); | 
|---|
| 115 | xml.skipCurrentElement(); | 
|---|
| 116 | return false; | 
|---|
| 117 | } | 
|---|
| 118 |  | 
|---|
| 119 | // parse data | 
|---|
| 120 | propertyData.name = propertyName; | 
|---|
| 121 | propertyData.type = attributes.value(QLatin1String( "type")).toString(); | 
|---|
| 122 |  | 
|---|
| 123 | if (!QDBusUtil::isValidSingleSignature(propertyData.type)) { | 
|---|
| 124 | // cannot be! | 
|---|
| 125 | qDBusParserError( "Invalid D-BUS type signature '%s' found in property '%s.%s' while parsing introspection", | 
|---|
| 126 | qPrintable(propertyData.type), qPrintable(ifaceData->name), | 
|---|
| 127 | qPrintable(propertyName)); | 
|---|
| 128 | } | 
|---|
| 129 |  | 
|---|
| 130 | const QString access = attributes.value(QLatin1String( "access")).toString(); | 
|---|
| 131 | if (access == QLatin1String( "read")) | 
|---|
| 132 | propertyData.access = QDBusIntrospection::Property::Read; | 
|---|
| 133 | else if (access == QLatin1String( "write")) | 
|---|
| 134 | propertyData.access = QDBusIntrospection::Property::Write; | 
|---|
| 135 | else if (access == QLatin1String( "readwrite")) | 
|---|
| 136 | propertyData.access = QDBusIntrospection::Property::ReadWrite; | 
|---|
| 137 | else { | 
|---|
| 138 | qDBusParserError( "Invalid D-BUS property access '%s' found in property '%s.%s' while parsing introspection", | 
|---|
| 139 | qPrintable(access), qPrintable(ifaceData->name), | 
|---|
| 140 | qPrintable(propertyName)); | 
|---|
| 141 | return false;       // invalid one! | 
|---|
| 142 | } | 
|---|
| 143 |  | 
|---|
| 144 | ifaceData->introspection += QLatin1String( "    <property access=\"") + access + QLatin1String( "\" type=\"") + propertyData.type + QLatin1String( "\" name=\"") + propertyName + QLatin1String( "\""); | 
|---|
| 145 |  | 
|---|
| 146 | if (!xml.readNextStartElement()) { | 
|---|
| 147 | ifaceData->introspection += QLatin1String( "/>\n"); | 
|---|
| 148 | } else { | 
|---|
| 149 | ifaceData->introspection += QLatin1String( ">\n"); | 
|---|
| 150 |  | 
|---|
| 151 | do { | 
|---|
| 152 | if (xml.name() == QLatin1String( "annotation")) { | 
|---|
| 153 | parseAnnotation(xml, propertyData.annotations, ifaceData); | 
|---|
| 154 | } else if (xml.prefix().isEmpty()) { | 
|---|
| 155 | qDBusParserError() << "Unknown element"<< xml.name() << "while checking for annotations"; | 
|---|
| 156 | } | 
|---|
| 157 | xml.skipCurrentElement(); | 
|---|
| 158 | } while (xml.readNextStartElement()); | 
|---|
| 159 |  | 
|---|
| 160 | ifaceData->introspection += QLatin1String( "    </property>\n"); | 
|---|
| 161 | } | 
|---|
| 162 |  | 
|---|
| 163 | if (!xml.isEndElement() || xml.name() != QLatin1String( "property")) { | 
|---|
| 164 | qDBusParserError() << "Invalid property specification"<< xml.tokenString() << xml.name(); | 
|---|
| 165 | return false; | 
|---|
| 166 | } | 
|---|
| 167 |  | 
|---|
| 168 | return true; | 
|---|
| 169 | } | 
|---|
| 170 |  | 
|---|
| 171 | static bool parseMethod(QXmlStreamReader &xml, QDBusIntrospection::Method &methodData, | 
|---|
| 172 | QDBusIntrospection::Interface *ifaceData) | 
|---|
| 173 | { | 
|---|
| 174 | Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String( "method")); | 
|---|
| 175 |  | 
|---|
| 176 | const QXmlStreamAttributes attributes = xml.attributes(); | 
|---|
| 177 | const QString methodName = attributes.value(QLatin1String( "name")).toString(); | 
|---|
| 178 | if (!QDBusUtil::isValidMemberName(methodName)) { | 
|---|
| 179 | qDBusParserError( "Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection", | 
|---|
| 180 | qPrintable(methodName), qPrintable(ifaceData->name)); | 
|---|
| 181 | return false; | 
|---|
| 182 | } | 
|---|
| 183 |  | 
|---|
| 184 | methodData.name = methodName; | 
|---|
| 185 | ifaceData->introspection += QLatin1String( "    <method name=\"") + methodName + QLatin1String( "\""); | 
|---|
| 186 |  | 
|---|
| 187 | QDBusIntrospection::Arguments outArguments; | 
|---|
| 188 | QDBusIntrospection::Arguments inArguments; | 
|---|
| 189 | QDBusIntrospection::Annotations annotations; | 
|---|
| 190 |  | 
|---|
| 191 | if (!xml.readNextStartElement()) { | 
|---|
| 192 | ifaceData->introspection += QLatin1String( "/>\n"); | 
|---|
| 193 | } else { | 
|---|
| 194 | ifaceData->introspection += QLatin1String( ">\n"); | 
|---|
| 195 |  | 
|---|
| 196 | do { | 
|---|
| 197 | if (xml.name() == QLatin1String( "annotation")) { | 
|---|
| 198 | parseAnnotation(xml, annotations, ifaceData); | 
|---|
| 199 | } else if (xml.name() == QLatin1String( "arg")) { | 
|---|
| 200 | const QXmlStreamAttributes attributes = xml.attributes(); | 
|---|
| 201 | const QString direction = attributes.value(QLatin1String( "direction")).toString(); | 
|---|
| 202 | QDBusIntrospection::Argument argument; | 
|---|
| 203 | if (!attributes.hasAttribute(QLatin1String( "direction")) | 
|---|
| 204 | || direction == QLatin1String( "in")) { | 
|---|
| 205 | parseArg(attributes, argument, ifaceData); | 
|---|
| 206 | inArguments << argument; | 
|---|
| 207 | } else if (direction == QLatin1String( "out")) { | 
|---|
| 208 | parseArg(attributes, argument, ifaceData); | 
|---|
| 209 | outArguments << argument; | 
|---|
| 210 | } | 
|---|
| 211 | } else if (xml.prefix().isEmpty()) { | 
|---|
| 212 | qDBusParserError() << "Unknown element"<< xml.name() << "while checking for method arguments"; | 
|---|
| 213 | } | 
|---|
| 214 | xml.skipCurrentElement(); | 
|---|
| 215 | } while (xml.readNextStartElement()); | 
|---|
| 216 |  | 
|---|
| 217 | ifaceData->introspection += QLatin1String( "    </method>\n"); | 
|---|
| 218 | } | 
|---|
| 219 |  | 
|---|
| 220 | methodData.inputArgs = inArguments; | 
|---|
| 221 | methodData.outputArgs = outArguments; | 
|---|
| 222 | methodData.annotations = annotations; | 
|---|
| 223 |  | 
|---|
| 224 | return true; | 
|---|
| 225 | } | 
|---|
| 226 |  | 
|---|
| 227 |  | 
|---|
| 228 | static bool parseSignal(QXmlStreamReader &xml, QDBusIntrospection::Signal &signalData, | 
|---|
| 229 | QDBusIntrospection::Interface *ifaceData) | 
|---|
| 230 | { | 
|---|
| 231 | Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String( "signal")); | 
|---|
| 232 |  | 
|---|
| 233 | const QXmlStreamAttributes attributes = xml.attributes(); | 
|---|
| 234 | const QString signalName = attributes.value(QLatin1String( "name")).toString(); | 
|---|
| 235 |  | 
|---|
| 236 | if (!QDBusUtil::isValidMemberName(signalName)) { | 
|---|
| 237 | qDBusParserError( "Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection", | 
|---|
| 238 | qPrintable(signalName), qPrintable(ifaceData->name)); | 
|---|
| 239 | return false; | 
|---|
| 240 | } | 
|---|
| 241 |  | 
|---|
| 242 | signalData.name = signalName; | 
|---|
| 243 | ifaceData->introspection += QLatin1String( "    <signal name=\"") + signalName + QLatin1String( "\""); | 
|---|
| 244 |  | 
|---|
| 245 | QDBusIntrospection::Arguments arguments; | 
|---|
| 246 | QDBusIntrospection::Annotations annotations; | 
|---|
| 247 |  | 
|---|
| 248 | if (!xml.readNextStartElement()) { | 
|---|
| 249 | ifaceData->introspection += QLatin1String( "/>\n"); | 
|---|
| 250 | } else { | 
|---|
| 251 | ifaceData->introspection += QLatin1String( ">\n"); | 
|---|
| 252 |  | 
|---|
| 253 | do { | 
|---|
| 254 | if (xml.name() == QLatin1String( "annotation")) { | 
|---|
| 255 | parseAnnotation(xml, annotations, ifaceData); | 
|---|
| 256 | } else if (xml.name() == QLatin1String( "arg")) { | 
|---|
| 257 | const QXmlStreamAttributes attributes = xml.attributes(); | 
|---|
| 258 | QDBusIntrospection::Argument argument; | 
|---|
| 259 | if (!attributes.hasAttribute(QLatin1String( "direction")) || | 
|---|
| 260 | attributes.value(QLatin1String( "direction")) == QLatin1String( "out")) { | 
|---|
| 261 | parseArg(attributes, argument, ifaceData); | 
|---|
| 262 | arguments << argument; | 
|---|
| 263 | } | 
|---|
| 264 | } else { | 
|---|
| 265 | qDBusParserError() << "Unknown element"<< xml.name() << "while checking for signal arguments"; | 
|---|
| 266 | } | 
|---|
| 267 | xml.skipCurrentElement(); | 
|---|
| 268 | } while (xml.readNextStartElement()); | 
|---|
| 269 |  | 
|---|
| 270 | ifaceData->introspection += QLatin1String( "    </signal>\n"); | 
|---|
| 271 | } | 
|---|
| 272 |  | 
|---|
| 273 | signalData.outputArgs = arguments; | 
|---|
| 274 | signalData.annotations = annotations; | 
|---|
| 275 |  | 
|---|
| 276 | return true; | 
|---|
| 277 | } | 
|---|
| 278 |  | 
|---|
| 279 | static void readInterface(QXmlStreamReader &xml, QDBusIntrospection::Object *objData, | 
|---|
| 280 | QDBusIntrospection::Interfaces *interfaces) | 
|---|
| 281 | { | 
|---|
| 282 | const QString ifaceName = xml.attributes().value(QLatin1String( "name")).toString(); | 
|---|
| 283 | if (!QDBusUtil::isValidInterfaceName(ifaceName)) { | 
|---|
| 284 | qDBusParserError( "Invalid D-BUS interface name '%s' found while parsing introspection", | 
|---|
| 285 | qPrintable(ifaceName)); | 
|---|
| 286 | return; | 
|---|
| 287 | } | 
|---|
| 288 |  | 
|---|
| 289 | objData->interfaces.append(ifaceName); | 
|---|
| 290 |  | 
|---|
| 291 | QDBusIntrospection::Interface *ifaceData = new QDBusIntrospection::Interface; | 
|---|
| 292 | ifaceData->name = ifaceName; | 
|---|
| 293 | ifaceData->introspection += QLatin1String( "  <interface name=\"") + ifaceName + QLatin1String( "\">\n"); | 
|---|
| 294 |  | 
|---|
| 295 | while (xml.readNextStartElement()) { | 
|---|
| 296 | if (xml.name() == QLatin1String( "method")) { | 
|---|
| 297 | QDBusIntrospection::Method methodData; | 
|---|
| 298 | if (parseMethod(xml, methodData, ifaceData)) | 
|---|
| 299 | ifaceData->methods.insert(methodData.name, methodData); | 
|---|
| 300 | } else if (xml.name() == QLatin1String( "signal")) { | 
|---|
| 301 | QDBusIntrospection::Signal signalData; | 
|---|
| 302 | if (parseSignal(xml, signalData, ifaceData)) | 
|---|
| 303 | ifaceData->signals_.insert(signalData.name, signalData); | 
|---|
| 304 | } else if (xml.name() == QLatin1String( "property")) { | 
|---|
| 305 | QDBusIntrospection::Property propertyData; | 
|---|
| 306 | if (parseProperty(xml, propertyData, ifaceData)) | 
|---|
| 307 | ifaceData->properties.insert(propertyData.name, propertyData); | 
|---|
| 308 | } else if (xml.name() == QLatin1String( "annotation")) { | 
|---|
| 309 | parseAnnotation(xml, ifaceData->annotations, ifaceData, true); | 
|---|
| 310 | xml.skipCurrentElement(); // skip over annotation object | 
|---|
| 311 | } else { | 
|---|
| 312 | if (xml.prefix().isEmpty()) { | 
|---|
| 313 | qDBusParserError() << "Unknown element while parsing interface"<< xml.name(); | 
|---|
| 314 | } | 
|---|
| 315 | xml.skipCurrentElement(); | 
|---|
| 316 | } | 
|---|
| 317 | } | 
|---|
| 318 |  | 
|---|
| 319 | ifaceData->introspection += QLatin1String( "  </interface>"); | 
|---|
| 320 |  | 
|---|
| 321 | interfaces->insert(ifaceName, QSharedDataPointer<QDBusIntrospection::Interface>(ifaceData)); | 
|---|
| 322 |  | 
|---|
| 323 | if (!xml.isEndElement() || xml.name() != QLatin1String( "interface")) { | 
|---|
| 324 | qDBusParserError() << "Invalid Interface specification"; | 
|---|
| 325 | } | 
|---|
| 326 | } | 
|---|
| 327 |  | 
|---|
| 328 | static void readNode(const QXmlStreamReader &xml, QDBusIntrospection::Object *objData, int nodeLevel) | 
|---|
| 329 | { | 
|---|
| 330 | const QString objName = xml.attributes().value(QLatin1String( "name")).toString(); | 
|---|
| 331 | const QString fullName = objData->path.endsWith(QLatin1Char('/')) | 
|---|
| 332 | ? (objData->path + objName) | 
|---|
| 333 | : QString(objData->path + QLatin1Char('/') + objName); | 
|---|
| 334 | if (!QDBusUtil::isValidObjectPath(fullName)) { | 
|---|
| 335 | qDBusParserError( "Invalid D-BUS object path '%s' found while parsing introspection", | 
|---|
| 336 | qPrintable(fullName)); | 
|---|
| 337 | return; | 
|---|
| 338 | } | 
|---|
| 339 |  | 
|---|
| 340 | if (nodeLevel > 0) | 
|---|
| 341 | objData->childObjects.append(objName); | 
|---|
| 342 | } | 
|---|
| 343 |  | 
|---|
| 344 | QDBusXmlParser::QDBusXmlParser(const QString& service, const QString& path, | 
|---|
| 345 | const QString& xmlData) | 
|---|
| 346 | : m_service(service), m_path(path), m_object(new QDBusIntrospection::Object) | 
|---|
| 347 | { | 
|---|
| 348 | //    qDBusParserError() << "parsing" << xmlData; | 
|---|
| 349 |  | 
|---|
| 350 | m_object->service = m_service; | 
|---|
| 351 | m_object->path = m_path; | 
|---|
| 352 |  | 
|---|
| 353 | QXmlStreamReader xml(xmlData); | 
|---|
| 354 |  | 
|---|
| 355 | int nodeLevel = -1; | 
|---|
| 356 |  | 
|---|
| 357 | while (!xml.atEnd()) { | 
|---|
| 358 | xml.readNext(); | 
|---|
| 359 |  | 
|---|
| 360 | switch (xml.tokenType()) { | 
|---|
| 361 | case QXmlStreamReader::StartElement: | 
|---|
| 362 | if (xml.name() == QLatin1String( "node")) { | 
|---|
| 363 | readNode(xml, m_object, ++nodeLevel); | 
|---|
| 364 | } else if (xml.name() == QLatin1String( "interface")) { | 
|---|
| 365 | readInterface(xml, m_object, &m_interfaces); | 
|---|
| 366 | } else { | 
|---|
| 367 | if (xml.prefix().isEmpty()) { | 
|---|
| 368 | qDBusParserError() << "skipping unknown element"<< xml.name(); | 
|---|
| 369 | } | 
|---|
| 370 | xml.skipCurrentElement(); | 
|---|
| 371 | } | 
|---|
| 372 | break; | 
|---|
| 373 | case QXmlStreamReader::EndElement: | 
|---|
| 374 | if (xml.name() == QLatin1String( "node")) { | 
|---|
| 375 | --nodeLevel; | 
|---|
| 376 | } else { | 
|---|
| 377 | qDBusParserError() << "Invalid Node declaration"<< xml.name(); | 
|---|
| 378 | } | 
|---|
| 379 | break; | 
|---|
| 380 | case QXmlStreamReader::StartDocument: | 
|---|
| 381 | case QXmlStreamReader::EndDocument: | 
|---|
| 382 | case QXmlStreamReader::DTD: | 
|---|
| 383 | // not interested | 
|---|
| 384 | break; | 
|---|
| 385 | case QXmlStreamReader::Comment: | 
|---|
| 386 | // ignore comments and processing instructions | 
|---|
| 387 | break; | 
|---|
| 388 | case QXmlStreamReader::Characters: | 
|---|
| 389 | // ignore whitespace | 
|---|
| 390 | if (xml.isWhitespace()) | 
|---|
| 391 | break; | 
|---|
| 392 | Q_FALLTHROUGH(); | 
|---|
| 393 | default: | 
|---|
| 394 | qDBusParserError() << "unknown token"<< xml.name() << xml.tokenString(); | 
|---|
| 395 | break; | 
|---|
| 396 | } | 
|---|
| 397 | } | 
|---|
| 398 |  | 
|---|
| 399 | if (xml.hasError()) { | 
|---|
| 400 | qDBusParserError() << "xml error"<< xml.errorString() << "doc"<< xmlData; | 
|---|
| 401 | } | 
|---|
| 402 | } | 
|---|
| 403 |  | 
|---|
| 404 | QT_END_NAMESPACE | 
|---|
| 405 |  | 
|---|
| 406 | #endif // QT_NO_DBUS | 
|---|
| 407 |  | 
|---|