diff options
-rw-r--r-- | src/corelib/kernel/qmetaobjectbuilder.cpp | 52 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobjectbuilder_p.h | 5 | ||||
-rw-r--r-- | src/dbus/qdbusmetaobject.cpp | 3 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp | 16 |
4 files changed, 56 insertions, 20 deletions
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index 4518d702cd..11ab39af1a 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -1075,8 +1075,14 @@ int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name) \brief The QMetaStringTable class can generate a meta-object string table at runtime. */ -QMetaStringTable::QMetaStringTable() - : m_index(0) {} +QMetaStringTable::QMetaStringTable(const QByteArray &className) + : m_index(0) + , m_className(className) +{ + const int index = enter(m_className); + Q_ASSERT(index == 0); + Q_UNUSED(index); +} // Enters the given value into the string table (if it hasn't already been // entered). Returns the index of the string. @@ -1106,30 +1112,45 @@ int QMetaStringTable::blobSize() const return size; } +static void writeString(char *out, int i, const QByteArray &str, + const int offsetOfStringdataMember, int &stringdataOffset) +{ + int size = str.size(); + qptrdiff offset = offsetOfStringdataMember + stringdataOffset + - i * sizeof(QByteArrayData); + const QByteArrayData data = + Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset); + + memcpy(out + i * sizeof(QByteArrayData), &data, sizeof(QByteArrayData)); + + memcpy(out + offsetOfStringdataMember + stringdataOffset, str.constData(), size); + out[offsetOfStringdataMember + stringdataOffset + size] = '\0'; + + stringdataOffset += size + 1; +} + // Writes strings to string data struct. // The struct consists of an array of QByteArrayData, followed by a char array // containing the actual strings. This format must match the one produced by // moc (see generator.cpp). -void QMetaStringTable::writeBlob(char *out) +void QMetaStringTable::writeBlob(char *out) const { Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (preferredAlignment()-1))); int offsetOfStringdataMember = m_entries.size() * sizeof(QByteArrayData); int stringdataOffset = 0; - for (int i = 0; i < m_entries.size(); ++i) { - const QByteArray &str = m_entries.key(i); - int size = str.size(); - qptrdiff offset = offsetOfStringdataMember + stringdataOffset - - i * sizeof(QByteArrayData); - const QByteArrayData data = - Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset); - memcpy(out + i * sizeof(QByteArrayData), &data, sizeof(QByteArrayData)); + // qt_metacast expects the first string in the string table to be the class name. + writeString(out, /*index*/0, m_className, offsetOfStringdataMember, stringdataOffset); - memcpy(out + offsetOfStringdataMember + stringdataOffset, str.constData(), size); - out[offsetOfStringdataMember + stringdataOffset + size] = '\0'; + for (Entries::ConstIterator it = m_entries.constBegin(), end = m_entries.constEnd(); + it != end; ++it) { + const int i = it.value(); + if (i == 0) + continue; + const QByteArray &str = it.key(); - stringdataOffset += size + 1; + writeString(out, i, str, offsetOfStringdataMember, stringdataOffset); } } @@ -1270,8 +1291,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, // Reset the current data position to just past the QMetaObjectPrivate. dataIndex = MetaObjectPrivateFieldCount; - QMetaStringTable strings; - strings.enter(d->className); + QMetaStringTable strings(d->className); // Output the class infos, Q_ASSERT(!buf || dataIndex == pmeta->classInfoData); diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h index f79ce2f2f1..110aaf9ce2 100644 --- a/src/corelib/kernel/qmetaobjectbuilder_p.h +++ b/src/corelib/kernel/qmetaobjectbuilder_p.h @@ -323,18 +323,19 @@ private: class Q_CORE_EXPORT QMetaStringTable { public: - QMetaStringTable(); + QMetaStringTable(const QByteArray &className); int enter(const QByteArray &value); static int preferredAlignment(); int blobSize() const; - void writeBlob(char *out); + void writeBlob(char *out) const; private: typedef QHash<QByteArray, int> Entries; // string --> index mapping Entries m_entries; int m_index; + QByteArray m_className; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::AddMembers) diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp index 51c0b27668..13c538bb59 100644 --- a/src/dbus/qdbusmetaobject.cpp +++ b/src/dbus/qdbusmetaobject.cpp @@ -445,8 +445,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) data_size += 2 + mm.inputTypes.count() + mm.outputTypes.count(); idata.resize(data_size + 1); - QMetaStringTable strings; - strings.enter(className.toLatin1()); + QMetaStringTable strings(className.toLatin1()); int offset = header->methodData; int parametersOffset = offset + header->methodCount * 5; diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 8f6bd50cca..5cf3e6d97c 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -75,6 +75,8 @@ private slots: void usage_connect(); void usage_templateConnect(); + void classNameFirstInStringData(); + private: static bool checkForSideEffects (const QMetaObjectBuilder& builder, @@ -1694,6 +1696,20 @@ void tst_QMetaObjectBuilder::usage_templateConnect() QVERIFY(!con); } +void tst_QMetaObjectBuilder::classNameFirstInStringData() +{ + QMetaObjectBuilder builder; + builder.addMetaObject(&SomethingOfEverything::staticMetaObject); + builder.setClassName(QByteArrayLiteral("TestClass")); + QMetaObject *mo = builder.toMetaObject(); + + QByteArrayDataPtr header; + header.ptr = const_cast<QByteArrayData*>(mo->d.stringdata); + QCOMPARE(QByteArray(header), QByteArrayLiteral("TestClass")); + + free(mo); +} + QTEST_MAIN(tst_QMetaObjectBuilder) #include "tst_qmetaobjectbuilder.moc" |