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
16extern int servicesDebugArea();
17
18KMimeTypeFactory::KMimeTypeFactory(KSycoca *db)
19 : KSycocaFactory(KST_KMimeTypeFactory, db)
20{
21}
22
23KMimeTypeFactory::~KMimeTypeFactory()
24{
25}
26
27int 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
37int 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
56KMimeTypeFactory::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
77QStringList 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
95KMimeTypeFactory::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
103QStringList KMimeTypeFactory::resourceDirs()
104{
105 return KSycocaFactory::allDirectories(QStringLiteral("mime"));
106}
107
108////
109
110class KMimeTypeFactory::MimeTypeEntryPrivate : public KSycocaEntryPrivate
111{
112public:
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
136void KMimeTypeFactory::MimeTypeEntryPrivate::save(QDataStream &s)
137{
138 KSycocaEntryPrivate::save(s);
139 s << m_name << m_serviceOffersOffset;
140}
141
142////
143
144KMimeTypeFactory::MimeTypeEntry::MimeTypeEntry(const QString &file, const QString &name)
145 : KSycocaEntry(*new MimeTypeEntryPrivate(file, name.toLower()))
146{
147}
148
149KMimeTypeFactory::MimeTypeEntry::MimeTypeEntry(QDataStream &s, int offset)
150 : KSycocaEntry(*new MimeTypeEntryPrivate(s, offset))
151{
152}
153
154KMimeTypeFactory::MimeTypeEntry::~MimeTypeEntry()
155{
156}
157
158int KMimeTypeFactory::MimeTypeEntry::serviceOffersOffset() const
159{
160 Q_D(const MimeTypeEntry);
161 return d->m_serviceOffersOffset;
162}
163
164void KMimeTypeFactory::MimeTypeEntry::setServiceOffersOffset(int off)
165{
166 Q_D(MimeTypeEntry);
167 d->m_serviceOffersOffset = off;
168}
169

source code of kservice/src/services/kmimetypefactory.cpp