1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QMIMEPROVIDER_P_H
6#define QMIMEPROVIDER_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include "qmimedatabase_p.h"
20
21QT_REQUIRE_CONFIG(mimetype);
22
23#include "qmimeglobpattern_p.h"
24#include <QtCore/qdatetime.h>
25#include <QtCore/qset.h>
26#include <QtCore/qmap.h>
27
28QT_BEGIN_NAMESPACE
29
30class QMimeMagicRuleMatcher;
31
32class QMimeProviderBase
33{
34 Q_DISABLE_COPY(QMimeProviderBase)
35
36public:
37 QMimeProviderBase(QMimeDatabasePrivate *db, const QString &directory);
38 virtual ~QMimeProviderBase() {}
39
40 virtual bool isValid() = 0;
41 virtual bool isInternalDatabase() const = 0;
42 virtual QMimeType mimeTypeForName(const QString &name) = 0;
43 virtual void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) = 0;
44 virtual void addParents(const QString &mime, QStringList &result) = 0;
45 virtual QString resolveAlias(const QString &name) = 0;
46 virtual void addAliases(const QString &name, QStringList &result) = 0;
47 virtual void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) = 0;
48 virtual void addAllMimeTypes(QList<QMimeType> &result) = 0;
49 virtual bool loadMimeTypePrivate(QMimeTypePrivate &) { return false; }
50 virtual void loadIcon(QMimeTypePrivate &) {}
51 virtual void loadGenericIcon(QMimeTypePrivate &) {}
52 virtual void ensureLoaded() {}
53 virtual void excludeMimeTypeGlobs(const QStringList &) {}
54
55 QString directory() const { return m_directory; }
56
57 QMimeDatabasePrivate *m_db;
58 QString m_directory;
59
60 /*
61 MimeTypes with "glob-deleteall" tags are handled differently by each provider
62 sub-class:
63 - QMimeBinaryProvider parses glob-deleteall tags lazily, i.e. only when loadMimeTypePrivate()
64 is called, and clears the glob patterns associated with mimetypes that have this tag
65 - QMimeXMLProvider parses glob-deleteall from the the start, i.e. when a XML file is
66 parsed with QMimeTypeParser
67
68 The two lists below are used to let both provider types (XML and Binary) communicate
69 about mimetypes with glob-deleteall.
70 */
71 /*
72 List of mimetypes in _this_ Provider that have a "glob-deleteall" tag,
73 glob patterns for those mimetypes should be ignored in all _other_ lower
74 precedence Providers.
75 */
76 QStringList m_mimeTypesWithDeletedGlobs;
77
78 /*
79 List of mimetypes with glob patterns that are "overwritten" in _this_ Provider,
80 by a "glob-deleteall" tag in a mimetype definition in a _higher precedence_
81 Provider. With QMimeBinaryProvider, we can't change the data in the binary mmap'ed
82 file, hence the need for this list.
83 */
84 QStringList m_mimeTypesWithExcludedGlobs;
85};
86
87/*
88 Parses the files 'mime.cache' and 'types' on demand
89 */
90class QMimeBinaryProvider final : public QMimeProviderBase
91{
92public:
93 QMimeBinaryProvider(QMimeDatabasePrivate *db, const QString &directory);
94 virtual ~QMimeBinaryProvider();
95
96 bool isValid() override;
97 bool isInternalDatabase() const override;
98 QMimeType mimeTypeForName(const QString &name) override;
99 void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) override;
100 void addParents(const QString &mime, QStringList &result) override;
101 QString resolveAlias(const QString &name) override;
102 void addAliases(const QString &name, QStringList &result) override;
103 void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) override;
104 void addAllMimeTypes(QList<QMimeType> &result) override;
105 bool loadMimeTypePrivate(QMimeTypePrivate &) override;
106 void loadIcon(QMimeTypePrivate &) override;
107 void loadGenericIcon(QMimeTypePrivate &) override;
108 void ensureLoaded() override;
109 void excludeMimeTypeGlobs(const QStringList &toExclude) override;
110
111private:
112 struct CacheFile;
113
114 int matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int offset,
115 const QString &fileName);
116 bool matchSuffixTree(QMimeGlobMatchResult &result, CacheFile *cacheFile, int numEntries,
117 int firstOffset, const QString &fileName, qsizetype charPos,
118 bool caseSensitiveCheck);
119 bool matchMagicRule(CacheFile *cacheFile, int numMatchlets, int firstOffset, const QByteArray &data);
120 bool isMimeTypeGlobsExcluded(const char *name);
121 QLatin1StringView iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime);
122 void loadMimeTypeList();
123 bool checkCacheChanged();
124
125 std::unique_ptr<CacheFile> m_cacheFile;
126 QStringList m_cacheFileNames;
127 QSet<QString> m_mimetypeNames;
128 bool m_mimetypeListLoaded;
129 struct MimeTypeExtra
130 {
131 // Both retrieved on demand in loadMimeTypePrivate
132 QHash<QString, QString> localeComments;
133 QStringList globPatterns;
134 };
135 QMap<QString, MimeTypeExtra> m_mimetypeExtra;
136};
137
138/*
139 Parses the raw XML files (slower)
140 */
141class QMimeXMLProvider final : public QMimeProviderBase
142{
143public:
144 enum InternalDatabaseEnum { InternalDatabase };
145#if QT_CONFIG(mimetype_database)
146 enum : bool { InternalDatabaseAvailable = true };
147#else
148 enum : bool { InternalDatabaseAvailable = false };
149#endif
150 QMimeXMLProvider(QMimeDatabasePrivate *db, InternalDatabaseEnum);
151 QMimeXMLProvider(QMimeDatabasePrivate *db, const QString &directory);
152 ~QMimeXMLProvider();
153
154 bool isValid() override;
155 bool isInternalDatabase() const override;
156 QMimeType mimeTypeForName(const QString &name) override;
157 void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) override;
158 void addParents(const QString &mime, QStringList &result) override;
159 QString resolveAlias(const QString &name) override;
160 void addAliases(const QString &name, QStringList &result) override;
161 void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) override;
162 void addAllMimeTypes(QList<QMimeType> &result) override;
163 void ensureLoaded() override;
164
165 bool load(const QString &fileName, QString *errorMessage);
166
167 // Called by the mimetype xml parser
168 void addMimeType(const QMimeType &mt);
169 void excludeMimeTypeGlobs(const QStringList &toExclude) override;
170 void addGlobPattern(const QMimeGlobPattern &glob);
171 void addParent(const QString &child, const QString &parent);
172 void addAlias(const QString &alias, const QString &name);
173 void addMagicMatcher(const QMimeMagicRuleMatcher &matcher);
174
175private:
176 void load(const QString &fileName);
177 void load(const char *data, qsizetype len);
178
179 typedef QHash<QString, QMimeType> NameMimeTypeMap;
180 NameMimeTypeMap m_nameMimeTypeMap;
181
182 typedef QHash<QString, QString> AliasHash;
183 AliasHash m_aliases;
184
185 typedef QHash<QString, QStringList> ParentsHash;
186 ParentsHash m_parents;
187 QMimeAllGlobPatterns m_mimeTypeGlobs;
188
189 QList<QMimeMagicRuleMatcher> m_magicMatchers;
190 QStringList m_allFiles;
191};
192
193QT_END_NAMESPACE
194
195#endif // QMIMEPROVIDER_P_H
196

source code of qtbase/src/corelib/mimetypes/qmimeprovider_p.h