Something not fun.
[potpourri.git] / src / XMLParser.cpp
blobb932119e4eccb553b84ea9c9f3508a78048ca38a
1 // Copyright 2008 Brian Caine
3 // This file is part of Potpourri.
5 // Potpourri is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // Potpourri is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTIBILITY of FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with Potpourri. If not, see <http://www.gnu.org/licenses/>.
19 // NOTES:
21 // This is the implementation for XMLParser
23 #include <iostream>
25 #include "XMLParser.h"
27 using namespace fragrant;
29 XMLParser* XMLParser::getXMLParser()
31 if (pointer)
32 return pointer;
34 XMLParser* parser = new XMLParser();
36 if (!was_made)
38 delete parser;
39 parser = 0;
40 std::cerr << "XMLParser::getXMLParser(): Error making XMLParser"
41 << std::endl;
44 was_made = false;
46 pointer = parser;
47 return pointer;
50 XMLParser::~XMLParser()
52 pointer = 0;
53 xmlFreeParserCtxt(context_pointer);
54 xmlCleanupParser();
57 bool XMLParser::validateXMLData(xmlDocPtr document, std::string schema)
59 bool results;
61 xmlDocPtr relax_doc = 0;
63 xmlRelaxNGParserCtxtPtr relax_context = 0;
64 xmlRelaxNGPtr relax_pointer = 0;
65 xmlRelaxNGValidCtxtPtr relax_valid = 0;
67 std::string filename = relaxng_root + schema;
69 relax_doc = xmlCtxtReadFile(context_pointer,
70 filename.c_str(), 0, XML_PARSE_RECOVER);
72 results = static_cast<bool>(relax_doc);
74 if (results)
76 relax_context = xmlRelaxNGNewDocParserCtxt(relax_doc);
77 results = static_cast<bool>(relax_context);
80 if (results)
82 relax_pointer = xmlRelaxNGParse(relax_context);
83 results = static_cast<bool>(relax_pointer);
86 if (results)
88 relax_valid = xmlRelaxNGNewValidCtxt(relax_pointer);
89 results = static_cast<bool>(relax_valid);
92 if (results)
93 results = !xmlRelaxNGValidateDoc(relax_valid, document);
95 // clean up
97 if (relax_doc)
98 xmlFreeDoc(relax_doc);
100 if (relax_context)
101 xmlRelaxNGFreeParserCtxt(relax_context);
103 if (relax_pointer)
104 xmlRelaxNGFree(relax_pointer);
106 if (relax_valid)
107 xmlRelaxNGFreeValidCtxt(relax_valid);
109 return results;
112 XMLS_Results XMLParser::parseSprite(std::string input)
114 // defs
116 XMLS_Results results;
118 xmlDocPtr document = 0;
120 results.error = false;
122 document = xmlCtxtReadMemory(context_pointer,
123 input.c_str(), input.size(), 0, 0, XML_PARSE_RECOVER);
124 results.error = !document;
126 if (!results.error)
127 results.error = !validateXMLData(document, XMLS_RELAXNG);
129 // parse
131 xmlNode* root_node = xmlDocGetRootElement(document);
133 if (!results.error)
135 printDebugNode((xmlNode*)root_node);
137 xmlNode* cur_node = root_node->children;
138 for (cur_node; cur_node; cur_node = cur_node->next)
139 if (cur_node->type == XML_ELEMENT_NODE)
141 if (std::string((char*)(cur_node->name)) == XMLS_SOURCE)
143 XMLS_Source source = parseSpriteSource(cur_node);
144 results.sources.push_back(source);
146 if (std::string((char*)cur_node->name) == XMLS_SECTION)
148 XMLS_Section section = parseSpriteSection(cur_node);
149 results.sections.push_back(section);
151 if (std::string((char*)cur_node->name) == XMLS_SPRITE)
153 XMLS_Sprite sprite = parseSpriteSprite(cur_node);
154 results.sprites.push_back(sprite);
159 // clean up
161 if (document)
162 xmlFreeDoc(document);
164 return results;
167 void XMLParser::setRELAXNGRoot(std::string new_root)
169 relaxng_root = new_root;
170 return;
173 XMLS_Section XMLParser::parseSpriteSection(xmlNode *top)
175 XMLS_Section results;
176 results.error = true;
178 if (std::string((char*)top->name) != XMLS_SECTION)
179 return results;
180 else
181 results.error = false;
183 xmlNode* cur = 0;
184 for (cur = top->children; cur; cur = cur->next)
185 if (cur->type == XML_ELEMENT_NODE)
187 if (std::string((char*)cur->name) == XMLS_X)
188 results.x = strtol((char*)cur->children->content, 0, 10);
190 if (std::string((char*)cur->name) == XMLS_Y)
191 results.y = strtol((char*)cur->children->content, 0, 10);
193 if (std::string((char*)cur->name) == XMLS_WIDTH)
194 results.width = strtol((char*)cur->children->content, 0, 10);
196 if (std::string((char*)cur->name) == XMLS_HEIGHT)
197 results.height = strtol((char*)cur->children->content, 0, 10);
199 if (std::string((char*)cur->name) == XMLS_SOURCE)
200 results.source = std::string((char*)cur->children->content);
202 if (std::string((char*)cur->name) == XMLS_NAME)
203 results.name = std::string((char*)cur->children->content);
206 return results;
209 XMLS_Source XMLParser::parseSpriteSource(xmlNode *top)
211 XMLS_Source results;
212 results.error = true;
214 if (std::string((char*)top->name) != XMLS_SOURCE)
215 return results;
216 else
217 results.error = false;
219 xmlNode* cur;
220 for (cur = top->children; cur; cur = cur->next)
221 if (cur->type == XML_ELEMENT_NODE)
223 if (std::string((char*)cur->name) == XMLS_FILENAME)
224 results.filename = std::string((char*)cur->children->content);
226 if (std::string((char*)cur->name) == XMLS_NAME)
227 results.name = std::string((char*)cur->children->content);
230 return results;
233 XMLS_Sprite XMLParser::parseSpriteSprite(xmlNode *top)
235 XMLS_Sprite results;
236 results.error = true;
238 if (std::string((char*)top->name) != XMLS_SPRITE)
239 return results;
240 else
241 results.error = false;
243 xmlNode* cur;
244 for (cur = top->children; cur; cur = cur->next)
245 if (cur->type == XML_ELEMENT_NODE)
247 if (std::string((char*)cur->name) == XMLS_NAME)
248 results.name = std::string((char*)cur->children->content);
250 if (std::string((char*)cur->name) == XMLS_ITEMS)
251 results.items = parseSpriteItems(cur);
253 if (std::string((char*)cur->name) == XMLS_SEQUENCE)
254 results.frames = parseSpriteFrames(cur);
257 return results;
260 std::vector<std::string> XMLParser::parseSpriteItems(xmlNode* top)
262 std::vector<std::string> results;
264 if (std::string((char*)top->name) != XMLS_ITEMS)
265 return results;
267 xmlNode* cur;
268 for (cur = top->children; cur; cur = cur->next)
269 if (cur->type == XML_ELEMENT_NODE)
271 results.push_back(std::string((char*)cur->children->content));
274 return results;
277 std::vector<Frame> XMLParser::parseSpriteFrames(xmlNode* top)
279 std::vector<Frame> results;
281 if (std::string((char*)top->name) != XMLS_SEQUENCE)
282 return results;
284 xmlNode* cur;
285 for (cur = top->children; cur; cur = cur->next)
286 if (cur->type == XML_ELEMENT_NODE)
288 xmlNode* frame_cur;
289 Frame temp;
290 for (frame_cur = cur->children; frame_cur; frame_cur = frame_cur->next)
291 if (frame_cur->type = XML_ELEMENT_NODE)
293 if (std::string((char*)frame_cur->name) == XMLS_ITEM)
294 temp.frame = strtol((char*)frame_cur->children->content, 0, 10);
296 if (std::string((char*)frame_cur->name) == XMLS_DURATION)
297 temp.duration = strtol((char*)
298 frame_cur->children->content, 0, 10);
301 results.push_back(temp);
304 return results;
307 XMLParser::XMLParser()
309 LIBXML_TEST_VERSION
311 was_made = true;
313 context_pointer = 0;
314 context_pointer = xmlNewParserCtxt();
316 if (!context_pointer)
317 was_made = false;
320 bool XMLParser::was_made = false;
321 XMLParser* XMLParser::pointer = 0;
323 void fragrant::printDebugNode(xmlNode* top)
325 xmlNode* cur_node = 0;
326 for (cur_node = top; cur_node; cur_node = cur_node->next)
328 if (cur_node->type == XML_ELEMENT_NODE)
330 std::cout << "node type: Element, name: " << cur_node->name
331 << std::endl;
333 if (std::string((char*)cur_node->name) == "item")
334 std::cout << "THE NODE item is " << cur_node->children->content << std::endl;
337 if (cur_node->type == XML_TEXT_NODE)
339 std::cout << "node type: Text, value: " << cur_node->content
340 << std::endl;
343 fragrant::printDebugNode(static_cast<xmlNode*>(cur_node->children));
346 return;