From 016633931f708f6495874a8722c7aae657e37438 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 6 Feb 2012 19:00:13 +0100 Subject: 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 --- src/dbus/qdbusmetaobject.cpp | 88 +++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp index c83865978c..734b21c0fb 100644 --- a/src/dbus/qdbusmetaobject.cpp +++ b/src/dbus/qdbusmetaobject.cpp @@ -360,9 +360,39 @@ void QDBusMetaObjectGenerator::parseProperties() void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) { + class MetaStringTable + { + public: + typedef QHash 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)); -- cgit v1.2.3