Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
Config.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Config.h"
7#include "Errors.h"
8
9#include <algorithm>
10#include <cctype>
11#include <fstream>
12
13namespace
14{
15 std::string Trim(std::string value)
16 {
17 std::string::iterator first = std::find_if(value.begin(), value.end(), [](unsigned char c) { return !std::isspace(c); });
18 std::string::reverse_iterator last = std::find_if(value.rbegin(), value.rend(), [](unsigned char c) { return !std::isspace(c); });
19
20 if (first == value.end())
21 return "";
22
23 return std::string(first, last.base());
24 }
25
26 std::string StripComment(std::string const& line)
27 {
28 bool quoted = false;
29 char quote = '\0';
30
31 for (std::string::size_type i = 0; i < line.size(); ++i)
32 {
33 char c = line[i];
34
35 if ((c == '"' || c == '\'') && (i == 0 || line[i - 1] != '\\'))
36 {
37 if (!quoted)
38 {
39 quoted = true;
40 quote = c;
41 }
42 else if (quote == c)
43 quoted = false;
44 }
45 else if (!quoted && (c == '#' || c == ';'))
46 return line.substr(0, i);
47 }
48
49 return line;
50 }
51
52 std::string StripQuotes(std::string value)
53 {
54 if (value.size() >= 2)
55 {
56 char first = value.front();
57 char last = value.back();
58
59 if ((first == '"' && last == '"') || (first == '\'' && last == '\''))
60 return value.substr(1, value.size() - 2);
61 }
62
63 return value;
64 }
65}
66
67// Defined here as it must not be exposed to end-users.
68bool ConfigMgr::GetValueHelper(const char* name, std::string& result)
69{
71
72 if (!_configLoaded)
73 return false;
74
75 for (Config::const_iterator section = _config.begin(); section != _config.end(); ++section)
76 {
77 ConfigSection::const_iterator value = section->second.find(name);
78 if (value != section->second.end())
79 {
80 result = value->second;
81 return true;
82 }
83 }
84
85 return false;
86}
87
88bool ConfigMgr::LoadInitial(char const* file)
89{
90 ASSERT(file);
91
93
94 _filename = file;
95 _config.clear();
96 _configLoaded = false;
97
98 if (LoadData(_filename.c_str()))
99 {
100 _configLoaded = true;
101 return true;
102 }
103
104 _config.clear();
105 return false;
106}
107
108bool ConfigMgr::LoadMore(char const* file)
109{
110 ASSERT(file);
112
113 GuardType guard(_configLock);
114
115 return LoadData(file);
116}
117
119{
120 return LoadInitial(_filename.c_str());
121}
122
123bool ConfigMgr::LoadData(char const* file)
124{
125 std::ifstream input(file);
126 if (!input.is_open())
127 return false;
128
129 std::string section;
130 std::string line;
131
132 while (std::getline(input, line))
133 {
134 line = Trim(StripComment(line));
135
136 if (line.empty())
137 continue;
138
139 if (line.front() == '[' && line.back() == ']')
140 {
141 section = Trim(line.substr(1, line.size() - 2));
142 _config[section];
143 continue;
144 }
145
146 std::string::size_type separator = line.find('=');
147 if (separator == std::string::npos)
148 continue;
149
150 std::string key = Trim(line.substr(0, separator));
151 std::string value = StripQuotes(Trim(line.substr(separator + 1)));
152
153 if (!key.empty())
154 _config[section][key] = value;
155 }
156
157 return true;
158}
159
160std::string ConfigMgr::GetStringDefault(const char* name, const std::string& def)
161{
162 std::string val;
163 return GetValueHelper(name, val) ? val : def;
164}
165
166bool ConfigMgr::GetBoolDefault(const char* name, bool def)
167{
168 std::string val;
169
170 if (!GetValueHelper(name, val))
171 return def;
172
173 return (val == "true" || val == "TRUE" || val == "yes" || val == "YES" ||
174 val == "1");
175}
176
177int ConfigMgr::GetIntDefault(const char* name, int def)
178{
179 std::string val;
180 return GetValueHelper(name, val) ? atoi(val.c_str()) : def;
181}
182
183float ConfigMgr::GetFloatDefault(const char* name, float def)
184{
185 std::string val;
186 return GetValueHelper(name, val) ? (float)atof(val.c_str()) : def;
187}
188
189std::string const& ConfigMgr::GetFilename()
190{
191 GuardType guard(_configLock);
192 return _filename;
193}
194
195std::list<std::string> ConfigMgr::GetKeysByString(std::string const& name)
196{
197 GuardType guard(_configLock);
198
199 std::list<std::string> keys;
200 if (!_configLoaded)
201 return keys;
202
203 for (Config::const_iterator section = _config.begin(); section != _config.end(); ++section)
204 {
205 for (ConfigSection::const_iterator value = section->second.begin(); value != section->second.end(); ++value)
206 {
207 size_t pos = value->first.find(name);
208
209 if (pos != std::string::npos)
210 keys.push_back(value->first);
211 }
212 }
213
214 return keys;
215}
#define ASSERT
Definition Errors.h:29
std::string _filename
Definition Config.h:55
std::string const & GetFilename()
Definition Config.cpp:189
bool LoadMore(char const *file)
Definition Config.cpp:108
bool LoadData(char const *file)
Definition Config.cpp:123
bool _configLoaded
Definition Config.h:57
int GetIntDefault(const char *name, int def)
Definition Config.cpp:177
Config _config
Definition Config.h:56
bool Reload()
Definition Config.cpp:118
std::list< std::string > GetKeysByString(std::string const &name)
Definition Config.cpp:195
std::lock_guard< std::mutex > GuardType
Definition Config.h:53
LockType _configLock
Definition Config.h:58
std::string GetStringDefault(const char *name, const std::string &def)
Definition Config.cpp:160
bool LoadInitial(char const *file)
Method used only for loading main configuration files (authserver.conf and worldserver....
Definition Config.cpp:88
float GetFloatDefault(const char *name, float def)
Definition Config.cpp:183
bool GetBoolDefault(const char *name, bool def)
Definition Config.cpp:166
bool GetValueHelper(const char *name, std::string &result)
Definition Config.cpp:68