GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/configuration.h Lines: 24 39 61.5 %
Date: 2017-11-29 Branches: 31 112 27.7 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2004-2009  The Mana World Development Team
4
 *  Copyright (C) 2009-2010  The Mana Developers
5
 *  Copyright (C) 2011-2017  The ManaPlus Developers
6
 *
7
 *  This file is part of The ManaPlus Client.
8
 *
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or
12
 *  any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
#ifndef CONFIGURATION_H
24
#define CONFIGURATION_H
25
26
#include "utils/stringutils.h"
27
#ifdef ENABLE_PUGIXML
28
#include "utils/xmlwriter.h"
29
#else
30
#include "utils/xml.h"
31
#endif  // ENABLE_PUGIXML
32
33
#include "defaults.h"
34
#include "localconsts.h"
35
36
class ConfigListener;
37
class ConfigurationObject;
38
39
/**
40
 * Configuration list manager interface; responsible for
41
 * serializing/deserializing configuration choices in containers.
42
 *
43
 * \param T Type of the container elements to serialise
44
 * \param CONT Type of the container we (de)serialise
45
 */
46
template <class T, class CONT>
47
class ConfigurationListManager notfinal
48
{
49
    public:
50
2
        ConfigurationListManager()
51
        { }
52
53
        A_DELETE_COPY(ConfigurationListManager)
54
55
        /**
56
         * Writes a value into a configuration object
57
         *
58
         * \param value The value to write out
59
         * \param obj The configuation object to write to
60
         * \return obj, or otherwise NULL to indicate that this option should
61
         *         be skipped
62
         */
63
        virtual ConfigurationObject *writeConfigItem(const T &value,
64
                                                     ConfigurationObject
65
                                                     *const obj) const = 0;
66
67
        /**
68
         * Reads a value from a configuration object
69
         *
70
         * \param obj The configuration object to read from
71
         * \param container The container to insert the object to
72
         */
73
        virtual CONT readConfigItem(const ConfigurationObject *const obj,
74
                                    CONT container)
75
                                    const A_WARN_UNUSED = 0;
76
77
        virtual ~ConfigurationListManager()
78
        { }
79
};
80
81
/**
82
 * Configuration object, mapping values to names and possibly containing
83
 * lists of further configuration objects
84
 *
85
 * \ingroup CORE
86
 */
87
class ConfigurationObject notfinal
88
{
89
    friend class Configuration;
90
91
    public:
92
        A_DELETE_COPY(ConfigurationObject)
93
94
        virtual ~ConfigurationObject();
95
96
        /**
97
         * Sets an option using a string value.
98
         *
99
         * \param key Option identifier.
100
         * \param value Value.
101
         */
102
        virtual void setValue(const std::string &key,
103
                              const std::string &value);
104
105
        void deleteKey(const std::string &key);
106
107
        /**
108
         * Gets a value as string.
109
         *
110
         * \param key Option identifier.
111
         * \param deflt Default option if not there or error.
112
         */
113
        std::string getValue(const std::string &key,
114
                             const std::string &deflt) const A_WARN_UNUSED;
115
116
        int getValue(const std::string &key,
117
                     const int deflt) const A_WARN_UNUSED;
118
119
        int getValueInt(const std::string &key,
120
                        const int deflt) const A_WARN_UNUSED;
121
122
        bool getValueBool(const std::string &key,
123
                          const bool deflt) const A_WARN_UNUSED;
124
125
        unsigned getValue(const std::string &key,
126
                          const unsigned deflt) const A_WARN_UNUSED;
127
128
        double getValue(const std::string &key,
129
                        const double deflt) const A_WARN_UNUSED;
130
131
        /**
132
         * Re-sets all data in the configuration
133
         */
134
        void clear();
135
136
        /**
137
         * Serialises a container into a list of configuration options
138
         *
139
         * \param name Name of the list the elements should be stored under
140
         * \param begin Iterator start
141
         * \param end Iterator end
142
         * \param manager An object capable of serialising T items
143
         */
144
        template <class IT, class T, class CONT>
145
384
        void setList(const std::string &name, IT begin, IT end,
146
                     ConfigurationListManager<T, CONT> *manager)
147
        {
148
384
            if (!manager)
149
                return;
150
151
384
            ConfigurationObject *nextobj = new ConfigurationObject;
152
384
            deleteList(name);
153
384
            ConfigurationList *list = &(mContainerOptions[name]);
154
155
768
            for (IT it = begin; it != end; it++)
156
            {
157
                ConfigurationObject *const wrobj
158
                    = manager->writeConfigItem(*it, nextobj);
159
                if (wrobj)
160
                {   // wrote something
161
                    nextobj = new ConfigurationObject;
162
                    list->push_back(wrobj);
163
                }
164
                else
165
                {
166
                    nextobj->clear();  // you never know...
167
                }
168
            }
169
170
384
            delete nextobj;
171
        }
172
173
       /**
174
        * Serialises a container into a list of configuration options
175
        *
176
        * \param name Name of the list the elements should be read from under
177
        * \param empty Initial (empty) container to write to
178
        * \param manager An object capable of deserialising items into CONT
179
        */
180
        template<class T, class CONT>
181
        CONT getList(const std::string &name, CONT empty,
182
                     ConfigurationListManager<T, CONT> *manager)
183
        {
184
            ConfigurationList *const list = &(mContainerOptions[name]);
185
            CONT container = empty;
186
187
            if (!manager)
188
                return container;
189
190
            for (ConfigurationList::const_iterator it = list->begin();
191
                 it != list->end();
192
                 ++ it)
193
            {
194
                container = manager->readConfigItem(*it, container);
195
            }
196
197
            return container;
198
        }
199
200
#ifdef DEBUG_CONFIG
201
        void enableKeyLogging()
202
        { mLogKeys = true; }
203
204
        void setIsMain(bool b)
205
        { mIsMain = b; }
206
#endif  // DEBUG_CONFIG
207
208
    protected:
209
        ConfigurationObject();
210
211
        virtual void initFromXML(XmlNodeConstPtrConst parentNode);
212
        virtual void writeToXML(XmlTextWriterPtr writer);
213
214
        void deleteList(const std::string &name);
215
216
        typedef std::map<std::string, std::string> Options;
217
        Options mOptions;
218
219
        typedef std::list<ConfigurationObject *> ConfigurationList;
220
        std::map<std::string, ConfigurationList> mContainerOptions;
221
222
#ifdef DEBUG_CONFIG
223
        bool mLogKeys;
224
        bool mIsMain;
225
#endif  // DEBUG_CONFIG
226
};
227
228
#define valTest(num) mStatsRe##num
229
230
/**
231
 * Configuration handler for reading (and writing).
232
 *
233
 * \ingroup CORE
234
 */
235
class Configuration final : public ConfigurationObject
236
{
237
    public:
238
        Configuration();
239
240
        A_DELETE_COPY(Configuration)
241
242
        ~Configuration();
243
244
        /**
245
         * Reads config file and parse all options into memory.
246
         *
247
         * @param filename path to config file
248
         * @param useResManager Make use of the resource manager.
249
         */
250
        void init(const std::string &filename,
251
                  const UseVirtFs useResManager = UseVirtFs_false,
252
                  const SkipError skipError = SkipError_false);
253
254
        void reInit();
255
256
        void unload();
257
258
        DefaultsData &getDefaultValues()
259
2306
        { return mDefaultsData; }
260
261
        /**
262
         * Writes the current settings back to the config file.
263
         */
264
        void write();
265
266
        /**
267
         * Adds a listener to the listen list of the specified config option.
268
         */
269
        void addListener(const std::string &key,
270
                         ConfigListener *const listener);
271
272
        /**
273
         * Removes a listener from the listen list of the specified config
274
         * option.
275
         */
276
        void removeListener(const std::string &key,
277
                            ConfigListener *const listener);
278
279
        void removeListeners(ConfigListener *const listener);
280
281
#ifdef ENABLE_CHECKS
282
        void checkListeners(ConfigListener *const listener,
283
                            const char *const file,
284
                            const unsigned line);
285
#endif  // ENABLE_CHECKS
286
287
        void setValue(const std::string &key,
288
                      const std::string &value) override;
289
290
        void incValue(const std::string &key);
291
292
        void setSilent(const std::string &key,
293
                       const std::string &value);
294
295
3366
        inline void setValue(const std::string &key,
296
                             const char *const value)
297

13464
        { if (value != nullptr) setValue(key, std::string(value)); }
298
299
4
        inline void setSilent(const std::string &key,
300
                              const char *const value)
301

16
        { if (value != nullptr) setSilent(key, std::string(value)); }
302
303
558
        inline void setValue(const std::string &key,
304
                             const float value)
305
1116
        { setValue(key, toString(value)); }
306
307
2
        inline void setValue(const std::string &key,
308
                             const double value)
309
4
        { setValue(key, toString(value)); }
310
311
34562
        inline void setValue(const std::string &key,
312
                             const int value)
313
69124
        { setValue(key, toString(value)); }
314
315
        inline void setValueInt(const std::string &key,
316
                                const int value)
317
        { setValue(key, toString(value)); }
318
319
384
        inline void setValue(const std::string &key,
320
                             const unsigned value)
321
768
        { setValue(key, toString(value)); }
322
323
        inline void setValue(const std::string &key,
324
                             const bool value)
325
















3040
        { setValue(key, value ? "1" : "0"); }
326
327
        inline void setSilent(const std::string &key,
328
                              const bool value)
329

4
        { setSilent(key, value ? "1" : "0"); }
330
331
        int resetIntValue(const std::string &key);
332
333
        bool resetBoolValue(const std::string &key);
334
335
        const std::string &getConfigPath() const noexcept2 A_WARN_UNUSED
336
        { return mConfigPath; }
337
338
        /**
339
         * returns a value corresponding to the given key.
340
         * The default value returned in based on fallbacks registry.
341
         * @see defaults.h
342
         */
343
        int getIntValue(const std::string &key) const A_WARN_UNUSED_NON_TESTS;
344
345
        float getFloatValue(const std::string &key) const
346
                            A_WARN_UNUSED_NON_TESTS;
347
348
        std::string getStringValue(const std::string &key) const
349
                                   A_WARN_UNUSED_NON_TESTS;
350
351
        bool getBoolValue(const std::string &key) const
352
                          A_WARN_UNUSED_NON_TESTS;
353
354
        std::string getDirectory() const noexcept2 A_WARN_UNUSED
355
        { return mDirectory; }
356
357
        void removeOldKeys();
358
359
        std::string getFileName() const noexcept2 A_WARN_UNUSED
360
4612
        { return mFilename; }
361
362
        void writeUpdated();
363
364
        /**
365
         * Clean up the default values member.
366
         */
367
        void cleanDefaults();
368
369
    private:
370
        typedef std::list<ConfigListener*> Listeners;
371
        typedef Listeners::iterator ListenerIterator;
372
        typedef std::map<std::string, Listeners> ListenerMap;
373
        typedef ListenerMap::iterator ListenerMapIterator;
374
        ListenerMap mListenerMap;
375
376
        // Location of config file
377
        std::string mConfigPath;
378
        /// Defaults of value for a given key
379
        DefaultsData mDefaultsData;
380
        std::string mDirectory;
381
        std::string mFilename;
382
        UseVirtFs mUseResManager;
383
        bool mUpdated;
384
};
385
386
extern Configuration branding;
387
extern Configuration config;
388
extern Configuration serverConfig;
389
extern Configuration paths;
390
extern Configuration features;
391
392
#endif  // CONFIGURATION_H