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

KDECore

  • sources
  • kde-4.14
  • kdelibs
  • 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 
30 KMimeGlobsFileParser::KMimeGlobsFileParser()
31 {
32 }
33 
34 KMimeGlobsFileParser::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 
41 KMimeGlobsFileParser::AllGlobs KMimeGlobsFileParser::parseGlobs(const QStringList& globFiles)
42 {
43  QStringList parsedFiles;
44  return parseGlobFiles(globFiles, parsedFiles);
45 }
46 
47 KMimeGlobsFileParser::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
71 bool 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 
147 static 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 
158 void 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 
193 KMimeGlobsFileParser::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 
216 void 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 }
QIODevice
KDE_MAKE_VERSION
#define KDE_MAKE_VERSION(a, b, c)
Make a number from the major, minor and release number of a KDE version.
Definition: kdeversion.h.cmake:75
QMutableHashIterator::hasNext
bool hasNext() const
KMimeGlobsFileParser::GlobList::hasPattern
bool hasPattern(const QString &mime, const QString &pattern) const
Definition: kmimeglobsfileparser_p.h:57
KMimeGlobsFileParser::parseGlobs
AllGlobs parseGlobs()
Definition: kmimeglobsfileparser.cpp:34
kdebug.h
kmimetype.h
QTextStream::readLine
QString readLine(qint64 maxlen)
QListIterator::previous
const T & previous()
QMutableHashIterator
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
KMimeGlobsFileParser::AllGlobs::removeMime
void removeMime(const QString &mime)
Definition: kmimeglobsfileparser.cpp:216
KGlobal::dirs
KStandardDirs * dirs()
Returns the application standard dirs object.
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
KMimeGlobsFileParser::AllGlobs::patternsMap
PatternsMap patternsMap() const
Definition: kmimeglobsfileparser.cpp:193
KMimeGlobsFileParser::Globs2WithWeight
Definition: kmimeglobsfileparser_p.h:96
kmimetyperepository_p.h
KMimeType::sharedMimeInfoVersion
static int sharedMimeInfoVersion()
Returns the version of the installed update-mime-database program (from freedesktop.org shared-mime-info).
Definition: kmimetype.cpp:738
KMimeGlobsFileParser::AllGlobs::addGlob
void addGlob(const Glob &glob)
Definition: kmimeglobsfileparser.cpp:158
QFile::exists
bool exists() const
QIODevice::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
QFile
QTextStream
QString::lastIndexOf
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QList::value
T value(int i) const
KMimeGlobsFileParser::Format
Format
Definition: kmimeglobsfileparser_p.h:96
KMimeGlobsFileParser::Glob::flags
int flags
Definition: kmimeglobsfileparser_p.h:49
QString::clear
void clear()
KMimeGlobsFileParser::Glob::mimeType
QString mimeType
Definition: kmimeglobsfileparser_p.h:51
kglobal.h
QList::count
int count(const T &value) const
KMimeGlobsFileParser::AllGlobs::m_highWeightGlobs
GlobList m_highWeightGlobs
Definition: kmimeglobsfileparser_p.h:93
QList::append
void append(const T &value)
QTextStream::atEnd
bool atEnd() const
QHash< QString, QStringList >
QString::isEmpty
bool isEmpty() const
QHash::begin
iterator begin()
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
QMutableHashIterator::next
Item next()
QListIterator::toBack
void toBack()
QString
KMimeGlobsFileParser::Glob
Definition: kmimeglobsfileparser_p.h:45
QStringList
QString::toLower
QString toLower() const
KMimeGlobsFileParser::parseGlobFile
static bool parseGlobFile(QIODevice *file, Format format, AllGlobs &globs)
Definition: kmimeglobsfileparser.cpp:71
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QLatin1Char
KMimeGlobsFileParser::KMimeGlobsFileParser
KMimeGlobsFileParser()
Definition: kmimeglobsfileparser.cpp:30
isFastPattern
static bool isFastPattern(const QString &pattern)
Definition: kmimeglobsfileparser.cpp:147
KMimeGlobsFileParser::parseGlobFiles
static AllGlobs parseGlobFiles(const QStringList &globFiles, QStringList &parsedFiles)
Definition: kmimeglobsfileparser.cpp:47
KMimeGlobsFileParser::OldGlobs
Definition: kmimeglobsfileparser_p.h:96
kmimeglobsfileparser_p.h
QListIterator::hasPrevious
bool hasPrevious() const
KMimeGlobsFileParser::AllGlobs::m_lowWeightGlobs
GlobList m_lowWeightGlobs
Definition: kmimeglobsfileparser_p.h:94
QString::mid
QString mid(int position, int n) const
QLatin1String
kstandarddirs.h
QString::fromLatin1
QString fromLatin1(const char *str, int size)
KMimeTypeRepository::CaseSensitive
Definition: kmimetyperepository_p.h:66
QListIterator
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::end
iterator end()
KMimeGlobsFileParser::Glob::weight
int weight
Definition: kmimeglobsfileparser_p.h:48
KMimeGlobsFileParser::AllGlobs::m_fastPatterns
QHash< QString, QStringList > m_fastPatterns
Definition: kmimeglobsfileparser_p.h:92
KMimeGlobsFileParser::AllGlobs
Result of the globs parsing, as data structures ready for efficient mimetype matching.
Definition: kmimeglobsfileparser_p.h:85
KMimeGlobsFileParser::Glob::pattern
QString pattern
Definition: kmimeglobsfileparser_p.h:50
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:11 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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