177#if QT_CONFIG(xmlstreamreader)
178 QMimeTypeXMLData data;
180 QStack<QMimeMagicRule *> currentRules;
181 QList<QMimeMagicRule> rules;
182 QXmlStreamReader reader(dev);
183 ParseState ps = ParseBeginning;
184 while (!reader.atEnd()) {
185 switch (reader.readNext()) {
186 case QXmlStreamReader::StartElement: {
187 ps = nextState(ps, reader.name());
188 const QXmlStreamAttributes atts = reader.attributes();
190 case ParseMimeType: {
191 const QString name = atts.value(QLatin1StringView(mimeTypeAttributeC)).toString();
192 if (name.isEmpty()) {
193 reader.raiseError(QStringLiteral(
"Missing 'type'-attribute"));
199 case ParseGenericIcon:
200 data.genericIconName = atts.value(QLatin1StringView(nameAttributeC)).toString();
203 data.iconName = atts.value(QLatin1StringView(nameAttributeC)).toString();
205 case ParseGlobPattern: {
206 const QString pattern = atts.value(QLatin1StringView(patternAttributeC)).toString();
207 unsigned weight = atts.value(QLatin1StringView(weightAttributeC)).toInt();
208 const bool caseSensitive = atts.value(QLatin1StringView(caseSensitiveAttributeC)) ==
"true"_L1;
211 weight = QMimeGlobPattern::DefaultWeight;
213 Q_ASSERT(!data.name.isEmpty());
214 const QMimeGlobPattern glob(pattern, data.name, weight, caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
215 if (!process(glob, errorMessage))
217 data.addGlobPattern(pattern);
220 case ParseGlobDeleteAll:
221 data.globPatterns.clear();
222 data.hasGlobDeleteAll =
true;
224 case ParseSubClass: {
225 const QString inheritsFrom = atts.value(QLatin1StringView(mimeTypeAttributeC)).toString();
226 if (!inheritsFrom.isEmpty())
227 processParent(data.name, inheritsFrom);
232 QString locale = atts.value(QLatin1StringView(localeAttributeC)).toString();
233 const QString comment = reader.readElementText();
234 if (locale.isEmpty())
235 locale = QString::fromLatin1(
"default");
237 locale.replace(u'-', u'_');
238 data.localeComments.insert(locale, comment);
242 const QString alias = atts.value(QLatin1StringView(mimeTypeAttributeC)).toString();
243 if (!alias.isEmpty())
244 processAlias(alias, data.name);
249 const auto priorityS = atts.value(QLatin1StringView(priorityAttributeC));
250 if (!priorityS.isEmpty()) {
251 if (!parseNumber(priorityS, &priority, errorMessage))
255 currentRules.clear();
259 case ParseMagicMatchRule: {
263 if (currentRules.size() >= QMimeMagicRule::MaxRecursionDepth) {
264 reader.raiseError(
"<match> elements nested more than "_L1
265 + QString::number(QMimeMagicRule::MaxRecursionDepth)
266 +
" levels deep"_L1);
269 auto result = createMagicMatchRule(atts, m_regexRules);
270 if (Q_UNLIKELY(!result.rule.isValid()))
271 qWarning(
"QMimeDatabase: Error parsing %ls\n%ls",
272 qUtf16Printable(fileName), qUtf16Printable(result.errorMessage));
273 QList<QMimeMagicRule> *ruleList;
274 if (currentRules.isEmpty())
277 ruleList = ¤tRules.top()->m_subMatches;
278 ruleList->append(std::move(result.rule));
280 currentRules.push(&ruleList->last());
284 reader.raiseError(
"Unexpected element <"_L1 + reader.name() + u'>');
292 case QXmlStreamReader::EndElement:
294 const auto elementName = reader.name();
295 if (elementName == QLatin1StringView(mimeTypeTagC)) {
296 if (!process(data, errorMessage))
299 }
else if (elementName == QLatin1StringView(matchTagC)) {
303 }
else if (elementName == QLatin1StringView(magicTagC)) {
306 QMimeMagicRuleMatcher ruleMatcher(data.name, priority);
307 ruleMatcher.addRules(rules);
308 processMagicMatcher(ruleMatcher);
310 ps = ParseOtherMimeTypeSubTag;
319 if (Q_UNLIKELY(reader.hasError())) {
321 *errorMessage = QString::asprintf(
"An error has been encountered at line %lld of %ls: %ls:",
323 qUtf16Printable(fileName),
324 qUtf16Printable(reader.errorString()));
333 *errorMessage =
"QXmlStreamReader is not available, cannot parse '%1'."_L1.arg(fileName);