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"
30 ////////////////////////////////////////////////////////////////////////
31 // Implementation of XMLAttributes.
32 ////////////////////////////////////////////////////////////////////////
34 XMLAttributes::XMLAttributes ()
38 XMLAttributes::~XMLAttributes ()
43 XMLAttributes::findAttribute (const char * name) const
46 for (int i = 0; i < s; i++) {
47 if (strcmp(name, getName(i)) == 0)
54 XMLAttributes::hasAttribute (const char * name) const
56 return (findAttribute(name) != -1);
60 XMLAttributes::getValue (const char * name) const
62 int pos = findAttribute(name);
70 ////////////////////////////////////////////////////////////////////////
71 // Implementation of XMLAttributesDefault.
72 ////////////////////////////////////////////////////////////////////////
74 XMLAttributesDefault::XMLAttributesDefault ()
78 XMLAttributesDefault::XMLAttributesDefault (const XMLAttributes &atts)
81 for (int i = 0; i < s; i++)
82 addAttribute(atts.getName(i), atts.getValue(i));
85 XMLAttributesDefault::~XMLAttributesDefault ()
90 XMLAttributesDefault::size () const
92 return _atts.size() / 2;
96 XMLAttributesDefault::getName (int i) const
98 return _atts[i*2].c_str();
102 XMLAttributesDefault::getValue (int i) const
104 return _atts[i*2+1].c_str();
108 XMLAttributesDefault::addAttribute (const char * name, const char * value)
110 _atts.push_back(name);
111 _atts.push_back(value);
115 XMLAttributesDefault::setName (int i, const char * name)
121 XMLAttributesDefault::setValue (int i, const char * name)
127 XMLAttributesDefault::setValue (const char * name, const char * value)
129 int pos = findAttribute(name);
132 setValue(pos, value);
134 addAttribute(name, value);
139 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141 void XMLVisitor::savePosition(void)
143 column = XML_GetCurrentColumnNumber(parser);
144 line = XML_GetCurrentLineNumber(parser);
147 ////////////////////////////////////////////////////////////////////////
148 // Attribute list wrapper for Expat.
149 ////////////////////////////////////////////////////////////////////////
152 ExpatAtts::size () const
155 for (int i = 0; _atts[i] != 0; i += 2)
161 ExpatAtts::getName (int i) const
167 ExpatAtts::getValue (int i) const
173 ExpatAtts::getValue (const char * name) const
175 return XMLAttributes::getValue(name);
179 ////////////////////////////////////////////////////////////////////////
180 // Static callback functions for Expat.
181 ////////////////////////////////////////////////////////////////////////
183 #define VISITOR (*((XMLVisitor *)userData))
186 start_element (void * userData, const char * name, const char ** atts)
188 VISITOR.savePosition();
189 VISITOR.startElement(name, ExpatAtts(atts));
193 end_element (void * userData, const char * name)
195 VISITOR.savePosition();
196 VISITOR.endElement(name);
200 character_data (void * userData, const char * s, int len)
202 VISITOR.savePosition();
203 VISITOR.data(s, len);
207 processing_instruction (void * userData,
211 VISITOR.savePosition();
212 VISITOR.pi(target, data);
219 ////////////////////////////////////////////////////////////////////////
220 // Implementation of XMLReader.
221 ////////////////////////////////////////////////////////////////////////
224 readXML (istream &input, XMLVisitor &visitor, const string &path)
226 XML_Parser parser = XML_ParserCreate(0);
227 XML_SetUserData(parser, &visitor);
228 XML_SetElementHandler(parser, start_element, end_element);
229 XML_SetCharacterDataHandler(parser, character_data);
230 XML_SetProcessingInstructionHandler(parser, processing_instruction);
232 visitor.setParser(parser);
233 visitor.setPath(path);
237 while (!input.eof()) {
239 // FIXME: get proper error string from system
241 sg_io_exception ex ("Problem reading file",
243 XML_GetCurrentLineNumber(parser),
244 XML_GetCurrentColumnNumber(parser)),
245 "SimGear XML Parser");
246 visitor.setParser(0);
247 XML_ParserFree(parser);
251 input.read(buf,16384);
252 if (!XML_Parse(parser, buf, input.gcount(), false)) {
253 sg_io_exception ex (XML_ErrorString(XML_GetErrorCode(parser)),
255 XML_GetCurrentLineNumber(parser),
256 XML_GetCurrentColumnNumber(parser)),
257 "SimGear XML Parser");
258 visitor.setParser(0);
259 XML_ParserFree(parser);
265 // Verify end of document.
266 if (!XML_Parse(parser, buf, 0, true)) {
267 sg_io_exception ex (XML_ErrorString(XML_GetErrorCode(parser)),
269 XML_GetCurrentLineNumber(parser),
270 XML_GetCurrentColumnNumber(parser)),
271 "SimGear XML Parser");
272 visitor.setParser(0);
273 XML_ParserFree(parser);
277 visitor.setParser(0);
278 XML_ParserFree(parser);
283 readXML (const string &path, XMLVisitor &visitor)
285 ifstream input(path.c_str());
288 readXML(input, visitor, path);
289 } catch (sg_io_exception &) {
292 } catch (sg_throwable &) {
297 throw sg_io_exception("Failed to open file", sg_location(path),
298 "SimGear XML Parser");
304 readXML (const char *buf, const int size, XMLVisitor &visitor)
306 XML_Parser parser = XML_ParserCreate(0);
307 XML_SetUserData(parser, &visitor);
308 XML_SetElementHandler(parser, start_element, end_element);
309 XML_SetCharacterDataHandler(parser, character_data);
310 XML_SetProcessingInstructionHandler(parser, processing_instruction);
314 if (!XML_Parse(parser, buf, size, false)) {
315 sg_io_exception ex (XML_ErrorString(XML_GetErrorCode(parser)),
316 sg_location("In-memory XML buffer",
317 XML_GetCurrentLineNumber(parser),
318 XML_GetCurrentColumnNumber(parser)),
319 "SimGear XML Parser");
320 XML_ParserFree(parser);
324 XML_ParserFree(parser);
328 // end of easyxml.cxx