OSDN Git Service

First version
[st-ro/stro.git] / src / common / yamlwrapper.cpp
1 /**
2 *               This file is a part of rAthena++.
3 *               Copyright(C) 2017 rAthena Development Team
4 *               https://rathena.org - https://github.com/rathena
5 *
6 *       This program is free software: you can redistribute it and/or modify
7 *       it under the terms of the GNU General Public License as published by
8 *       the Free Software Foundation, either version 3 of the License, or
9 *       (at your option) any later version.
10 *
11 *       This program is distributed in the hope that it will be useful,
12 *       but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *       GNU General Public License for more details.
15 *
16 *       You should have received a copy of the GNU General Public License
17 *       along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 *       Author(s)
20 *               Jittapan Pluemsumran <secret@rathena.org>
21 */
22
23 #include "yamlwrapper.h"
24 #include <cstring>
25 #include "malloc.h"
26 #include "showmsg.h"
27
28 extern "C" {
29
30 yamlwrapper::yamlwrapper(YAML::Node node) {
31         try {
32                 this->root = node;
33         }
34         catch (std::exception) {
35                 //ignore
36         }
37 }
38
39 yamliterator::yamliterator(YAML::Node sequence_) {
40         this->sequence = sequence_;
41         this->index = 0;
42 }
43
44 yamliterator* yamlwrapper::iterator() {
45         return new yamliterator(this->root);
46 }
47
48 yamlwrapper* yaml_load_file(const char* file_name) {
49         YAML::Node node;
50
51         try {
52                 node = YAML::LoadFile(file_name);
53         } catch (YAML::ParserException &e) {
54                 ShowError("YAML Exception Caught: %s\n", e.what());
55                 return NULL;
56         } catch (YAML::BadFile) {
57                 return NULL;
58         }
59
60         return new yamlwrapper(node);
61 }
62
63 extern "C++" YAML::Node yaml_get_node(const YAML::Node& node,const std::string& key) {
64         if (key.empty())
65                 return node;
66
67         size_t pos = key.find('.');
68
69         if (pos == std::string::npos)
70                 return node[key];
71         else
72                 return yaml_get_node(node[key.substr(0, pos)], key.substr(pos+1));
73 }
74
75 void yaml_destroy_wrapper(yamlwrapper* wrapper) {
76         delete wrapper;
77 }
78
79 char* yaml_get_c_string(yamlwrapper* wrapper, const char* key) {
80         std::string cpp_str = yaml_get_node(wrapper->root, std::string(key)).as<std::string>();
81         const char* c_str = cpp_str.c_str();
82         size_t str_size = std::strlen(c_str) + 1;
83         char* buf = (char*)aCalloc(1, str_size);
84         strcpy(buf, c_str);
85         return buf;
86 }
87
88 extern "C++" {
89         template<typename T>
90         T yaml_get_value(yamlwrapper* wrapper, const char* key) {
91                 if (wrapper == nullptr || key == nullptr)
92                         return {};
93                 try {
94                         return yaml_get_node(wrapper->root, std::string(key)).as<T>();
95                 }
96                 catch (const std::exception& e) {
97                         ShowError("Error during YAML node value resolving in node %s.\n", e.what());
98                         return {};
99                 }
100         }
101 }
102
103 int yaml_get_int(yamlwrapper* wrapper, const char* key) {
104         return yaml_get_value<int>(wrapper, key);
105 }
106
107 int16 yaml_get_int16(yamlwrapper* wrapper, const char* key) {
108         return yaml_get_value<int16>(wrapper, key);
109 }
110
111 int32 yaml_get_int32(yamlwrapper* wrapper, const char* key) {
112         return yaml_get_value<int32>(wrapper, key);
113 }
114
115 int64 yaml_get_int64(yamlwrapper* wrapper, const char* key) {
116         return yaml_get_value<int64>(wrapper, key);
117 }
118
119 int yaml_get_uint(yamlwrapper* wrapper, const char* key) {
120         return yaml_get_value<unsigned int>(wrapper, key);
121 }
122
123 int16 yaml_get_uint16(yamlwrapper* wrapper, const char* key) {
124         return yaml_get_value<uint16>(wrapper, key);
125 }
126
127 int32 yaml_get_uint32(yamlwrapper* wrapper, const char* key) {
128         return yaml_get_value<uint32>(wrapper, key);
129 }
130
131 int64 yaml_get_uint64(yamlwrapper* wrapper, const char* key) {
132         return yaml_get_value<uint64>(wrapper, key);
133 }
134
135 bool yaml_get_boolean(yamlwrapper* wrapper, const char* key) {
136         return yaml_get_value<bool>(wrapper, key);
137 }
138
139 char* yaml_as_c_string(yamlwrapper* wrapper) {
140         std::string cpp_str = wrapper->root.as<std::string>();
141         const char* c_str = cpp_str.c_str();
142         size_t str_size = std::strlen(c_str) + 1;
143         char* buf = (char*)aCalloc(1, str_size);
144         strcpy(buf, c_str);
145         return buf;
146 }
147
148 extern "C++" {
149         template<typename T>
150         T yaml_as_value(yamlwrapper* wrapper) {
151                 if (wrapper == nullptr)
152                         return {};
153                 try {
154                         return wrapper->root.as<T>();
155                 }
156                 catch (const std::exception& e) {
157                         ShowError("Error during YAML node value resolving in node %s.\n", e.what());
158                         return {};
159                 }
160         }
161 }
162
163 int yaml_as_int(yamlwrapper* wrapper) {
164         return yaml_as_value<int>(wrapper);
165 }
166
167 int16 yaml_as_int16(yamlwrapper* wrapper) {
168         return yaml_as_value<int16>(wrapper);
169 }
170
171 int32 yaml_as_int32(yamlwrapper* wrapper) {
172         return yaml_as_value<int32>(wrapper);
173 }
174
175 int64 yaml_as_int64(yamlwrapper* wrapper) {
176         return yaml_as_value<int64>(wrapper);
177 }
178
179 int yaml_as_uint(yamlwrapper* wrapper) {
180         return yaml_as_value<unsigned int>(wrapper);
181 }
182
183 int16 yaml_as_uint16(yamlwrapper* wrapper) {
184         return yaml_as_value<uint16>(wrapper);
185 }
186
187 int32 yaml_as_uint32(yamlwrapper* wrapper) {
188         return yaml_as_value<uint32>(wrapper);
189 }
190
191 int64 yaml_as_uint64(yamlwrapper* wrapper) {
192         return yaml_as_value<uint64>(wrapper);
193 }
194
195 bool yaml_as_boolean(yamlwrapper* wrapper) {
196         return yaml_as_value<bool>(wrapper);
197 }
198
199 bool yaml_node_is_defined(yamlwrapper* wrapper, const char* key) {
200         if (wrapper == nullptr || key == nullptr)
201                 return false;
202         return yaml_get_node(wrapper->root, std::string(key)).IsDefined();
203 }
204
205 yamlwrapper* yaml_get_subnode(yamlwrapper* wrapper, const char* key) {
206         return new yamlwrapper(yaml_get_node(wrapper->root, std::string(key)));
207 }
208
209 char* yaml_verify_nodes(yamlwrapper* wrapper, int amount, char** nodes) {
210         for (int i = 0; i < amount; i++) {
211                 if (!yaml_node_is_defined(wrapper, nodes[i]))
212                         return nodes[i];
213         }
214         return NULL;
215 }
216
217 yamliterator* yaml_get_iterator(yamlwrapper* wrapper) {
218         return new yamliterator(wrapper->root);
219 }
220
221 bool yaml_iterator_is_valid(yamliterator* it) {
222         return it->sequence.IsSequence();
223 }
224
225 yamlwrapper* yaml_iterator_first(yamliterator* it) {
226         it->index++;
227         return new yamlwrapper(it->sequence[0]);
228 }
229
230 yamlwrapper* yaml_iterator_next(yamliterator* it) {
231         return new yamlwrapper(it->sequence[it->index++]);
232 }
233
234 bool yaml_iterator_has_next(yamliterator* it) {
235         return it->index <= it->sequence.size();
236 }
237
238 void yaml_iterator_destroy(yamliterator* it) {
239         delete it;
240 }
241
242 } /* extern "C" */