summaryrefslogtreecommitdiffstats
path: root/src/dbus/qdbusmetaobject.cpp
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2012-02-19 13:25:04 +0100
committerQt by Nokia <qt-info@nokia.com>2012-02-29 12:50:14 +0100
commit3b844c16e0988b017c67b2329cbe34d4da112b33 (patch)
tree8635c99500e01aaf938de45ff98c76034fec5276 /src/dbus/qdbusmetaobject.cpp
parent019a5f2dd50404abfb06f26d31aa6292eb6344fc (diff)
Port QDBusMetaObject to Qt5 meta-property/method descriptor format
Adapts QDBusMetaObject to be in sync with the moc/meta-object changes for property and method descriptors (storing the name and argument count of methods, and more elaborate type information). Now that the method name is stored in the standard method descriptor, QtDBus doesn't need to store it separately anymore, and the QMetaObjectPrivate::rawStringData() function can be removed. Change-Id: I04efdbe05b52bbd85405e1713509e55308ac42da Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/dbus/qdbusmetaobject.cpp')
-rw-r--r--src/dbus/qdbusmetaobject.cpp152
1 files changed, 107 insertions, 45 deletions
diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp
index eb2d3dffa8..7b8a67f343 100644
--- a/src/dbus/qdbusmetaobject.cpp
+++ b/src/dbus/qdbusmetaobject.cpp
@@ -70,7 +70,7 @@ public:
private:
struct Method {
- QByteArray parameters;
+ QList<QByteArray> parameterNames;
QByteArray typeName;
QByteArray tag;
QByteArray name;
@@ -104,10 +104,12 @@ private:
void parseMethods();
void parseSignals();
void parseProperties();
+
+ static int aggregateParameterCount(const QMap<QByteArray, Method> &map);
};
static const int intsPerProperty = 2;
-static const int intsPerMethod = 3;
+static const int intsPerMethod = 2;
struct QDBusMetaObjectPrivate : public QMetaObjectPrivate
{
@@ -133,6 +135,30 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature,
const QDBusIntrospection::Annotations &annotations,
const char *direction, int id)
{
+ struct QDBusRawTypeHandler {
+ static void destroy(void *)
+ {
+ qFatal("Cannot destroy placeholder type QDBusRawType");
+ }
+
+ static void *create(const void *)
+ {
+ qFatal("Cannot create placeholder type QDBusRawType");
+ return 0;
+ }
+
+ static void destruct(void *)
+ {
+ qFatal("Cannot destruct placeholder type QDBusRawType");
+ }
+
+ static void *construct(void *, const void *)
+ {
+ qFatal("Cannot construct placeholder type QDBusRawType");
+ return 0;
+ }
+ };
+
Type result;
result.id = QVariant::Invalid;
@@ -158,8 +184,13 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature,
if (type == QVariant::Invalid || signature != QDBusMetaType::typeToSignature(type)) {
// type is still unknown or doesn't match back to the signature that it
// was expected to, so synthesize a fake type
- type = QMetaType::VoidStar;
typeName = "QDBusRawType<0x" + signature.toHex() + ">*";
+ type = QMetaType::registerType(typeName, QDBusRawTypeHandler::destroy,
+ QDBusRawTypeHandler::create,
+ QDBusRawTypeHandler::destruct,
+ QDBusRawTypeHandler::construct,
+ sizeof(void *),
+ QMetaType::MovableType);
}
result.name = typeName;
@@ -216,8 +247,7 @@ void QDBusMetaObjectGenerator::parseMethods()
mm.inputTypes.append(type.id);
- mm.parameters.append(arg.name.toLatin1());
- mm.parameters.append(',');
+ mm.parameterNames.append(arg.name.toLatin1());
prototype.append(type.name);
prototype.append(',');
@@ -241,8 +271,7 @@ void QDBusMetaObjectGenerator::parseMethods()
mm.typeName = type.name;
} else {
// non-const ref parameter
- mm.parameters.append(arg.name.toLatin1());
- mm.parameters.append(',');
+ mm.parameterNames.append(arg.name.toLatin1());
prototype.append(type.name);
prototype.append("&,");
@@ -251,12 +280,10 @@ void QDBusMetaObjectGenerator::parseMethods()
if (!ok) continue;
// convert the last commas:
- if (!mm.parameters.isEmpty()) {
- mm.parameters.truncate(mm.parameters.length() - 1);
+ if (!mm.parameterNames.isEmpty())
prototype[prototype.length() - 1] = ')';
- } else {
+ else
prototype.append(')');
- }
// check the async tag
if (m.annotations.value(QLatin1String(ANNOTATION_NO_WAIT)) == QLatin1String("true"))
@@ -296,8 +323,7 @@ void QDBusMetaObjectGenerator::parseSignals()
mm.inputTypes.append(type.id);
- mm.parameters.append(arg.name.toLatin1());
- mm.parameters.append(',');
+ mm.parameterNames.append(arg.name.toLatin1());
prototype.append(type.name);
prototype.append(',');
@@ -305,12 +331,10 @@ void QDBusMetaObjectGenerator::parseSignals()
if (!ok) continue;
// convert the last commas:
- if (!mm.parameters.isEmpty()) {
- mm.parameters.truncate(mm.parameters.length() - 1);
+ if (!mm.parameterNames.isEmpty())
prototype[prototype.length() - 1] = ')';
- } else {
+ else
prototype.append(')');
- }
// meta method flags
mm.flags = AccessProtected | MethodSignal | MethodScriptable;
@@ -343,17 +367,25 @@ void QDBusMetaObjectGenerator::parseProperties()
if (p.access != QDBusIntrospection::Property::Read)
mp.flags |= Writable;
- if (mp.typeName == "QDBusVariant")
- mp.flags |= QMetaType::QVariant << 24;
- else if (mp.type < 0xff)
- // encode the type in the flags
- mp.flags |= mp.type << 24;
-
// add the property:
properties.insert(name, mp);
}
}
+// Returns the sum of all parameters (including return type) for the given
+// \a map of methods. This is needed for calculating the size of the methods'
+// parameter type/name meta-data.
+int QDBusMetaObjectGenerator::aggregateParameterCount(const QMap<QByteArray, Method> &map)
+{
+ int sum = 0;
+ QMap<QByteArray, Method>::const_iterator it;
+ for (it = map.constBegin(); it != map.constEnd(); ++it) {
+ const Method &m = it.value();
+ sum += m.inputTypes.size() + qMax(1, m.outputTypes.size());
+ }
+ return sum;
+}
+
void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
{
// this code here is mostly copied from qaxbase.cpp
@@ -367,6 +399,12 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
QVarLengthArray<int> idata;
idata.resize(sizeof(QDBusMetaObjectPrivate) / sizeof(int));
+ int methodParametersDataSize =
+ ((aggregateParameterCount(signals_)
+ + aggregateParameterCount(methods)) * 2) // types and parameter names
+ - signals_.count() // return "parameters" don't have names
+ - methods.count(); // ditto
+
QDBusMetaObjectPrivate *header = reinterpret_cast<QDBusMetaObjectPrivate *>(idata.data());
Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 7, "QtDBus meta-object generator should generate the same version as moc");
header->revision = QMetaObjectPrivate::OutputRevision;
@@ -376,7 +414,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
header->methodCount = signals_.count() + methods.count();
header->methodData = idata.size();
header->propertyCount = properties.count();
- header->propertyData = header->methodData + header->methodCount * 5;
+ header->propertyData = header->methodData + header->methodCount * 5 + methodParametersDataSize;
header->enumeratorCount = 0;
header->enumeratorData = 0;
header->constructorCount = 0;
@@ -388,7 +426,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
header->methodDBusData = header->propertyDBusData + header->propertyCount * intsPerProperty;
int data_size = idata.size() +
- (header->methodCount * (5+intsPerMethod)) +
+ (header->methodCount * (5+intsPerMethod)) + methodParametersDataSize +
(header->propertyCount * (3+intsPerProperty));
foreach (const Method &mm, signals_)
data_size += 2 + mm.inputTypes.count() + mm.outputTypes.count();
@@ -400,6 +438,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
strings.enter(className.toLatin1());
int offset = header->methodData;
+ int parametersOffset = offset + header->methodCount * 5;
int signatureOffset = header->methodDBusData;
int typeidOffset = header->methodDBusData + header->methodCount * intsPerMethod;
idata[typeidOffset++] = 0; // eod
@@ -410,16 +449,45 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
QMap<QByteArray, Method> &map = (x == 0) ? signals_ : methods;
for (QMap<QByteArray, Method>::ConstIterator it = map.constBegin();
it != map.constEnd(); ++it) {
- // form "prototype\0parameters\0typeName\0tag\0methodname\0"
const Method &mm = it.value();
- idata[offset++] = strings.enter(it.key()); // prototype
- idata[offset++] = strings.enter(mm.parameters);
- idata[offset++] = strings.enter(mm.typeName);
+ int argc = mm.inputTypes.size() + qMax(0, mm.outputTypes.size() - 1);
+
+ idata[offset++] = strings.enter(mm.name);
+ idata[offset++] = argc;
+ idata[offset++] = parametersOffset;
idata[offset++] = strings.enter(mm.tag);
idata[offset++] = mm.flags;
- idata[signatureOffset++] = strings.enter(mm.name);
+ // Parameter types
+ for (int i = -1; i < argc; ++i) {
+ int type;
+ QByteArray typeName;
+ if (i < 0) { // Return type
+ if (!mm.outputTypes.isEmpty())
+ type = mm.outputTypes.first();
+ else
+ type = QMetaType::Void;
+ } else if (i < mm.inputTypes.size()) {
+ type = mm.inputTypes.at(i);
+ } else {
+ Q_ASSERT(mm.outputTypes.size() > 1);
+ type = mm.outputTypes.at(i - mm.inputTypes.size() + 1);
+ // Output parameters are references; type id not available
+ typeName = QMetaType::typeName(type);
+ typeName.append('&');
+ }
+ Q_ASSERT(type || (i < 0));
+ int typeInfo;
+ if (!typeName.isEmpty())
+ typeInfo = IsUnresolvedType | strings.enter(typeName);
+ else
+ typeInfo = type;
+ idata[parametersOffset++] = typeInfo;
+ }
+ // Parameter names
+ for (int i = 0; i < argc; ++i)
+ idata[parametersOffset++] = strings.enter(mm.parameterNames.at(i));
idata[signatureOffset++] = typeidOffset;
idata[typeidOffset++] = mm.inputTypes.count();
@@ -433,9 +501,12 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
}
}
- Q_ASSERT(offset == header->propertyData);
+ Q_ASSERT(offset == header->methodData + header->methodCount * 5);
+ Q_ASSERT(parametersOffset = header->propertyData);
Q_ASSERT(signatureOffset == header->methodDBusData + header->methodCount * intsPerMethod);
Q_ASSERT(typeidOffset == idata.size());
+ offset += methodParametersDataSize;
+ Q_ASSERT(offset == header->propertyData);
// add each property
signatureOffset = header->propertyDBusData;
@@ -443,9 +514,10 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
it != properties.constEnd(); ++it) {
const Property &mp = it.value();
- // form is "name\0typeName\0signature\0"
+ // form is name, typeinfo, flags
idata[offset++] = strings.enter(it.key()); // name
- idata[offset++] = strings.enter(mp.typeName);
+ Q_ASSERT(mp.type != 0);
+ idata[offset++] = mp.type;
idata[offset++] = mp.flags;
idata[signatureOffset++] = strings.enter(mp.signature);
@@ -578,22 +650,12 @@ static inline const QDBusMetaObjectPrivate *priv(const uint* data)
return reinterpret_cast<const QDBusMetaObjectPrivate *>(data);
}
-const char *QDBusMetaObject::dbusNameForMethod(int id) const
-{
- //id -= methodOffset();
- if (id >= 0 && id < priv(d.data)->methodCount) {
- int handle = priv(d.data)->methodDBusData + id*intsPerMethod;
- return QMetaObjectPrivate::rawStringData(this, d.data[handle]);
- }
- return 0;
-}
-
const int *QDBusMetaObject::inputTypesForMethod(int id) const
{
//id -= methodOffset();
if (id >= 0 && id < priv(d.data)->methodCount) {
int handle = priv(d.data)->methodDBusData + id*intsPerMethod;
- return reinterpret_cast<const int*>(d.data + d.data[handle + 1]);
+ return reinterpret_cast<const int*>(d.data + d.data[handle]);
}
return 0;
}
@@ -603,7 +665,7 @@ const int *QDBusMetaObject::outputTypesForMethod(int id) const
//id -= methodOffset();
if (id >= 0 && id < priv(d.data)->methodCount) {
int handle = priv(d.data)->methodDBusData + id*intsPerMethod;
- return reinterpret_cast<const int*>(d.data + d.data[handle + 2]);
+ return reinterpret_cast<const int*>(d.data + d.data[handle + 1]);
}
return 0;
}