diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2016-07-28 17:40:21 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2016-08-01 15:28:04 +0000 |
commit | 143f22babb43d50dd5ee99f73f04016c84d6171a (patch) | |
tree | cbb7f02861d503aa3f85cc68450f7fa43746c439 /src | |
parent | 897eb7f1290428dcc257e999b099d0ef14349e35 (diff) |
Add a checksum to QQmlPropertyCache
By running an md5 hash over the meta-object data and string tables this will
allow us to detect changes to meta-objects and invalidate QML disk caches.
Change-Id: I15b92de4cdf0cb525281b86e1c7b8ba0b11347a0
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qqmlpropertycache.cpp | 42 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache_p.h | 5 |
2 files changed, 47 insertions, 0 deletions
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 01be38ada1..322e519706 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -1413,6 +1413,48 @@ bool QQmlPropertyCache::determineMetaObjectSizes(const QMetaObject &mo, int *fie return true; } +bool QQmlPropertyCache::addToHash(QCryptographicHash &hash, const QMetaObject &mo) +{ + int fieldCount = 0; + int stringCount = 0; + if (!determineMetaObjectSizes(mo, &fieldCount, &stringCount)) { + return false; + } + + hash.addData(reinterpret_cast<const char *>(mo.d.data), fieldCount * sizeof(uint)); + for (int i = 0; i < stringCount; ++i) { + const QByteArrayDataPtr data = { const_cast<QByteArrayData*>(&mo.d.stringdata[i]) }; + hash.addData(QByteArray(data)); + } + + return true; +} + +QByteArray QQmlPropertyCache::checksum(bool *ok) +{ + if (!_checksum.isEmpty()) { + *ok = true; + return _checksum; + } + + QCryptographicHash hash(QCryptographicHash::Md5); + + if (_parent) { + hash.addData(_parent->checksum(ok)); + if (!*ok) + return QByteArray(); + } + + if (!addToHash(hash, *createMetaObject())) { + *ok = false; + return QByteArray(); + } + + _checksum = hash.result(); + *ok = !_checksum.isEmpty(); + return _checksum; +} + /*! \internal \a index MUST be in the signal index range (see QObjectPrivate::signalIndex()). This is different from QMetaMethod::methodIndex(). diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index fd29cc8e6a..750537e707 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE +class QCryptographicHash; class QMetaProperty; class QQmlEngine; class QJSEngine; @@ -367,6 +368,9 @@ public: void toMetaObjectBuilder(QMetaObjectBuilder &); static bool determineMetaObjectSizes(const QMetaObject &mo, int *fieldCount, int *stringCount); + static bool addToHash(QCryptographicHash &hash, const QMetaObject &mo); + + QByteArray checksum(bool *ok); protected: virtual void destroy(); @@ -437,6 +441,7 @@ private: QByteArray _dynamicStringData; QString _defaultPropertyName; QQmlPropertyCacheMethodArguments *argumentsCache; + QByteArray _checksum; }; // QQmlMetaObject serves as a wrapper around either QMetaObject or QQmlPropertyCache. |