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/>.
21 // This is the implementation for XMLParser
25 #include "XMLParser.h"
27 using namespace fragrant
;
29 XMLParser
* XMLParser::getXMLParser()
34 XMLParser
* parser
= new XMLParser();
40 std::cerr
<< "XMLParser::getXMLParser(): Error making XMLParser"
50 XMLParser::~XMLParser()
53 xmlFreeParserCtxt(context_pointer
);
57 bool XMLParser::validateXMLData(xmlDocPtr document
, std::string schema
)
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
);
76 relax_context
= xmlRelaxNGNewDocParserCtxt(relax_doc
);
77 results
= static_cast<bool>(relax_context
);
82 relax_pointer
= xmlRelaxNGParse(relax_context
);
83 results
= static_cast<bool>(relax_pointer
);
88 relax_valid
= xmlRelaxNGNewValidCtxt(relax_pointer
);
89 results
= static_cast<bool>(relax_valid
);
93 results
= !xmlRelaxNGValidateDoc(relax_valid
, document
);
98 xmlFreeDoc(relax_doc
);
101 xmlRelaxNGFreeParserCtxt(relax_context
);
104 xmlRelaxNGFree(relax_pointer
);
107 xmlRelaxNGFreeValidCtxt(relax_valid
);
112 XMLS_Results
XMLParser::parseSprite(std::string input
)
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
;
127 results
.error
= !validateXMLData(document
, XMLS_RELAXNG
);
131 xmlNode
* root_node
= xmlDocGetRootElement(document
);
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
);
162 xmlFreeDoc(document
);
167 void XMLParser::setRELAXNGRoot(std::string new_root
)
169 relaxng_root
= new_root
;
173 XMLS_Section
XMLParser::parseSpriteSection(xmlNode
*top
)
175 XMLS_Section results
;
176 results
.error
= true;
178 if (std::string((char*)top
->name
) != XMLS_SECTION
)
181 results
.error
= false;
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
);
209 XMLS_Source
XMLParser::parseSpriteSource(xmlNode
*top
)
212 results
.error
= true;
214 if (std::string((char*)top
->name
) != XMLS_SOURCE
)
217 results
.error
= false;
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
);
233 XMLS_Sprite
XMLParser::parseSpriteSprite(xmlNode
*top
)
236 results
.error
= true;
238 if (std::string((char*)top
->name
) != XMLS_SPRITE
)
241 results
.error
= false;
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
);
260 std::vector
<std::string
> XMLParser::parseSpriteItems(xmlNode
* top
)
262 std::vector
<std::string
> results
;
264 if (std::string((char*)top
->name
) != XMLS_ITEMS
)
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
));
277 std::vector
<Frame
> XMLParser::parseSpriteFrames(xmlNode
* top
)
279 std::vector
<Frame
> results
;
281 if (std::string((char*)top
->name
) != XMLS_SEQUENCE
)
285 for (cur
= top
->children
; cur
; cur
= cur
->next
)
286 if (cur
->type
== XML_ELEMENT_NODE
)
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
);
307 XMLParser::XMLParser()
314 context_pointer
= xmlNewParserCtxt();
316 if (!context_pointer
)
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
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
343 fragrant::printDebugNode(static_cast<xmlNode
*>(cur_node
->children
));