diff options
Diffstat (limited to 'src/corelib/mimetypes/qmimeprovider.cpp')
-rw-r--r-- | src/corelib/mimetypes/qmimeprovider.cpp | 351 |
1 files changed, 203 insertions, 148 deletions
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index cbb1ccd527..458cd46385 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -9,7 +9,6 @@ #include <qstandardpaths.h> #include "qmimemagicrulematcher_p.h" -#include <QMap> #include <QXmlStreamReader> #include <QBuffer> #include <QDir> @@ -20,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) @@ -51,18 +50,6 @@ QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; -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(); -} - struct QMimeBinaryProvider::CacheFile { CacheFile(const QString &fileName); @@ -90,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) { @@ -110,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; } @@ -124,10 +148,7 @@ bool QMimeBinaryProvider::CacheFile::reload() return load(); } -QMimeBinaryProvider::~QMimeBinaryProvider() -{ - delete m_cacheFile; -} +QMimeBinaryProvider::~QMimeBinaryProvider() = default; bool QMimeBinaryProvider::isValid() { @@ -155,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 @@ -168,7 +189,7 @@ void QMimeBinaryProvider::ensureLoaded() { if (!m_cacheFile) { const QString cacheFileName = m_directory + "/mime.cache"_L1; - m_cacheFile = new CacheFile(cacheFileName); + m_cacheFile = std::make_unique<CacheFile>(cacheFileName); m_mimetypeListLoaded = false; m_mimetypeExtra.clear(); } else { @@ -179,31 +200,15 @@ void QMimeBinaryProvider::ensureLoaded() return; // nothing to do } } - if (!m_cacheFile->isValid()) { // verify existence and version - delete m_cacheFile; - m_cacheFile = nullptr; - } + if (!m_cacheFile->isValid()) // verify existence and version + m_cacheFile.reset(); } -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); -} - -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) @@ -211,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) { @@ -241,16 +255,24 @@ void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile const Qt::CaseSensitivity qtCaseSensitive = caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; 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(QLatin1StringView(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; @@ -277,13 +299,15 @@ 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(QLatin1StringView(mimeType), weight, - u'*' + QStringView{fileName}.mid(charPos + 1), + result.addMatch(mimeType, weight, + u'*' + QStringView{ fileName }.mid(charPos + 1), fileName.size() - charPos - 2); success = true; } @@ -298,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); @@ -323,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); @@ -334,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(QLatin1StringView(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; + } } } } @@ -371,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; } @@ -419,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); } } } @@ -432,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)); } } } @@ -448,55 +473,72 @@ 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 + u'/' + data.name.toLower() + ".xml"_L1; + QString mimeFile = m_directory + u'/' + mimeName.toLower() + ".xml"_L1; if (!QFile::exists(mimeFile)) - mimeFile = m_directory + u'/' + data.name + ".xml"_L1; // 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() != "mime-type"_L1) { - return false; + return m_mimetypeExtra.cend(); } 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(); @@ -509,15 +551,13 @@ bool QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data) extra.localeComments.insert(lang, text); continue; // we called readElementText, so we're at the EndElement already. } else if (tag == "glob-deleteall"_L1) { // as written out by shared-mime-info >= 0.70 - extra.globPatterns.clear(); - mainPattern.clear(); + 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(); } @@ -533,11 +573,12 @@ 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 @@ -566,22 +607,16 @@ QLatin1StringView QMimeBinaryProvider::iconForMime(CacheFile *cacheFile, int pos return QLatin1StringView(); } -void QMimeBinaryProvider::loadIcon(QMimeTypePrivate &data) +QString QMimeBinaryProvider::icon(const QString &name) { - const QByteArray inputMime = data.name.toLatin1(); - const QLatin1StringView 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 QLatin1StringView icon = iconForMime(m_cacheFile, PosGenericIconsListOffset, inputMime); - if (!icon.isEmpty()) { - data.genericIconName = icon; - } + const QByteArray inputMime = name.toLatin1(); + return iconForMime(m_cacheFile.get(), PosGenericIconsListOffset, inputMime); } //// @@ -666,41 +701,37 @@ 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 + u'/' + xmlFile); @@ -716,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; @@ -761,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) @@ -783,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) @@ -805,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))); } } } |