summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2012-02-18 20:37:50 +0100
committerQt by Nokia <qt-info@nokia.com>2012-02-29 12:50:14 +0100
commit2632f76b421d50cb2135c796a379293007583a1d (patch)
treeabbfe07a0e6876f048164ffc4e22f7d99c83603c /src/corelib
parentf95181c7bb340744a0ce172e8c5a8fcdc2543297 (diff)
Port QMetaObjectBuilder to new meta-object string data format
Bring QMetaObjectBuilder up-to-date with latest moc changes (generating the string table as an array of QByteArrayData). Change-Id: I5b2f63daa687e9bc8eab10a53fab2d72e4529ea2 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp106
1 files changed, 73 insertions, 33 deletions
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp
index 82c74a34f3..3aad49b2f9 100644
--- a/src/corelib/kernel/qmetaobjectbuilder.cpp
+++ b/src/corelib/kernel/qmetaobjectbuilder.cpp
@@ -1073,33 +1073,78 @@ int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name)
class MetaStringTable
{
public:
- typedef QHash<QByteArray, int> Entries; // string --> offset mapping
- typedef Entries::const_iterator const_iterator;
- Entries::const_iterator constBegin() const
- { return m_entries.constBegin(); }
- Entries::const_iterator constEnd() const
- { return m_entries.constEnd(); }
+ MetaStringTable() : m_index(0) {}
- MetaStringTable() : m_offset(0) {}
+ int enter(const QByteArray &value);
- int enter(const QByteArray &value)
- {
- Entries::iterator it = m_entries.find(value);
- if (it != m_entries.end())
- return it.value();
- int pos = m_offset;
- m_entries.insert(value, pos);
- m_offset += value.size() + 1;
- return pos;
- }
-
- int arraySize() const { return m_offset; }
+ static int preferredAlignment();
+ int blobSize() const;
+ void writeBlob(char *out);
private:
+ typedef QHash<QByteArray, int> Entries; // string --> index mapping
Entries m_entries;
- int m_offset;
+ int m_index;
};
+// Enters the given value into the string table (if it hasn't already been
+// entered). Returns the index of the string.
+int MetaStringTable::enter(const QByteArray &value)
+{
+ Entries::iterator it = m_entries.find(value);
+ if (it != m_entries.end())
+ return it.value();
+ int pos = m_index;
+ m_entries.insert(value, pos);
+ ++m_index;
+ return pos;
+}
+
+int MetaStringTable::preferredAlignment()
+{
+#ifdef Q_ALIGNOF
+ return Q_ALIGNOF(QByteArrayData);
+#else
+ return sizeof(void *);
+#endif
+}
+
+// Returns the size (in bytes) required for serializing this string table.
+int MetaStringTable::blobSize() const
+{
+ int size = m_entries.size() * sizeof(QByteArrayData);
+ Entries::const_iterator it;
+ for (it = m_entries.constBegin(); it != m_entries.constEnd(); ++it)
+ size += it.key().size() + 1;
+ return size;
+}
+
+// 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 MetaStringTable::writeBlob(char *out)
+{
+ 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_REFCOUNT_INITIALIZE_STATIC, size, 0, 0, offset };
+
+ memcpy(out + i * sizeof(QByteArrayData), &data, sizeof(QByteArrayData));
+
+ memcpy(out + offsetOfStringdataMember + stringdataOffset, str.constData(), size);
+ out[offsetOfStringdataMember + stringdataOffset + size] = '\0';
+
+ stringdataOffset += size + 1;
+ }
+}
+
// Build the parameter array string for a method.
static QByteArray buildParameterNames
(const QByteArray& signature, const QList<QByteArray>& parameterNames)
@@ -1182,7 +1227,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
}
}
if (buf) {
- Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 6, "QMetaObjectBuilder should generate the same version as moc");
+ Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 7, "QMetaObjectBuilder should generate the same version as moc");
pmeta->revision = QMetaObjectPrivate::OutputRevision;
pmeta->flags = d->flags;
pmeta->className = 0; // Class name is always the first string.
@@ -1240,13 +1285,14 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
// Find the start of the data and string tables.
int *data = reinterpret_cast<int *>(pmeta);
size += dataIndex * sizeof(int);
+ ALIGN(size, void *);
char *str = reinterpret_cast<char *>(buf + size);
if (buf) {
if (relocatable) {
- meta->d.stringdata = reinterpret_cast<const char *>((quintptr)size);
+ meta->d.stringdata = reinterpret_cast<const QByteArrayData *>((quintptr)size);
meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize);
} else {
- meta->d.stringdata = str;
+ meta->d.stringdata = reinterpret_cast<const QByteArrayData *>(str);
meta->d.data = reinterpret_cast<uint *>(data);
}
}
@@ -1390,16 +1436,10 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
dataIndex += 5;
}
- size += strings.arraySize();
+ size += strings.blobSize();
- if (buf) {
- // Write strings to string data array.
- MetaStringTable::const_iterator it;
- for (it = strings.constBegin(); it != strings.constEnd(); ++it) {
- memcpy(str + it.value(), it.key().constData(), it.key().size());
- str[it.value() + it.key().size()] = '\0';
- }
- }
+ if (buf)
+ strings.writeBlob(str);
// Output the zero terminator in the data array.
if (buf)
@@ -1508,7 +1548,7 @@ void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output,
quintptr dataOffset = (quintptr)dataMo->d.data;
output->d.superdata = superclass;
- output->d.stringdata = buf + stringdataOffset;
+ output->d.stringdata = reinterpret_cast<const QByteArrayData *>(buf + stringdataOffset);
output->d.data = reinterpret_cast<const uint *>(buf + dataOffset);
output->d.extradata = 0;
}