diff options
author | Kent Hansen <kent.hansen@nokia.com> | 2012-02-11 07:02:13 +0100 |
---|---|---|
committer | Jędrzej Nowacki <jedrzej.nowacki@digia.com> | 2014-10-31 12:17:57 +0100 |
commit | 0678d7c43c1658d2d2ec984be5844054031649a2 (patch) | |
tree | 4d31d02a75ab78befa8553abbe1de26a4ed3e848 | |
parent | 3de0f442b5857915f26be6600bc8e54d1af08208 (diff) |
Add QMetaType::type(QByteArray) function
QMetaType::type(const char *) requires that the string argument is
0-terminated. This new overload makes it possible to query the type
of a string with an explicit length.
In particular, QByteArrays constructed by QByteArray::fromRawData(),
for example from a substring of a normalized method signature (the
"int" part of "mySlot(int"), can now be queried without making a copy
of the string.
Also, Qt5 meta-objects represent type names as QByteArray literals,
which can be fed directly to this new QMetaType::type() overload (no
need to call strlen).
Change-Id: I60d35aa6bdc0f77e0997f98b0e30e12fd3d5e100
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 25 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 5 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 59 | ||||
-rw-r--r-- | tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp | 18 |
4 files changed, 101 insertions, 6 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 311648c33a..4540e96de6 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -801,7 +801,7 @@ static inline int qMetaTypeStaticType(const char *typeName, int length) { int i = 0; while (types[i].typeName && ((length != types[i].typeNameLength) - || strcmp(typeName, types[i].typeName))) { + || memcmp(typeName, types[i].typeName, length))) { ++i; } return types[i].type; @@ -821,7 +821,7 @@ static int qMetaTypeCustomType_unlocked(const char *typeName, int length) for (int v = 0; v < ct->count(); ++v) { const QCustomTypeInfo &customInfo = ct->at(v); if ((length == customInfo.typeName.size()) - && !strcmp(typeName, customInfo.typeName.constData())) { + && !memcmp(typeName, customInfo.typeName.constData(), length)) { if (customInfo.alias >= 0) return customInfo.alias; return v + QMetaType::User; @@ -1048,9 +1048,8 @@ bool QMetaType::isRegistered(int type) Implementation of QMetaType::type(). */ template <bool tryNormalizedType> -static inline int qMetaTypeTypeImpl(const char *typeName) +static inline int qMetaTypeTypeImpl(const char *typeName, int length) { - int length = qstrlen(typeName); if (!length) return QMetaType::UnknownType; int type = qMetaTypeStaticType(typeName, length); @@ -1080,7 +1079,7 @@ static inline int qMetaTypeTypeImpl(const char *typeName) */ int QMetaType::type(const char *typeName) { - return qMetaTypeTypeImpl</*tryNormalizedType=*/true>(typeName); + return qMetaTypeTypeImpl</*tryNormalizedType=*/true>(typeName, qstrlen(typeName)); } /*! @@ -1092,7 +1091,21 @@ int QMetaType::type(const char *typeName) */ int qMetaTypeTypeInternal(const char *typeName) { - return qMetaTypeTypeImpl</*tryNormalizedType=*/false>(typeName); + return qMetaTypeTypeImpl</*tryNormalizedType=*/false>(typeName, qstrlen(typeName)); +} + +/*! + \since 5.5 + \overload + + Returns a handle to the type called \a typeName, or 0 if there is + no such type. + + \sa isRegistered(), typeName() +*/ +int QMetaType::type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName) +{ + return qMetaTypeTypeImpl</*tryNormalizedType=*/true>(typeName.constData(), typeName.size()); } #ifndef QT_NO_DATASTREAM diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 08b2fb083a..947bf77796 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -472,6 +472,11 @@ public: static int registerTypedef(const char *typeName, int aliasId); static int registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, int aliasId); static int type(const char *typeName); +#ifndef Q_QDOC + static int type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName); +#else + static int type(const QByteArray &typeName); +#endif static const char *typeName(int type); static int sizeOf(int type); static TypeFlags typeFlags(int type); diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index a35896283a..fa328de619 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -79,6 +79,10 @@ private slots: void normalizedTypes(); void typeName_data(); void typeName(); + void type_data(); + void type(); + void type_fromSubString_data(); + void type_fromSubString(); void create_data(); void create(); void createCopy_data(); @@ -385,6 +389,61 @@ void tst_QMetaType::typeName() QCOMPARE(name.toLatin1(), QMetaObject::normalizedType(name.toLatin1().constData())); } +void tst_QMetaType::type_data() +{ + QTest::addColumn<QMetaType::Type>("aType"); + QTest::addColumn<QByteArray>("aTypeName"); + +#define TST_QMETATYPE_TYPE_DATA(MetaTypeName, MetaTypeId, RealType)\ + QTest::newRow(#RealType) << QMetaType::MetaTypeName << QByteArray( #RealType ); +#define TST_QMETATYPE_TYPE_DATA_ALIAS(MetaTypeName, MetaTypeId, AliasType, RealTypeString)\ + QTest::newRow(RealTypeString) << QMetaType::MetaTypeName << QByteArray( #AliasType ); + + QTest::newRow("empty") << QMetaType::UnknownType << QByteArray(); + + QT_FOR_EACH_STATIC_TYPE(TST_QMETATYPE_TYPE_DATA) + QT_FOR_EACH_STATIC_ALIAS_TYPE(TST_QMETATYPE_TYPE_DATA_ALIAS) + +#undef TST_QMETATYPE_TYPE_DATA +#undef TST_METATYPE_TYPE_DATA_ALIAS +} + +void tst_QMetaType::type() +{ + QFETCH(QMetaType::Type, aType); + QFETCH(QByteArray, aTypeName); + + // QMetaType::type(QByteArray) + QCOMPARE(QMetaType::type(aTypeName), int(aType)); + // QMetaType::type(const char *) + QCOMPARE(QMetaType::type(aTypeName.constData()), int(aType)); +} + +void tst_QMetaType::type_fromSubString_data() +{ + QTest::addColumn<int>("offset"); + QTest::addColumn<int>("size"); + QTest::addColumn<int>("expectedType"); + + // The test string is defined in the test function below + QTest::newRow("int") << 0 << 3 << int(QMetaType::Int); + QTest::newRow("boo") << 3 << 3 << 0; + QTest::newRow("bool") << 3 << 4 << int(QMetaType::Bool); + QTest::newRow("intbool") << 0 << 7 << 0; + QTest::newRow("QMetaType::Type") << 7 << 15 << ::qMetaTypeId<QMetaType::Type>(); + QTest::newRow("double") << 22 << 6 << int(QMetaType::Double); +} + +void tst_QMetaType::type_fromSubString() +{ + static const char *types = "intboolQMetaType::Typedoublexxx"; + QFETCH(int, offset); + QFETCH(int, size); + QFETCH(int, expectedType); + QByteArray ba = QByteArray::fromRawData(types + offset, size); + QCOMPARE(QMetaType::type(ba), expectedType); +} + #define FOR_EACH_PRIMITIVE_METATYPE(F) \ QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \ QT_FOR_EACH_STATIC_CORE_POINTER(F) \ diff --git a/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp index 9403c3fbb4..53cf26d0f1 100644 --- a/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/benchmarks/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -45,6 +45,8 @@ public: private slots: void typeBuiltin_data(); void typeBuiltin(); + void typeBuiltin_QByteArray_data(); + void typeBuiltin_QByteArray(); void typeBuiltinNotNormalized_data(); void typeBuiltinNotNormalized(); void typeCustom(); @@ -94,6 +96,7 @@ void tst_QMetaType::typeBuiltin_data() } } +// QMetaType::type(const char *) void tst_QMetaType::typeBuiltin() { QFETCH(QByteArray, typeName); @@ -104,6 +107,21 @@ void tst_QMetaType::typeBuiltin() } } +void tst_QMetaType::typeBuiltin_QByteArray_data() +{ + typeBuiltin_data(); +} + +// QMetaType::type(QByteArray) +void tst_QMetaType::typeBuiltin_QByteArray() +{ + QFETCH(QByteArray, typeName); + QBENCHMARK { + for (int i = 0; i < 100000; ++i) + QMetaType::type(typeName); + } +} + void tst_QMetaType::typeBuiltinNotNormalized_data() { QTest::addColumn<QByteArray>("typeName"); |