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 <lars.knoll@qt.io>
This commit is contained in:
Thiago Macieira 2021-09-11 20:00:08 -05:00
parent 2bea9b74ba
commit a0d66b60b7
6 changed files with 52 additions and 28 deletions

View File

@ -334,22 +334,24 @@ QFactoryLoader::QFactoryLoader(const char *iid,
#endif
}
QList<QJsonObject> QFactoryLoader::metaData() const
QFactoryLoader::MetaDataList QFactoryLoader::metaData() const
{
Q_D(const QFactoryLoader);
QList<QJsonObject> metaData;
QList<QPluginParsedMetaData> 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<const char *>(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<QStaticPlugin> 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<QStaticPlugin> staticPlugins = QPluginLoader::staticPlugins();
for (QStaticPlugin plugin : staticPlugins) {
QByteArrayView pluginData(static_cast<const char *>(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<int, QString> QFactoryLoader::keyMap() const
{
QMultiMap<int, QString> result;
const QList<QJsonObject> metaDataList = metaData();
const QList<QPluginParsedMetaData> 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<int, QString> QFactoryLoader::keyMap() const
int QFactoryLoader::indexOf(const QString &needle) const
{
const QList<QJsonObject> metaDataList = metaData();
const QList<QPluginParsedMetaData> 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))

View File

@ -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<const char *>(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<int, QString> keyMap() const;
int indexOf(const QString &needle) const;
QList<QJsonObject> metaData() const;
// this is a temporary gimmick to convert other Qt modules
struct TemporaryHolder {
QList<QPluginParsedMetaData> metaData;
TemporaryHolder(QList<QPluginParsedMetaData> &&md) : metaData(std::move(md)) {}
operator QList<QPluginParsedMetaData>() const { return std::move(metaData); }
Q_DECL_DEPRECATED_X("Update caller to use QList<QPluginParsedMetaData>()")
operator QList<QJsonObject>() const
{
QList<QJsonObject> 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;
};

View File

@ -150,6 +150,7 @@ public:
private:
qsizetype rawMetaDataSize;
const void *rawMetaData;
friend class QFactoryLoader;
};
Q_DECLARE_TYPEINFO(QStaticPlugin, Q_PRIMITIVE_TYPE);

View File

@ -39,7 +39,7 @@
#include "private/qimagereaderwriterhelpers_p.h"
#include <qjsonarray.h>
#include <qcborarray.h>
#include <qmutex.h>
#include <private/qfactoryloader_p.h>
@ -81,13 +81,12 @@ static void appendImagePluginMimeTypes(QFactoryLoader *loader,
QList<QByteArray> *result,
QList<QByteArray> *resultKeys = nullptr)
{
QList<QJsonObject> metaDataList = loader->metaData();
QList<QPluginParsedMetaData> 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<QImageIOPlugin *>(loader->instance(i));
const int keyCount = keys.size();
for (int k = 0; k < keyCount; ++k) {

View File

@ -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<QPluginParsedMetaData>(plugins->metaData()).size();
for (qsizetype i = 0; i < size; ++i) {
QIosOptionalPluginInterface *plugin = qobject_cast<QIosOptionalPluginInterface *>(plugins->instance(i));
m_viewController = [plugin->createImagePickerController(this) retain];
if (m_viewController)

View File

@ -125,7 +125,8 @@ void QIOSIntegration::initialize()
#endif
QMacInternalPasteboardMime::initializeMimeTypes();
for (int i = 0; i < m_optionalPlugins->metaData().size(); ++i)
qsizetype size = QList<QPluginParsedMetaData>(m_optionalPlugins->metaData()).size();
for (qsizetype i = 0; i < size; ++i)
qobject_cast<QIosOptionalPluginInterface *>(m_optionalPlugins->instance(i))->initPlugin();
}