summaryrefslogtreecommitdiffstats
path: root/src/corelib/mimetypes/qmimeglobpattern.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/mimetypes/qmimeglobpattern.cpp')
-rw-r--r--src/corelib/mimetypes/qmimeglobpattern.cpp108
1 files changed, 75 insertions, 33 deletions
diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp
index 1016884437..a81112d227 100644
--- a/src/corelib/mimetypes/qmimeglobpattern.cpp
+++ b/src/corelib/mimetypes/qmimeglobpattern.cpp
@@ -88,6 +88,40 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q
}
}
+QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString &pattern) const
+{
+ const int patternLength = pattern.length();
+ if (!patternLength)
+ return OtherPattern;
+
+ const bool starCount = pattern.count(QLatin1Char('*')) == 1;
+ const bool hasSquareBracket = pattern.indexOf(QLatin1Char('[')) != -1;
+ const bool hasQuestionMark = pattern.indexOf(QLatin1Char('?')) != -1;
+
+ if (!hasSquareBracket && !hasQuestionMark) {
+ if (starCount == 1) {
+ // Patterns like "*~", "*.extension"
+ if (pattern.at(0) == QLatin1Char('*'))
+ return SuffixPattern;
+ // Patterns like "README*" (well this is currently the only one like that...)
+ if (pattern.at(patternLength - 1) == QLatin1Char('*'))
+ return PrefixPattern;
+ }
+ // Names without any wildcards like "README"
+ if (starCount == 0)
+ return LiteralPattern;
+ }
+
+ if (pattern == QLatin1String("[0-9][0-9][0-9].vdr"))
+ return VdrPattern;
+
+ if (pattern == QLatin1String("*.anim[1-9j]"))
+ return AnimPattern;
+
+ return OtherPattern;
+}
+
+
/*!
\internal
\class QMimeGlobPattern
@@ -97,58 +131,66 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q
\sa QMimeType, QMimeDatabase, QMimeMagicRuleMatcher, QMimeMagicRule
*/
-bool QMimeGlobPattern::matchFileName(const QString &inputFilename) const
+bool QMimeGlobPattern::matchFileName(const QString &inputFileName) const
{
// "Applications MUST match globs case-insensitively, except when the case-sensitive
// attribute is set to true."
// The constructor takes care of putting case-insensitive patterns in lowercase.
- const QString filename = m_caseSensitivity == Qt::CaseInsensitive ? inputFilename.toLower() : inputFilename;
+ const QString fileName = m_caseSensitivity == Qt::CaseInsensitive
+ ? inputFileName.toLower() : inputFileName;
- const int pattern_len = m_pattern.length();
- if (!pattern_len)
+ const int patternLength = m_pattern.length();
+ if (!patternLength)
return false;
- const int len = filename.length();
-
- const int starCount = m_pattern.count(QLatin1Char('*'));
+ const int fileNameLength = fileName.length();
- // Patterns like "*~", "*.extension"
- if (m_pattern[0] == QLatin1Char('*') && m_pattern.indexOf(QLatin1Char('[')) == -1 && starCount == 1)
- {
- if (len + 1 < pattern_len) return false;
+ switch (m_patternType) {
+ case SuffixPattern: {
+ if (fileNameLength + 1 < patternLength)
+ return false;
- const QChar *c1 = m_pattern.unicode() + pattern_len - 1;
- const QChar *c2 = filename.unicode() + len - 1;
+ const QChar *c1 = m_pattern.unicode() + patternLength - 1;
+ const QChar *c2 = fileName.unicode() + fileNameLength - 1;
int cnt = 1;
- while (cnt < pattern_len && *c1-- == *c2--)
+ while (cnt < patternLength && *c1-- == *c2--)
++cnt;
- return cnt == pattern_len;
+ return cnt == patternLength;
}
-
- // Patterns like "README*" (well this is currently the only one like that...)
- if (starCount == 1 && m_pattern.at(pattern_len - 1) == QLatin1Char('*')) {
- if (len + 1 < pattern_len) return false;
- if (m_pattern.at(0) == QLatin1Char('*'))
- return filename.indexOf(m_pattern.midRef(1, pattern_len - 2)) != -1;
+ case PrefixPattern: {
+ if (fileNameLength + 1 < patternLength)
+ return false;
const QChar *c1 = m_pattern.unicode();
- const QChar *c2 = filename.unicode();
+ const QChar *c2 = fileName.unicode();
int cnt = 1;
- while (cnt < pattern_len && *c1++ == *c2++)
+ while (cnt < patternLength && *c1++ == *c2++)
++cnt;
- return cnt == pattern_len;
+ return cnt == patternLength;
}
-
- // Names without any wildcards like "README"
- if (m_pattern.indexOf(QLatin1Char('[')) == -1 && starCount == 0 && m_pattern.indexOf(QLatin1Char('?')))
- return (m_pattern == filename);
-
- // Other (quite rare) patterns, like "*.anim[1-9j]": use slow but correct method
+ case LiteralPattern:
+ return (m_pattern == fileName);
+ case VdrPattern: // "[0-9][0-9][0-9].vdr" case
+ return fileNameLength == 7
+ && fileName.at(0).isDigit() && fileName.at(1).isDigit() && fileName.at(2).isDigit()
+ && QStringView{fileName}.mid(3, 4) == QLatin1String(".vdr");
+ case AnimPattern: { // "*.anim[1-9j]" case
+ if (fileNameLength < 6)
+ return false;
+ const QChar lastChar = fileName.at(fileNameLength - 1);
+ const bool lastCharOK = (lastChar.isDigit() && lastChar != QLatin1Char('0'))
+ || lastChar == QLatin1Char('j');
+ return lastCharOK && QStringView{fileName}.mid(fileNameLength - 6, 5) == QLatin1String(".anim");
+ }
+ case OtherPattern:
+ // Other fallback patterns: slow but correct method
#if QT_CONFIG(regularexpression)
- QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(m_pattern));
- return rx.match(filename).hasMatch();
+ QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(m_pattern));
+ return rx.match(fileName).hasMatch();
#else
- return false;
+ return false;
#endif
+ }
+ return false;
}
static bool isSimplePattern(const QString &pattern)