diff --git a/src/plugins/coreplugin/mimedatabase.cpp b/src/plugins/coreplugin/mimedatabase.cpp index ad5853deb24..f185529152e 100644 --- a/src/plugins/coreplugin/mimedatabase.cpp +++ b/src/plugins/coreplugin/mimedatabase.cpp @@ -712,13 +712,16 @@ unsigned MimeType::matchesFileBySuffix(Internal::FileMatchContext &c) const unsigned MimeType::matchesFileByContent(Internal::FileMatchContext &c) const { - unsigned priority = 0; - // Nope, try magic matchers on context data if (m_d->magicMatchers.isEmpty()) - return priority; + return 0; - const QByteArray data = c.data(); + return matchesData(c.data()); +} + +unsigned MimeType::matchesData(const QByteArray &data) const +{ + unsigned priority = 0; if (!data.isEmpty()) { foreach (const IMagicMatcher::IMagicMatcherSharedPointer &matcher, m_d->magicMatchers) { if (matcher->matches(data)) { @@ -1093,6 +1096,7 @@ public: MimeType findByType(const QString &type) const; MimeType findByFile(const QFileInfo &f) const; + MimeType findByData(const QByteArray &data) const; QStringList filterStrings() const; @@ -1132,6 +1136,7 @@ private: bool addMimeTypes(QIODevice *device, const QString &fileName, QString *errorMessage); inline const QString &resolveAlias(const QString &name) const; MimeType findByFile(const QFileInfo &f, unsigned *priority) const; + MimeType findByData(const QByteArray &data, unsigned *priority) const; void determineLevels(); void raiseLevelRecursion(MimeMapEntry &e, int level); @@ -1367,6 +1372,49 @@ MimeType MimeDatabasePrivate::findByFile(const QFileInfo &f, unsigned *priorityP return candidate; } +// Debugging wrapper around findByData() +MimeType MimeDatabasePrivate::findByData(const QByteArray &data) const +{ + unsigned priority = 0; + if (debugMimeDB) + qDebug() << '>' << Q_FUNC_INFO << data.left(20).toHex(); + const MimeType rc = findByData(data, &priority); + if (debugMimeDB) { + if (rc) { + qDebug() << "(this); + db->determineLevels(); + } + + *priorityPtr = 0; + MimeType candidate; + + const TypeMimeTypeMap::const_iterator cend = m_typeMimeTypeMap.constEnd(); + for (int level = m_maxLevel; level >= 0; level--) + for (TypeMimeTypeMap::const_iterator it = m_typeMimeTypeMap.constBegin(); it != cend; ++it) + if (it.value().level == level) { + const unsigned contentPriority = it.value().type.matchesData(data); + if (contentPriority && contentPriority > *priorityPtr) { + *priorityPtr = contentPriority; + candidate = it.value().type; + } + } + + return candidate; +} + // Return all known suffixes QStringList MimeDatabasePrivate::suffixes() const { @@ -1623,6 +1671,14 @@ MimeType MimeDatabase::findByFile(const QFileInfo &f) const return rc; } +MimeType MimeDatabase::findByData(const QByteArray &data) const +{ + m_mutex.lock(); + const MimeType rc = m_d->findByData(data); + m_mutex.unlock(); + return rc; +} + bool MimeDatabase::addMimeType(const MimeType &mt) { m_mutex.lock(); diff --git a/src/plugins/coreplugin/mimedatabase.h b/src/plugins/coreplugin/mimedatabase.h index 722a0158705..32a457f388b 100644 --- a/src/plugins/coreplugin/mimedatabase.h +++ b/src/plugins/coreplugin/mimedatabase.h @@ -261,6 +261,7 @@ private: explicit MimeType(const MimeTypeData &d); unsigned matchesFileBySuffix(Internal::FileMatchContext &c) const; unsigned matchesFileByContent(Internal::FileMatchContext &c) const; + unsigned matchesData(const QByteArray &data) const; friend class Internal::BaseMimeTypeParser; friend class MimeDatabasePrivate; @@ -293,6 +294,9 @@ public: // Returns a mime type or Null one if none found MimeType findByFile(const QFileInfo &f) const; + // Returns a mime type or Null one if none found + MimeType findByData(const QByteArray &data) const; + // Convenience that mutex-locks the DB and calls a function // of the signature 'void f(const MimeType &, const QFileInfo &, const QString &)' // for each filename of a sequence. This avoids locking the DB for each