add mime type detection for stand-alone byte arrays

Reviewed-by: Leandro Melo
This commit is contained in:
Oswald Buddenhagen
2011-03-09 11:37:51 +01:00
parent 7007326837
commit f3d6cd9cd1
2 changed files with 64 additions and 4 deletions

View File

@@ -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() << "<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();