FEBio  1.5.0
FEBio/XMLReader.h
00001 // XMLReader.h: interface for the XMLReader class.
00002 //
00004 
00005 #if !defined(AFX_XMLREADER_H__667494D8_4C95_4342_BC31_6C1C097A4C81__INCLUDED_)
00006 #define AFX_XMLREADER_H__667494D8_4C95_4342_BC31_6C1C097A4C81__INCLUDED_
00007 
00008 #if _MSC_VER > 1000
00009 #pragma once
00010 #endif // _MSC_VER > 1000
00011 
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include <ctype.h>
00016 #include "vec3d.h"
00017 #include <string>
00018 
00019 class XMLReader  
00020 {
00021 public:
00022         enum {MAX_TAG   = 128};
00023         enum {MAX_ATT   =   8};
00024         enum {MAX_LEVEL = 16};
00025 
00026         class XMLTag
00027         {
00028         // TODO: I would like to get rid of the m_szroot element and replace it with a 
00029         // parent tag. The root element can then be identified by the tag that 
00030         // does not have a parent
00031         public:
00032                 char    m_sztag[MAX_TAG];                       // tag name
00033                 char    m_szatt[MAX_ATT][MAX_TAG];      // tag attributes
00034                 char    m_szatv[MAX_ATT][MAX_TAG];      // value of attributes
00035 
00036                 std::string     m_szval;        // tag value
00037 
00038                 int             m_nlevel;       // depth level
00039                 char    m_szroot[MAX_LEVEL][MAX_TAG];   // name tag of parent's
00040 
00041                 int             m_natt; // nr of attributes
00042 
00043                 XMLReader*      m_preader;              // pointer to reader
00044                 fpos_t  m_fpos;                         // file position of next tag
00045                 int             m_nstart_line;          // line number at beginning of tag
00046                 int             m_ncurrent_line;        // current line number
00047 
00048                 bool    m_bend;         // end tag flag
00049                 bool    m_bleaf;        // this is a leaf (i.e. has no child elements)
00050                 bool    m_bempty;       // empty tag (i.e. no value)
00051 
00052                 void operator ++ () { m_preader->NextTag(*this); }
00053 
00054 
00055                 XMLTag();
00056 
00057                 void clear()
00058                 {
00059                         m_sztag[0] = 0;
00060                         m_szval.clear();
00061                         m_natt = 0;
00062                         m_bend = false;
00063                         m_bleaf = true;
00064                         m_bempty = false;
00065                 }
00066 
00067         public:
00068                 bool operator == (const char* sztag) { return (strcmp(sztag, m_sztag) == 0); }
00069                 bool operator != (const char* sztag) { return (strcmp(sztag, m_sztag) != 0); }
00070 
00071                 bool isend() { return m_bend; }
00072                 bool isleaf() { return m_bleaf; }
00073                 bool isempty() { return m_bempty; }
00074 
00075         public:
00076                 const char* AttributeValue(const char* szat, bool bopt = false);
00077 
00078                 bool AttributeValue(const char* szat, int&    n, bool bopt = false);
00079                 bool AttributeValue(const char* szat, double& d, bool bopt = false);
00080                 
00081                 const char* Name() { return m_sztag; }
00082 
00083                 void value(char* szstr) { strcpy(szstr, m_szval.c_str()); }
00084                 void value(double& val) { val = atof(m_szval.c_str()); } 
00085                 void value(float& val)  { val = (float) atof(m_szval.c_str()); }
00086                 void value(bool& val) { int n=0; sscanf(m_szval.c_str(), "%d", &n); val = (n != 0); }
00087                 void value(int& val) { val = atoi(m_szval.c_str()); }
00088                 void value(long& val) { val = (long) atoi(m_szval.c_str()); }
00089                 void value(short& val) { val = (short) atoi(m_szval.c_str()); }
00090                 int value(double* pf, int n);
00091                 int value(float* pf, int n);
00092                 int value(int* pi, int n);
00093                 void value(vec3d& v);
00094 
00095                 const char* szvalue() { return m_szval.c_str(); }
00096         };
00097 
00098         // exceptions -----------
00099 
00100         class Error{};
00101 
00102         class EndOfFile{};
00103 
00104         class UnexpectedEOF{};
00105 
00106         class XMLSyntaxError{};
00107 
00108         class UnmatchedEndTag
00109         {
00110         public:
00111                 XMLTag tag;
00112                 UnmatchedEndTag(XMLTag& t) : tag(t) {}
00113         };
00114 
00115         class InvalidTag
00116         {
00117         public:
00118                 XMLTag tag;
00119                 InvalidTag(XMLTag& t) : tag(t) {}
00120         };
00121 
00122         class InvalidValue
00123         {
00124         public:
00125                 XMLTag tag;
00126                 InvalidValue(XMLTag& t) : tag(t) {}
00127         };
00128 
00129         class InvalidAttributeValue
00130         {
00131         public:
00132                 XMLTag tag;
00133                 char szatt[MAX_TAG];
00134                 char szval[MAX_TAG];
00135                 InvalidAttributeValue(XMLTag& t, const char* sza, const char* szv) : tag(t)
00136                 { 
00137                         strcpy(szatt, sza);
00138                         strcpy(szval, szv);
00139                 }
00140         };
00141 
00142         class MissingAttribute
00143         {
00144         public:
00145                 XMLTag tag;
00146                 char szatt[MAX_TAG];
00147                 MissingAttribute(XMLTag& t, const char* sza) : tag(t) { strcpy(szatt, sza); }
00148         };
00149 
00150         //------------------------
00151 
00152 
00153 public:
00154         XMLReader();
00155         virtual ~XMLReader();
00156 
00157         FILE* GetFilePtr() { return m_fp; } 
00158 
00159         bool Open(const char* szfile);
00160 
00161         void Close();
00162 
00163         bool FindTag(const char* sztag, XMLTag& tag);
00164 
00165         void NextTag(XMLTag& tag);
00166 
00167         int GetCurrentLine() { return m_nline; }
00168 
00169 protected:
00170         char GetChar();
00171         void ReadTag(XMLTag& tag);
00172         void ReadValue(XMLTag& tag);
00173         void ReadEndTag(XMLTag& tag);
00174 
00175 protected:
00176         FILE*   m_fp;           // the file pointer
00177         int             m_nline;        // current line (used only as temp storage)
00178 
00179         friend class XMLTag;
00180 };
00181 
00182 typedef XMLReader::XMLTag XMLTag;
00183 
00184 #endif // !defined(AFX_XMLREADER_H__667494D8_4C95_4342_BC31_6C1C097A4C81__INCLUDED_)