2 * \file easyxml.cxx - implementation of EasyXML interfaces.
3 * Written by David Megginson, 2000-2001
4 * This file is in the Public Domain, and comes with NO WARRANTY of any kind.
8 # include <simgear_config.h>
11 #include <simgear/compiler.h>
13 #include <string.h> // strcmp()
15 #include "easyxml.hxx"
20 # include "sg_expat.h"
31 ////////////////////////////////////////////////////////////////////////
32 // Implementation of XMLAttributes.
33 ////////////////////////////////////////////////////////////////////////
35 XMLAttributes::XMLAttributes ()
39 XMLAttributes::~XMLAttributes ()
44 XMLAttributes::findAttribute (const char * name) const
47 for (int i = 0; i < s; i++) {
48 if (strcmp(name, getName(i)) == 0)
55 XMLAttributes::hasAttribute (const char * name) const
57 return (findAttribute(name) != -1);
61 XMLAttributes::getValue (const char * name) const
63 int pos = findAttribute(name);
71 ////////////////////////////////////////////////////////////////////////
72 // Implementation of XMLAttributesDefault.
73 ////////////////////////////////////////////////////////////////////////
75 XMLAttributesDefault::XMLAttributesDefault ()
79 XMLAttributesDefault::XMLAttributesDefault (const XMLAttributes &atts)
82 for (int i = 0; i < s; i++)
83 addAttribute(atts.getName(i), atts.getValue(i));
86 XMLAttributesDefault::~XMLAttributesDefault ()
91 XMLAttributesDefault::size () const
93 return _atts.size() / 2;
97 XMLAttributesDefault::getName (int i) const
99 return _atts[i*2].c_str();
103 XMLAttributesDefault::getValue (int i) const
105 return _atts[i*2+1].c_str();
109 XMLAttributesDefault::addAttribute (const char * name, const char * value)
111 _atts.push_back(name);
112 _atts.push_back(value);
116 XMLAttributesDefault::setName (int i, const char * name)
122 XMLAttributesDefault::setValue (int i, const char * name)
128 XMLAttributesDefault::setValue (const char * name, const char * value)
130 int pos = findAttribute(name);
133 setValue(pos, value);
135 addAttribute(name, value);
140 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142 void XMLVisitor::savePosition(void)
145 column = XML_GetCurrentColumnNumber(parser);
146 line = XML_GetCurrentLineNumber(parser);
150 ////////////////////////////////////////////////////////////////////////
151 // Attribute list wrapper for Expat.
152 ////////////////////////////////////////////////////////////////////////
155 ExpatAtts::size () const
158 for (int i = 0; _atts[i] != 0; i += 2)
164 ExpatAtts::getName (int i) const
170 ExpatAtts::getValue (int i) const
176 ExpatAtts::getValue (const char * name) const
178 return XMLAttributes::getValue(name);
182 ////////////////////////////////////////////////////////////////////////
183 // Static callback functions for Expat.
184 ////////////////////////////////////////////////////////////////////////
186 #define VISITOR (*((XMLVisitor *)userData))
189 start_element (void * userData, const char * name, const char ** atts)
191 VISITOR.savePosition();
192 VISITOR.startElement(name, ExpatAtts(atts));
196 end_element (void * userData, const char * name)
198 VISITOR.savePosition();
199 VISITOR.endElement(name);
203 character_data (void * userData, const char * s, int len)
205 VISITOR.savePosition();
206 VISITOR.data(s, len);
210 processing_instruction (void * userData,
214 VISITOR.savePosition();
215 VISITOR.pi(target, data);
222 ////////////////////////////////////////////////////////////////////////
223 // Implementation of XMLReader.
224 ////////////////////////////////////////////////////////////////////////
227 readXML (istream &input, XMLVisitor &visitor, const string &path)
229 XML_Parser parser = XML_ParserCreate(0);
230 XML_SetUserData(parser, &visitor);
231 XML_SetElementHandler(parser, start_element, end_element);
232 XML_SetCharacterDataHandler(parser, character_data);
233 XML_SetProcessingInstructionHandler(parser, processing_instruction);
235 visitor.setParser(parser);
236 visitor.setPath(path);
240 while (!input.eof()) {
242 // FIXME: get proper error string from system
244 sg_io_exception ex ("Problem reading file",
246 XML_GetCurrentLineNumber(parser),
247 XML_GetCurrentColumnNumber(parser)),
248 "SimGear XML Parser");
249 visitor.setParser(0);
250 XML_ParserFree(parser);
254 input.read(buf,16384);
255 if (!XML_Parse(parser, buf, input.gcount(), false)) {
256 sg_io_exception ex (XML_ErrorString(XML_GetErrorCode(parser)),
258 XML_GetCurrentLineNumber(parser),
259 XML_GetCurrentColumnNumber(parser)),
260 "SimGear XML Parser");
261 visitor.setParser(0);
262 XML_ParserFree(parser);
268 // Verify end of document.
269 if (!XML_Parse(parser, buf, 0, true)) {
270 sg_io_exception ex (XML_ErrorString(XML_GetErrorCode(parser)),
272 XML_GetCurrentLineNumber(parser),
273 XML_GetCurrentColumnNumber(parser)),
274 "SimGear XML Parser");
275 visitor.setParser(0);
276 XML_ParserFree(parser);
280 visitor.setParser(0);
281 XML_ParserFree(parser);
286 readXML (const string &path, XMLVisitor &visitor)
288 ifstream input(path.c_str());
291 readXML(input, visitor, path);
292 } catch (sg_io_exception &) {
295 } catch (sg_throwable &) {
300 throw sg_io_exception("Failed to open file", sg_location(path),
301 "SimGear XML Parser");
307 readXML (const char *buf, const int size, XMLVisitor &visitor)
309 XML_Parser parser = XML_ParserCreate(0);
310 XML_SetUserData(parser, &visitor);
311 XML_SetElementHandler(parser, start_element, end_element);
312 XML_SetCharacterDataHandler(parser, character_data);
313 XML_SetProcessingInstructionHandler(parser, processing_instruction);
317 if (!XML_Parse(parser, buf, size, false)) {
318 sg_io_exception ex (XML_ErrorString(XML_GetErrorCode(parser)),
319 sg_location("In-memory XML buffer",
320 XML_GetCurrentLineNumber(parser),
321 XML_GetCurrentColumnNumber(parser)),
322 "SimGear XML Parser");
323 XML_ParserFree(parser);
327 XML_ParserFree(parser);
331 // end of easyxml.cxx