summaryrefslogtreecommitdiffstats
path: root/src/corelib/mimetypes/qmimeprovider.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/mimetypes/qmimeprovider.cpp')
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp432
1 files changed, 228 insertions, 204 deletions
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index f152094dcd..458cd46385 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -1,43 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Copyright (C) 2018 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com>
-** Copyright (C) 2019 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// Copyright (C) 2018 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com>
+// Copyright (C) 2019 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qmimeprovider_p.h"
@@ -55,7 +19,7 @@
#include <QtEndian>
#if QT_CONFIG(mimetype_database)
-# if defined(Q_CC_MSVC)
+# if defined(Q_CC_MSVC_ONLY)
# pragma section(".qtmimedatabase", read, shared)
__declspec(allocate(".qtmimedatabase")) __declspec(align(4096))
# elif defined(Q_OS_DARWIN)
@@ -84,17 +48,7 @@ __attribute__((section(".qtmimedatabase"), aligned(4096)))
QT_BEGIN_NAMESPACE
-QMimeProviderBase::QMimeProviderBase(QMimeDatabasePrivate *db, const QString &directory)
- : m_db(db), m_directory(directory)
-{
-}
-
-
-QMimeBinaryProvider::QMimeBinaryProvider(QMimeDatabasePrivate *db, const QString &directory)
- : QMimeProviderBase(db, directory), m_mimetypeListLoaded(false)
-{
- ensureLoaded();
-}
+using namespace Qt::StringLiterals;
struct QMimeBinaryProvider::CacheFile
{
@@ -123,6 +77,43 @@ struct QMimeBinaryProvider::CacheFile
bool m_valid;
};
+static inline void appendIfNew(QStringList &list, const QString &str)
+{
+ if (!list.contains(str))
+ list.push_back(str);
+}
+
+QMimeProviderBase::QMimeProviderBase(QMimeDatabasePrivate *db, const QString &directory)
+ : m_db(db), m_directory(directory)
+{
+}
+
+QMimeProviderBase *QMimeProviderBase::overrideProvider() const
+{
+ return m_overrideProvider;
+}
+
+void QMimeProviderBase::setOverrideProvider(QMimeProviderBase *provider)
+{
+ m_overrideProvider = provider;
+}
+
+bool QMimeProviderBase::isMimeTypeGlobsExcluded(const QString &name) const
+{
+ if (m_overrideProvider) {
+ if (m_overrideProvider->hasGlobDeleteAll(name))
+ return true;
+ return m_overrideProvider->isMimeTypeGlobsExcluded(name);
+ }
+ return false;
+}
+
+QMimeBinaryProvider::QMimeBinaryProvider(QMimeDatabasePrivate *db, const QString &directory)
+ : QMimeProviderBase(db, directory), m_mimetypeListLoaded(false)
+{
+ ensureLoaded();
+}
+
QMimeBinaryProvider::CacheFile::CacheFile(const QString &fileName)
: file(fileName), m_valid(false)
{
@@ -143,7 +134,7 @@ bool QMimeBinaryProvider::CacheFile::load()
const int minor = getUint16(2);
m_valid = (major == 1 && minor >= 1 && minor <= 2);
}
- m_mtime = QFileInfo(file).lastModified();
+ m_mtime = QFileInfo(file).lastModified(QTimeZone::UTC);
return m_valid;
}
@@ -157,10 +148,7 @@ bool QMimeBinaryProvider::CacheFile::reload()
return load();
}
-QMimeBinaryProvider::~QMimeBinaryProvider()
-{
- delete m_cacheFile;
-}
+QMimeBinaryProvider::~QMimeBinaryProvider() = default;
bool QMimeBinaryProvider::isValid()
{
@@ -188,7 +176,7 @@ enum {
bool QMimeBinaryProvider::checkCacheChanged()
{
QFileInfo fileInfo(m_cacheFile->file);
- if (fileInfo.lastModified() > m_cacheFile->m_mtime) {
+ if (fileInfo.lastModified(QTimeZone::UTC) > m_cacheFile->m_mtime) {
// Deletion can't happen by just running update-mime-database.
// But the user could use rm -rf :-)
m_cacheFile->reload(); // will mark itself as invalid on failure
@@ -200,8 +188,8 @@ bool QMimeBinaryProvider::checkCacheChanged()
void QMimeBinaryProvider::ensureLoaded()
{
if (!m_cacheFile) {
- const QString cacheFileName = m_directory + QLatin1String("/mime.cache");
- m_cacheFile = new CacheFile(cacheFileName);
+ const QString cacheFileName = m_directory + "/mime.cache"_L1;
+ m_cacheFile = std::make_unique<CacheFile>(cacheFileName);
m_mimetypeListLoaded = false;
m_mimetypeExtra.clear();
} else {
@@ -212,31 +200,15 @@ void QMimeBinaryProvider::ensureLoaded()
return; // nothing to do
}
}
- if (!m_cacheFile->isValid()) { // verify existence and version
- delete m_cacheFile;
- m_cacheFile = nullptr;
- }
-}
-
-static QMimeType mimeTypeForNameUnchecked(const QString &name)
-{
- QMimeTypePrivate data;
- data.name = name;
- data.fromCache = true;
- // The rest is retrieved on demand.
- // comment and globPatterns: in loadMimeTypePrivate
- // iconName: in loadIcon
- // genericIconName: in loadGenericIcon
- return QMimeType(data);
+ if (!m_cacheFile->isValid()) // verify existence and version
+ m_cacheFile.reset();
}
-QMimeType QMimeBinaryProvider::mimeTypeForName(const QString &name)
+bool QMimeBinaryProvider::knowsMimeType(const QString &name)
{
if (!m_mimetypeListLoaded)
loadMimeTypeList();
- if (!m_mimetypeNames.contains(name))
- return QMimeType(); // unknown mimetype
- return mimeTypeForNameUnchecked(name);
+ return m_mimetypeNames.contains(name);
}
void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result)
@@ -244,25 +216,34 @@ void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobM
if (fileName.isEmpty())
return;
Q_ASSERT(m_cacheFile);
- const QString lowerFileName = fileName.toLower();
+ int numMatches = 0;
// Check literals (e.g. "Makefile")
- matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosLiteralListOffset), fileName);
+ numMatches = matchGlobList(result, m_cacheFile.get(),
+ m_cacheFile->getUint32(PosLiteralListOffset), fileName);
// Check the very common *.txt cases with the suffix tree
- if (result.m_matchingMimeTypes.isEmpty()) {
+ if (numMatches == 0) {
+ const QString lowerFileName = fileName.toLower();
const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
- if (result.m_matchingMimeTypes.isEmpty())
- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
+ if (matchSuffixTree(result, m_cacheFile.get(), numRoots, firstRootOffset, lowerFileName,
+ lowerFileName.size() - 1, false)) {
+ ++numMatches;
+ } else if (matchSuffixTree(result, m_cacheFile.get(), numRoots, firstRootOffset, fileName,
+ fileName.size() - 1, true)) {
+ ++numMatches;
+ }
}
// Check complex globs (e.g. "callgrind.out[0-9]*" or "README*")
- if (result.m_matchingMimeTypes.isEmpty())
- matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ if (numMatches == 0)
+ matchGlobList(result, m_cacheFile.get(), m_cacheFile->getUint32(PosGlobListOffset),
+ fileName);
}
-void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName)
+int QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off,
+ const QString &fileName)
{
+ int numMatches = 0;
const int numGlobs = cacheFile->getUint32(off);
//qDebug() << "Loading" << numGlobs << "globs from" << cacheFile->file.fileName() << "at offset" << cacheFile->globListOffset;
for (int i = 0; i < numGlobs; ++i) {
@@ -272,18 +253,26 @@ void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile
const int weight = flagsAndWeight & 0xff;
const bool caseSensitive = flagsAndWeight & 0x100;
const Qt::CaseSensitivity qtCaseSensitive = caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
- const QString pattern = QLatin1String(cacheFile->getCharStar(globOffset));
+ const QString pattern = QLatin1StringView(cacheFile->getCharStar(globOffset));
- const char *mimeType = cacheFile->getCharStar(mimeTypeOffset);
+ const QLatin1StringView mimeType(cacheFile->getCharStar(mimeTypeOffset));
//qDebug() << pattern << mimeType << weight << caseSensitive;
- QMimeGlobPattern glob(pattern, QString() /*unused*/, weight, qtCaseSensitive);
+ if (isMimeTypeGlobsExcluded(mimeType))
+ continue;
- if (glob.matchFileName(fileName))
- result.addMatch(QLatin1String(mimeType), weight, pattern);
+ QMimeGlobPattern glob(pattern, QString() /*unused*/, weight, qtCaseSensitive);
+ if (glob.matchFileName(fileName)) {
+ result.addMatch(mimeType, weight, pattern);
+ ++numMatches;
+ }
}
+ return numMatches;
}
-bool QMimeBinaryProvider::matchSuffixTree(QMimeGlobMatchResult &result, QMimeBinaryProvider::CacheFile *cacheFile, int numEntries, int firstOffset, const QString &fileName, int charPos, bool caseSensitiveCheck)
+bool QMimeBinaryProvider::matchSuffixTree(QMimeGlobMatchResult &result,
+ QMimeBinaryProvider::CacheFile *cacheFile, int numEntries,
+ int firstOffset, const QString &fileName,
+ qsizetype charPos, bool caseSensitiveCheck)
{
QChar fileChar = fileName[charPos];
int min = 0;
@@ -310,13 +299,16 @@ bool QMimeBinaryProvider::matchSuffixTree(QMimeGlobMatchResult &result, QMimeBin
if (mch != 0)
break;
const int mimeTypeOffset = cacheFile->getUint32(childOff + 4);
- const char *mimeType = cacheFile->getCharStar(mimeTypeOffset);
+ const QLatin1StringView mimeType(cacheFile->getCharStar(mimeTypeOffset));
+ if (isMimeTypeGlobsExcluded(mimeType))
+ continue;
const int flagsAndWeight = cacheFile->getUint32(childOff + 8);
const int weight = flagsAndWeight & 0xff;
const bool caseSensitive = flagsAndWeight & 0x100;
if (caseSensitiveCheck || !caseSensitive) {
- result.addMatch(QLatin1String(mimeType), weight,
- QLatin1Char('*') + QStringView{fileName}.mid(charPos + 1), fileName.size() - charPos - 2);
+ result.addMatch(mimeType, weight,
+ u'*' + QStringView{ fileName }.mid(charPos + 1),
+ fileName.size() - charPos - 2);
success = true;
}
}
@@ -330,7 +322,7 @@ bool QMimeBinaryProvider::matchSuffixTree(QMimeGlobMatchResult &result, QMimeBin
bool QMimeBinaryProvider::matchMagicRule(QMimeBinaryProvider::CacheFile *cacheFile, int numMatchlets, int firstOffset, const QByteArray &data)
{
const char *dataPtr = data.constData();
- const int dataSize = data.size();
+ const qsizetype dataSize = data.size();
for (int matchlet = 0; matchlet < numMatchlets; ++matchlet) {
const int off = firstOffset + matchlet * 32;
const int rangeStart = cacheFile->getUint32(off);
@@ -355,7 +347,7 @@ bool QMimeBinaryProvider::matchMagicRule(QMimeBinaryProvider::CacheFile *cacheFi
return false;
}
-void QMimeBinaryProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate)
+void QMimeBinaryProvider::findByMagic(const QByteArray &data, QMimeMagicResult &result)
{
const int magicListOffset = m_cacheFile->getUint32(PosMagicListOffset);
const int numMatches = m_cacheFile->getUint32(magicListOffset);
@@ -366,14 +358,16 @@ void QMimeBinaryProvider::findByMagic(const QByteArray &data, int *accuracyPtr,
const int off = firstMatchOffset + i * 16;
const int numMatchlets = m_cacheFile->getUint32(off + 8);
const int firstMatchletOffset = m_cacheFile->getUint32(off + 12);
- if (matchMagicRule(m_cacheFile, numMatchlets, firstMatchletOffset, data)) {
+ if (matchMagicRule(m_cacheFile.get(), numMatchlets, firstMatchletOffset, data)) {
const int mimeTypeOffset = m_cacheFile->getUint32(off + 4);
const char *mimeType = m_cacheFile->getCharStar(mimeTypeOffset);
- *accuracyPtr = m_cacheFile->getUint32(off);
- // Return the first match. We have no rules for conflicting magic data...
- // (mime.cache itself is sorted, but what about local overrides with a lower prio?)
- candidate = mimeTypeForNameUnchecked(QLatin1String(mimeType));
- return;
+ const int accuracy = static_cast<int>(m_cacheFile->getUint32(off));
+ if (accuracy > result.accuracy) {
+ result.accuracy = accuracy;
+ result.candidate = QString::fromLatin1(mimeType);
+ // Return the first match, mime.cache is sorted
+ return;
+ }
}
}
}
@@ -403,8 +397,7 @@ void QMimeBinaryProvider::addParents(const QString &mime, QStringList &result)
const int parentOffset = m_cacheFile->getUint32(parentsOffset + 4 + 4 * i);
const char *aParent = m_cacheFile->getCharStar(parentOffset);
const QString strParent = QString::fromLatin1(aParent);
- if (!result.contains(strParent))
- result.append(strParent);
+ appendIfNew(result, strParent);
}
break;
}
@@ -431,7 +424,7 @@ QString QMimeBinaryProvider::resolveAlias(const QString &name)
} else {
const int mimeOffset = m_cacheFile->getUint32(off + 4);
const char *mimeType = m_cacheFile->getCharStar(mimeOffset);
- return QLatin1String(mimeType);
+ return QLatin1StringView(mimeType);
}
}
return QString();
@@ -451,8 +444,7 @@ void QMimeBinaryProvider::addAliases(const QString &name, QStringList &result)
const int aliasOffset = m_cacheFile->getUint32(off);
const char *alias = m_cacheFile->getCharStar(aliasOffset);
const QString strAlias = QString::fromLatin1(alias);
- if (!result.contains(strAlias))
- result.append(strAlias);
+ appendIfNew(result, strAlias);
}
}
}
@@ -464,13 +456,14 @@ void QMimeBinaryProvider::loadMimeTypeList()
m_mimetypeNames.clear();
// Unfortunately mime.cache doesn't have a full list of all mimetypes.
// So we have to parse the plain-text files called "types".
- QFile file(m_directory + QStringLiteral("/types"));
+ QFile file(m_directory + QStringView(u"/types"));
if (file.open(QIODevice::ReadOnly)) {
while (!file.atEnd()) {
- QByteArray line = file.readLine();
- if (line.endsWith('\n'))
- line.chop(1);
- m_mimetypeNames.insert(QString::fromLatin1(line));
+ const QByteArray line = file.readLine();
+ auto lineView = QByteArrayView(line);
+ if (lineView.endsWith('\n'))
+ lineView.chop(1);
+ m_mimetypeNames.insert(QString::fromLatin1(lineView));
}
}
}
@@ -480,80 +473,95 @@ void QMimeBinaryProvider::addAllMimeTypes(QList<QMimeType> &result)
{
loadMimeTypeList();
if (result.isEmpty()) {
- result.reserve(m_mimetypeNames.count());
- for (const QString &name : qAsConst(m_mimetypeNames))
- result.append(mimeTypeForNameUnchecked(name));
+ result.reserve(m_mimetypeNames.size());
+ for (const QString &name : std::as_const(m_mimetypeNames))
+ result.append(QMimeType(QMimeTypePrivate(name)));
} else {
- for (const QString &name : qAsConst(m_mimetypeNames))
+ for (const QString &name : std::as_const(m_mimetypeNames))
if (std::find_if(result.constBegin(), result.constEnd(), [name](const QMimeType &mime) -> bool { return mime.name() == name; })
== result.constEnd())
- result.append(mimeTypeForNameUnchecked(name));
+ result.append(QMimeType(QMimeTypePrivate(name)));
}
}
-bool QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
+QMimeTypePrivate::LocaleHash QMimeBinaryProvider::localeComments(const QString &name)
{
-#ifdef QT_NO_XMLSTREAMREADER
- Q_UNUSED(data);
- qWarning("Cannot load mime type since QXmlStreamReader is not available.");
- return false;
-#else
- if (data.loaded)
- return true;
+ MimeTypeExtraMap::const_iterator it = loadMimeTypeExtra(name);
+ if (it != m_mimetypeExtra.cend())
+ return it->second.localeComments;
+ return {};
+}
+
+bool QMimeBinaryProvider::hasGlobDeleteAll(const QString &name)
+{
+ MimeTypeExtraMap::const_iterator it = loadMimeTypeExtra(name);
+ if (it != m_mimetypeExtra.cend())
+ return it->second.hasGlobDeleteAll;
+ return {};
+}
+
+QStringList QMimeBinaryProvider::globPatterns(const QString &name)
+{
+ MimeTypeExtraMap::const_iterator it = loadMimeTypeExtra(name);
+ if (it != m_mimetypeExtra.cend())
+ return it->second.globPatterns;
+ return {};
+}
- auto it = m_mimetypeExtra.constFind(data.name);
- if (it == m_mimetypeExtra.constEnd()) {
+QMimeBinaryProvider::MimeTypeExtraMap::const_iterator
+QMimeBinaryProvider::loadMimeTypeExtra(const QString &mimeName)
+{
+#if QT_CONFIG(xmlstreamreader)
+ auto it = m_mimetypeExtra.find(mimeName);
+ if (it == m_mimetypeExtra.cend()) {
// load comment and globPatterns
// shared-mime-info since 1.3 lowercases the xml files
- QString mimeFile = m_directory + QLatin1Char('/') + data.name.toLower() + QLatin1String(".xml");
+ QString mimeFile = m_directory + u'/' + mimeName.toLower() + ".xml"_L1;
if (!QFile::exists(mimeFile))
- mimeFile = m_directory + QLatin1Char('/') + data.name + QLatin1String(".xml"); // pre-1.3
+ mimeFile = m_directory + u'/' + mimeName + ".xml"_L1; // pre-1.3
QFile qfile(mimeFile);
if (!qfile.open(QFile::ReadOnly))
- return false;
+ return m_mimetypeExtra.cend();
- auto insertIt = m_mimetypeExtra.insert(data.name, MimeTypeExtra{});
- it = insertIt;
- MimeTypeExtra &extra = insertIt.value();
+ it = m_mimetypeExtra.try_emplace(mimeName).first;
+ MimeTypeExtra &extra = it->second;
QString mainPattern;
QXmlStreamReader xml(&qfile);
if (xml.readNextStartElement()) {
- if (xml.name() != QLatin1String("mime-type")) {
- return false;
+ if (xml.name() != "mime-type"_L1) {
+ return m_mimetypeExtra.cend();
}
- const auto name = xml.attributes().value(QLatin1String("type"));
+ const auto name = xml.attributes().value("type"_L1);
if (name.isEmpty())
- return false;
- if (name.compare(data.name, Qt::CaseInsensitive))
- qWarning() << "Got name" << name << "in file" << mimeFile << "expected" << data.name;
+ return m_mimetypeExtra.cend();
+ if (name.compare(mimeName, Qt::CaseInsensitive))
+ qWarning() << "Got name" << name << "in file" << mimeFile << "expected" << mimeName;
while (xml.readNextStartElement()) {
const auto tag = xml.name();
- if (tag == QLatin1String("comment")) {
- QString lang = xml.attributes().value(QLatin1String("xml:lang")).toString();
+ if (tag == "comment"_L1) {
+ QString lang = xml.attributes().value("xml:lang"_L1).toString();
const QString text = xml.readElementText();
if (lang.isEmpty()) {
- lang = QLatin1String("default"); // no locale attribute provided, treat it as default.
+ lang = "default"_L1; // no locale attribute provided, treat it as default.
}
extra.localeComments.insert(lang, text);
continue; // we called readElementText, so we're at the EndElement already.
- } else if (tag == QLatin1String("glob-deleteall")) { // as written out by shared-mime-info >= 0.70
- 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('*'))) {
+ } else if (tag == "glob-deleteall"_L1) { // as written out by shared-mime-info >= 0.70
+ extra.hasGlobDeleteAll = true;
+ } else if (tag == "glob"_L1) { // as written out by shared-mime-info >= 0.70
+ const QString pattern = xml.attributes().value("pattern"_L1).toString();
+ if (mainPattern.isEmpty() && pattern.startsWith(u'*')) {
mainPattern = pattern;
}
- if (!extra.globPatterns.contains(pattern))
- extra.globPatterns.append(pattern);
+ appendIfNew(extra.globPatterns, pattern);
}
xml.skipCurrentElement();
}
- Q_ASSERT(xml.name() == QLatin1String("mime-type"));
+ Q_ASSERT(xml.name() == "mime-type"_L1);
}
// Let's assume that shared-mime-info is at least version 0.70
@@ -565,15 +573,17 @@ bool QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
extra.globPatterns.prepend(mainPattern);
}
}
- const MimeTypeExtra &e = it.value();
- data.localeComments = e.localeComments;
- data.globPatterns = e.globPatterns;
- return true;
-#endif //QT_NO_XMLSTREAMREADER
+ return it;
+#else
+ Q_UNUSED(mimeName);
+ qWarning("Cannot load mime type since QXmlStreamReader is not available.");
+ return m_mimetypeExtra.cend();
+#endif // feature xmlstreamreader
}
// Binary search in the icons or generic-icons list
-QLatin1String QMimeBinaryProvider::iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime)
+QLatin1StringView QMimeBinaryProvider::iconForMime(CacheFile *cacheFile, int posListOffset,
+ const QByteArray &inputMime)
{
const int iconsListOffset = cacheFile->getUint32(posListOffset);
const int numIcons = cacheFile->getUint32(iconsListOffset);
@@ -591,28 +601,22 @@ QLatin1String QMimeBinaryProvider::iconForMime(CacheFile *cacheFile, int posList
end = medium - 1;
else {
const int iconOffset = cacheFile->getUint32(off + 4);
- return QLatin1String(cacheFile->getCharStar(iconOffset));
+ return QLatin1StringView(cacheFile->getCharStar(iconOffset));
}
}
- return QLatin1String();
+ return QLatin1StringView();
}
-void QMimeBinaryProvider::loadIcon(QMimeTypePrivate &data)
+QString QMimeBinaryProvider::icon(const QString &name)
{
- const QByteArray inputMime = data.name.toLatin1();
- const QLatin1String icon = iconForMime(m_cacheFile, PosIconsListOffset, inputMime);
- if (!icon.isEmpty()) {
- data.iconName = icon;
- }
+ const QByteArray inputMime = name.toLatin1();
+ return iconForMime(m_cacheFile.get(), PosIconsListOffset, inputMime);
}
-void QMimeBinaryProvider::loadGenericIcon(QMimeTypePrivate &data)
+QString QMimeBinaryProvider::genericIcon(const QString &name)
{
- const QByteArray inputMime = data.name.toLatin1();
- const QLatin1String icon = iconForMime(m_cacheFile, PosGenericIconsListOffset, inputMime);
- if (!icon.isEmpty()) {
- data.genericIconName = icon;
- }
+ const QByteArray inputMime = name.toLatin1();
+ return iconForMime(m_cacheFile.get(), PosGenericIconsListOffset, inputMime);
}
////
@@ -697,43 +701,39 @@ bool QMimeXMLProvider::isInternalDatabase() const
#endif
}
-QMimeType QMimeXMLProvider::mimeTypeForName(const QString &name)
+bool QMimeXMLProvider::knowsMimeType(const QString &name)
{
- return m_nameMimeTypeMap.value(name);
+ return m_nameMimeTypeMap.contains(name);
}
void QMimeXMLProvider::addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result)
{
- m_mimeTypeGlobs.matchingGlobs(fileName, result);
+ auto filterFunc = [this](const QString &name) { return !isMimeTypeGlobsExcluded(name); };
+ m_mimeTypeGlobs.matchingGlobs(fileName, result, filterFunc);
}
-void QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate)
+void QMimeXMLProvider::findByMagic(const QByteArray &data, QMimeMagicResult &result)
{
- QString candidateName;
- bool foundOne = false;
- for (const QMimeMagicRuleMatcher &matcher : qAsConst(m_magicMatchers)) {
+ for (const QMimeMagicRuleMatcher &matcher : std::as_const(m_magicMatchers)) {
if (matcher.matches(data)) {
const int priority = matcher.priority();
- if (priority > *accuracyPtr) {
- *accuracyPtr = priority;
- candidateName = matcher.mimetype();
- foundOne = true;
+ if (priority > result.accuracy) {
+ result.accuracy = priority;
+ result.candidate = matcher.mimetype();
}
}
}
- if (foundOne)
- candidate = mimeTypeForName(candidateName);
}
void QMimeXMLProvider::ensureLoaded()
{
QStringList allFiles;
- const QString packageDir = m_directory + QStringLiteral("/packages");
+ const QString packageDir = m_directory + QStringView(u"/packages");
QDir dir(packageDir);
const QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot);
- allFiles.reserve(files.count());
+ allFiles.reserve(files.size());
for (const QString &xmlFile : files)
- allFiles.append(packageDir + QLatin1Char('/') + xmlFile);
+ allFiles.append(packageDir + u'/' + xmlFile);
if (m_allFiles == allFiles)
return;
@@ -747,10 +747,35 @@ void QMimeXMLProvider::ensureLoaded()
//qDebug() << "Loading" << m_allFiles;
- for (const QString &file : qAsConst(allFiles))
+ for (const QString &file : std::as_const(allFiles))
load(file);
}
+QMimeTypePrivate::LocaleHash QMimeXMLProvider::localeComments(const QString &name)
+{
+ return m_nameMimeTypeMap.value(name).localeComments;
+}
+
+bool QMimeXMLProvider::hasGlobDeleteAll(const QString &name)
+{
+ return m_nameMimeTypeMap.value(name).hasGlobDeleteAll;
+}
+
+QStringList QMimeXMLProvider::globPatterns(const QString &name)
+{
+ return m_nameMimeTypeMap.value(name).globPatterns;
+}
+
+QString QMimeXMLProvider::icon(const QString &name)
+{
+ return m_nameMimeTypeMap.value(name).iconName;
+}
+
+QString QMimeXMLProvider::genericIcon(const QString &name)
+{
+ return m_nameMimeTypeMap.value(name).genericIconName;
+}
+
void QMimeXMLProvider::load(const QString &fileName)
{
QString errorMessage;
@@ -763,7 +788,7 @@ bool QMimeXMLProvider::load(const QString &fileName, QString *errorMessage)
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (errorMessage)
- *errorMessage = QLatin1String("Cannot open ") + fileName + QLatin1String(": ") + file.errorString();
+ *errorMessage = "Cannot open "_L1 + fileName + ": "_L1 + file.errorString();
return false;
}
@@ -792,10 +817,9 @@ void QMimeXMLProvider::addGlobPattern(const QMimeGlobPattern &glob)
m_mimeTypeGlobs.addGlob(glob);
}
-void QMimeXMLProvider::addMimeType(const QMimeType &mt)
+void QMimeXMLProvider::addMimeType(const QMimeTypeXMLData &mt)
{
- Q_ASSERT(!mt.d.data()->fromCache);
- m_nameMimeTypeMap.insert(mt.name(), mt);
+ m_nameMimeTypeMap.insert(mt.name, mt);
}
void QMimeXMLProvider::addParents(const QString &mime, QStringList &result)
@@ -814,13 +838,10 @@ void QMimeXMLProvider::addParent(const QString &child, const QString &parent)
void QMimeXMLProvider::addAliases(const QString &name, QStringList &result)
{
// Iterate through the whole hash. This method is rarely used.
- for (auto it = m_aliases.constBegin(), end = m_aliases.constEnd() ; it != end ; ++it) {
- if (it.value() == name) {
- if (!result.contains(it.key()))
- result.append(it.key());
- }
+ for (const auto &[alias, mimeName] : std::as_const(m_aliases).asKeyValueRange()) {
+ if (mimeName == name)
+ appendIfNew(result, alias);
}
-
}
QString QMimeXMLProvider::resolveAlias(const QString &name)
@@ -836,13 +857,16 @@ void QMimeXMLProvider::addAlias(const QString &alias, const QString &name)
void QMimeXMLProvider::addAllMimeTypes(QList<QMimeType> &result)
{
if (result.isEmpty()) { // fast path
- result = m_nameMimeTypeMap.values();
+ for (auto it = m_nameMimeTypeMap.constBegin(), end = m_nameMimeTypeMap.constEnd();
+ it != end; ++it) {
+ result.append(QMimeType(QMimeTypePrivate(it.value().name)));
+ }
} else {
for (auto it = m_nameMimeTypeMap.constBegin(), end = m_nameMimeTypeMap.constEnd() ; it != end ; ++it) {
const QString newMime = it.key();
if (std::find_if(result.constBegin(), result.constEnd(), [newMime](const QMimeType &mime) -> bool { return mime.name() == newMime; })
== result.constEnd())
- result.append(it.value());
+ result.append(QMimeType(QMimeTypePrivate(it.value().name)));
}
}
}