summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetaobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qmetaobject.cpp')
-rw-r--r--src/corelib/kernel/qmetaobject.cpp706
1 files changed, 647 insertions, 59 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 4d629dd933..0a1fb3daf7 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -189,6 +189,53 @@ static inline int stringSize(const QMetaObject *mo, int index)
return qstrlen(legacyString(mo, index));
}
+static inline QByteArray typeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
+{
+ if (typeInfo & IsUnresolvedType) {
+ return toByteArray(stringData(mo, typeInfo & TypeNameIndexMask));
+ } else {
+ // ### Use the QMetaType::typeName() that returns QByteArray
+ const char *t = QMetaType::typeName(typeInfo);
+ return QByteArray::fromRawData(t, qstrlen(t));
+ }
+}
+
+static inline const char *rawTypeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
+{
+ return typeNameFromTypeInfo(mo, typeInfo).constData();
+}
+
+static inline int typeFromTypeInfo(const QMetaObject *mo, uint typeInfo)
+{
+ if (!(typeInfo & IsUnresolvedType))
+ return typeInfo;
+ return QMetaType::type(toByteArray(stringData(mo, typeInfo & TypeNameIndexMask)));
+}
+
+class QMetaMethodPrivate : public QMetaMethod
+{
+public:
+ static const QMetaMethodPrivate *get(const QMetaMethod *q)
+ { return static_cast<const QMetaMethodPrivate *>(q); }
+
+ inline QByteArray signature() const;
+ inline QByteArray name() const;
+ inline int typesDataIndex() const;
+ inline const char *rawReturnTypeName() const;
+ inline int returnType() const;
+ inline int parameterCount() const;
+ inline int parametersDataIndex() const;
+ inline uint parameterTypeInfo(int index) const;
+ inline int parameterType(int index) const;
+ inline void getParameterTypes(int *types) const;
+ inline QList<QByteArray> parameterTypes() const;
+ inline QList<QByteArray> parameterNames() const;
+ inline QByteArray tag() const;
+
+private:
+ QMetaMethodPrivate();
+};
+
/*!
\since 4.5
@@ -539,7 +586,37 @@ int QMetaObject::classInfoCount() const
return n;
}
+// Returns true if the method defined by the given meta-object&handle
+// matches the given name, argument count and argument types, otherwise
+// returns false.
+static bool methodMatch(const QMetaObject *m, int handle,
+ const QByteArray &name, int argc,
+ const QArgumentType *types)
+{
+ Q_ASSERT(priv(m->d.data)->revision >= 7);
+ if (int(m->d.data[handle + 1]) != argc)
+ return false;
+
+ if (toByteArray(stringData(m, m->d.data[handle])) != name)
+ return false;
+
+ int paramsIndex = m->d.data[handle + 2] + 1;
+ for (int i = 0; i < argc; ++i) {
+ uint typeInfo = m->d.data[paramsIndex + i];
+ if (types[i].type()) {
+ if (types[i].type() != typeFromTypeInfo(m, typeInfo))
+ return false;
+ } else {
+ if (types[i].name() != typeNameFromTypeInfo(m, typeInfo))
+ return false;
+ }
+ }
+
+ return true;
+}
+
/** \internal
+* \obsolete
* helper function for indexOf{Method,Slot,Signal}, returns the relative index of the method within
* the baseObject
* \a MethodType might be MethodSignal or MethodSlot, or 0 to match everything.
@@ -550,6 +627,8 @@ static inline int indexOfMethodRelative(const QMetaObject **baseObject,
const char *method,
bool normalizeStringData)
{
+ QByteArray methodName;
+ QArgumentTypeArray methodArgumentTypes;
for (const QMetaObject *m = *baseObject; m; m = m->d.superdata) {
int i = (MethodType == MethodSignal && priv(m->d.data)->revision >= 4)
? (priv(m->d.data)->signalCount - 1) : (priv(m->d.data)->methodCount - 1);
@@ -557,10 +636,21 @@ static inline int indexOfMethodRelative(const QMetaObject **baseObject,
? (priv(m->d.data)->signalCount) : 0;
if (!normalizeStringData) {
for (; i >= end; --i) {
- const char *stringdata = rawStringData(m, m->d.data[priv(m->d.data)->methodData + 5*i]);
- if (method[0] == stringdata[0] && strcmp(method + 1, stringdata + 1) == 0) {
- *baseObject = m;
- return i;
+ if (priv(m->d.data)->revision >= 7) {
+ if (methodName.isEmpty())
+ methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodArgumentTypes);
+ int handle = priv(m->d.data)->methodData + 5*i;
+ if (methodMatch(m, handle, methodName, methodArgumentTypes.size(),
+ methodArgumentTypes.constData())) {
+ *baseObject = m;
+ return i;
+ }
+ } else {
+ const char *stringdata = legacyString(m, m->d.data[priv(m->d.data)->methodData + 5*i]);
+ if (method[0] == stringdata[0] && strcmp(method + 1, stringdata + 1) == 0) {
+ *baseObject = m;
+ return i;
+ }
}
}
} else if (priv(m->d.data)->revision < 5) {
@@ -577,6 +667,34 @@ static inline int indexOfMethodRelative(const QMetaObject **baseObject,
return -1;
}
+/** \internal
+* helper function for indexOf{Method,Slot,Signal}, returns the relative index of the method within
+* the baseObject
+* \a MethodType might be MethodSignal or MethodSlot, or 0 to match everything.
+*/
+template<int MethodType>
+static inline int indexOfMethodRelative(const QMetaObject **baseObject,
+ const QByteArray &name, int argc,
+ const QArgumentType *types)
+{
+ for (const QMetaObject *m = *baseObject; m; m = m->d.superdata) {
+ Q_ASSERT(priv(m->d.data)->revision >= 7);
+ int i = (MethodType == MethodSignal)
+ ? (priv(m->d.data)->signalCount - 1) : (priv(m->d.data)->methodCount - 1);
+ const int end = (MethodType == MethodSlot)
+ ? (priv(m->d.data)->signalCount) : 0;
+
+ for (; i >= end; --i) {
+ int handle = priv(m->d.data)->methodData + 5*i;
+ if (methodMatch(m, handle, name, argc, types)) {
+ *baseObject = m;
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
/*!
\since 4.5
@@ -592,10 +710,16 @@ int QMetaObject::indexOfConstructor(const char *constructor) const
{
if (priv(d.data)->revision < 2)
return -1;
- for (int i = priv(d.data)->constructorCount-1; i >= 0; --i) {
- const char *data = rawStringData(this, d.data[priv(d.data)->constructorData + 5*i]);
- if (data[0] == constructor[0] && strcmp(constructor + 1, data + 1) == 0) {
- return i;
+ else if (priv(d.data)->revision >= 7) {
+ QArgumentTypeArray types;
+ QByteArray name = QMetaObjectPrivate::decodeMethodSignature(constructor, types);
+ return QMetaObjectPrivate::indexOfConstructor(this, name, types.size(), types.constData());
+ } else {
+ for (int i = priv(d.data)->constructorCount-1; i >= 0; --i) {
+ const char *data = legacyString(this, d.data[priv(d.data)->constructorData + 5*i]);
+ if (data[0] == constructor[0] && strcmp(constructor + 1, data + 1) == 0) {
+ return i;
+ }
}
}
return -1;
@@ -612,16 +736,60 @@ int QMetaObject::indexOfConstructor(const char *constructor) const
int QMetaObject::indexOfMethod(const char *method) const
{
const QMetaObject *m = this;
- int i = indexOfMethodRelative<0>(&m, method, false);
- if (i < 0) {
- m = this;
- i = indexOfMethodRelative<0>(&m, method, true);
+ int i;
+ if (priv(m->d.data)->revision >= 7) {
+ QArgumentTypeArray types;
+ QByteArray name = QMetaObjectPrivate::decodeMethodSignature(method, types);
+ i = indexOfMethodRelative<0>(&m, name, types.size(), types.constData());
+ } else {
+ i = indexOfMethodRelative<0>(&m, method, false);
+ if (i < 0) {
+ m = this;
+ i = indexOfMethodRelative<0>(&m, method, true);
+ }
}
if (i >= 0)
i += m->methodOffset();
return i;
}
+// Parses a string of comma-separated types into QArgumentTypes.
+static void argumentTypesFromString(const char *str, const char *end,
+ QArgumentTypeArray &types)
+{
+ Q_ASSERT(str <= end);
+ while (str != end) {
+ if (!types.isEmpty())
+ ++str; // Skip comma
+ const char *begin = str;
+ int level = 0;
+ while (str != end && (level > 0 || *str != ',')) {
+ if (*str == '<')
+ ++level;
+ else if (*str == '>')
+ --level;
+ ++str;
+ }
+ types += QArgumentType(QByteArray(begin, str - begin));
+ }
+}
+
+// Given a method \a signature (e.g. "foo(int,double)"), this function
+// populates the argument \a types array and returns the method name.
+QByteArray QMetaObjectPrivate::decodeMethodSignature(
+ const char *signature, QArgumentTypeArray &types)
+{
+ const char *lparens = strchr(signature, '(');
+ if (!lparens)
+ return QByteArray();
+ const char *rparens = strchr(lparens + 1, ')');
+ if (!rparens || *(rparens+1))
+ return QByteArray();
+ int nameLength = lparens - signature;
+ argumentTypesFromString(lparens + 1, rparens, types);
+ return QByteArray::fromRawData(signature, nameLength);
+}
+
/*!
Finds \a signal and returns its index; otherwise returns -1.
@@ -636,10 +804,17 @@ int QMetaObject::indexOfMethod(const char *method) const
int QMetaObject::indexOfSignal(const char *signal) const
{
const QMetaObject *m = this;
- int i = QMetaObjectPrivate::indexOfSignalRelative(&m, signal, false);
- if (i < 0) {
- m = this;
- i = QMetaObjectPrivate::indexOfSignalRelative(&m, signal, true);
+ int i;
+ if (priv(m->d.data)->revision >= 7) {
+ QArgumentTypeArray types;
+ QByteArray name = QMetaObjectPrivate::decodeMethodSignature(signal, types);
+ i = QMetaObjectPrivate::indexOfSignalRelative(&m, name, types.size(), types.constData());
+ } else {
+ i = QMetaObjectPrivate::indexOfSignalRelative(&m, signal, false);
+ if (i < 0) {
+ m = this;
+ i = QMetaObjectPrivate::indexOfSignalRelative(&m, signal, true);
+ }
}
if (i >= 0)
i += m->methodOffset();
@@ -647,6 +822,7 @@ int QMetaObject::indexOfSignal(const char *signal) const
}
/*! \internal
+ \obsolete
Same as QMetaObject::indexOfSignal, but the result is the local offset to the base object.
\a baseObject will be adjusted to the enclosing QMetaObject, or 0 if the signal is not found
@@ -668,6 +844,31 @@ int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject,
return i;
}
+/*! \internal
+ Same as QMetaObject::indexOfSignal, but the result is the local offset to the base object.
+
+ \a baseObject will be adjusted to the enclosing QMetaObject, or 0 if the signal is not found
+*/
+int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject,
+ const QByteArray &name, int argc,
+ const QArgumentType *types)
+{
+ int i = indexOfMethodRelative<MethodSignal>(baseObject, name, argc, types);
+#ifndef QT_NO_DEBUG
+ const QMetaObject *m = *baseObject;
+ if (i >= 0 && m && m->d.superdata) {
+ int conflict = indexOfMethod(m->d.superdata, name, argc, types);
+ if (conflict >= 0) {
+ QMetaMethod conflictMethod = m->d.superdata->method(conflict);
+ qWarning("QMetaObject::indexOfSignal: signal %s from %s redefined in %s",
+ conflictMethod.methodSignature().constData(),
+ rawStringData(m->d.superdata, 0), rawStringData(m, 0));
+ }
+ }
+ #endif
+ return i;
+}
+
/*!
Finds \a slot and returns its index; otherwise returns -1.
@@ -679,9 +880,16 @@ int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject,
int QMetaObject::indexOfSlot(const char *slot) const
{
const QMetaObject *m = this;
- int i = QMetaObjectPrivate::indexOfSlotRelative(&m, slot, false);
- if (i < 0)
- i = QMetaObjectPrivate::indexOfSlotRelative(&m, slot, true);
+ int i;
+ if (priv(m->d.data)->revision >= 7) {
+ QArgumentTypeArray types;
+ QByteArray name = QMetaObjectPrivate::decodeMethodSignature(slot, types);
+ i = QMetaObjectPrivate::indexOfSlotRelative(&m, name, types.size(), types.constData());
+ } else {
+ i = QMetaObjectPrivate::indexOfSlotRelative(&m, slot, false);
+ if (i < 0)
+ i = QMetaObjectPrivate::indexOfSlotRelative(&m, slot, true);
+ }
if (i >= 0)
i += m->methodOffset();
return i;
@@ -695,6 +903,104 @@ int QMetaObjectPrivate::indexOfSlotRelative(const QMetaObject **m,
return indexOfMethodRelative<MethodSlot>(m, slot, normalizeStringData);
}
+// same as indexOfSignalRelative but for slots.
+int QMetaObjectPrivate::indexOfSlotRelative(const QMetaObject **m,
+ const QByteArray &name, int argc,
+ const QArgumentType *types)
+{
+ return indexOfMethodRelative<MethodSlot>(m, name, argc, types);
+}
+
+int QMetaObjectPrivate::indexOfSignal(const QMetaObject *m, const QByteArray &name,
+ int argc, const QArgumentType *types)
+{
+ int i = indexOfSignalRelative(&m, name, argc, types);
+ if (i >= 0)
+ i += m->methodOffset();
+ return i;
+}
+
+int QMetaObjectPrivate::indexOfSlot(const QMetaObject *m, const QByteArray &name,
+ int argc, const QArgumentType *types)
+{
+ int i = indexOfSlotRelative(&m, name, argc, types);
+ if (i >= 0)
+ i += m->methodOffset();
+ return i;
+}
+
+int QMetaObjectPrivate::indexOfMethod(const QMetaObject *m, const QByteArray &name,
+ int argc, const QArgumentType *types)
+{
+ int i = indexOfMethodRelative<0>(&m, name, argc, types);
+ if (i >= 0)
+ i += m->methodOffset();
+ return i;
+}
+
+int QMetaObjectPrivate::indexOfConstructor(const QMetaObject *m, const QByteArray &name,
+ int argc, const QArgumentType *types)
+{
+ for (int i = priv(m->d.data)->constructorCount-1; i >= 0; --i) {
+ int handle = priv(m->d.data)->constructorData + 5*i;
+ if (methodMatch(m, handle, name, argc, types))
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ \internal
+
+ Returns true if the \a signalTypes and \a methodTypes are
+ compatible; otherwise returns false.
+*/
+bool QMetaObjectPrivate::checkConnectArgs(int signalArgc, const QArgumentType *signalTypes,
+ int methodArgc, const QArgumentType *methodTypes)
+{
+ if (signalArgc < methodArgc)
+ return false;
+ for (int i = 0; i < methodArgc; ++i) {
+ if (signalTypes[i] != methodTypes[i])
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \internal
+
+ Returns true if the \a signal and \a method arguments are
+ compatible; otherwise returns false.
+*/
+bool QMetaObjectPrivate::checkConnectArgs(const QMetaMethodPrivate *signal,
+ const QMetaMethodPrivate *method)
+{
+ if (signal->methodType() != QMetaMethod::Signal)
+ return false;
+ if (signal->parameterCount() < method->parameterCount())
+ return false;
+ const QMetaObject *smeta = signal->enclosingMetaObject();
+ const QMetaObject *rmeta = method->enclosingMetaObject();
+ for (int i = 0; i < method->parameterCount(); ++i) {
+ uint sourceTypeInfo = signal->parameterTypeInfo(i);
+ uint targetTypeInfo = method->parameterTypeInfo(i);
+ if ((sourceTypeInfo & IsUnresolvedType)
+ || (targetTypeInfo & IsUnresolvedType)) {
+ QByteArray sourceName = typeNameFromTypeInfo(smeta, sourceTypeInfo);
+ QByteArray targetName = typeNameFromTypeInfo(rmeta, targetTypeInfo);
+ if (sourceName != targetName)
+ return false;
+ } else {
+ int sourceType = typeFromTypeInfo(smeta, sourceTypeInfo);
+ int targetType = typeFromTypeInfo(rmeta, targetTypeInfo);
+ if (sourceType != targetType)
+ return false;
+ }
+ }
+ return true;
+}
+
static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, const char *name)
{
while (self) {
@@ -872,12 +1178,16 @@ QMetaProperty QMetaObject::property(int index) const
if (i >= 0 && i < priv(d.data)->propertyCount) {
int handle = priv(d.data)->propertyData + 3*i;
int flags = d.data[handle + 2];
- const char *type = rawStringData(this, d.data[handle + 1]);
result.mobj = this;
result.handle = handle;
result.idx = i;
if (flags & EnumOrFlag) {
+ const char *type;
+ if (priv(d.data)->revision >= 7)
+ type = rawTypeNameFromTypeInfo(this, d.data[handle + 1]);
+ else
+ type = legacyString(this, d.data[handle + 1]);
result.menum = enumerator(indexOfEnumerator(type));
if (!result.menum.isValid()) {
const char *enum_name = type;
@@ -977,6 +1287,21 @@ bool QMetaObject::checkConnectArgs(const char *signal, const char *method)
return false;
}
+/*!
+ \since 5.0
+ \overload
+
+ Returns true if the \a signal and \a method arguments are
+ compatible; otherwise returns false.
+*/
+bool QMetaObject::checkConnectArgs(const QMetaMethod &signal,
+ const QMetaMethod &method)
+{
+ return QMetaObjectPrivate::checkConnectArgs(
+ QMetaMethodPrivate::get(&signal),
+ QMetaMethodPrivate::get(&method));
+}
+
static void qRemoveWhitespace(const char *s, char *d)
{
char last = 0;
@@ -1318,6 +1643,120 @@ bool QMetaObject::invokeMethod(QObject *obj,
\internal
*/
+QByteArray QMetaMethodPrivate::signature() const
+{
+ Q_ASSERT(priv(mobj->d.data)->revision >= 7);
+ QByteArray result;
+ result.reserve(256);
+ result += name();
+ result += '(';
+ QList<QByteArray> argTypes = parameterTypes();
+ for (int i = 0; i < argTypes.size(); ++i) {
+ if (i)
+ result += ',';
+ result += argTypes.at(i);
+ }
+ result += ')';
+ return result;
+}
+
+QByteArray QMetaMethodPrivate::name() const
+{
+ Q_ASSERT(priv(mobj->d.data)->revision >= 7);
+ return toByteArray(stringData(mobj, mobj->d.data[handle]));
+}
+
+int QMetaMethodPrivate::typesDataIndex() const
+{
+ Q_ASSERT(priv(mobj->d.data)->revision >= 7);
+ return mobj->d.data[handle + 2];
+}
+
+const char *QMetaMethodPrivate::rawReturnTypeName() const
+{
+ Q_ASSERT(priv(mobj->d.data)->revision >= 7);
+ uint typeInfo = mobj->d.data[typesDataIndex()];
+ if (typeInfo & IsUnresolvedType)
+ return rawStringData(mobj, typeInfo & TypeNameIndexMask);
+ else {
+ if (typeInfo == QMetaType::Void) {
+ // QMetaMethod::typeName() is documented to return an empty string
+ // if the return type is void, but QMetaType::typeName() returns
+ // "void".
+ return "";
+ }
+ return QMetaType::typeName(typeInfo);
+ }
+}
+
+int QMetaMethodPrivate::returnType() const
+{
+ return parameterType(-1);
+}
+
+int QMetaMethodPrivate::parameterCount() const
+{
+ Q_ASSERT(priv(mobj->d.data)->revision >= 7);
+ return mobj->d.data[handle + 1];
+}
+
+int QMetaMethodPrivate::parametersDataIndex() const
+{
+ Q_ASSERT(priv(mobj->d.data)->revision >= 7);
+ return typesDataIndex() + 1;
+}
+
+uint QMetaMethodPrivate::parameterTypeInfo(int index) const
+{
+ Q_ASSERT(priv(mobj->d.data)->revision >= 7);
+ return mobj->d.data[parametersDataIndex() + index];
+}
+
+int QMetaMethodPrivate::parameterType(int index) const
+{
+ Q_ASSERT(priv(mobj->d.data)->revision >= 7);
+ return typeFromTypeInfo(mobj, parameterTypeInfo(index));
+}
+
+void QMetaMethodPrivate::getParameterTypes(int *types) const
+{
+ Q_ASSERT(priv(mobj->d.data)->revision >= 7);
+ int dataIndex = parametersDataIndex();
+ int argc = parameterCount();
+ for (int i = 0; i < argc; ++i) {
+ int id = typeFromTypeInfo(mobj, mobj->d.data[dataIndex++]);
+ *(types++) = id;
+ }
+}
+
+QList<QByteArray> QMetaMethodPrivate::parameterTypes() const
+{
+ Q_ASSERT(priv(mobj->d.data)->revision >= 7);
+ QList<QByteArray> list;
+ int argc = parameterCount();
+ int paramsIndex = parametersDataIndex();
+ for (int i = 0; i < argc; ++i)
+ list += typeNameFromTypeInfo(mobj, mobj->d.data[paramsIndex + i]);
+ return list;
+}
+
+QList<QByteArray> QMetaMethodPrivate::parameterNames() const
+{
+ Q_ASSERT(priv(mobj->d.data)->revision >= 7);
+ QList<QByteArray> list;
+ int argc = parameterCount();
+ int namesIndex = parametersDataIndex() + argc;
+ for (int i = 0; i < argc; ++i)
+ list += toByteArray(stringData(mobj, mobj->d.data[namesIndex + i]));
+ return list;
+}
+
+QByteArray QMetaMethodPrivate::tag() const
+{
+ Q_ASSERT(priv(mobj->d.data)->revision >= 7);
+ return toByteArray(stringData(mobj, mobj->d.data[handle + 3]));
+}
+
/*!
\since 5.0
@@ -1330,7 +1769,92 @@ QByteArray QMetaMethod::methodSignature() const
{
if (!mobj)
return QByteArray();
- return toByteArray(stringData(mobj, mobj->d.data[handle]));
+ if (priv(mobj->d.data)->revision >= 7) {
+ return QMetaMethodPrivate::get(this)->signature();
+ } else {
+ const char *sig = rawStringData(mobj, mobj->d.data[handle]);
+ return QByteArray::fromRawData(sig, qstrlen(sig));
+ }
+}
+
+/*!
+ \since 5.0
+
+ Returns the name of this method.
+
+ \sa methodSignature(), parameterCount()
+*/
+QByteArray QMetaMethod::name() const
+{
+ if (!mobj)
+ return QByteArray();
+ return QMetaMethodPrivate::get(this)->name();
+}
+
+/*!
+ \since 5.0
+
+ Returns the return type of this method.
+
+ The return value is one of the types that are registered
+ with QMetaType, or 0 if the type is not registered.
+
+ \sa parameterType(), QMetaType, typeName()
+*/
+int QMetaMethod::returnType() const
+ {
+ if (!mobj)
+ return 0;
+ return QMetaMethodPrivate::get(this)->returnType();
+}
+
+/*!
+ \since 5.0
+
+ Returns the number of parameters of this method.
+
+ \sa parameterType(), parameterNames()
+*/
+int QMetaMethod::parameterCount() const
+{
+ if (!mobj)
+ return 0;
+ return QMetaMethodPrivate::get(this)->parameterCount();
+}
+
+/*!
+ \since 5.0
+
+ Returns the type of the parameter at the given \a index.
+
+ The return value is one of the types that are registered
+ with QMetaType, or 0 if the type is not registered.
+
+ \sa parameterCount(), returnType(), QMetaType
+*/
+int QMetaMethod::parameterType(int index) const
+{
+ if (!mobj || index < 0)
+ return 0;
+ if (index >= QMetaMethodPrivate::get(this)->parameterCount())
+ return 0;
+ return QMetaMethodPrivate::get(this)->parameterType(index);
+}
+
+/*!
+ \since 5.0
+ \internal
+
+ Gets the parameter \a types of this method. The storage
+ for \a types must be able to hold parameterCount() items.
+
+ \sa parameterCount(), returnType(), parameterType()
+*/
+void QMetaMethod::getParameterTypes(int *types) const
+{
+ if (!mobj)
+ return;
+ QMetaMethodPrivate::get(this)->getParameterTypes(types);
}
/*!
@@ -1342,8 +1866,12 @@ QList<QByteArray> QMetaMethod::parameterTypes() const
{
if (!mobj)
return QList<QByteArray>();
- return QMetaObjectPrivate::parameterTypeNamesFromSignature(
- rawStringData(mobj, mobj->d.data[handle]));
+ if (priv(mobj->d.data)->revision >= 7) {
+ return QMetaMethodPrivate::get(this)->parameterTypes();
+ } else {
+ return QMetaObjectPrivate::parameterTypeNamesFromSignature(
+ legacyString(mobj, mobj->d.data[handle]));
+ }
}
/*!
@@ -1356,36 +1884,43 @@ QList<QByteArray> QMetaMethod::parameterNames() const
QList<QByteArray> list;
if (!mobj)
return list;
- const char *names = rawStringData(mobj, mobj->d.data[handle + 1]);
- if (*names == 0) {
- // do we have one or zero arguments?
- const char *signature = rawStringData(mobj, mobj->d.data[handle]);
- while (*signature && *signature != '(')
- ++signature;
- if (*++signature != ')')
- list += QByteArray();
+ if (priv(mobj->d.data)->revision >= 7) {
+ return QMetaMethodPrivate::get(this)->parameterNames();
} else {
- --names;
- do {
- const char *begin = ++names;
- while (*names && *names != ',')
- ++names;
- list += QByteArray(begin, names - begin);
- } while (*names);
+ const char *names = rawStringData(mobj, mobj->d.data[handle + 1]);
+ if (*names == 0) {
+ // do we have one or zero arguments?
+ const char *signature = rawStringData(mobj, mobj->d.data[handle]);
+ while (*signature && *signature != '(')
+ ++signature;
+ if (*++signature != ')')
+ list += QByteArray();
+ } else {
+ --names;
+ do {
+ const char *begin = ++names;
+ while (*names && *names != ',')
+ ++names;
+ list += QByteArray(begin, names - begin);
+ } while (*names);
+ }
+ return list;
}
- return list;
}
/*!
- Returns the return type of this method, or an empty string if the
+ Returns the return type name of this method, or an empty string if the
return type is \e void.
*/
const char *QMetaMethod::typeName() const
{
if (!mobj)
return 0;
- return rawStringData(mobj, mobj->d.data[handle + 2]);
+ if (priv(mobj->d.data)->revision >= 7)
+ return QMetaMethodPrivate::get(this)->rawReturnTypeName();
+ else
+ return legacyString(mobj, mobj->d.data[handle + 2]);
}
/*!
@@ -1422,7 +1957,10 @@ const char *QMetaMethod::tag() const
{
if (!mobj)
return 0;
- return rawStringData(mobj, mobj->d.data[handle + 3]);
+ if (priv(mobj->d.data)->revision >= 7)
+ return QMetaMethodPrivate::get(this)->tag().constData();
+ else
+ return legacyString(mobj, mobj->d.data[handle + 3]);
}
@@ -1623,7 +2161,9 @@ bool QMetaMethod::invoke(QObject *object,
break;
}
int metaMethodArgumentCount = 0;
- {
+ if (priv(mobj->d.data)->revision >= 7) {
+ metaMethodArgumentCount = QMetaMethodPrivate::get(this)->parameterCount();
+ } else {
// based on QMetaObject::parameterNames()
const char *names = rawStringData(mobj, mobj->d.data[handle + 1]);
if (*names == 0) {
@@ -2058,7 +2598,10 @@ QByteArray QMetaEnum::valueToKeys(int value) const
v = v & ~k;
if (!keys.isEmpty())
keys += '|';
- keys += rawStringData(mobj, mobj->d.data[data + 2*i]);
+ if (priv(mobj->d.data)->revision >= 7)
+ keys += toByteArray(stringData(mobj, mobj->d.data[data + 2*i]));
+ else
+ keys += legacyString(mobj, mobj->d.data[data + 2*i]);
}
}
return keys;
@@ -2150,7 +2693,10 @@ const char *QMetaProperty::typeName() const
if (!mobj)
return 0;
int handle = priv(mobj->d.data)->propertyData + 3*idx;
- return rawStringData(mobj, mobj->d.data[handle + 1]);
+ if (priv(mobj->d.data)->revision >= 7)
+ return rawTypeNameFromTypeInfo(mobj, mobj->d.data[handle + 1]);
+ else
+ return legacyString(mobj, mobj->d.data[handle + 1]);
}
/*!
@@ -2164,9 +2710,16 @@ QVariant::Type QMetaProperty::type() const
if (!mobj)
return QVariant::Invalid;
int handle = priv(mobj->d.data)->propertyData + 3*idx;
- uint flags = mobj->d.data[handle + 2];
- uint type = flags >> 24;
+ uint type;
+ if (priv(mobj->d.data)->revision >= 7) {
+ type = typeFromTypeInfo(mobj, mobj->d.data[handle + 1]);
+ if (type >= QMetaType::User)
+ return QVariant::UserType;
+ } else {
+ uint flags = mobj->d.data[handle + 2];
+ type = flags >> 24;
+ }
if (type)
return QVariant::Type(type);
if (isEnumType()) {
@@ -2194,11 +2747,22 @@ QVariant::Type QMetaProperty::type() const
*/
int QMetaProperty::userType() const
{
- QVariant::Type tp = type();
- if (tp != QVariant::UserType)
- return tp;
+ if (!mobj)
+ return 0;
+ if (priv(mobj->d.data)->revision >= 7) {
+ int handle = priv(mobj->d.data)->propertyData + 3*idx;
+ int type = typeFromTypeInfo(mobj, mobj->d.data[handle + 1]);
+ if (type)
+ return type;
+ } else {
+ QVariant::Type tp = type();
+ if (tp != QVariant::UserType)
+ return tp;
+ }
if (isEnumType()) {
int enumMetaTypeId = QMetaType::type(qualifiedName(menum));
+ if (enumMetaTypeId == 0)
+ return QVariant::Int; // Match behavior of QMetaType::type()
return enumMetaTypeId;
}
return QMetaType::type(typeName());
@@ -2298,13 +2862,25 @@ QVariant QMetaProperty::read(const QObject *object) const
t = enumMetaTypeId;
} else {
int handle = priv(mobj->d.data)->propertyData + 3*idx;
- uint flags = mobj->d.data[handle + 2];
- const char *typeName = rawStringData(mobj, mobj->d.data[handle + 1]);
- t = (flags >> 24);
- if (t == QVariant::Invalid)
- t = QMetaType::type(typeName);
- if (t == QVariant::Invalid)
- t = QVariant::nameToType(typeName);
+ const char *typeName = 0;
+ if (priv(mobj->d.data)->revision >= 7) {
+ uint typeInfo = mobj->d.data[handle + 1];
+ if (!(typeInfo & IsUnresolvedType))
+ t = typeInfo;
+ else {
+ typeName = rawStringData(mobj, typeInfo & TypeNameIndexMask);
+ t = QMetaType::type(typeName);
+ }
+ } else {
+ uint flags = mobj->d.data[handle + 2];
+ t = (flags >> 24);
+ if (t == QVariant::Invalid) {
+ typeName = legacyString(mobj, mobj->d.data[handle + 1]);
+ t = QMetaType::type(typeName);
+ if (t == QVariant::Invalid)
+ t = QVariant::nameToType(typeName);
+ }
+ }
if (t == QVariant::Invalid) {
qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property '%s::%s'", typeName, mobj->className(), name());
return QVariant();
@@ -2367,8 +2943,20 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const
v.convert(QVariant::Int);
} else {
int handle = priv(mobj->d.data)->propertyData + 3*idx;
- uint flags = mobj->d.data[handle + 2];
- t = flags >> 24;
+ const char *typeName = 0;
+ if (priv(mobj->d.data)->revision >= 7) {
+ uint typeInfo = mobj->d.data[handle + 1];
+ if (!(typeInfo & IsUnresolvedType))
+ t = typeInfo;
+ else {
+ typeName = rawStringData(mobj, typeInfo & TypeNameIndexMask);
+ t = QMetaType::type(typeName);
+ }
+ } else {
+ uint flags = mobj->d.data[handle + 2];
+ t = flags >> 24;
+ typeName = legacyString(mobj, mobj->d.data[handle + 1]);
+ }
if (t == QVariant::Invalid) {
const char *typeName = rawStringData(mobj, mobj->d.data[handle + 1]);
const char *vtypeName = value.typeName();