summaryrefslogtreecommitdiffstats
path: root/src/corelib/mimetypes
diff options
context:
space:
mode:
authorAlexander Volkov <avolkov@astralinux.ru>2021-05-06 20:13:35 +0300
committerAlexander Volkov <avolkov@astralinux.ru>2021-06-17 17:36:29 +0300
commitd8dbc2b95aa89a9f2c8515bd12d2729a018dded4 (patch)
tree9decd7b10b2810fbfc4a7b40d7e49ee6337b6e1e /src/corelib/mimetypes
parentada29a19cd4b995dfd3e3059ccdf360ba13de08c (diff)
QMimeBinaryProvider: cache comments and globPatterns
Avoid multiple re-reads of xml files, for example in dolphin, which displays MIME type comments as file types. Change-Id: Ia124930e2a1fdc99d8a4d160f2288a00f55e0e8e Reviewed-by: David Faure <david.faure@kdab.com>
Diffstat (limited to 'src/corelib/mimetypes')
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp15
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp92
-rw-r--r--src/corelib/mimetypes/qmimeprovider_p.h9
3 files changed, 62 insertions, 54 deletions
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index 2bbe6c3ad7..0be220e124 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -228,7 +228,20 @@ void QMimeDatabasePrivate::loadMimeTypePrivate(QMimeTypePrivate &mimePrivate)
return; // invalid mimetype
if (!mimePrivate.loaded) { // XML provider sets loaded=true, binary provider does this on demand
Q_ASSERT(mimePrivate.fromCache);
- QMimeBinaryProvider::loadMimeTypePrivate(mimePrivate);
+ bool found = false;
+ for (const auto &provider : providers()) {
+ if (provider->loadMimeTypePrivate(mimePrivate)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ const QString file = mimePrivate.name + QLatin1String(".xml");
+ qWarning() << "No file found for" << file << ", even though update-mime-info said it would exist.\n"
+ "Either it was just removed, or the directory doesn't have executable permission..."
+ << QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime"), QStandardPaths::LocateDirectory);
+ }
+ mimePrivate.loaded = true;
}
}
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index 11643b8a1e..92be90658e 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -203,11 +203,14 @@ void QMimeBinaryProvider::ensureLoaded()
const QString cacheFileName = m_directory + QLatin1String("/mime.cache");
m_cacheFile = new CacheFile(cacheFileName);
m_mimetypeListLoaded = false;
+ m_mimetypeExtra.clear();
} else {
- if (checkCacheChanged())
+ if (checkCacheChanged()) {
m_mimetypeListLoaded = false;
- else
+ m_mimetypeExtra.clear();
+ } else {
return; // nothing to do
+ }
}
if (!m_cacheFile->isValid()) { // verify existence and version
delete m_cacheFile;
@@ -489,47 +492,44 @@ void QMimeBinaryProvider::addAllMimeTypes(QList<QMimeType> &result)
}
}
-void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
+bool QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
{
#ifdef QT_NO_XMLSTREAMREADER
Q_UNUSED(data);
qWarning("Cannot load mime type since QXmlStreamReader is not available.");
- return;
+ return false;
#else
if (data.loaded)
- return;
- data.loaded = true;
- // load comment and globPatterns
-
- const QString file = data.name + QLatin1String(".xml");
- // shared-mime-info since 1.3 lowercases the xml files
- QStringList mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/") + file.toLower());
- if (mimeFiles.isEmpty())
- mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/") + file); // pre-1.3
- if (mimeFiles.isEmpty()) {
- qWarning() << "No file found for" << file << ", even though update-mime-info said it would exist.\n"
- "Either it was just removed, or the directory doesn't have executable permission..."
- << QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime"), QStandardPaths::LocateDirectory);
- return;
- }
+ return true;
+
+ auto it = m_mimetypeExtra.constFind(data.name);
+ if (it == m_mimetypeExtra.constEnd()) {
+ // load comment and globPatterns
- QString mainPattern;
+ // shared-mime-info since 1.3 lowercases the xml files
+ QString mimeFile = m_directory + QLatin1Char('/') + data.name.toLower() + QLatin1String(".xml");
+ if (!QFile::exists(mimeFile))
+ mimeFile = m_directory + QLatin1Char('/') + data.name + QLatin1String(".xml"); // pre-1.3
- for (QStringList::const_reverse_iterator it = mimeFiles.crbegin(), end = mimeFiles.crend(); it != end; ++it) { // global first, then local.
- QFile qfile(*it);
+ QFile qfile(mimeFile);
if (!qfile.open(QFile::ReadOnly))
- continue;
+ return false;
+
+ auto insertIt = m_mimetypeExtra.insert(data.name, MimeTypeExtra{});
+ it = insertIt;
+ MimeTypeExtra &extra = insertIt.value();
+ QString mainPattern;
QXmlStreamReader xml(&qfile);
if (xml.readNextStartElement()) {
if (xml.name() != QLatin1String("mime-type")) {
- continue;
+ return false;
}
const auto name = xml.attributes().value(QLatin1String("type"));
if (name.isEmpty())
- continue;
+ return false;
if (name.compare(data.name, Qt::CaseInsensitive))
- qWarning() << "Got name" << name << "in file" << file << "expected" << data.name;
+ qWarning() << "Got name" << name << "in file" << mimeFile << "expected" << data.name;
while (xml.readNextStartElement()) {
const auto tag = xml.name();
@@ -539,49 +539,37 @@ void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
if (lang.isEmpty()) {
lang = QLatin1String("default"); // no locale attribute provided, treat it as default.
}
- data.localeComments.insert(lang, text);
+ extra.localeComments.insert(lang, text);
continue; // we called readElementText, so we're at the EndElement already.
- } else if (tag == QLatin1String("icon")) { // as written out by shared-mime-info >= 0.40
- data.iconName = xml.attributes().value(QLatin1String("name")).toString();
} else if (tag == QLatin1String("glob-deleteall")) { // as written out by shared-mime-info >= 0.70
- data.globPatterns.clear();
+ extra.globPatterns.clear();
mainPattern.clear();
} else if (tag == QLatin1String("glob")) { // as written out by shared-mime-info >= 0.70
const QString pattern = xml.attributes().value(QLatin1String("pattern")).toString();
if (mainPattern.isEmpty() && pattern.startsWith(QLatin1Char('*'))) {
mainPattern = pattern;
}
- if (!data.globPatterns.contains(pattern))
- data.globPatterns.append(pattern);
+ if (!extra.globPatterns.contains(pattern))
+ extra.globPatterns.append(pattern);
}
xml.skipCurrentElement();
}
Q_ASSERT(xml.name() == QLatin1String("mime-type"));
}
- }
- // Let's assume that shared-mime-info is at least version 0.70
- // Otherwise we would need 1) a version check, and 2) code for parsing patterns from the globs file.
-#if 1
- if (!mainPattern.isEmpty() && (data.globPatterns.isEmpty() || data.globPatterns.constFirst() != mainPattern)) {
- // ensure it's first in the list of patterns
- data.globPatterns.removeAll(mainPattern);
- data.globPatterns.prepend(mainPattern);
- }
-#else
- const bool globsInXml = sharedMimeInfoVersion() >= QT_VERSION_CHECK(0, 70, 0);
- if (globsInXml) {
- if (!mainPattern.isEmpty() && data.globPatterns.constFirst() != mainPattern) {
+ // Let's assume that shared-mime-info is at least version 0.70
+ // Otherwise we would need 1) a version check, and 2) code for parsing patterns from the globs file.
+ if (!mainPattern.isEmpty() &&
+ (extra.globPatterns.isEmpty() || extra.globPatterns.constFirst() != mainPattern)) {
// ensure it's first in the list of patterns
- data.globPatterns.removeAll(mainPattern);
- data.globPatterns.prepend(mainPattern);
+ extra.globPatterns.removeAll(mainPattern);
+ extra.globPatterns.prepend(mainPattern);
}
- } else {
- // Fallback: get the patterns from the globs file
- // TODO: This would be the only way to support shared-mime-info < 0.70
- // But is this really worth the effort?
}
-#endif
+ const MimeTypeExtra &e = it.value();
+ data.localeComments = e.localeComments;
+ data.globPatterns = e.globPatterns;
+ return true;
#endif //QT_NO_XMLSTREAMREADER
}
diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h
index f9c8ef384c..affc554698 100644
--- a/src/corelib/mimetypes/qmimeprovider_p.h
+++ b/src/corelib/mimetypes/qmimeprovider_p.h
@@ -79,6 +79,7 @@ public:
virtual void addAliases(const QString &name, QStringList &result) = 0;
virtual void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) = 0;
virtual void addAllMimeTypes(QList<QMimeType> &result) = 0;
+ virtual bool loadMimeTypePrivate(QMimeTypePrivate &) { return false; }
virtual void loadIcon(QMimeTypePrivate &) {}
virtual void loadGenericIcon(QMimeTypePrivate &) {}
virtual void ensureLoaded() {}
@@ -107,7 +108,7 @@ public:
void addAliases(const QString &name, QStringList &result) override;
void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) override;
void addAllMimeTypes(QList<QMimeType> &result) override;
- static void loadMimeTypePrivate(QMimeTypePrivate &);
+ bool loadMimeTypePrivate(QMimeTypePrivate &) override;
void loadIcon(QMimeTypePrivate &) override;
void loadGenericIcon(QMimeTypePrivate &) override;
void ensureLoaded() override;
@@ -126,6 +127,12 @@ private:
QStringList m_cacheFileNames;
QSet<QString> m_mimetypeNames;
bool m_mimetypeListLoaded;
+ struct MimeTypeExtra
+ {
+ QHash<QString, QString> localeComments;
+ QStringList globPatterns;
+ };
+ QMap<QString, MimeTypeExtra> m_mimetypeExtra;
};
/*