00001
00007 #include <simgear/compiler.h>
00008
00009 #include <string.h>
00010
00011 #include "easyxml.hxx"
00012 #include "xmlparse.h"
00013
00014 #include <fstream>
00015 #include <iostream>
00016
00017 using std::ifstream;
00018
00019
00020
00022
00024
00025 XMLAttributes::XMLAttributes ()
00026 {
00027 }
00028
00029 XMLAttributes::~XMLAttributes ()
00030 {
00031 }
00032
00033 int
00034 XMLAttributes::findAttribute (const char * name) const
00035 {
00036 int s = size();
00037 for (int i = 0; i < s; i++) {
00038 if (strcmp(name, getName(i)) == 0)
00039 return i;
00040 }
00041 return -1;
00042 }
00043
00044 bool
00045 XMLAttributes::hasAttribute (const char * name) const
00046 {
00047 return (findAttribute(name) != -1);
00048 }
00049
00050 const char *
00051 XMLAttributes::getValue (const char * name) const
00052 {
00053 int pos = findAttribute(name);
00054 if (pos >= 0)
00055 return getValue(pos);
00056 else
00057 return 0;
00058 }
00059
00060
00062
00064
00065 XMLAttributesDefault::XMLAttributesDefault ()
00066 {
00067 }
00068
00069 XMLAttributesDefault::XMLAttributesDefault (const XMLAttributes &atts)
00070 {
00071 int s = atts.size();
00072 for (int i = 0; i < s; i++)
00073 addAttribute(atts.getName(i), atts.getValue(i));
00074 }
00075
00076 XMLAttributesDefault::~XMLAttributesDefault ()
00077 {
00078 }
00079
00080 int
00081 XMLAttributesDefault::size () const
00082 {
00083 return _atts.size() / 2;
00084 }
00085
00086 const char *
00087 XMLAttributesDefault::getName (int i) const
00088 {
00089 return _atts[i*2].c_str();
00090 }
00091
00092 const char *
00093 XMLAttributesDefault::getValue (int i) const
00094 {
00095 return _atts[i*2+1].c_str();
00096 }
00097
00098 void
00099 XMLAttributesDefault::addAttribute (const char * name, const char * value)
00100 {
00101 _atts.push_back(name);
00102 _atts.push_back(value);
00103 }
00104
00105 void
00106 XMLAttributesDefault::setName (int i, const char * name)
00107 {
00108 _atts[i*2] = name;
00109 }
00110
00111 void
00112 XMLAttributesDefault::setValue (int i, const char * name)
00113 {
00114 _atts[i*2+1] = name;
00115 }
00116
00117 void
00118 XMLAttributesDefault::setValue (const char * name, const char * value)
00119 {
00120 int pos = findAttribute(name);
00121 if (pos >= 0) {
00122 setName(pos, name);
00123 setValue(pos, value);
00124 } else {
00125 addAttribute(name, value);
00126 }
00127 }
00128
00129
00130
00132
00134
00135 class ExpatAtts : public XMLAttributes
00136 {
00137 public:
00138 ExpatAtts (const char ** atts) : _atts(atts) {}
00139
00140 virtual int size () const;
00141 virtual const char * getName (int i) const;
00142 virtual const char * getValue (int i) const;
00143
00144 private:
00145 const char ** _atts;
00146 };
00147
00148 int
00149 ExpatAtts::size () const
00150 {
00151 int s = 0;
00152 for (int i = 0; _atts[i] != 0; i += 2)
00153 s++;
00154 return s;
00155 }
00156
00157 const char *
00158 ExpatAtts::getName (int i) const
00159 {
00160 return _atts[i*2];
00161 }
00162
00163 const char *
00164 ExpatAtts::getValue (int i) const
00165 {
00166 return _atts[i*2+1];
00167 }
00168
00169
00170
00172
00174
00175 #define VISITOR (*((XMLVisitor *)userData))
00176
00177 static void
00178 start_element (void * userData, const char * name, const char ** atts)
00179 {
00180 VISITOR.startElement(name, ExpatAtts(atts));
00181 }
00182
00183 static void
00184 end_element (void * userData, const char * name)
00185 {
00186 VISITOR.endElement(name);
00187 }
00188
00189 static void
00190 character_data (void * userData, const char * s, int len)
00191 {
00192 VISITOR.data(s, len);
00193 }
00194
00195 static void
00196 processing_instruction (void * userData,
00197 const char * target,
00198 const char * data)
00199 {
00200 VISITOR.pi(target, data);
00201 }
00202
00203 #undef VISITOR
00204
00205
00206
00208
00210
00211 void
00212 readXML (istream &input, XMLVisitor &visitor, const string &path)
00213 {
00214 XML_Parser parser = XML_ParserCreate(0);
00215 XML_SetUserData(parser, &visitor);
00216 XML_SetElementHandler(parser, start_element, end_element);
00217 XML_SetCharacterDataHandler(parser, character_data);
00218 XML_SetProcessingInstructionHandler(parser, processing_instruction);
00219
00220 visitor.startXML();
00221
00222 char buf[16384];
00223 while (!input.eof()) {
00224
00225
00226 if (!input.good()) {
00227 sg_io_exception ex ("Problem reading file",
00228 sg_location(path,
00229 XML_GetCurrentLineNumber(parser),
00230 XML_GetCurrentColumnNumber(parser)),
00231 "SimGear XML Parser");
00232 XML_ParserFree(parser);
00233 throw ex;
00234 }
00235
00236 input.read(buf,16384);
00237 if (!XML_Parse(parser, buf, input.gcount(), false)) {
00238 sg_io_exception ex (XML_ErrorString(XML_GetErrorCode(parser)),
00239 sg_location(path,
00240 XML_GetCurrentLineNumber(parser),
00241 XML_GetCurrentColumnNumber(parser)),
00242 "SimGear XML Parser");
00243 XML_ParserFree(parser);
00244 throw ex;
00245 }
00246
00247 }
00248
00249
00250 if (!XML_Parse(parser, buf, 0, true)) {
00251 sg_io_exception ex (XML_ErrorString(XML_GetErrorCode(parser)),
00252 sg_location(path,
00253 XML_GetCurrentLineNumber(parser),
00254 XML_GetCurrentColumnNumber(parser)),
00255 "SimGear XML Parser");
00256 XML_ParserFree(parser);
00257 throw ex;
00258 }
00259
00260 XML_ParserFree(parser);
00261 visitor.endXML();
00262 }
00263
00264 void
00265 readXML (const string &path, XMLVisitor &visitor)
00266 {
00267 ifstream input(path.c_str());
00268 if (input.good()) {
00269 try {
00270 readXML(input, visitor, path);
00271 } catch (sg_io_exception &) {
00272 input.close();
00273 throw;
00274 } catch (sg_throwable &) {
00275 input.close();
00276 throw;
00277 }
00278 } else {
00279 throw sg_io_exception("Failed to open file", sg_location(path),
00280 "SimGear XML Parser");
00281 }
00282 input.close();
00283 }
00284
00285 void
00286 readXML (const char *buf, const int size, XMLVisitor &visitor)
00287 {
00288 XML_Parser parser = XML_ParserCreate(0);
00289 XML_SetUserData(parser, &visitor);
00290 XML_SetElementHandler(parser, start_element, end_element);
00291 XML_SetCharacterDataHandler(parser, character_data);
00292 XML_SetProcessingInstructionHandler(parser, processing_instruction);
00293
00294 visitor.startXML();
00295
00296 if (!XML_Parse(parser, buf, size, false)) {
00297 sg_io_exception ex (XML_ErrorString(XML_GetErrorCode(parser)),
00298 sg_location("In-memory XML buffer",
00299 XML_GetCurrentLineNumber(parser),
00300 XML_GetCurrentColumnNumber(parser)),
00301 "SimGear XML Parser");
00302 XML_ParserFree(parser);
00303 throw ex;
00304 }
00305
00306 XML_ParserFree(parser);
00307 visitor.endXML();
00308 }
00309
00310