KIO

workerconfig.cpp
1// -*- c++ -*-
2/*
3 This file is part of the KDE libraries
4 SPDX-FileCopyrightText: 2001 Waldo Bastian <bastian@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-only
7*/
8
9#include "workerconfig.h"
10
11#include <QHash>
12#include <QThreadStorage>
13
14#include <KConfig>
15#include <KSharedConfig>
16#include <kprotocolinfo.h>
17#include <kprotocolmanager.h>
18
19using namespace KIO;
20
21namespace KIO
22{
23class WorkerConfigProtocol
24{
25public:
26 WorkerConfigProtocol() = default;
27 ~WorkerConfigProtocol()
28 {
29 delete configFile;
30 }
31
32 WorkerConfigProtocol(const WorkerConfigProtocol &) = delete;
33 WorkerConfigProtocol &operator=(const WorkerConfigProtocol &) = delete;
34
35public:
36 MetaData global;
38 KConfig *configFile;
39};
40
41static void readConfig(KConfig *config, const QString &group, MetaData *metaData)
42{
43 *metaData += config->entryMap(group);
44}
45
46class WorkerConfigPrivate
47{
48public:
49 void readGlobalConfig();
50 WorkerConfigProtocol *readProtocolConfig(const QString &_protocol);
51 WorkerConfigProtocol *findProtocolConfig(const QString &_protocol);
52 void readConfigProtocolHost(const QString &_protocol, WorkerConfigProtocol *scp, const QString &host);
53
54public:
55 MetaData global;
57};
58
59void WorkerConfigPrivate::readGlobalConfig()
60{
61 global.clear();
62 // Read stuff...
63 readConfig(KSharedConfig::openConfig().data(), QStringLiteral("Socks"), &global); // Socks settings.
64 global += KProtocolManager::entryMap(QStringLiteral("<default>"));
65}
66
67WorkerConfigProtocol *WorkerConfigPrivate::readProtocolConfig(const QString &_protocol)
68{
69 WorkerConfigProtocol *scp = protocol.value(_protocol, nullptr);
70 if (!scp) {
71 QString filename = KProtocolInfo::config(_protocol);
72 scp = new WorkerConfigProtocol;
73 scp->configFile = new KConfig(filename, KConfig::NoGlobals);
74 protocol.insert(_protocol, scp);
75 }
76 // Read global stuff...
77 readConfig(scp->configFile, QStringLiteral("<default>"), &(scp->global));
78 return scp;
79}
80
81WorkerConfigProtocol *WorkerConfigPrivate::findProtocolConfig(const QString &_protocol)
82{
83 WorkerConfigProtocol *scp = protocol.value(_protocol, nullptr);
84 if (!scp) {
85 scp = readProtocolConfig(_protocol);
86 }
87 return scp;
88}
89
90void WorkerConfigPrivate::readConfigProtocolHost(const QString &, WorkerConfigProtocol *scp, const QString &host)
91{
92 MetaData metaData;
93 scp->host.insert(host, metaData);
94
95 // Read stuff
96 // Break host into domains
97 QString domain = host;
98
99 if (!domain.contains(QLatin1Char('.'))) {
100 // Host without domain.
101 if (scp->configFile->hasGroup(QStringLiteral("<local>"))) {
102 readConfig(scp->configFile, QStringLiteral("<local>"), &metaData);
103 scp->host.insert(host, metaData);
104 }
105 }
106
107 int pos = 0;
108 do {
109 pos = host.lastIndexOf(QLatin1Char('.'), pos - 1);
110
111 if (pos < 0) {
112 domain = host;
113 } else {
114 domain = host.mid(pos + 1);
115 }
116
117 if (scp->configFile->hasGroup(domain)) {
118 readConfig(scp->configFile, domain.toLower(), &metaData);
119 scp->host.insert(host, metaData);
120 }
121 } while (pos > 0);
122}
123
124class WorkerConfigSingleton
125{
126public:
127 WorkerConfig instance;
128};
129
130template<typename T>
131T *perThreadGlobalStatic()
132{
133 static QThreadStorage<T *> s_storage;
134 if (!s_storage.hasLocalData()) {
135 s_storage.setLocalData(new T);
136 }
137 return s_storage.localData();
138}
139// Q_GLOBAL_STATIC(WorkerConfigSingleton, _self)
140// TODO: export symbol here, or make compile unit local by "static"?
141WorkerConfigSingleton *_workerConfigSelf()
142{
143 return perThreadGlobalStatic<WorkerConfigSingleton>();
144}
145
146WorkerConfig *WorkerConfig::self()
147{
148 return &_workerConfigSelf()->instance;
149}
150
151WorkerConfig::WorkerConfig()
152 : d(new WorkerConfigPrivate)
153{
154 d->readGlobalConfig();
155}
156
157WorkerConfig::~WorkerConfig()
158{
159 qDeleteAll(d->protocol);
160}
161
162void WorkerConfig::setConfigData(const QString &protocol, const QString &host, const QString &key, const QString &value)
163{
164 MetaData config;
165 config.insert(key, value);
166 setConfigData(protocol, host, config);
167}
168
169void WorkerConfig::setConfigData(const QString &protocol, const QString &host, const MetaData &config)
170{
171 if (protocol.isEmpty()) {
172 d->global += config;
173 } else {
174 WorkerConfigProtocol *scp = d->findProtocolConfig(protocol);
175 if (host.isEmpty()) {
176 scp->global += config;
177 } else {
178 if (!scp->host.contains(host)) {
179 d->readConfigProtocolHost(protocol, scp, host);
180 }
181
182 MetaData hostConfig = scp->host.value(host);
183 hostConfig += config;
184 scp->host.insert(host, hostConfig);
185 }
186 }
187}
188
190{
191 MetaData config = d->global;
192 WorkerConfigProtocol *scp = d->findProtocolConfig(protocol);
193 config += scp->global;
194 if (host.isEmpty()) {
195 return config;
196 }
197
198 if (!scp->host.contains(host)) {
199 d->readConfigProtocolHost(protocol, scp, host);
200 Q_EMIT configNeeded(protocol, host);
201 }
202 MetaData hostConfig = scp->host.value(host);
203 config += hostConfig;
204
205 return config;
206}
207
208QString WorkerConfig::configData(const QString &protocol, const QString &host, const QString &key)
209{
210 return configData(protocol, host).value(key);
211}
212
214{
215 qDeleteAll(d->protocol);
216 d->protocol.clear();
217 d->readGlobalConfig();
218}
219
220}
221
222#include "moc_workerconfig.cpp"
bool hasGroup(const QString &group) const
QMap< QString, QString > entryMap(const QString &aGroup=QString()) const
MetaData is a simple map of key/value strings.
This class manages the configuration for KIO workers based on protocol and host.
void reset()
Undo any changes made by calls to setConfigData.
void setConfigData(const QString &protocol, const QString &host, const QString &key, const QString &value)
Configure workers of type protocol by setting key to value.
void configNeeded(const QString &protocol, const QString &host)
This signal is raised when a worker of type protocol deals with host for the first time.
MetaData configData(const QString &protocol, const QString &host)
Query worker configuration for workers of type protocol when dealing with host.
static QString config(const QString &protocol)
Returns the name of the config file associated with the specified protocol.
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
A namespace for KIO globals.
iterator insert(const Key &key, const T &value)
T value(const Key &key) const const
void clear()
iterator insert(const Key &key, const T &value)
T value(const Key &key, const T &defaultValue) const const
Q_EMITQ_EMIT
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
qsizetype lastIndexOf(QChar ch, Qt::CaseSensitivity cs) const const
QString mid(qsizetype position, qsizetype n) const const
QString toLower() const const
bool hasLocalData() const const
void setLocalData(T data)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:58:45 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.