1/*
2 * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#include "config.h"
24#include "resourcemanager.h"
25#include "configmanager.h"
26
27#include <framework/otml/otml.h>
28
29Config::Config()
30{
31 m_confsDoc = OTMLDocument::create();
32 m_fileName = "";
33}
34
35bool Config::load(const std::string& file)
36{
37 m_fileName = file;
38
39 if(!g_resources.fileExists(file))
40 return false;
41
42 try {
43 OTMLDocumentPtr confsDoc = OTMLDocument::parse(file);
44 if(confsDoc)
45 m_confsDoc = confsDoc;
46 return true;
47 } catch(stdext::exception& e) {
48 g_logger.error(stdext::format("Unable to parse configuration file '%s': ", e.what()));
49 return false;
50 }
51}
52
53bool Config::unload()
54{
55 if(isLoaded()) {
56 m_confsDoc = nullptr;
57 m_fileName = "";
58 return true;
59 }
60 return false;
61}
62
63bool Config::save()
64{
65 if(m_fileName.length() == 0)
66 return false;
67 return m_confsDoc->save(m_fileName);
68}
69
70void Config::clear()
71{
72 m_confsDoc->clear();
73}
74
75void Config::setValue(const std::string& key, const std::string& value)
76{
77 if (key.empty()) {
78 return;
79 }
80 if(value.empty()) {
81 remove(key);
82 return;
83 }
84
85 OTMLNodePtr child = OTMLNode::create(key, value);
86 m_confsDoc->addChild(child);
87}
88
89void Config::setList(const std::string& key, const std::vector<std::string>& list)
90{
91 remove(key);
92
93 if(list.size() == 0)
94 return;
95
96 OTMLNodePtr child = OTMLNode::create(key, true);
97 for(const std::string& value : list)
98 child->writeIn(value);
99 m_confsDoc->addChild(child);
100}
101
102bool Config::exists(const std::string& key)
103{
104 return m_confsDoc->hasChildAt(key);
105}
106
107std::string Config::getValue(const std::string& key)
108{
109 OTMLNodePtr child = m_confsDoc->get(key);
110 if(child)
111 return child->value();
112 else
113 return "";
114}
115
116std::vector<std::string> Config::getList(const std::string& key)
117{
118 std::vector<std::string> list;
119 OTMLNodePtr child = m_confsDoc->get(key);
120 if(child) {
121 for(const OTMLNodePtr& subchild : child->children())
122 list.push_back(subchild->value());
123 }
124 return list;
125}
126
127void Config::remove(const std::string& key)
128{
129 OTMLNodePtr child = m_confsDoc->get(key);
130 if(child)
131 m_confsDoc->removeChild(child);
132}
133
134void Config::setNode(const std::string& key, const OTMLNodePtr& node)
135{
136 remove(key);
137 mergeNode(key, node);
138}
139
140void Config::mergeNode(const std::string& key, const OTMLNodePtr& node)
141{
142 OTMLNodePtr clone = node->clone();
143 node->setTag(key);
144 node->setUnique(true);
145 m_confsDoc->addChild(node);
146}
147
148OTMLNodePtr Config::getNode(const std::string& key)
149{
150 return m_confsDoc->get(key);
151}
152
153int Config::getNodeSize(const std::string& key)
154{
155 auto node = m_confsDoc->get(key);
156 if (node)
157 return node->size();
158 return 0;
159}
160
161
162bool Config::isLoaded()
163{
164 return !m_fileName.empty() && m_confsDoc;
165}
166
167std::string Config::getFileName()
168{
169 return m_fileName;
170}
171