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