1 // easyxml.cxx - implementation of EasyXML interfaces.
3 #include <simgear/compiler.h>
5 #include <string.h> // strcmp()
11 ////////////////////////////////////////////////////////////////////////
12 // Implementation of XMLAttributes.
13 ////////////////////////////////////////////////////////////////////////
15 XMLAttributes::XMLAttributes ()
19 XMLAttributes::~XMLAttributes ()
24 XMLAttributes::findAttribute (const char * name) const
27 for (int i = 0; i < s; i++) {
28 if (strcmp(name, getName(i)) == 0)
35 XMLAttributes::hasAttribute (const char * name) const
37 return (findAttribute(name) != -1);
41 XMLAttributes::getValue (const char * name) const
43 int pos = findAttribute(name);
51 ////////////////////////////////////////////////////////////////////////
52 // Implementation of XMLAttributesDefault.
53 ////////////////////////////////////////////////////////////////////////
55 XMLAttributesDefault::XMLAttributesDefault ()
59 XMLAttributesDefault::XMLAttributesDefault (const XMLAttributes &atts)
62 for (int i = 0; i < s; i++)
63 addAttribute(atts.getName(i), atts.getValue(i));
66 XMLAttributesDefault::~XMLAttributesDefault ()
71 XMLAttributesDefault::size () const
73 return _atts.size() / 2;
77 XMLAttributesDefault::getName (int i) const
79 return _atts[i*2].c_str();
83 XMLAttributesDefault::getValue (int i) const
85 return _atts[i*2+1].c_str();
89 XMLAttributesDefault::addAttribute (const char * name, const char * value)
91 _atts.push_back(name);
92 _atts.push_back(value);
96 XMLAttributesDefault::setName (int i, const char * name)
102 XMLAttributesDefault::setValue (int i, const char * name)
108 XMLAttributesDefault::setValue (const char * name, const char * value)
110 int pos = findAttribute(name);
113 setValue(pos, value);
115 addAttribute(name, value);
121 ////////////////////////////////////////////////////////////////////////
122 // Attribute list wrapper for Expat.
123 ////////////////////////////////////////////////////////////////////////
125 class ExpatAtts : public XMLAttributes
128 ExpatAtts (const char ** atts) : _atts(atts) {}
130 virtual int size () const;
131 virtual const char * getName (int i) const;
132 virtual const char * getValue (int i) const;
139 ExpatAtts::size () const
142 for (int i = 0; _atts[i] != 0; i += 2)
148 ExpatAtts::getName (int i) const
154 ExpatAtts::getValue (int i) const
161 ////////////////////////////////////////////////////////////////////////
162 // Static callback functions for Expat.
163 ////////////////////////////////////////////////////////////////////////
165 #define VISITOR (*((XMLVisitor*)userData))
168 start_element (void * userData, const char * name, const char ** atts)
170 VISITOR.startElement(name, ExpatAtts(atts));
174 end_element (void * userData, const char * name)
176 VISITOR.endElement(name);
180 character_data (void * userData, const char * s, int len)
182 VISITOR.data(s, len);
186 processing_instruction (void * userData,
190 VISITOR.pi(target, data);
197 ////////////////////////////////////////////////////////////////////////
198 // Implementation of XMLReader.
199 ////////////////////////////////////////////////////////////////////////
202 readXML (istream &input, XMLVisitor &visitor)
206 XML_Parser parser = XML_ParserCreate(0);
207 XML_SetUserData(parser, &visitor);
208 XML_SetElementHandler(parser, start_element, end_element);
209 XML_SetCharacterDataHandler(parser, character_data);
210 XML_SetProcessingInstructionHandler(parser, processing_instruction);
215 while (!input.eof()) {
217 input.read(buf,16384);
218 // TODO: deal with bad stream.
219 if (!XML_Parse(parser, buf, input.gcount(), false)) {
220 visitor.error(XML_ErrorString(XML_GetErrorCode(parser)),
221 XML_GetCurrentColumnNumber(parser),
222 XML_GetCurrentLineNumber(parser));
227 // Verify end of document.
228 if (!XML_Parse(parser, buf, 0, true))
234 XML_ParserFree(parser);
239 // end of easyxml.cxx