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>
This commit is contained in:
parent
f95181c7bb
commit
2632f76b42
@ -1073,33 +1073,78 @@ int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name)
|
|||||||
class MetaStringTable
|
class MetaStringTable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef QHash<QByteArray, int> Entries; // string --> offset mapping
|
MetaStringTable() : m_index(0) {}
|
||||||
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_offset(0) {}
|
int enter(const QByteArray &value);
|
||||||
|
|
||||||
int enter(const QByteArray &value)
|
static int preferredAlignment();
|
||||||
{
|
int blobSize() const;
|
||||||
Entries::iterator it = m_entries.find(value);
|
void writeBlob(char *out);
|
||||||
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; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef QHash<QByteArray, int> Entries; // string --> index mapping
|
||||||
Entries m_entries;
|
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.
|
// Build the parameter array string for a method.
|
||||||
static QByteArray buildParameterNames
|
static QByteArray buildParameterNames
|
||||||
(const QByteArray& signature, const QList<QByteArray>& parameterNames)
|
(const QByteArray& signature, const QList<QByteArray>& parameterNames)
|
||||||
@ -1182,7 +1227,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (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->revision = QMetaObjectPrivate::OutputRevision;
|
||||||
pmeta->flags = d->flags;
|
pmeta->flags = d->flags;
|
||||||
pmeta->className = 0; // Class name is always the first string.
|
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.
|
// Find the start of the data and string tables.
|
||||||
int *data = reinterpret_cast<int *>(pmeta);
|
int *data = reinterpret_cast<int *>(pmeta);
|
||||||
size += dataIndex * sizeof(int);
|
size += dataIndex * sizeof(int);
|
||||||
|
ALIGN(size, void *);
|
||||||
char *str = reinterpret_cast<char *>(buf + size);
|
char *str = reinterpret_cast<char *>(buf + size);
|
||||||
if (buf) {
|
if (buf) {
|
||||||
if (relocatable) {
|
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);
|
meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize);
|
||||||
} else {
|
} else {
|
||||||
meta->d.stringdata = str;
|
meta->d.stringdata = reinterpret_cast<const QByteArrayData *>(str);
|
||||||
meta->d.data = reinterpret_cast<uint *>(data);
|
meta->d.data = reinterpret_cast<uint *>(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1390,16 +1436,10 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
dataIndex += 5;
|
dataIndex += 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
size += strings.arraySize();
|
size += strings.blobSize();
|
||||||
|
|
||||||
if (buf) {
|
if (buf)
|
||||||
// Write strings to string data array.
|
strings.writeBlob(str);
|
||||||
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';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output the zero terminator in the data array.
|
// Output the zero terminator in the data array.
|
||||||
if (buf)
|
if (buf)
|
||||||
@ -1508,7 +1548,7 @@ void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output,
|
|||||||
quintptr dataOffset = (quintptr)dataMo->d.data;
|
quintptr dataOffset = (quintptr)dataMo->d.data;
|
||||||
|
|
||||||
output->d.superdata = superclass;
|
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.data = reinterpret_cast<const uint *>(buf + dataOffset);
|
||||||
output->d.extradata = 0;
|
output->d.extradata = 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user