1 | /* |
2 | This file is part of the KDE libraries |
3 | SPDX-FileCopyrightText: 2000 Waldo Bastian <bastian@kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #include "kservice.h" |
9 | #include "kservicegroupfactory_p.h" |
10 | #include "ksycoca.h" |
11 | #include "ksycocadict_p.h" |
12 | #include "ksycocatype.h" |
13 | |
14 | #include "servicesdebug.h" |
15 | |
16 | #include <QIODevice> |
17 | |
18 | KServiceGroupFactory::KServiceGroupFactory(KSycoca *db) |
19 | : KSycocaFactory(KST_KServiceGroupFactory, db) |
20 | , m_baseGroupDict(nullptr) |
21 | , m_baseGroupDictOffset(0) |
22 | { |
23 | if (!sycoca()->isBuilding()) { |
24 | QDataStream *str = stream(); |
25 | if (!str) { |
26 | return; |
27 | } |
28 | // Read Header |
29 | qint32 i; |
30 | (*str) >> i; |
31 | m_baseGroupDictOffset = i; |
32 | |
33 | const qint64 saveOffset = str->device()->pos(); |
34 | // Init index tables |
35 | m_baseGroupDict = new KSycocaDict(str, m_baseGroupDictOffset); |
36 | str->device()->seek(pos: saveOffset); |
37 | } |
38 | } |
39 | |
40 | KServiceGroupFactory::~KServiceGroupFactory() |
41 | { |
42 | delete m_baseGroupDict; |
43 | } |
44 | |
45 | KServiceGroup::Ptr KServiceGroupFactory::findGroupByDesktopPath(const QString &_name, bool deep) |
46 | { |
47 | if (!sycocaDict()) { |
48 | return KServiceGroup::Ptr(); // Error! |
49 | } |
50 | int offset = sycocaDict()->find_string(key: _name); |
51 | if (!offset) { |
52 | return KServiceGroup::Ptr(); // Not found |
53 | } |
54 | |
55 | KServiceGroup::Ptr newGroup(createGroup(offset, deep)); |
56 | |
57 | // Check whether the dictionary was right. |
58 | if (newGroup && (newGroup->relPath() != _name)) { |
59 | // No it wasn't... |
60 | newGroup = nullptr; // Not found |
61 | } |
62 | return newGroup; |
63 | } |
64 | |
65 | KServiceGroup::Ptr KServiceGroupFactory::findBaseGroup(const QString &_baseGroupName, bool deep) |
66 | { |
67 | if (!m_baseGroupDict) { |
68 | return KServiceGroup::Ptr(); // Error! |
69 | } |
70 | |
71 | // Warning : this assumes we're NOT building a database |
72 | // But since findBaseGroup isn't called in that case... |
73 | // [ see KServiceTypeFactory for how to do it if needed ] |
74 | |
75 | int offset = m_baseGroupDict->find_string(key: _baseGroupName); |
76 | if (!offset) { |
77 | return KServiceGroup::Ptr(); // Not found |
78 | } |
79 | |
80 | KServiceGroup::Ptr newGroup(createGroup(offset, deep)); |
81 | |
82 | // Check whether the dictionary was right. |
83 | if (newGroup && (newGroup->baseGroupName() != _baseGroupName)) { |
84 | // No it wasn't... |
85 | newGroup = nullptr; // Not found |
86 | } |
87 | return newGroup; |
88 | } |
89 | |
90 | KServiceGroup *KServiceGroupFactory::createGroup(int offset, bool deep) const |
91 | { |
92 | KSycocaType type; |
93 | QDataStream *str = sycoca()->findEntry(offset, type); |
94 | if (type != KST_KServiceGroup) { |
95 | qCWarning(SERVICES) << "KServiceGroupFactory: unexpected object entry in KSycoca database (type = " << int(type) << ")" ; |
96 | return nullptr; |
97 | } |
98 | |
99 | KServiceGroup *newEntry = new KServiceGroup(*str, offset, deep); |
100 | if (!newEntry->isValid()) { |
101 | qCWarning(SERVICES) << "KServiceGroupFactory: corrupt object in KSycoca database!" ; |
102 | delete newEntry; |
103 | newEntry = nullptr; |
104 | } |
105 | return newEntry; |
106 | } |
107 | |
108 | KServiceGroup *KServiceGroupFactory::createEntry(int offset) const |
109 | { |
110 | return createGroup(offset, deep: true); |
111 | } |
112 | |
113 | void KServiceGroupFactory::virtual_hook(int id, void *data) |
114 | { |
115 | KSycocaFactory::virtual_hook(id, data); |
116 | } |
117 | |