summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp52
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder_p.h5
-rw-r--r--src/dbus/qdbusmetaobject.cpp3
-rw-r--r--tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp16
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"