CSEngine
Loading...
Searching...
No Matches
XML.cpp
1#include "../../AssetsDef.h"
2#include "XML.h"
3#include "../../../Manager/AssetMgr.h"
4
5/************************************************************************************************************************************************/
6
7XValue::XValue() {}
8
9XValue::XValue(const std::string& str) : std::string(str) {}
10
11XValue& XValue::operator=(const std::string& str) {
12 this->assign(str);
13 return *this;
14}
15
16std::vector<float> XValue::toFloatVector() const {
17 std::string buffer = "";
18 std::vector<float> array;
19
20 for (unsigned int i = 0; i < this->length(); i++) {
21 int acsii = (int) this->at(i);
22 buffer += (char) acsii;
23
24 if (acsii == 32 || i == this->length() - 1) {
25 float f = atof(buffer.c_str());
26 array.push_back(f);
27 buffer.clear();
28 }
29 }
30
31 return array;
32}
33
34std::vector<int> XValue::toIntegerVector() const {
35 std::string buffer = "";
36 std::vector<int> array;
37
38 for (unsigned int i = 0; i < this->length(); i++) {
39 int acsii = (int) this->at(i);
40 buffer += (char) acsii;
41
42 if (acsii == 32 || i == this->length() - 1) {
43 float f = atoi(buffer.c_str());
44 array.push_back(f);
45 buffer.clear();
46 }
47 }
48
49 return array;
50}
51
52std::vector<std::string> XValue::toStringVector() const {
53 std::string buffer = "";
54 std::vector<std::string> array;
55
56 for (unsigned int i = 0; i < this->length(); i++) {
57 int acsii = (int) this->at(i);
58 if(acsii != 32)
59 buffer += (char) acsii;
60
61 if (acsii == 32 || i == this->length() - 1) {
62 array.push_back(buffer);
63 buffer.clear();
64 }
65 }
66
67 return array;
68}
69
70/************************************************************************************************************************************************/
71
72XAttrib::XAttrib() {}
73
74XAttrib::XAttrib(const std::string& str) {
75 size_t index = str.find('=');
76 name = str.substr(0, index); // copy the name from the indices: 0 to the equal to sign's index
77 value = str.substr(index + 2, str.substr(index + 2).size() -
78 1); // copy the value, skip the equal to sign and the 2 quotation marks
79}
80
81XAttrib::XAttrib(const char* _name, const char* _value) {
82 this->name = std::string(_name);
83 this->value = std::string(_value);
84}
85
86std::string XAttrib::toString() const {
87 return (name + "=\"" + value + "\"");
88}
89
90/************************************************************************************************************************************************/
91
92const XNode* XNode::_getNode(const char* node_name) const {
93 if (strcmp(node_name, this->name.c_str()) == 0)
94 return this;
95
96 for (unsigned int i = 0; i < this->children.size(); i++) {
97 const XNode* res = this->children.at(i)._getNode(node_name);
98 if (res != NULL) return res;
99 }
100
101 return NULL;
102}
103
104const XNode*
105XNode::_getNodeByAttribute(const char* node_name, const char* attrib_name, const char* attrib_value) const {
106 if (node_name == NULL || strcmp(node_name, this->name.c_str()) == 0) {
107 for (unsigned int i = 0; i < this->attributes.size(); i++) {
108 if (attrib_name == NULL || strcmp(attrib_name, this->attributes.at(i).name.c_str()) == 0) {
109 if (attrib_value == NULL || strcmp(attrib_value, this->attributes.at(i).value.c_str()) == 0) {
110 return this;
111 }
112 }
113 }
114 }
115
116 for (unsigned int i = 0; i < this->children.size(); i++) {
117 const XNode* res = this->children.at(i)._getNodeByAttribute(node_name, attrib_name, attrib_value);
118 if (res != NULL) return res;
119 }
120
121 return NULL;
122}
123
124XNode::XNode() {
125 this->parent = NULL;
126 this->name = "";
127 this->value = "";
128 this->attributes = std::vector<XAttrib>();
129 this->children = std::vector<XNode>();
130}
131
132void XNode::print() const // print the string representation in the format: name: value ...attributes...
133{
134 printf("%s: [%s] ", name.c_str(), value.c_str());
135 for (unsigned int i = 0; i < this->attributes.size(); i++)
136 printf("%s ", this->attributes.at(i).toString().c_str());
137 printf("\n");
138}
139
140const XNode& XNode::getNode(const char* name) const {
141 const XNode* res = this->_getNode(name);
142 if (!res) {
143 printf("Error: Node [%s] not found.", name);
144 throw -1;
145 }
146 return *res;
147}
148
149const XAttrib& XNode::getAttribute(const char* name) const {
150 for (unsigned int i = 0; i < this->attributes.size(); i++) {
151 if (strcmp(this->attributes.at(i).name.c_str(), name) == 0) return this->attributes.at(i);
152 }
153
154 printf("Warning: Attribute [%s] not found.", name);
155 throw -1;
156}
157
158bool XNode::hasAttribute(const char* name) const {
159 for (const auto & attribute : this->attributes) {
160 if (strcmp(attribute.name.c_str(), name) == 0) return true;
161 }
162 return false;
163}
164
165const XNode& XNode::getNodeByAttribute(const char* node_name, const char* attrib_name, const char* attrib_value) const {
166 const XNode* res = this->_getNodeByAttribute(node_name, attrib_name, attrib_value);
167 if (!res) {
168 printf("Warning: Node with ");
169 if (node_name != NULL) printf("name \"%s\" and ", node_name);
170 printf("attribute [");
171 printf("%s=", attrib_name == NULL ? "\"\"" : attrib_name);
172 printf("%s", attrib_value == NULL ? "\"\"" : attrib_value);
173 printf("] not found.\n");
174 throw -1;
175 }
176 return *res;
177}
178
179bool XNode::hasNodeByAttribute(const char* node_name, const char* attrib_name, const char* attrib_value) const {
180 const XNode* res = this->_getNodeByAttribute(node_name, attrib_name, attrib_value);
181 return res != nullptr;
182}
183
184const XNode& XNode::getChild(const char* name) const {
185 for (unsigned int i = 0; i < this->children.size(); i++) {
186 if (strcmp(this->children[i].name.c_str(), name) == 0) return this->children[i];
187 }
188
189 printf("Error: Node [%s] not found.\n", name);
190 throw -1;
191}
192
193bool XNode::hasChild(const char* name) const {
194 for (const auto & child : this->children) {
195 if (strcmp(child.name.c_str(), name) == 0) return true;
196 }
197 return false;
198}
199
200/************************************************************************************************************************************************/
201
202int XFILE::read(std::string& buffer) {
203 buffer.clear();
204 for (; file_index < file.length(); file_index++) {
205 //file_index++;
206 char c = file[file_index];
207 if (c == '>') {
208 file_index++; // get the next character to check what kind of a line this is
209
210// if (file_index >= file.length() && c != '\n') // move back if we have not reached the end of the file or line
211// file_index--;
212
213 return XML_NODE; // this must be a node since this statement was ended by '>'
214 } else if (c == '<' && buffer.length() > 0) {
215 return XML_VALUE; // this must be a value since this statement was ended by '<'
216 } else if (c != '<') // check again if this isnt '<' since the last statement checks length as well
217 {
218 if (c == ' ' && buffer.length() == 0)
219 continue;
220 buffer += c;
221 }
222 }
223
224 return XML_EOF; // if we have reached here then the file is done being read
225}
226
227const XNode* XFILE::loadBuffer(std::string buffer) {
228 this->file = buffer;
229 if (file.empty()) {
230 throw -1;
231 }
232
233 return this->getRoot();
234}
235
236XFILE::XFILE(const char* str) { // read the file into the node heirchy
237 this->file = CSE::AssetMgr::LoadAssetFile(str);
238 if (file.empty()) {
239#ifndef __ANDROID__
240 printf("XML file [%s] not found!\n", str);
241#endif
242 throw -1;
243 }
244}
245
246const XNode* XFILE::getRoot() {
247 XNode* root = new XNode();
248 XNode* current = root;
249
250 std::string buffer;
251 int ret = 0;
252 while (ret = read(buffer), ret != XML_EOF) // read the next node/value
253 {
254 if (buffer[0] == '?') // comment
255 continue;
256
257 else if (buffer[0] == '/') // end of node
258 {
259 if (buffer.substr(1) != current->name) // confirm the node names match
260 printf("[WARNING]: Name mismatch: [%s] vs [%s]\n", buffer.substr(1).c_str(), current->name.c_str());
261 current = current->parent;
262 } else if (ret == XML_VALUE) { // if this is a value string, we simply set it to the current node
263 current->value = buffer;
264 }
265 else if (buffer.find(' ') == std::string::npos) // this node has no attributes, simply append it to the children
266 {
267 XNode node = XNode();
268 node.name = buffer;
269 node.sub_index = file_index;
270 node.parent = current;
271 current->children.push_back(node);
272
273 if (buffer.back() != '/') // this node does not instant terminate, set it to the current node
274 current = &current->children.back();
275 else // this node does instant terminate, make sure you remove the '/' at the end
276 current->children.back().name.pop_back();
277 } else // this node does have attributes
278 {
279 char* str = (char*) malloc(buffer.length() + 1); // allocate and initalize the buffer
280 if (!str) throw -1;
281 strcpy(str, buffer.c_str());
282
283 char* token = strtok(str, " "); // start tokenizing
284 XNode node = XNode();
285 node.sub_index = file_index;
286 node.name = token; // the first token is the name
287 node.parent = current;
288
289 while (true) // parse the attribute tokens
290 {
291 token = strtok(NULL, " "); // get the next token
292 if (token == NULL)
293 break;
294
295 if (token[strlen(token) - 1] == '/') // if the current token ends with a '/', then remove it
296 token[strlen(token) - 1] = '\0';
297
298 XAttrib attribute = XAttrib(std::string(token));
299 node.attributes.push_back(attribute);
300 }
301
302 current->children.push_back(node);
303 if (buffer.back() != '/') // if this node does not instant-terminate, set it to the current node
304 current = &current->children.back();
305 free(str);
306 }
307// current->file_end = file_index;
308 }
309
310 return root;
311}
312
313XFILE::~XFILE() {
314// fclose(this->file);
315}
Definition XML.h:29
Definition XML.h:43
Definition XML.h:14