Store only unique strings in the QtDBus meta-object string table

Do like moc: If the string has already been entered into the table,
just return its position, don't make a new copy. This can save
space, for example, if there are several properties of the same type;
the typename only occurs once in the string table but will be
referenced by several property descriptors.

Change-Id: I63e5c73d28ba117fd00a5261d0e89f3a3d83df9a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Kent Hansen 2012-02-06 19:00:13 +01:00 committed by Qt by Nokia
parent 3d3f5f84fe
commit 016633931f

View File

@ -360,9 +360,39 @@ void QDBusMetaObjectGenerator::parseProperties()
void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
{
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_offset(0) {}
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; }
private:
Entries m_entries;
int m_offset;
};
// this code here is mostly copied from qaxbase.cpp
// with a few modifications to make it cleaner
QString className = interface;
className.replace(QLatin1Char('.'), QLatin1String("::"));
if (className.isEmpty())
@ -400,10 +430,8 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
data_size += 2 + mm.inputTypes.count() + mm.outputTypes.count();
idata.resize(data_size + 1);
char null('\0');
QByteArray stringdata = className.toLatin1();
stringdata += null;
stringdata.reserve(8192);
MetaStringTable strings;
strings.enter(className.toLatin1());
int offset = header->methodData;
int signatureOffset = header->methodDBusData;
@ -419,29 +447,15 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
// form "prototype\0parameters\0typeName\0tag\0methodname\0inputSignature\0outputSignature"
const Method &mm = it.value();
idata[offset++] = stringdata.length();
stringdata += it.key(); // prototype
stringdata += null;
idata[offset++] = stringdata.length();
stringdata += mm.parameters;
stringdata += null;
idata[offset++] = stringdata.length();
stringdata += mm.typeName;
stringdata += null;
idata[offset++] = stringdata.length();
stringdata += mm.tag;
stringdata += null;
idata[offset++] = strings.enter(it.key()); // prototype
idata[offset++] = strings.enter(mm.parameters);
idata[offset++] = strings.enter(mm.typeName);
idata[offset++] = strings.enter(mm.tag);
idata[offset++] = mm.flags;
idata[signatureOffset++] = stringdata.length();
stringdata += mm.name;
stringdata += null;
idata[signatureOffset++] = stringdata.length();
stringdata += mm.inputSignature;
stringdata += null;
idata[signatureOffset++] = stringdata.length();
stringdata += mm.outputSignature;
stringdata += null;
idata[signatureOffset++] = strings.enter(mm.name);
idata[signatureOffset++] = strings.enter(mm.inputSignature);
idata[signatureOffset++] = strings.enter(mm.outputSignature);
idata[signatureOffset++] = typeidOffset;
idata[typeidOffset++] = mm.inputTypes.count();
@ -466,25 +480,25 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
const Property &mp = it.value();
// form is "name\0typeName\0signature\0"
idata[offset++] = stringdata.length();
stringdata += it.key(); // name
stringdata += null;
idata[offset++] = stringdata.length();
stringdata += mp.typeName;
stringdata += null;
idata[offset++] = strings.enter(it.key()); // name
idata[offset++] = strings.enter(mp.typeName);
idata[offset++] = mp.flags;
idata[signatureOffset++] = stringdata.length();
stringdata += mp.signature;
stringdata += null;
idata[signatureOffset++] = strings.enter(mp.signature);
idata[signatureOffset++] = mp.type;
}
Q_ASSERT(offset == header->propertyDBusData);
Q_ASSERT(signatureOffset == header->methodDBusData);
char *string_data = new char[stringdata.length()];
memcpy(string_data, stringdata, stringdata.length());
char *string_data = new char[strings.arraySize()];
{
MetaStringTable::const_iterator it;
for (it = strings.constBegin(); it != strings.constEnd(); ++it) {
memcpy(string_data + it.value(), it.key().constData(), it.key().size());
string_data[it.value() + it.key().size()] = '\0';
}
}
uint *uint_data = new uint[idata.size()];
memcpy(uint_data, idata.data(), idata.size() * sizeof(int));