qmimeglobpattern.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtCore module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qmimeglobpattern_p.h"-
41-
42#ifndef QT_NO_MIMETYPE-
43-
44#include <QRegExp>-
45#include <QStringList>-
46#include <QDebug>-
47-
48QT_BEGIN_NAMESPACE-
49-
50/*!-
51 \internal-
52 \class QMimeGlobMatchResult-
53 \inmodule QtCore-
54 \brief The QMimeGlobMatchResult class accumulates results from glob matching.-
55-
56 Handles glob weights, and preferring longer matches over shorter matches.-
57*/-
58-
59void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const QString &pattern)-
60{-
61 // Is this a lower-weight pattern than the last match? Skip this match then.-
62 if (weight < m_weight)-
63 return;-
64 bool replace = weight > m_weight;-
65 if (!replace) {-
66 // Compare the length of the match-
67 if (pattern.length() < m_matchingPatternLength)-
68 return; // too short, ignore-
69 else if (pattern.length() > m_matchingPatternLength) {-
70 // longer: clear any previous match (like *.bz2, when pattern is *.tar.bz2)-
71 replace = true;-
72 }-
73 }-
74 if (replace) {-
75 m_matchingMimeTypes.clear();-
76 // remember the new "longer" length-
77 m_matchingPatternLength = pattern.length();-
78 m_weight = weight;-
79 }-
80 if (!m_matchingMimeTypes.contains(mimeType)) {-
81 m_matchingMimeTypes.append(mimeType);-
82 if (pattern.startsWith(QLatin1String("*.")))-
83 m_foundSuffix = pattern.mid(2);-
84 }-
85}-
86-
87/*!-
88 \internal-
89 \class QMimeGlobPattern-
90 \inmodule QtCore-
91 \brief The QMimeGlobPattern class contains the glob pattern for file names for MIME type matching.-
92-
93 \sa QMimeType, QMimeDatabase, QMimeMagicRuleMatcher, QMimeMagicRule-
94*/-
95-
96bool QMimeGlobPattern::matchFileName(const QString &inputFilename) const-
97{-
98 // "Applications MUST match globs case-insensitively, except when the case-sensitive-
99 // attribute is set to true."-
100 // The constructor takes care of putting case-insensitive patterns in lowercase.-
101 const QString filename = m_caseSensitivity == Qt::CaseInsensitive ? inputFilename.toLower() : inputFilename;-
102-
103 const int pattern_len = m_pattern.length();-
104 if (!pattern_len)-
105 return false;-
106 const int len = filename.length();-
107-
108 const int starCount = m_pattern.count(QLatin1Char('*'));-
109-
110 // Patterns like "*~", "*.extension"-
111 if (m_pattern[0] == QLatin1Char('*') && m_pattern.indexOf(QLatin1Char('[')) == -1 && starCount == 1)-
112 {-
113 if (len + 1 < pattern_len) return false;-
114-
115 const QChar *c1 = m_pattern.unicode() + pattern_len - 1;-
116 const QChar *c2 = filename.unicode() + len - 1;-
117 int cnt = 1;-
118 while (cnt < pattern_len && *c1-- == *c2--)-
119 ++cnt;-
120 return cnt == pattern_len;-
121 }-
122-
123 // Patterns like "README*" (well this is currently the only one like that...)-
124 if (starCount == 1 && m_pattern.at(pattern_len - 1) == QLatin1Char('*')) {-
125 if (len + 1 < pattern_len) return false;-
126 if (m_pattern.at(0) == QLatin1Char('*'))-
127 return filename.indexOf(m_pattern.mid(1, pattern_len - 2)) != -1;-
128-
129 const QChar *c1 = m_pattern.unicode();-
130 const QChar *c2 = filename.unicode();-
131 int cnt = 1;-
132 while (cnt < pattern_len && *c1++ == *c2++)-
133 ++cnt;-
134 return cnt == pattern_len;-
135 }-
136-
137 // Names without any wildcards like "README"-
138 if (m_pattern.indexOf(QLatin1Char('[')) == -1 && starCount == 0 && m_pattern.indexOf(QLatin1Char('?')))-
139 return (m_pattern == filename);-
140-
141 // Other (quite rare) patterns, like "*.anim[1-9j]": use slow but correct method-
142 QRegExp rx(m_pattern, Qt::CaseSensitive, QRegExp::WildcardUnix);-
143 return rx.exactMatch(filename);-
144}-
145-
146static bool isFastPattern(const QString &pattern)-
147{-
148 // starts with "*.", has no other '*' and no other '.'-
149 return pattern.lastIndexOf(QLatin1Char('*')) == 0-
150 && pattern.lastIndexOf(QLatin1Char('.')) == 1-
151 // and contains no other special character-
152 && !pattern.contains(QLatin1Char('?'))-
153 && !pattern.contains(QLatin1Char('['))-
154 ;-
155}-
156-
157void QMimeAllGlobPatterns::addGlob(const QMimeGlobPattern &glob)-
158{-
159 const QString &pattern = glob.pattern();-
160 Q_ASSERT(!pattern.isEmpty());-
161-
162 // Store each patterns into either m_fastPatternDict (*.txt, *.html etc. with default weight 50)-
163 // or for the rest, like core.*, *.tar.bz2, *~, into highWeightPatternOffset (>50)-
164 // or lowWeightPatternOffset (<=50)-
165-
166 if (glob.weight() == 50 && isFastPattern(pattern) && !glob.isCaseSensitive()) {-
167 // The bulk of the patterns is *.foo with weight 50 --> those go into the fast patterns hash.-
168 const QString extension = pattern.mid(2).toLower();-
169 QStringList &patterns = m_fastPatterns[extension]; // find or create-
170 if (!patterns.contains(glob.mimeType()))-
171 patterns.append(glob.mimeType());-
172 } else {-
173 if (glob.weight() > 50) {-
174 if (!m_highWeightGlobs.hasPattern(glob.mimeType(), glob.pattern()))-
175 m_highWeightGlobs.append(glob);-
176 } else {-
177 if (!m_lowWeightGlobs.hasPattern(glob.mimeType(), glob.pattern()))-
178 m_lowWeightGlobs.append(glob);-
179 }-
180 }-
181}-
182-
183void QMimeAllGlobPatterns::removeMimeType(const QString &mimeType)-
184{-
185 QMutableHashIterator<QString, QStringList> itfor (auto &x : m_fastPatterns);-
while (it.hasNext()) {
it)
186 x
never executed: x.removeAll(mimeType);
.next().value().removeAll(mimeType);
never executed: x.removeAll(mimeType);
0
187 }m_highWeightGlobs.removeMimeType(mimeType);-
188 m_lowWeightGlobs.removeMimeType(mimeType);-
189}
never executed: end of block
0
190-
191void QMimeGlobPatternList::match(QMimeGlobMatchResult &result,-
192 const QString &fileName) const-
193{-
194-
195 QMimeGlobPatternList::const_iterator it = this->constBegin();-
196 const QMimeGlobPatternList::const_iterator endIt = this->constEnd();-
197 for (; it != endIt; ++it) {-
198 const QMimeGlobPattern &glob = *it;-
199 if (glob.matchFileName(fileName))-
200 result.addMatch(glob.mimeType(), glob.weight(), glob.pattern());-
201 }-
202}-
203-
204QStringList QMimeAllGlobPatterns::matchingGlobs(const QString &fileName, QString *foundSuffix) const-
205{-
206 // First try the high weight matches (>50), if any.-
207 QMimeGlobMatchResult result;-
208 m_highWeightGlobs.match(result, fileName);-
209 if (result.m_matchingMimeTypes.isEmpty()) {
result.m_match...ypes.isEmpty()Description
TRUEevaluated 96 times by 1 test
Evaluated by:
  • tst_QMimeDatabase
FALSEnever evaluated
0-96
210-
211 // Now use the "fast patterns" dict, for simple *.foo patterns with weight 50-
212 // (which is most of them, so this optimization is definitely worth it)-
213 const int lastDot = fileName.lastIndexOf(QLatin1Char('.'));-
214 if (lastDot != -1) { // if no '.', skip the extension lookup
lastDot != -1Description
TRUEevaluated 71 times by 1 test
Evaluated by:
  • tst_QMimeDatabase
FALSEevaluated 25 times by 1 test
Evaluated by:
  • tst_QMimeDatabase
25-71
215 const int ext_len = fileName.length() - lastDot - 1;-
216 const QString simpleExtension = fileName.right(ext_len).toLower();-
217 // (toLower because fast patterns are always case-insensitive and saved as lowercase)-
218-
219 const QStringList matchingMimeTypes = m_fastPatterns.value(simpleExtension);-
220 foreachconst QString simplePattern = QLatin1String("*.") + simpleExtension;-
221 for (const QString &mime ,: matchingMimeTypes)-
222 {result.addMatch(mime, 50, QLatin1String("*.") + simpleExtensionsimplePattern);}
executed 57 times by 1 test: result.addMatch(mime, 50, simplePattern);
Executed by:
  • tst_QMimeDatabase
57
223 // Can't return yet; *.tar.bz2 has to win over *.bz2, so we need the low-weight mimetypes anyway,-
224 // at least those with weight 50.-
225 }
executed 71 times by 1 test: end of block
Executed by:
  • tst_QMimeDatabase
71
226-
227 // Finally, try the low weight matches (<=50)-
228 m_lowWeightGlobs.match(result, fileName);-
229 }
executed 96 times by 1 test: end of block
Executed by:
  • tst_QMimeDatabase
96
230 if (foundSuffix)
foundSuffixDescription
TRUEevaluated 8 times by 1 test
Evaluated by:
  • tst_QMimeDatabase
FALSEevaluated 88 times by 1 test
Evaluated by:
  • tst_QMimeDatabase
8-88
231 *foundSuffix = result.m_foundSuffix;
executed 8 times by 1 test: *foundSuffix = result.m_foundSuffix;
Executed by:
  • tst_QMimeDatabase
8
232 return result.m_matchingMimeTypes;
executed 96 times by 1 test: return result.m_matchingMimeTypes;
Executed by:
  • tst_QMimeDatabase
96
233}-
234-
235void QMimeAllGlobPatterns::clear()-
236{-
237 m_fastPatterns.clear();-
238 m_highWeightGlobs.clear();-
239 m_lowWeightGlobs.clear();-
240}-
241-
242QT_END_NAMESPACE-
243-
244#endif // QT_NO_MIMETYPE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9