📄 qdbusmetaobject.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the tools applications of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qdbusmetaobject_p.h"#include <QtCore/qbytearray.h>#include <QtCore/qhash.h>#include <QtCore/qstring.h>#include <QtCore/qvarlengtharray.h>#include "qdbusutil_p.h"#include "qdbuserror.h"#include "qdbusmetatype.h"#include "qdbusargument.h"#include "qdbusintrospection_p.h"#include "qdbusabstractinterface_p.h"class QDBusMetaObjectGenerator{public: QDBusMetaObjectGenerator(const QString &interface, const QDBusIntrospection::Interface *parsedData); void write(QDBusMetaObject *obj); void writeWithoutXml(QDBusMetaObject *obj);private: struct Method { QByteArray parameters; QByteArray typeName; QByteArray tag; QByteArray inputSignature; QByteArray outputSignature; QVarLengthArray<int, 4> inputTypes; QVarLengthArray<int, 4> outputTypes; int flags; }; struct Property { QByteArray typeName; QByteArray signature; int type; int flags; }; struct Type { int id; QByteArray name; }; enum PropertyFlags { Invalid = 0x00000000, Readable = 0x00000001, Writable = 0x00000002, Resettable = 0x00000004, EnumOrFlag = 0x00000008, StdCppSet = 0x00000100, // Override = 0x00000200, Designable = 0x00001000, ResolveDesignable = 0x00002000, Scriptable = 0x00004000, ResolveScriptable = 0x00008000, Stored = 0x00010000, ResolveStored = 0x00020000, Editable = 0x00040000, ResolveEditable = 0x00080000, User = 0x00100000, ResolveUser = 0x00200000 }; enum MethodFlags { AccessPrivate = 0x00, AccessProtected = 0x01, AccessPublic = 0x02, AccessMask = 0x03, //mask MethodMethod = 0x00, MethodSignal = 0x04, MethodSlot = 0x08, MethodTypeMask = 0x0c, MethodCompatibility = 0x10, MethodCloned = 0x20, MethodScriptable = 0x40 }; QMap<QByteArray, Method> methods; QMap<QByteArray, Property> properties; const QDBusIntrospection::Interface *data; QString interface; Type findType(const QByteArray &signature, const QDBusIntrospection::Annotations &annotations, const char *direction = "Out", int id = -1); void parseMethods(); void parseSignals(); void parseProperties();};static const int intsPerProperty = 2;static const int intsPerMethod = 4;// ### from kernel/qmetaobject.cpp (Qt 4.1.2):struct QDBusMetaObjectPrivate{ int revision; int className; int classInfoCount, classInfoData; int methodCount, methodData; int propertyCount, propertyData; int enumeratorCount, enumeratorData; // this is specific for QDBusMetaObject: int propertyDBusData; int methodDBusData;};QDBusMetaObjectGenerator::QDBusMetaObjectGenerator(const QString &interfaceName, const QDBusIntrospection::Interface *parsedData) : data(parsedData), interface(interfaceName){ if (data) { parseProperties(); parseSignals(); // call parseSignals first so that slots override signals parseMethods(); }}QDBusMetaObjectGenerator::TypeQDBusMetaObjectGenerator::findType(const QByteArray &signature, const QDBusIntrospection::Annotations &annotations, const char *direction, int id){ Type result; result.id = QVariant::Invalid; int type = QDBusMetaType::signatureToType(signature); if (type == QVariant::Invalid) { // it's not a type normally handled by our meta type system // it must contain an annotation QString annotationName = QString::fromLatin1("com.trolltech.QtDBus.QtTypeName"); if (id >= 0) annotationName += QString::fromLatin1(".%1%2") .arg(QLatin1String(direction)) .arg(id); // extract from annotations: QByteArray typeName = annotations.value(annotationName).toLatin1(); // verify that it's a valid one if (typeName.isEmpty()) return result; // invalid type = QVariant::nameToType(typeName); if (type == QVariant::UserType) type = QMetaType::type(typeName); if (type == QVariant::Invalid || signature != QDBusMetaType::typeToSignature(type)) return result; // unknown type is invalid too result.name = typeName; } else { result.name = QVariant::typeToName( QVariant::Type(type) ); } result.id = type; return result; // success}void QDBusMetaObjectGenerator::parseMethods(){ // // TODO: // Add cloned methods when the remote object has return types // QDBusIntrospection::Methods::ConstIterator method_it = data->methods.constBegin(); QDBusIntrospection::Methods::ConstIterator method_end = data->methods.constEnd(); for ( ; method_it != method_end; ++method_it) { const QDBusIntrospection::Method &m = *method_it; Method mm; QByteArray prototype = m.name.toLatin1(); prototype += '('; bool ok = true; // build the input argument list for (int i = 0; i < m.inputArgs.count(); ++i) { const QDBusIntrospection::Argument &arg = m.inputArgs.at(i); Type type = findType(arg.type.toLatin1(), m.annotations, "In", i); if (type.id == QVariant::Invalid) { ok = false; break; } mm.inputSignature += arg.type.toLatin1(); mm.inputTypes.append(type.id); mm.parameters.append(arg.name.toLatin1()); mm.parameters.append(','); prototype.append(type.name); prototype.append(','); } if (!ok) continue; // build the output argument list: for (int i = 0; i < m.outputArgs.count(); ++i) { const QDBusIntrospection::Argument &arg = m.outputArgs.at(i); Type type = findType(arg.type.toLatin1(), m.annotations, "Out", i); if (type.id == QVariant::Invalid) { ok = false; break; } mm.outputSignature += arg.type.toLatin1(); mm.outputTypes.append(type.id); if (i == 0) { // return value mm.typeName = type.name; } else { // non-const ref parameter mm.parameters.append(arg.name.toLatin1()); mm.parameters.append(','); prototype.append(type.name); prototype.append("&,"); } } if (!ok) continue; // convert the last commas: if (!mm.parameters.isEmpty()) { mm.parameters.truncate(mm.parameters.length() - 1); prototype[prototype.length() - 1] = ')'; } else { prototype.append(')'); } // check the async tag if (m.annotations.value(QLatin1String(ANNOTATION_NO_WAIT)) == QLatin1String("true")) mm.tag = "Q_NOREPLY"; // meta method flags mm.flags = AccessPublic | MethodSlot | MethodScriptable; // add methods.insert(QMetaObject::normalizedSignature(prototype), mm); }}void QDBusMetaObjectGenerator::parseSignals(){ QDBusIntrospection::Signals::ConstIterator signal_it = data->signals_.constBegin(); QDBusIntrospection::Signals::ConstIterator signal_end = data->signals_.constEnd(); for ( ; signal_it != signal_end; ++signal_it) { const QDBusIntrospection::Signal &s = *signal_it; Method mm; QByteArray prototype = s.name.toLatin1(); prototype += '('; bool ok = true; // build the output argument list for (int i = 0; i < s.outputArgs.count(); ++i) { const QDBusIntrospection::Argument &arg = s.outputArgs.at(i); Type type = findType(arg.type.toLatin1(), s.annotations, "Out", i); if (type.id == QVariant::Invalid) { ok = false; break; } mm.inputSignature += arg.type.toLatin1(); mm.inputTypes.append(type.id); mm.parameters.append(arg.name.toLatin1()); mm.parameters.append(','); prototype.append(type.name); prototype.append(','); } if (!ok) continue; // convert the last commas: if (!mm.parameters.isEmpty()) { mm.parameters.truncate(mm.parameters.length() - 1); prototype[prototype.length() - 1] = ')'; } else { prototype.append(')'); } // meta method flags mm.flags = AccessProtected | MethodSignal | MethodScriptable; // add methods.insert(QMetaObject::normalizedSignature(prototype), mm); }}void QDBusMetaObjectGenerator::parseProperties(){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -