X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fxml%2Feasyxml.cxx;h=65a35513201a2de40a24b11b9b7cb01a63d28593;hb=b9a34b1b05ce9cab1b4b67816d7d24bd2bc364b7;hp=2331fc375aea9d49ade461e689a2d8942b5614d5;hpb=60cbe9c1d4e9b4fb56008964eb1a4634046fd2a7;p=simgear.git diff --git a/simgear/xml/easyxml.cxx b/simgear/xml/easyxml.cxx index 2331fc37..65a35513 100644 --- a/simgear/xml/easyxml.cxx +++ b/simgear/xml/easyxml.cxx @@ -1,8 +1,22 @@ -// easyxml.cxx - implementation of EasyXML interfaces. +/** + * \file easyxml.cxx - implementation of EasyXML interfaces. + * Written by David Megginson, 2000-2001 + * This file is in the Public Domain, and comes with NO WARRANTY of any kind. + */ + +#include + +#include // strcmp() #include "easyxml.hxx" #include "xmlparse.h" +#include +#include + +using std::ifstream; + + //////////////////////////////////////////////////////////////////////// // Implementation of XMLAttributes. @@ -20,9 +34,10 @@ int XMLAttributes::findAttribute (const char * name) const { int s = size(); - for (int i = 0; i < s; i++) + for (int i = 0; i < s; i++) { if (strcmp(name, getName(i)) == 0) return i; + } return -1; } @@ -39,7 +54,7 @@ XMLAttributes::getValue (const char * name) const if (pos >= 0) return getValue(pos); else - return getValue(0); + return 0; } @@ -122,9 +137,9 @@ class ExpatAtts : public XMLAttributes public: ExpatAtts (const char ** atts) : _atts(atts) {} - int size () const; - const char * getName (int i) const; - const char * getValue (int i) const; + virtual int size () const; + virtual const char * getName (int i) const; + virtual const char * getValue (int i) const; private: const char ** _atts; @@ -157,13 +172,12 @@ ExpatAtts::getValue (int i) const // Static callback functions for Expat. //////////////////////////////////////////////////////////////////////// -#define VISITOR (*((XMLVisitor*)userData)) +#define VISITOR (*((XMLVisitor *)userData)) static void start_element (void * userData, const char * name, const char ** atts) { - ExpatAtts attributes(atts); - VISITOR.startElement(name, attributes); + VISITOR.startElement(name, ExpatAtts(atts)); } static void @@ -194,11 +208,9 @@ processing_instruction (void * userData, // Implementation of XMLReader. //////////////////////////////////////////////////////////////////////// -bool -readXML (istream &input, XMLVisitor &visitor) +void +readXML (istream &input, XMLVisitor &visitor, const string &path) { - bool retval = true; - XML_Parser parser = XML_ParserCreate(0); XML_SetUserData(parser, &visitor); XML_SetElementHandler(parser, start_element, end_element); @@ -210,22 +222,89 @@ readXML (istream &input, XMLVisitor &visitor) char buf[16384]; while (!input.eof()) { + // FIXME: get proper error string from system + if (!input.good()) { + sg_io_exception ex ("Problem reading file", + sg_location(path, + XML_GetCurrentLineNumber(parser), + XML_GetCurrentColumnNumber(parser)), + "SimGear XML Parser"); + XML_ParserFree(parser); + throw ex; + } + input.read(buf,16384); - // TODO: deal with bad stream. if (!XML_Parse(parser, buf, input.gcount(), false)) { - visitor.error(XML_ErrorString(XML_GetErrorCode(parser)), - XML_GetCurrentColumnNumber(parser), - XML_GetCurrentLineNumber(parser)); - retval = false; + sg_io_exception ex (XML_ErrorString(XML_GetErrorCode(parser)), + sg_location(path, + XML_GetCurrentLineNumber(parser), + XML_GetCurrentColumnNumber(parser)), + "SimGear XML Parser"); + XML_ParserFree(parser); + throw ex; } + } - if (retval) - visitor.endXML(); + // Verify end of document. + if (!XML_Parse(parser, buf, 0, true)) { + sg_io_exception ex (XML_ErrorString(XML_GetErrorCode(parser)), + sg_location(path, + XML_GetCurrentLineNumber(parser), + XML_GetCurrentColumnNumber(parser)), + "SimGear XML Parser"); + XML_ParserFree(parser); + throw ex; + } XML_ParserFree(parser); + visitor.endXML(); +} - return retval; +void +readXML (const string &path, XMLVisitor &visitor) +{ + ifstream input(path.c_str()); + if (input.good()) { + try { + readXML(input, visitor, path); + } catch (sg_io_exception &) { + input.close(); + throw; + } catch (sg_throwable &) { + input.close(); + throw; + } + } else { + throw sg_io_exception("Failed to open file", sg_location(path), + "SimGear XML Parser"); + } + input.close(); +} + +void +readXML (const char *buf, const int size, XMLVisitor &visitor) +{ + XML_Parser parser = XML_ParserCreate(0); + XML_SetUserData(parser, &visitor); + XML_SetElementHandler(parser, start_element, end_element); + XML_SetCharacterDataHandler(parser, character_data); + XML_SetProcessingInstructionHandler(parser, processing_instruction); + + visitor.startXML(); + + if (!XML_Parse(parser, buf, size, false)) { + sg_io_exception ex (XML_ErrorString(XML_GetErrorCode(parser)), + sg_location("In-memory XML buffer", + XML_GetCurrentLineNumber(parser), + XML_GetCurrentColumnNumber(parser)), + "SimGear XML Parser"); + XML_ParserFree(parser); + throw ex; + } + + XML_ParserFree(parser); + visitor.endXML(); } // end of easyxml.cxx