1 // easyxml.cxx - implementation of EasyXML interfaces.
3 #include <simgear/compiler.h>
5 #include <string.h> // strcmp()
12 SG_USING_STD(ifstream);
16 ////////////////////////////////////////////////////////////////////////
17 // Implementation of XMLAttributes.
18 ////////////////////////////////////////////////////////////////////////
20 XMLAttributes::XMLAttributes ()
24 XMLAttributes::~XMLAttributes ()
29 XMLAttributes::findAttribute (const char * name) const
32 for (int i = 0; i < s; i++) {
33 if (strcmp(name, getName(i)) == 0)
40 XMLAttributes::hasAttribute (const char * name) const
42 return (findAttribute(name) != -1);
46 XMLAttributes::getValue (const char * name) const
48 int pos = findAttribute(name);
56 ////////////////////////////////////////////////////////////////////////
57 // Implementation of XMLAttributesDefault.
58 ////////////////////////////////////////////////////////////////////////
60 XMLAttributesDefault::XMLAttributesDefault ()
64 XMLAttributesDefault::XMLAttributesDefault (const XMLAttributes &atts)
67 for (int i = 0; i < s; i++)
68 addAttribute(atts.getName(i), atts.getValue(i));
71 XMLAttributesDefault::~XMLAttributesDefault ()
76 XMLAttributesDefault::size () const
78 return _atts.size() / 2;
82 XMLAttributesDefault::getName (int i) const
84 return _atts[i*2].c_str();
88 XMLAttributesDefault::getValue (int i) const
90 return _atts[i*2+1].c_str();
94 XMLAttributesDefault::addAttribute (const char * name, const char * value)
96 _atts.push_back(name);
97 _atts.push_back(value);
101 XMLAttributesDefault::setName (int i, const char * name)
107 XMLAttributesDefault::setValue (int i, const char * name)
113 XMLAttributesDefault::setValue (const char * name, const char * value)
115 int pos = findAttribute(name);
118 setValue(pos, value);
120 addAttribute(name, value);
126 ////////////////////////////////////////////////////////////////////////
127 // Attribute list wrapper for Expat.
128 ////////////////////////////////////////////////////////////////////////
130 class ExpatAtts : public XMLAttributes
133 ExpatAtts (const char ** atts) : _atts(atts) {}
135 virtual int size () const;
136 virtual const char * getName (int i) const;
137 virtual const char * getValue (int i) const;
144 ExpatAtts::size () const
147 for (int i = 0; _atts[i] != 0; i += 2)
153 ExpatAtts::getName (int i) const
159 ExpatAtts::getValue (int i) const
166 ////////////////////////////////////////////////////////////////////////
167 // Static callback functions for Expat.
168 ////////////////////////////////////////////////////////////////////////
170 #define VISITOR (*((XMLVisitor *)userData))
173 start_element (void * userData, const char * name, const char ** atts)
175 VISITOR.startElement(name, ExpatAtts(atts));
179 end_element (void * userData, const char * name)
181 VISITOR.endElement(name);
185 character_data (void * userData, const char * s, int len)
187 VISITOR.data(s, len);
191 processing_instruction (void * userData,
195 VISITOR.pi(target, data);
202 ////////////////////////////////////////////////////////////////////////
203 // Implementation of XMLReader.
204 ////////////////////////////////////////////////////////////////////////
207 readXML (istream &input, XMLVisitor &visitor, const string &path)
209 XML_Parser parser = XML_ParserCreate(0);
210 XML_SetUserData(parser, &visitor);
211 XML_SetElementHandler(parser, start_element, end_element);
212 XML_SetCharacterDataHandler(parser, character_data);
213 XML_SetProcessingInstructionHandler(parser, processing_instruction);
218 while (!input.eof()) {
220 // FIXME: get proper error string from system
222 XML_ParserFree(parser);
223 throw sg_io_exception("Problem reading file",
225 XML_GetCurrentLineNumber(parser),
226 XML_GetCurrentColumnNumber(parser)),
227 "SimGear XML Parser");
230 input.read(buf,16384);
231 if (!XML_Parse(parser, buf, input.gcount(), false)) {
232 XML_ParserFree(parser);
233 throw sg_io_exception(XML_ErrorString(XML_GetErrorCode(parser)),
235 XML_GetCurrentLineNumber(parser),
236 XML_GetCurrentColumnNumber(parser)),
237 "SimGear XML Parser");
242 // Verify end of document.
243 if (!XML_Parse(parser, buf, 0, true)) {
244 XML_ParserFree(parser);
245 throw sg_io_exception(XML_ErrorString(XML_GetErrorCode(parser)),
247 XML_GetCurrentLineNumber(parser),
248 XML_GetCurrentColumnNumber(parser)),
249 "SimGear XML Parser");
252 XML_ParserFree(parser);
256 readXML (const string &path, XMLVisitor &visitor)
258 ifstream input(path.c_str());
261 readXML(input, visitor, path);
262 } catch (sg_io_exception &e) {
265 } catch (sg_throwable &t) {
270 throw sg_io_exception("Failed to open file", sg_location(path),
271 "SimGear XML Parser");
276 // end of easyxml.cxx