1 // easyxml.cxx - implementation of EasyXML interfaces.
7 #include <simgear/compiler.h>
9 #include <string.h> // strcmp()
11 #include "easyxml.hxx"
15 ////////////////////////////////////////////////////////////////////////
16 // Implementation of XMLAttributes.
17 ////////////////////////////////////////////////////////////////////////
19 XMLAttributes::XMLAttributes ()
23 XMLAttributes::~XMLAttributes ()
28 XMLAttributes::findAttribute (const char * name) const
31 for (int i = 0; i < s; i++) {
32 if (strcmp(name, getName(i)) == 0)
39 XMLAttributes::hasAttribute (const char * name) const
41 return (findAttribute(name) != -1);
45 XMLAttributes::getValue (const char * name) const
47 int pos = findAttribute(name);
55 ////////////////////////////////////////////////////////////////////////
56 // Implementation of XMLAttributesDefault.
57 ////////////////////////////////////////////////////////////////////////
59 XMLAttributesDefault::XMLAttributesDefault ()
63 XMLAttributesDefault::XMLAttributesDefault (const XMLAttributes &atts)
66 for (int i = 0; i < s; i++)
67 addAttribute(atts.getName(i), atts.getValue(i));
70 XMLAttributesDefault::~XMLAttributesDefault ()
75 XMLAttributesDefault::size () const
77 return _atts.size() / 2;
81 XMLAttributesDefault::getName (int i) const
83 return _atts[i*2].c_str();
87 XMLAttributesDefault::getValue (int i) const
89 return _atts[i*2+1].c_str();
93 XMLAttributesDefault::addAttribute (const char * name, const char * value)
95 _atts.push_back(name);
96 _atts.push_back(value);
100 XMLAttributesDefault::setName (int i, const char * name)
106 XMLAttributesDefault::setValue (int i, const char * name)
112 XMLAttributesDefault::setValue (const char * name, const char * value)
114 int pos = findAttribute(name);
117 setValue(pos, value);
119 addAttribute(name, value);
125 ////////////////////////////////////////////////////////////////////////
126 // Attribute list wrapper for Expat.
127 ////////////////////////////////////////////////////////////////////////
129 class ExpatAtts : public XMLAttributes
132 ExpatAtts (const char ** atts) : _atts(atts) {}
134 virtual int size () const;
135 virtual const char * getName (int i) const;
136 virtual const char * getValue (int i) const;
143 ExpatAtts::size () const
146 for (int i = 0; _atts[i] != 0; i += 2)
152 ExpatAtts::getName (int i) const
158 ExpatAtts::getValue (int i) const
165 ////////////////////////////////////////////////////////////////////////
166 // Static callback functions for Expat.
167 ////////////////////////////////////////////////////////////////////////
169 #define VISITOR (*((XMLVisitor*)userData))
172 start_element (void * userData, const char * name, const char ** atts)
174 VISITOR.startElement(name, ExpatAtts(atts));
178 end_element (void * userData, const char * name)
180 VISITOR.endElement(name);
184 character_data (void * userData, const char * s, int len)
186 VISITOR.data(s, len);
190 processing_instruction (void * userData,
194 VISITOR.pi(target, data);
201 ////////////////////////////////////////////////////////////////////////
202 // Implementation of XMLReader.
203 ////////////////////////////////////////////////////////////////////////
206 readXML (istream &input, XMLVisitor &visitor)
210 XML_Parser parser = XML_ParserCreate(0);
211 XML_SetUserData(parser, &visitor);
212 XML_SetElementHandler(parser, start_element, end_element);
213 XML_SetCharacterDataHandler(parser, character_data);
214 XML_SetProcessingInstructionHandler(parser, processing_instruction);
219 while (!input.eof()) {
221 input.read(buf,16384);
222 // TODO: deal with bad stream.
223 if (!XML_Parse(parser, buf, input.gcount(), false)) {
224 visitor.error(XML_ErrorString(XML_GetErrorCode(parser)),
225 XML_GetCurrentColumnNumber(parser),
226 XML_GetCurrentLineNumber(parser));
231 // Verify end of document.
232 if (!XML_Parse(parser, buf, 0, true))
238 XML_ParserFree(parser);
243 // end of easyxml.cxx