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.cpp168
1 files changed, 96 insertions, 72 deletions
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index 9013cdf161..a55f8314df 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -186,25 +186,11 @@ void QMimeBinaryProvider::ensureLoaded()
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)
@@ -354,7 +340,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, int *accuracyPtr, QString *candidate)
{
const int magicListOffset = m_cacheFile->getUint32(PosMagicListOffset);
const int numMatches = m_cacheFile->getUint32(magicListOffset);
@@ -371,7 +357,7 @@ void QMimeBinaryProvider::findByMagic(const QByteArray &data, int *accuracyPtr,
*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));
+ *candidate = QString::fromLatin1(mimeType);
return;
}
}
@@ -480,35 +466,63 @@ void QMimeBinaryProvider::addAllMimeTypes(QList<QMimeType> &result)
if (result.isEmpty()) {
result.reserve(m_mimetypeNames.size());
for (const QString &name : std::as_const(m_mimetypeNames))
- result.append(mimeTypeForNameUnchecked(name));
+ result.append(QMimeType(QMimeTypePrivate(name)));
} else {
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)
{
-#if QT_CONFIG(xmlstreamreader)
- if (data.loaded)
- return true;
+ MimeTypeExtraMap::const_iterator it = loadMimeTypeExtra(name);
+ if (it != m_mimetypeExtra.constEnd()) {
+ const MimeTypeExtra &e = it.value();
+ return e.localeComments;
+ }
+ return {};
+}
- auto it = m_mimetypeExtra.constFind(data.name);
+bool QMimeBinaryProvider::hasGlobDeleteAll(const QString &name)
+{
+ MimeTypeExtraMap::const_iterator it = loadMimeTypeExtra(name);
+ if (it != m_mimetypeExtra.constEnd()) {
+ const MimeTypeExtra &e = it.value();
+ return e.hasGlobDeleteAll;
+ }
+ return {};
+}
+
+QStringList QMimeBinaryProvider::globPatterns(const QString &name)
+{
+ MimeTypeExtraMap::const_iterator it = loadMimeTypeExtra(name);
+ if (it != m_mimetypeExtra.constEnd()) {
+ const MimeTypeExtra &e = it.value();
+ return e.globPatterns;
+ }
+ return {};
+}
+
+QMimeBinaryProvider::MimeTypeExtraMap::const_iterator
+QMimeBinaryProvider::loadMimeTypeExtra(const QString &mimeName)
+{
+#if QT_CONFIG(xmlstreamreader)
+ auto it = m_mimetypeExtra.constFind(mimeName);
if (it == m_mimetypeExtra.constEnd()) {
// 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.constEnd();
- auto insertIt = m_mimetypeExtra.insert(data.name, MimeTypeExtra{});
+ auto insertIt = m_mimetypeExtra.insert(mimeName, MimeTypeExtra{});
it = insertIt;
MimeTypeExtra &extra = insertIt.value();
QString mainPattern;
@@ -516,13 +530,13 @@ bool QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
QXmlStreamReader xml(&qfile);
if (xml.readNextStartElement()) {
if (xml.name() != "mime-type"_L1) {
- return false;
+ return m_mimetypeExtra.constEnd();
}
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.constEnd();
+ if (name.compare(mimeName, Qt::CaseInsensitive))
+ qWarning() << "Got name" << name << "in file" << mimeFile << "expected" << mimeName;
while (xml.readNextStartElement()) {
const auto tag = xml.name();
@@ -535,8 +549,7 @@ 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'*')) {
@@ -558,14 +571,11 @@ bool QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
extra.globPatterns.prepend(mainPattern);
}
}
- const MimeTypeExtra &e = it.value();
- data.localeComments = e.localeComments;
- data.globPatterns = e.globPatterns;
- return true;
+ return it;
#else
- Q_UNUSED(data);
+ Q_UNUSED(mimeName);
qWarning("Cannot load mime type since QXmlStreamReader is not available.");
- return false;
+ return m_mimetypeExtra.constEnd();
#endif // feature xmlstreamreader
}
@@ -595,22 +605,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.get(), 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.get(), PosGenericIconsListOffset, inputMime);
- if (!icon.isEmpty()) {
- data.genericIconName = icon;
- }
+ const QByteArray inputMime = name.toLatin1();
+ return iconForMime(m_cacheFile.get(), PosGenericIconsListOffset, inputMime);
}
////
@@ -695,9 +699,9 @@ 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)
@@ -705,22 +709,17 @@ void QMimeXMLProvider::addFileNameMatches(const QString &fileName, QMimeGlobMatc
m_mimeTypeGlobs.matchingGlobs(fileName, result);
}
-void QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate)
+void QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QString *candidate)
{
- QString candidateName;
- bool foundOne = false;
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;
+ *candidate = matcher.mimetype();
}
}
}
- if (foundOne)
- candidate = mimeTypeForName(candidateName);
}
void QMimeXMLProvider::ensureLoaded()
@@ -750,6 +749,31 @@ void QMimeXMLProvider::ensureLoaded()
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;
@@ -791,14 +815,11 @@ 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);
-
- QString name = mt.name();
- if (mt.d->hasGlobDeleteAll)
- appendIfNew(m_mimeTypesWithDeletedGlobs, name);
- m_nameMimeTypeMap.insert(mt.name(), mt);
+ if (mt.hasGlobDeleteAll)
+ appendIfNew(m_mimeTypesWithDeletedGlobs, mt.name);
+ m_nameMimeTypeMap.insert(mt.name, mt);
}
/*
@@ -814,7 +835,7 @@ void QMimeXMLProvider::excludeMimeTypeGlobs(const QStringList &toExclude)
for (const auto &mt : toExclude) {
auto it = m_nameMimeTypeMap.find(mt);
if (it != m_nameMimeTypeMap.end())
- it->d->globPatterns.clear();
+ it->globPatterns.clear();
m_mimeTypeGlobs.removeMimeType(mt);
}
}
@@ -854,13 +875,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)));
}
}
}