10#include "private/qcoreapplication_p.h"
11#include "private/qduplicatetracker_p.h"
12#include "private/qloggingregistry_p.h"
13#include "private/qobject_p.h"
33#include <qtcore_tracepoints_p.h>
47 return setError(QFactoryLoader::tr(
"Invalid metadata version"));
56 return setError(QFactoryLoader::tr(
"Metadata parsing error: %1").
arg(err.
error.
toString()));
57 if (!metadata.
isMap())
58 return setError(QFactoryLoader::tr(
"Unexpected metadata contents"));
62 DecodedArchRequirements archReq =
63 header.version == 0 ? decodeVersion0ArchRequirements(
header.plugin_arch_requirements)
64 : decodeVersion1ArchRequirements(
header.plugin_arch_requirements);
80 for (
auto it :
data.toMap()) {
82 if (
it.first.isInteger()) {
83 switch (
it.first.toInteger()) {
84#define CONVERT_TO_STRING(IntKey, StringKey, Description) \
85 case int(IntKey): key = QStringLiteral(StringKey); break;
89 key =
it.first.toString();
93 o.insert(
key,
it.second.toJsonValue());
104#if QT_CONFIG(library)
114 void updateSinglePath(
const QString &pluginDir);
118#if QT_CONFIG(library)
121 "qt.core.plugin.factoryloader")
124struct QFactoryLoaderGlobals
135QFactoryLoaderPrivate::~QFactoryLoaderPrivate()
141inline void QFactoryLoaderPrivate::updateSinglePath(
const QString &
path)
143 struct LibraryReleaser {
145 {
if (library) library->
release(); }
149 if (loadedPaths.hasSeen(
path))
152 qCDebug(lcFactoryLoader) <<
"checking directory path" <<
path <<
"...";
157#elif defined(Q_OS_ANDROID)
162 while (plugins.hasNext()) {
165 const bool isDebugPlugin =
fileName.endsWith(
"_debug.dylib"_L1);
166 const bool isDebugLibrary =
175 if (isDebugPlugin != isDebugLibrary)
177#elif defined(Q_PROCESSOR_X86)
187 std::unique_ptr<QLibraryPrivate, LibraryReleaser> library;
189 if (!library->isPlugin()) {
196 bool metaDataOk =
false;
203 const QCborArray k =
object.value(
"Keys"_L1).toArray();
207 qCDebug(lcFactoryLoader) <<
"Got keys from plugin meta data" <<
keys;
212 int keyUsageCount = 0;
218 constexpr int QtVersionNoPatch =
QT_VERSION_CHECK(QT_VERSION_MAJOR, QT_VERSION_MINOR, 0);
220 int prev_qt_version = 0;
224 if (!previous || (prev_qt_version > QtVersionNoPatch && qt_version <= QtVersionNoPatch)) {
229 if (keyUsageCount ||
keys.isEmpty()) {
232 libraryList += library.release();
237void QFactoryLoader::update()
250 d->updateSinglePath(
path);
252 if (!
d->extraSearchPath.isEmpty())
253 d->updateSinglePath(
d->extraSearchPath);
256 qCDebug(lcFactoryLoader) <<
"ignoring" <<
d->iid
257 <<
"since plugins are disabled in static builds";
261QFactoryLoader::~QFactoryLoader()
263 if (!qt_factoryloader_global.isDestroyed()) {
265 qt_factoryloader_global->loaders.removeOne(
this);
269#if defined(Q_OS_UNIX) && !defined (Q_OS_DARWIN)
273 return d->keyMap.value(
d->cs ?
key :
key.toLower());
277void QFactoryLoader::refreshAll()
279 if (qt_factoryloader_global.exists()) {
294 "For historical reasons, the suffix must start with '/' (and it can't be empty)");
299#if QT_CONFIG(library)
303 if (!
d->suffix.isEmpty() &&
d->suffix.at(0) == u
'/')
304 d->suffix.remove(0, 1);
309 qt_factoryloader_global->loaders.append(
this);
318#if QT_CONFIG(library)
320 if (
d->extraSearchPath ==
path)
324 QString oldPath = std::exchange(
d->extraSearchPath,
path);
327 d->updateSinglePath(
d->extraSearchPath);
330 d->loadedPaths.clear();
331 d->libraryList.clear();
344#if QT_CONFIG(library)
353 QByteArrayView pluginData(
static_cast<const char *
>(plugin.rawMetaData), plugin.rawMetaDataSize);
370#if QT_CONFIG(library)
372 if (index < d->libraryList.size()) {
381 index -=
d->libraryList.size();
388 QByteArrayView pluginData(
static_cast<const char *
>(plugin.rawMetaData), plugin.rawMetaDataSize);
394 return plugin.instance();
405 for (
int i = 0;
i < int(metaDataList.
size()); ++
i) {
417 for (
int i = 0;
i < int(metaDataList.
size()); ++
i) {
430#include "moc_qfactoryloader_p.cpp"
constexpr QByteArrayView sliced(qsizetype pos) const
constexpr qsizetype size() const noexcept
constexpr const_pointer data() const noexcept
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
QCborValue value(qint64 key) const
Returns the QCborValue element in this map that corresponds to key key, if there is one.
\inmodule QtCore\reentrant
qint64 toInteger(qint64 defaultValue=0) const
Returns the integer value stored in this QCborValue, if it is of the integer type.
bool isMap() const
Returns true if this QCborValue is of the map type.
static QThread * mainThread()
The QDirIterator class provides an iterator for directory entrylists.
void setExtraSearchPath(const QString &path)
int indexOf(const QString &needle) const
QMultiMap< int, QString > keyMap() const
QFactoryLoader(const char *iid, const QString &suffix=QString(), Qt::CaseSensitivity=Qt::CaseSensitive)
MetaDataList metaData() const
QObject * instance(int index) const
\inmodule QtCore \reentrant
\inmodule QtCore\reentrant
QPluginParsedMetaData metaData
QObject * pluginInstance()
static QLibraryPrivate * findOrCreate(const QString &fileName, const QString &version=QString(), QLibrary::LoadHints loadHints={ })
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
T value(qsizetype i) const
void append(parameter_type t)
void moveToThread(QThread *thread)
Changes the thread affinity for this object and its children.
static QList< QStaticPlugin > staticPlugins()
Returns a list of QStaticPlugins held by the plugin loader.
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
const QChar * constData() const
Returns a pointer to the data stored in the QString.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
QMap< QString, QString > map
[6]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
QTextStream & endl(QTextStream &stream)
Writes '\n' to the stream and flushes the stream.
static QString header(const QString &name)
#define CONVERT_TO_STRING(IntKey, StringKey, Description)
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qCDebug(category,...)
#define Q_LOGGING_CATEGORY_WITH_ENV_OVERRIDE(name, env, categoryName)
GLsizei const GLfloat * v
[13]
GLsizei const GLuint * paths
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei const GLchar *const * path
#define QT_PLUGIN_FOREACH_METADATA(F)
#define Q_ASSERT_X(cond, x, msg)
#define QStringLiteral(str)
#define Q_TRACE_POINT(provider, tracepoint,...)
#define QT_VERSION_CHECK(major, minor, patch)
static const struct @437 keyMap[]
char * toString(const MyType &t)
[31]
QString toString() const
Returns a text string that matches the error code in this QCborError object.
\inmodule QtCore\reentrant