1 | /* |
2 | This file is part of the KDE libraries |
3 | SPDX-FileCopyrightText: 1999 Waldo Bastian <bastian@kde.org> |
4 | SPDX-FileCopyrightText: 2006-2009 David Faure <faure@kde.org> |
5 | |
6 | SPDX-License-Identifier: LGPL-2.0-or-later |
7 | */ |
8 | |
9 | #include "kmimetypefactory_p.h" |
10 | #include "ksycocaentry_p.h" |
11 | #include "servicesdebug.h" |
12 | #include <QDataStream> |
13 | #include <ksycoca.h> |
14 | #include <ksycocadict_p.h> |
15 | |
16 | extern int servicesDebugArea(); |
17 | |
18 | KMimeTypeFactory::KMimeTypeFactory(KSycoca *db) |
19 | : KSycocaFactory(KST_KMimeTypeFactory, db) |
20 | { |
21 | } |
22 | |
23 | KMimeTypeFactory::~KMimeTypeFactory() |
24 | { |
25 | } |
26 | |
27 | int KMimeTypeFactory::entryOffset(const QString &mimeTypeName) |
28 | { |
29 | if (!sycocaDict()) { |
30 | return -1; // Error! |
31 | } |
32 | assert(!sycoca()->isBuilding()); |
33 | const int offset = sycocaDict()->find_string(key: mimeTypeName.toLower()); |
34 | return offset; |
35 | } |
36 | |
37 | int KMimeTypeFactory::serviceOffersOffset(const QString &mimeTypeName) |
38 | { |
39 | const int offset = entryOffset(mimeTypeName: mimeTypeName.toLower()); |
40 | if (!offset) { |
41 | return -1; // Not found |
42 | } |
43 | |
44 | MimeTypeEntry::Ptr newMimeType(createEntry(offset)); |
45 | if (!newMimeType) { |
46 | return -1; |
47 | } |
48 | // Check whether the dictionary was right. |
49 | if (newMimeType->name() != mimeTypeName.toLower()) { |
50 | // No it wasn't... |
51 | return -1; |
52 | } |
53 | return newMimeType->serviceOffersOffset(); |
54 | } |
55 | |
56 | KMimeTypeFactory::MimeTypeEntry *KMimeTypeFactory::createEntry(int offset) const |
57 | { |
58 | KSycocaType type; |
59 | QDataStream *str = sycoca()->findEntry(offset, type); |
60 | if (!str) { |
61 | return nullptr; |
62 | } |
63 | |
64 | if (type != KST_KMimeTypeEntry) { |
65 | qCWarning(SERVICES) << "KMimeTypeFactory: unexpected object entry in KSycoca database (type=" << int(type) << ")" ; |
66 | return nullptr; |
67 | } |
68 | MimeTypeEntry *newEntry = new MimeTypeEntry(*str, offset); |
69 | if (newEntry && !newEntry->isValid()) { |
70 | qCWarning(SERVICES) << "KMimeTypeFactory: corrupt object in KSycoca database!\n" ; |
71 | delete newEntry; |
72 | newEntry = nullptr; |
73 | } |
74 | return newEntry; |
75 | } |
76 | |
77 | QStringList KMimeTypeFactory::allMimeTypes() |
78 | { |
79 | // TODO: reimplement in terms of "listing xdgdata-mime", to avoid ksycoca dependency, |
80 | // then move to KMimeTypeRepository |
81 | const KSycocaEntry::List list = allEntries(); |
82 | QStringList result; |
83 | result.reserve(asize: list.size()); |
84 | |
85 | std::transform(first: list.cbegin(), last: list.cend(), result: std::back_inserter(x&: result), unary_op: [](const KSycocaEntry::Ptr &entry) { |
86 | Q_ASSERT(entry->isType(KST_KMimeTypeEntry)); |
87 | |
88 | MimeTypeEntry::Ptr mimeType(static_cast<MimeTypeEntry *>(entry.data())); |
89 | return mimeType->name(); |
90 | }); |
91 | |
92 | return result; |
93 | } |
94 | |
95 | KMimeTypeFactory::MimeTypeEntry::Ptr KMimeTypeFactory::findMimeTypeEntryByName(const QString &name) |
96 | { |
97 | Q_ASSERT(sycoca()->isBuilding()); |
98 | // We're building a database - the MIME type entry must be in memory |
99 | KSycocaEntry::Ptr servType = m_entryDict->value(key: name.toLower()); |
100 | return MimeTypeEntry::Ptr(static_cast<MimeTypeEntry *>(servType.data())); |
101 | } |
102 | |
103 | QStringList KMimeTypeFactory::resourceDirs() |
104 | { |
105 | return KSycocaFactory::allDirectories(QStringLiteral("mime" )); |
106 | } |
107 | |
108 | //// |
109 | |
110 | class KMimeTypeFactory::MimeTypeEntryPrivate : public KSycocaEntryPrivate |
111 | { |
112 | public: |
113 | K_SYCOCATYPE(KST_KMimeTypeEntry, KSycocaEntryPrivate) |
114 | MimeTypeEntryPrivate(const QString &file, const QString &name) |
115 | : KSycocaEntryPrivate(file) |
116 | , m_name(name) |
117 | , m_serviceOffersOffset(-1) |
118 | { |
119 | } |
120 | MimeTypeEntryPrivate(QDataStream &s, int offset) |
121 | : KSycocaEntryPrivate(s, offset) |
122 | , m_serviceOffersOffset(-1) |
123 | { |
124 | s >> m_name >> m_serviceOffersOffset; |
125 | } |
126 | QString name() const override |
127 | { |
128 | return m_name; |
129 | } |
130 | void save(QDataStream &s) override; |
131 | |
132 | QString m_name; |
133 | int m_serviceOffersOffset; |
134 | }; |
135 | |
136 | void KMimeTypeFactory::MimeTypeEntryPrivate::save(QDataStream &s) |
137 | { |
138 | KSycocaEntryPrivate::save(s); |
139 | s << m_name << m_serviceOffersOffset; |
140 | } |
141 | |
142 | //// |
143 | |
144 | KMimeTypeFactory::MimeTypeEntry::MimeTypeEntry(const QString &file, const QString &name) |
145 | : KSycocaEntry(*new MimeTypeEntryPrivate(file, name.toLower())) |
146 | { |
147 | } |
148 | |
149 | KMimeTypeFactory::MimeTypeEntry::MimeTypeEntry(QDataStream &s, int offset) |
150 | : KSycocaEntry(*new MimeTypeEntryPrivate(s, offset)) |
151 | { |
152 | } |
153 | |
154 | KMimeTypeFactory::MimeTypeEntry::~MimeTypeEntry() |
155 | { |
156 | } |
157 | |
158 | int KMimeTypeFactory::MimeTypeEntry::serviceOffersOffset() const |
159 | { |
160 | Q_D(const MimeTypeEntry); |
161 | return d->m_serviceOffersOffset; |
162 | } |
163 | |
164 | void KMimeTypeFactory::MimeTypeEntry::setServiceOffersOffset(int off) |
165 | { |
166 | Q_D(MimeTypeEntry); |
167 | d->m_serviceOffersOffset = off; |
168 | } |
169 | |