1 // easyxml.cxx - implementation of EasyXML interfaces.
3 #include <simgear/compiler.h>
5 #include <string.h> // strcmp()
12 #if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
13 SG_USING_STD(ifstream);
18 ////////////////////////////////////////////////////////////////////////
19 // Implementation of XMLAttributes.
20 ////////////////////////////////////////////////////////////////////////
22 XMLAttributes::XMLAttributes ()
26 XMLAttributes::~XMLAttributes ()
31 XMLAttributes::findAttribute (const char * name) const
34 for (int i = 0; i < s; i++) {
35 if (strcmp(name, getName(i)) == 0)
42 XMLAttributes::hasAttribute (const char * name) const
44 return (findAttribute(name) != -1);
48 XMLAttributes::getValue (const char * name) const
50 int pos = findAttribute(name);
58 ////////////////////////////////////////////////////////////////////////
59 // Implementation of XMLAttributesDefault.
60 ////////////////////////////////////////////////////////////////////////
62 XMLAttributesDefault::XMLAttributesDefault ()
66 XMLAttributesDefault::XMLAttributesDefault (const XMLAttributes &atts)
69 for (int i = 0; i < s; i++)
70 addAttribute(atts.getName(i), atts.getValue(i));
73 XMLAttributesDefault::~XMLAttributesDefault ()
78 XMLAttributesDefault::size () const
80 return _atts.size() / 2;
84 XMLAttributesDefault::getName (int i) const
86 return _atts[i*2].c_str();
90 XMLAttributesDefault::getValue (int i) const
92 return _atts[i*2+1].c_str();
96 XMLAttributesDefault::addAttribute (const char * name, const char * value)
98 _atts.push_back(name);
99 _atts.push_back(value);
103 XMLAttributesDefault::setName (int i, const char * name)
109 XMLAttributesDefault::setValue (int i, const char * name)
115 XMLAttributesDefault::setValue (const char * name, const char * value)
117 int pos = findAttribute(name);
120 setValue(pos, value);
122 addAttribute(name, value);
128 ////////////////////////////////////////////////////////////////////////
129 // Attribute list wrapper for Expat.
130 ////////////////////////////////////////////////////////////////////////
132 class ExpatAtts : public XMLAttributes
135 ExpatAtts (const char ** atts) : _atts(atts) {}
137 virtual int size () const;
138 virtual const char * getName (int i) const;
139 virtual const char * getValue (int i) const;
146 ExpatAtts::size () const
149 for (int i = 0; _atts[i] != 0; i += 2)
155 ExpatAtts::getName (int i) const
161 ExpatAtts::getValue (int i) const
168 ////////////////////////////////////////////////////////////////////////
169 // Static callback functions for Expat.
170 ////////////////////////////////////////////////////////////////////////
172 #define VISITOR (*((XMLVisitor *)userData))
175 start_element (void * userData, const char * name, const char ** atts)
177 VISITOR.startElement(name, ExpatAtts(atts));
181 end_element (void * userData, const char * name)
183 VISITOR.endElement(name);
187 character_data (void * userData, const char * s, int len)
189 VISITOR.data(s, len);
193 processing_instruction (void * userData,
197 VISITOR.pi(target, data);
204 ////////////////////////////////////////////////////////////////////////
205 // Implementation of XMLReader.
206 ////////////////////////////////////////////////////////////////////////
209 readXML (istream &input, XMLVisitor &visitor, const string &path)
211 XML_Parser parser = XML_ParserCreate(0);
212 XML_SetUserData(parser, &visitor);
213 XML_SetElementHandler(parser, start_element, end_element);
214 XML_SetCharacterDataHandler(parser, character_data);
215 XML_SetProcessingInstructionHandler(parser, processing_instruction);
220 while (!input.eof()) {
222 // FIXME: get proper error string from system
224 XML_ParserFree(parser);
225 throw sg_io_exception("Problem reading file",
227 XML_GetCurrentLineNumber(parser),
228 XML_GetCurrentColumnNumber(parser)),
229 "SimGear XML Parser");
232 input.read(buf,16384);
233 if (!XML_Parse(parser, buf, input.gcount(), false)) {
234 XML_ParserFree(parser);
235 throw sg_io_exception(XML_ErrorString(XML_GetErrorCode(parser)),
237 XML_GetCurrentLineNumber(parser),
238 XML_GetCurrentColumnNumber(parser)),
239 "SimGear XML Parser");
244 // Verify end of document.
245 if (!XML_Parse(parser, buf, 0, true)) {
246 XML_ParserFree(parser);
247 throw sg_io_exception(XML_ErrorString(XML_GetErrorCode(parser)),
249 XML_GetCurrentLineNumber(parser),
250 XML_GetCurrentColumnNumber(parser)),
251 "SimGear XML Parser");
254 XML_ParserFree(parser);
258 readXML (const string &path, XMLVisitor &visitor)
260 ifstream input(path.c_str());
263 readXML(input, visitor, path);
264 } catch (sg_io_exception &e) {
267 } catch (sg_throwable &t) {
272 throw sg_io_exception("Failed to open file", sg_location(path),
273 "SimGear XML Parser");
278 // end of easyxml.cxx