head 1.4; access; symbols; locks; strict; comment @# @; 1.4 date 2002.09.07.01.50.38; author curt; state Exp; branches; next 1.3; 1.3 date 2002.08.31.19.01.53; author curt; state Exp; branches; next 1.2; 1.2 date 2002.08.31.18.54.00; author curt; state Exp; branches; next 1.1; 1.1 date 2002.02.15.17.21.56; author curt; state Exp; branches; next ; desc @@ 1.4 log @Updated doxygen docs. @ text @
Main Page Class Hierarchy Compound List File List Compound Members File Members

# easyxml.cxx

    00001 // easyxml.cxx - implementation of EasyXML interfaces.
    00002
    00003 #include <simgear/compiler.h>
    00004
    00005 #include <string.h>             // strcmp()
    00006
    00007 #include "easyxml.hxx"
    00008 #include "xmlparse.h"
    00009
    00010 #include STL_FSTREAM
    00011
    00012 #if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
    00013 SG_USING_STD(ifstream);
    00014 #endif
    00015
    00016
    00017
    00019 // Implementation of XMLAttributes.
    00021
    00022 XMLAttributes::XMLAttributes ()
    00023 {
    00024 }
    00025
    00026 XMLAttributes::~XMLAttributes ()
    00027 {
    00028 }
    00029
    00030 int
    00031 XMLAttributes::findAttribute (const char * name) const
    00032 {
    00033   int s = size();
    00034   for (int i = 0; i < s; i++) {
    00035     if (strcmp(name, getName(i)) == 0)
    00036       return i;
    00037   }
    00038   return -1;
    00039 }
    00040
    00041 bool
    00042 XMLAttributes::hasAttribute (const char * name) const
    00043 {
    00044   return (findAttribute(name) != -1);
    00045 }
    00046
    00047 const char *
    00048 XMLAttributes::getValue (const char * name) const
    00049 {
    00050   int pos = findAttribute(name);
    00051   if (pos >= 0)
    00052     return getValue(pos);
    00053   else
    00054     return 0;
    00055 }
    00056
    00057
    00059 // Implementation of XMLAttributesDefault.
    00061
    00062 XMLAttributesDefault::XMLAttributesDefault ()
    00063 {
    00064 }
    00065
    00066 XMLAttributesDefault::XMLAttributesDefault (const XMLAttributes &atts)
    00067 {
    00068   int s = atts.size();
    00069   for (int i = 0; i < s; i++)
    00070     addAttribute(atts.getName(i), atts.getValue(i));
    00071 }
    00072
    00073 XMLAttributesDefault::~XMLAttributesDefault ()
    00074 {
    00075 }
    00076
    00077 int
    00078 XMLAttributesDefault::size () const
    00079 {
    00080   return _atts.size() / 2;
    00081 }
    00082
    00083 const char *
    00084 XMLAttributesDefault::getName (int i) const
    00085 {
    00086   return _atts[i*2].c_str();
    00087 }
    00088
    00089 const char *
    00090 XMLAttributesDefault::getValue (int i) const
    00091 {
    00092   return _atts[i*2+1].c_str();
    00093 }
    00094
    00095 void
    00096 XMLAttributesDefault::addAttribute (const char * name, const char * value)
    00097 {
    00098   _atts.push_back(name);
    00099   _atts.push_back(value);
    00100 }
    00101
    00102 void
    00103 XMLAttributesDefault::setName (int i, const char * name)
    00104 {
    00105   _atts[i*2] = name;
    00106 }
    00107
    00108 void
    00109 XMLAttributesDefault::setValue (int i, const char * name)
    00110 {
    00111   _atts[i*2+1] = name;
    00112 }
    00113
    00114 void
    00115 XMLAttributesDefault::setValue (const char * name, const char * value)
    00116 {
    00117   int pos = findAttribute(name);
    00118   if (pos >= 0) {
    00119     setName(pos, name);
    00120     setValue(pos, value);
    00121   } else {
    00122     addAttribute(name, value);
    00123   }
    00124 }
    00125
    00126
    00127
    00129 // Attribute list wrapper for Expat.
    00131
    00132 class ExpatAtts : public XMLAttributes
    00133 {
    00134 public:
    00135   ExpatAtts (const char ** atts) : _atts(atts) {}
    00136
    00137   virtual int size () const;
    00138   virtual const char * getName (int i) const;
    00139   virtual const char * getValue (int i) const;
    00140
    00141 private:
    00142   const char ** _atts;
    00143 };
    00144
    00145 int
    00146 ExpatAtts::size () const
    00147 {
    00148   int s = 0;
    00149   for (int i = 0; _atts[i] != 0; i += 2)
    00150     s++;
    00151   return s;
    00152 }
    00153
    00154 const char *
    00155 ExpatAtts::getName (int i) const
    00156 {
    00157   return _atts[i*2];
    00158 }
    00159
    00160 const char *
    00161 ExpatAtts::getValue (int i) const
    00162 {
    00163   return _atts[i*2+1];
    00164 }
    00165
    00166
    00167
    00169 // Static callback functions for Expat.
    00171
    00172 #define VISITOR (*((XMLVisitor *)userData))
    00173
    00174 static void
    00175 start_element (void * userData, const char * name, const char ** atts)
    00176 {
    00177   VISITOR.startElement(name, ExpatAtts(atts));
    00178 }
    00179
    00180 static void
    00181 end_element (void * userData, const char * name)
    00182 {
    00183   VISITOR.endElement(name);
    00184 }
    00185
    00186 static void
    00187 character_data (void * userData, const char * s, int len)
    00188 {
    00189   VISITOR.data(s, len);
    00190 }
    00191
    00192 static void
    00193 processing_instruction (void * userData,
    00194                         const char * target,
    00195                         const char * data)
    00196 {
    00197   VISITOR.pi(target, data);
    00198 }
    00199
    00200 #undef VISITOR
    00201
    00202
    00203
    00205 // Implementation of XMLReader.
    00207
    00208 void
    00209 readXML (istream &input, XMLVisitor &visitor, const string &path)
    00210 {
    00211   XML_Parser parser = XML_ParserCreate(0);
    00212   XML_SetUserData(parser, &visitor);
    00213   XML_SetElementHandler(parser, start_element, end_element);
    00214   XML_SetCharacterDataHandler(parser, character_data);
    00215   XML_SetProcessingInstructionHandler(parser, processing_instruction);
    00216
    00217   visitor.startXML();
    00218
    00219   char buf[16384];
    00220   while (!input.eof()) {
    00221
    00222                                 // FIXME: get proper error string from system
    00223     if (!input.good()) {
    00224       XML_ParserFree(parser);
    00225       throw sg_io_exception("Problem reading file",
    00226                             sg_location(path,
    00227                                         XML_GetCurrentLineNumber(parser),
    00228                                         XML_GetCurrentColumnNumber(parser)),
    00229                             "SimGear XML Parser");
    00230     }
    00231
    00232     input.read(buf,16384);
    00233     if (!XML_Parse(parser, buf, input.gcount(), false)) {
    00234       XML_ParserFree(parser);
    00235       throw sg_io_exception(XML_ErrorString(XML_GetErrorCode(parser)),
    00236                             sg_location(path,
    00237                                         XML_GetCurrentLineNumber(parser),
    00238                                         XML_GetCurrentColumnNumber(parser)),
    00239                             "SimGear XML Parser");
    00240     }
    00241
    00242   }
    00243
    00244                                 // Verify end of document.
    00245   if (!XML_Parse(parser, buf, 0, true)) {
    00246     XML_ParserFree(parser);
    00247     throw sg_io_exception(XML_ErrorString(XML_GetErrorCode(parser)),
    00248                           sg_location(path,
    00249                                       XML_GetCurrentLineNumber(parser),
    00250                                       XML_GetCurrentColumnNumber(parser)),
    00251                           "SimGear XML Parser");
    00252   }
    00253
    00254   XML_ParserFree(parser);
    00255 }
    00256
    00257 void
    00258 readXML (const string &path, XMLVisitor &visitor)
    00259 {
    00260   ifstream input(path.c_str());
    00261   if (input.good()) {
    00262     try {
    00263       readXML(input, visitor, path);
    00264     } catch (sg_io_exception &e) {
    00265       input.close();
    00266       throw e;
    00267     } catch (sg_throwable &t) {
    00268       input.close();
    00269       throw t;
    00270     }
    00271   } else {
    00272     throw sg_io_exception("Failed to open file", sg_location(path),
    00273                           "SimGear XML Parser");
    00274   }
    00275   input.close();
    00276 }
    00277
    00278 // end of easyxml.cxx

@ 1.3 log @Oops, try again. @ text @d277 1 a277 1