From a0d66b60b75cfe3d7580c7016959890693b2a132 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 11 Sep 2021 20:00:08 -0500 Subject: [PATCH] QFactoryLoader: continue the port from JSON to CBOR This continues the effort from the previous commit, by not passing through the JSON conversion at all, and simply using CBOR directly. The port in qtbase is complete, but in order to support the conversion in other modules without introducing breakages, there's a temporary class used for converting to QPluginParsedMetaData from QJsonObject. It'll be removed once all other modules have finished converting. Change-Id: I2de1b4dfacd443148279fffd16a3ed4ddaf34afc Reviewed-by: Lars Knoll --- src/corelib/plugin/qfactoryloader.cpp | 38 +++++++++++--------- src/corelib/plugin/qfactoryloader_p.h | 24 +++++++++++-- src/corelib/plugin/qplugin.h | 1 + src/gui/image/qimagereaderwriterhelpers.cpp | 11 +++--- src/plugins/platforms/ios/qiosfiledialog.mm | 3 +- src/plugins/platforms/ios/qiosintegration.mm | 3 +- 6 files changed, 52 insertions(+), 28 deletions(-) diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index 824bf60f7d..a315daa199 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -334,22 +334,24 @@ QFactoryLoader::QFactoryLoader(const char *iid, #endif } -QList QFactoryLoader::metaData() const +QFactoryLoader::MetaDataList QFactoryLoader::metaData() const { Q_D(const QFactoryLoader); - QList metaData; + QList metaData; #if QT_CONFIG(library) QMutexLocker locker(&d->mutex); for (int i = 0; i < d->libraryList.size(); ++i) - metaData.append(d->libraryList.at(i)->metaData.toJson()); + metaData.append(d->libraryList.at(i)->metaData); #endif + QLatin1String iid(d->iid.constData(), d->iid.size()); const auto staticPlugins = QPluginLoader::staticPlugins(); for (const QStaticPlugin &plugin : staticPlugins) { - const QJsonObject object = plugin.metaData(); - if (object.value(QLatin1String("IID")) != QLatin1String(d->iid.constData(), d->iid.size())) + QByteArrayView pluginData(static_cast(plugin.rawMetaData), plugin.rawMetaDataSize); + QPluginParsedMetaData parsed(pluginData); + if (parsed.isError() || parsed.value(QtPluginMetaDataKeys::IID) != iid) continue; - metaData.append(object); + metaData.append(std::move(parsed)); } return metaData; } @@ -375,14 +377,16 @@ QObject *QFactoryLoader::instance(int index) const lock.unlock(); #endif - QList staticPlugins = QPluginLoader::staticPlugins(); - for (int i = 0; i < staticPlugins.count(); ++i) { - const QJsonObject object = staticPlugins.at(i).metaData(); - if (object.value(QLatin1String("IID")) != QLatin1String(d->iid.constData(), d->iid.size())) + QLatin1String iid(d->iid.constData(), d->iid.size()); + const QList staticPlugins = QPluginLoader::staticPlugins(); + for (QStaticPlugin plugin : staticPlugins) { + QByteArrayView pluginData(static_cast(plugin.rawMetaData), plugin.rawMetaDataSize); + QPluginParsedMetaData parsed(pluginData); + if (parsed.isError() || parsed.value(QtPluginMetaDataKeys::IID) != iid) continue; if (index == 0) - return staticPlugins.at(i).instance(); + return plugin.instance(); --index; } @@ -392,10 +396,10 @@ QObject *QFactoryLoader::instance(int index) const QMultiMap QFactoryLoader::keyMap() const { QMultiMap result; - const QList metaDataList = metaData(); + const QList metaDataList = metaData(); for (int i = 0; i < metaDataList.size(); ++i) { - const QJsonObject metaData = metaDataList.at(i).value(QLatin1String("MetaData")).toObject(); - const QJsonArray keys = metaData.value(QLatin1String("Keys")).toArray(); + const QCborMap metaData = metaDataList.at(i).value(QtPluginMetaDataKeys::MetaData).toMap(); + const QCborArray keys = metaData.value(QLatin1String("Keys")).toArray(); const int keyCount = keys.size(); for (int k = 0; k < keyCount; ++k) result.insert(i, keys.at(k).toString()); @@ -405,10 +409,10 @@ QMultiMap QFactoryLoader::keyMap() const int QFactoryLoader::indexOf(const QString &needle) const { - const QList metaDataList = metaData(); + const QList metaDataList = metaData(); for (int i = 0; i < metaDataList.size(); ++i) { - const QJsonObject metaData = metaDataList.at(i).value(QLatin1String("MetaData")).toObject(); - const QJsonArray keys = metaData.value(QLatin1String("Keys")).toArray(); + const QCborMap metaData = metaDataList.at(i).value(QtPluginMetaDataKeys::MetaData).toMap(); + const QCborArray keys = metaData.value(QLatin1String("Keys")).toArray(); const int keyCount = keys.size(); for (int k = 0; k < keyCount; ++k) { if (!keys.at(k).toString().compare(needle, Qt::CaseInsensitive)) diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h index b7536d0349..2cfbcfaa65 100644 --- a/src/corelib/plugin/qfactoryloader_p.h +++ b/src/corelib/plugin/qfactoryloader_p.h @@ -58,6 +58,7 @@ #include "QtCore/private/qplugin_p.h" #include "QtCore/qcbormap.h" #include "QtCore/qcborvalue.h" +#include "QtCore/qjsonobject.h" #include "QtCore/qmap.h" #include "QtCore/qobject.h" #include "QtCore/qplugin.h" @@ -65,7 +66,6 @@ QT_BEGIN_NAMESPACE class QJsonDocument; -class QJsonObject; class QLibraryPrivate; class QPluginParsedMetaData @@ -87,7 +87,7 @@ public: bool parse(QPluginMetaData metaData) { return parse(QByteArrayView(reinterpret_cast(metaData.data), metaData.size)); } - QJsonObject toJson() const; + Q_CORE_EXPORT QJsonObject toJson() const; // if data is not a map, toMap() returns empty, so shall these functions QCborMap toCbor() const { return data.toMap(); } @@ -119,7 +119,25 @@ public: QMultiMap keyMap() const; int indexOf(const QString &needle) const; - QList metaData() const; + // this is a temporary gimmick to convert other Qt modules + struct TemporaryHolder { + QList metaData; + TemporaryHolder(QList &&md) : metaData(std::move(md)) {} + operator QList() const { return std::move(metaData); } + + Q_DECL_DEPRECATED_X("Update caller to use QList()") + operator QList() const + { + QList result; + result.reserve(metaData.size()); + for (const QPluginParsedMetaData &pmd : metaData) + result.append(pmd.toJson()); + return result; + } + }; + using MetaDataList = TemporaryHolder; + + MetaDataList metaData() const; QObject *instance(int index) const; }; diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h index 408e22f37d..5f4ef81bb6 100644 --- a/src/corelib/plugin/qplugin.h +++ b/src/corelib/plugin/qplugin.h @@ -150,6 +150,7 @@ public: private: qsizetype rawMetaDataSize; const void *rawMetaData; + friend class QFactoryLoader; }; Q_DECLARE_TYPEINFO(QStaticPlugin, Q_PRIMITIVE_TYPE); diff --git a/src/gui/image/qimagereaderwriterhelpers.cpp b/src/gui/image/qimagereaderwriterhelpers.cpp index dd56d887a7..dd4886b412 100644 --- a/src/gui/image/qimagereaderwriterhelpers.cpp +++ b/src/gui/image/qimagereaderwriterhelpers.cpp @@ -39,7 +39,7 @@ #include "private/qimagereaderwriterhelpers_p.h" -#include +#include #include #include @@ -81,13 +81,12 @@ static void appendImagePluginMimeTypes(QFactoryLoader *loader, QList *result, QList *resultKeys = nullptr) { - QList metaDataList = loader->metaData(); - + QList metaDataList = loader->metaData(); const int pluginCount = metaDataList.size(); for (int i = 0; i < pluginCount; ++i) { - const QJsonObject metaData = metaDataList.at(i).value(QLatin1String("MetaData")).toObject(); - const QJsonArray keys = metaData.value(QLatin1String("Keys")).toArray(); - const QJsonArray mimeTypes = metaData.value(QLatin1String("MimeTypes")).toArray(); + const QCborMap metaData = metaDataList.at(i).value(QtPluginMetaDataKeys::MetaData).toMap(); + const QCborArray keys = metaData.value(QLatin1String("Keys")).toArray(); + const QCborArray mimeTypes = metaData.value(QLatin1String("MimeTypes")).toArray(); QImageIOPlugin *plugin = qobject_cast(loader->instance(i)); const int keyCount = keys.size(); for (int k = 0; k < keyCount; ++k) { diff --git a/src/plugins/platforms/ios/qiosfiledialog.mm b/src/plugins/platforms/ios/qiosfiledialog.mm index edf04016fd..a56bf25c16 100644 --- a/src/plugins/platforms/ios/qiosfiledialog.mm +++ b/src/plugins/platforms/ios/qiosfiledialog.mm @@ -87,7 +87,8 @@ bool QIOSFileDialog::showImagePickerDialog(QWindow *parent) { if (!m_viewController) { QFactoryLoader *plugins = QIOSIntegration::instance()->optionalPlugins(); - for (int i = 0; i < plugins->metaData().size(); ++i) { + qsizetype size = QList(plugins->metaData()).size(); + for (qsizetype i = 0; i < size; ++i) { QIosOptionalPluginInterface *plugin = qobject_cast(plugins->instance(i)); m_viewController = [plugin->createImagePickerController(this) retain]; if (m_viewController) diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 725c280129..8938f97ae5 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -125,7 +125,8 @@ void QIOSIntegration::initialize() #endif QMacInternalPasteboardMime::initializeMimeTypes(); - for (int i = 0; i < m_optionalPlugins->metaData().size(); ++i) + qsizetype size = QList(m_optionalPlugins->metaData()).size(); + for (qsizetype i = 0; i < size; ++i) qobject_cast(m_optionalPlugins->instance(i))->initPlugin(); }