]> git.mxchange.org Git - simgear.git/blobdiff - simgear/xml/easyxml.cxx
Initial work on CMake support for SimGear.
[simgear.git] / simgear / xml / easyxml.cxx
index 2331fc375aea9d49ade461e689a2d8942b5614d5..65a35513201a2de40a24b11b9b7cb01a63d28593 100644 (file)
@@ -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 <simgear/compiler.h>
+
+#include <string.h>            // strcmp()
 
 #include "easyxml.hxx"
 #include "xmlparse.h"
 
+#include <fstream>
+#include <iostream>
+
+using std::ifstream;
+
+
 \f
 ////////////////////////////////////////////////////////////////////////
 // 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;
 }
 
 \f
@@ -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