• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • services
kmimeglobsfileparser.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 * Copyright 2007, 2010 David Faure <faure@kde.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "kmimeglobsfileparser_p.h"
21#include <kglobal.h>
22#include <kdeversion.h>
23#include <kmimetype.h>
24#include <kstandarddirs.h>
25#include "kmimetyperepository_p.h"
26#include <kdebug.h>
27#include <QtCore/QTextStream>
28#include <QtCore/QFile>
29
30KMimeGlobsFileParser::KMimeGlobsFileParser()
31{
32}
33
34KMimeGlobsFileParser::AllGlobs KMimeGlobsFileParser::parseGlobs()
35{
36 const QStringList globFiles = KGlobal::dirs()->findAllResources("xdgdata-mime", QString::fromLatin1("globs"));
37 //kDebug() << globFiles;
38 return parseGlobs(globFiles);
39}
40
41KMimeGlobsFileParser::AllGlobs KMimeGlobsFileParser::parseGlobs(const QStringList& globFiles)
42{
43 QStringList parsedFiles;
44 return parseGlobFiles(globFiles, parsedFiles);
45}
46
47KMimeGlobsFileParser::AllGlobs KMimeGlobsFileParser::parseGlobFiles(const QStringList& globFiles, QStringList& parsedFiles)
48{
49 KMimeGlobsFileParser::AllGlobs allGlobs;
50 QListIterator<QString> globIter(globFiles);
51 globIter.toBack();
52 // At each level, we must be able to override (not just add to) the information that we read at higher levels
53 // (if glob-deleteall is used).
54 while (globIter.hasPrevious()) { // global first, then local
55 Format format = OldGlobs;
56 QString fileName = globIter.previous();
57 QString fileNamev2 = fileName + QLatin1Char('2'); // NOTE: this relies on u-m-d always generating the old globs file
58 if (QFile::exists(fileNamev2)) {
59 fileName = fileNamev2;
60 format = Globs2WithWeight;
61 }
62 parsedFiles << fileName;
63 QFile globFile(fileName);
64 //kDebug() << "Now parsing" << fileName;
65 parseGlobFile(&globFile, format, allGlobs);
66 }
67 return allGlobs;
68}
69
70// uses a QIODevice to make unit tests possible
71bool KMimeGlobsFileParser::parseGlobFile(QIODevice* file, Format format, AllGlobs& globs)
72{
73 if (!file->open(QIODevice::ReadOnly))
74 return false;
75
76 // If we're not going to get the "cs" flag because smi is too old, then we need to emulate it for *.C at least.
77 const bool caseSensitiveHackNeeded = (KMimeType::sharedMimeInfoVersion() <= KDE_MAKE_VERSION(0, 60, 0));
78
79 QTextStream stream(file);
80 //stream.setCodec("UTF-8"); // should be all latin1
81 QString lastMime, lastPattern;
82 QString line;
83 while (!stream.atEnd()) {
84 line = stream.readLine();
85 if (line.isEmpty() || line.startsWith(QLatin1Char('#')))
86 continue;
87
88 const QStringList fields = line.split(QLatin1Char(':'), QString::KeepEmptyParts);
89 if (fields.count() < 2) // syntax error
90 continue;
91
92 //kDebug() << "line=" << line;
93
94 QString mimeTypeName, pattern;
95 QStringList flagList;
96 int weight = 50;
97 if (format == Globs2WithWeight) {
98 if (fields.count() < 3) // syntax error
99 continue;
100 weight = fields[0].toInt();
101 mimeTypeName = fields[1];
102 pattern = fields[2];
103 const QString flagsStr = fields.value(3); // could be empty
104 flagList = flagsStr.split(QLatin1Char(','), QString::SkipEmptyParts);
105 } else {
106 mimeTypeName = fields[0];
107 pattern = fields[1];
108 }
109 Q_ASSERT(!pattern.isEmpty());
110 Q_ASSERT(!pattern.contains(QLatin1Char(':')));
111
112 //kDebug() << " got:" << mimeTypeName << pattern;
113
114 if (lastMime == mimeTypeName && lastPattern == pattern) {
115 // Ignore duplicates, especially important for those with no flags after a line with flags:
116 // 50:text/x-csrc:*.c:cs
117 // 50:text/x-csrc:*.c
118 continue;
119 }
120
121 bool caseSensitive = flagList.contains(QLatin1String("cs"));
122
123 if (caseSensitiveHackNeeded && (pattern == QLatin1String("*.C") || pattern == QLatin1String("*.c") || pattern == QLatin1String("core")))
124 caseSensitive = true;
125
126 if (pattern == QLatin1String("__NOGLOBS__")) {
127 //kDebug() << "removing" << mimeTypeName;
128 globs.removeMime(mimeTypeName);
129 lastMime.clear();
130 } else {
131 int flags = 0;
132 if (caseSensitive)
133 flags = KMimeTypeRepository::CaseSensitive;
134
135 //if (mimeTypeName == "text/plain")
136 // kDebug() << "Adding pattern" << pattern << "to mimetype" << mimeTypeName << "from globs file, with weight" << weight;
137 //if (pattern.toLower() == "*.c")
138 // kDebug() << " Adding pattern" << pattern << "to mimetype" << mimeTypeName << "from globs file, with weight" << weight << "flags" << flags;
139 globs.addGlob(Glob(mimeTypeName, weight, pattern, flags));
140 lastMime = mimeTypeName;
141 lastPattern = pattern;
142 }
143 }
144 return true;
145}
146
147static bool isFastPattern(const QString& pattern)
148{
149 // starts with "*.", has no other '*' and no other '.'
150 return pattern.lastIndexOf(QLatin1Char('*')) == 0
151 && pattern.lastIndexOf(QLatin1Char('.')) == 1
152 // and contains no other special character
153 && !pattern.contains(QLatin1Char('?'))
154 && !pattern.contains(QLatin1Char('['))
155 ;
156}
157
158void KMimeGlobsFileParser::AllGlobs::addGlob(const Glob& glob)
159{
160 // Note that in each case, we check for duplicates to avoid inserting duplicated patterns.
161 // This can happen when installing kde.xml and freedesktop.org.xml
162 // in the same prefix, and they both have text/plain:*.txt
163
164 const QString &pattern = glob.pattern;
165 Q_ASSERT(!pattern.isEmpty());
166
167 //kDebug() << "pattern" << pattern << "glob.weight=" << glob.weight << "isFast=" << isFastPattern(pattern) << glob.flags;
168
169 // Store each patterns into either m_fastPatternDict (*.txt, *.html etc. with default weight 50)
170 // or for the rest, like core.*, *.tar.bz2, *~, into highWeightPatternOffset (>50)
171 // or lowWeightPatternOffset (<=50)
172
173 if (glob.weight == 50 && isFastPattern(pattern) && ((glob.flags & KMimeTypeRepository::CaseSensitive) == 0)) {
174 // The bulk of the patterns is *.foo with weight 50 --> those go into the fast patterns hash.
175 const QString extension = pattern.mid(2).toLower();
176 QStringList& patterns = m_fastPatterns[extension]; // find or create
177 if (!patterns.contains(glob.mimeType))
178 patterns.append(glob.mimeType);
179 } else {
180 Glob adjustedGlob(glob);
181 if ((adjustedGlob.flags & KMimeTypeRepository::CaseSensitive) == 0)
182 adjustedGlob.pattern = adjustedGlob.pattern.toLower();
183 if (adjustedGlob.weight > 50) {
184 if (!m_highWeightGlobs.hasPattern(adjustedGlob.mimeType, adjustedGlob.pattern))
185 m_highWeightGlobs.append(adjustedGlob);
186 } else {
187 if (!m_lowWeightGlobs.hasPattern(adjustedGlob.mimeType, adjustedGlob.pattern))
188 m_lowWeightGlobs.append(adjustedGlob);
189 }
190 }
191}
192
193KMimeGlobsFileParser::PatternsMap KMimeGlobsFileParser::AllGlobs::patternsMap() const
194{
195 PatternsMap patMap;
196
197 // This is just to fill in KMimeType::patterns. This has no real effect
198 // on the actual mimetype matching.
199
200 QHash<QString, QStringList>::const_iterator it = m_fastPatterns.begin();
201 const QHash<QString, QStringList>::const_iterator end = m_fastPatterns.end();
202 for (; it != end; ++it) {
203 Q_FOREACH(const QString& mime, it.value())
204 patMap[mime].append(QString::fromLatin1("*.") + it.key());
205 }
206
207 Q_FOREACH(const Glob& glob, m_highWeightGlobs)
208 patMap[glob.mimeType].append(glob.pattern);
209
210 Q_FOREACH(const Glob& glob, m_lowWeightGlobs)
211 patMap[glob.mimeType].append(glob.pattern);
212
213 return patMap;
214}
215
216void KMimeGlobsFileParser::AllGlobs::removeMime(const QString& mime)
217{
218 QMutableHashIterator<QString, QStringList> it(m_fastPatterns);
219 while (it.hasNext()) {
220 it.next().value().removeAll(mime);
221 }
222 m_highWeightGlobs.removeMime(mime);
223 m_lowWeightGlobs.removeMime(mime);
224}
KMimeGlobsFileParser::AllGlobs
Result of the globs parsing, as data structures ready for efficient mimetype matching.
Definition: kmimeglobsfileparser_p.h:86
KMimeGlobsFileParser::AllGlobs::patternsMap
PatternsMap patternsMap() const
Definition: kmimeglobsfileparser.cpp:193
KMimeGlobsFileParser::AllGlobs::m_highWeightGlobs
GlobList m_highWeightGlobs
Definition: kmimeglobsfileparser_p.h:93
KMimeGlobsFileParser::AllGlobs::m_fastPatterns
QHash< QString, QStringList > m_fastPatterns
Definition: kmimeglobsfileparser_p.h:92
KMimeGlobsFileParser::AllGlobs::removeMime
void removeMime(const QString &mime)
Definition: kmimeglobsfileparser.cpp:216
KMimeGlobsFileParser::AllGlobs::m_lowWeightGlobs
GlobList m_lowWeightGlobs
Definition: kmimeglobsfileparser_p.h:94
KMimeGlobsFileParser::AllGlobs::addGlob
void addGlob(const Glob &glob)
Definition: kmimeglobsfileparser.cpp:158
KMimeGlobsFileParser::GlobList::hasPattern
bool hasPattern(const QString &mime, const QString &pattern) const
Definition: kmimeglobsfileparser_p.h:57
KMimeGlobsFileParser::parseGlobFiles
static AllGlobs parseGlobFiles(const QStringList &globFiles, QStringList &parsedFiles)
Definition: kmimeglobsfileparser.cpp:47
KMimeGlobsFileParser::parseGlobs
AllGlobs parseGlobs()
Definition: kmimeglobsfileparser.cpp:34
KMimeGlobsFileParser::parseGlobFile
static bool parseGlobFile(QIODevice *file, Format format, AllGlobs &globs)
Definition: kmimeglobsfileparser.cpp:71
KMimeGlobsFileParser::Format
Format
Definition: kmimeglobsfileparser_p.h:96
KMimeGlobsFileParser::Globs2WithWeight
@ Globs2WithWeight
Definition: kmimeglobsfileparser_p.h:96
KMimeGlobsFileParser::OldGlobs
@ OldGlobs
Definition: kmimeglobsfileparser_p.h:96
KMimeGlobsFileParser::KMimeGlobsFileParser
KMimeGlobsFileParser()
Definition: kmimeglobsfileparser.cpp:30
KMimeTypeRepository::CaseSensitive
@ CaseSensitive
Definition: kmimetyperepository_p.h:66
KMimeType::sharedMimeInfoVersion
static int sharedMimeInfoVersion()
Returns the version of the installed update-mime-database program (from freedesktop....
Definition: kmimetype.cpp:738
KStandardDirs::findAllResources
QStringList findAllResources(const char *type, const QString &filter=QString(), SearchOptions options=NoSearchOptions) const
Tries to find all resources with the specified type.
Definition: kstandarddirs.cpp:900
QHash< QString, QStringList >
QIODevice
QStringList
QString
kdebug.h
kglobal.h
isFastPattern
static bool isFastPattern(const QString &pattern)
Definition: kmimeglobsfileparser.cpp:147
kmimeglobsfileparser_p.h
kmimetype.h
kmimetyperepository_p.h
kstandarddirs.h
KGlobal::dirs
KStandardDirs * dirs()
Returns the application standard dirs object.
KMimeGlobsFileParser::Glob
Definition: kmimeglobsfileparser_p.h:45
KMimeGlobsFileParser::Glob::pattern
QString pattern
Definition: kmimeglobsfileparser_p.h:50
KMimeGlobsFileParser::Glob::mimeType
QString mimeType
Definition: kmimeglobsfileparser_p.h:51
KMimeGlobsFileParser::Glob::weight
int weight
Definition: kmimeglobsfileparser_p.h:48
KMimeGlobsFileParser::Glob::flags
int flags
Definition: kmimeglobsfileparser_p.h:49
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal