Commit f3d6cd9c authored by Oswald Buddenhagen's avatar Oswald Buddenhagen

add mime type detection for stand-alone byte arrays

Reviewed-by: Leandro Melo
parent 70073268
......@@ -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;
return matchesData(c.data());
}
const QByteArray data = 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() << "<MimeDatabase::findByData: match prio=" << priority << rc.type();
} else {
qDebug() << "<MimeDatabase::findByData: no match";
}
}
return rc;
}
// Returns a mime type or Null one if none found
MimeType MimeDatabasePrivate::findByData(const QByteArray &data, unsigned *priorityPtr) const
{
// Is the hierarchy set up in case we find several matches?
if (m_maxLevel < 0) {
MimeDatabasePrivate *db = const_cast<MimeDatabasePrivate *>(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();
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment