OpenADFortTk (basic)
src/lib/support/xmlostream.cxx
Go to the documentation of this file.
00001 // ##########################################################
00002 // # This file is part of OpenADFortTk.                     #
00003 // # The full COPYRIGHT notice can be found in the top      #
00004 // # level directory of the OpenADFortTk source tree.       #
00005 // # For more information visit                             #
00006 // # http://www.mcs.anl.gov/openad                          #
00007 // ##########################################################
00008 #include "xmlostream.h"
00009 
00010 /*
00011   A table showing possible state movements.  The state-state table
00012   indicates whether it is possible to move from one state (in the left
00013   margin) to another state.  Given an initial state (in the left
00014   margin), the state-action table indicates the possible resulting
00015   states after an action
00016 
00017         States                         Actions
00018        |--------------------------------------------------------------------
00019        |          .....ELEM_....     | Beg  Beg  End  End   End  Beg  End
00020        |INIT FINI OP_I OP_A OPEN ERR | Elm  Attr Attr Attrs Elem Com  Com
00021        |-------------------------------------------------------------------- 
00022   INIT |no   no   yes  no   no   yes | OP_I ERR  ERR  ERR   ERR  COM  ERR
00023   FINI |no   no   yes  no   no   yes | OP_I ERR  ERR  ERR   ERR  COM  ERR
00024   ERR  |no   no   no   no   no   no  | .    .    .    .     .    .    .  
00025   OP_I |no   yes  err  yes  yes  yes | OP_I OP_A OP_I OPEN  FINI COM  ERR
00026        |                             |                      OPEN
00027   OP_A |no   yes  yes  yes  yes  yes | OP_I OP_A OP_I OPEN  FINI COM  ERR
00028        |                             |                      OPEN
00029   OPEN |no   yes  yes  no   yes  yes | OP_I ERR  ERR  OPEN  FINI COM  ERR
00030        |                             |                      OPEN
00031   COM  |                             | ERR  ERR  ERR  ERR   ERR  ERR  <>
00032 
00033  */
00034 
00035 // For a comments to public member functions, see the interface file.
00036 
00037 xml::ostream::ostream(std::streambuf* sb)
00038   : std::ostream(sb)
00039 {
00040   state = 0;
00041   
00042   SetState(INIT);
00043   indentAmnt = 0;
00044   indentStep = 2;
00045 }
00046 
00047 xml::ostream::~ostream()
00048 {
00049 }
00050 
00051 void
00052 xml::ostream::BegElem(const char* etag)
00053   throw (xml::ostream::Exception)
00054 {
00055   // Sanity check 
00056   if (IsStateComment()) {
00057     SetStateError();
00058     throw Exception("BegElem: Within a comment!");
00059   }
00060   
00061   if (IsState(ELEM_OPENA) || IsState(ELEM_OPENI)) {
00062     EndAttrs(); // state is updated
00063   }
00064   Indent();
00065   (*this) << '<' << etag;
00066   IndentIncr();
00067 
00068   elemstack.push_front(std::string(etag));
00069   SetState(ELEM_OPENI);
00070 }
00071 
00072 void
00073 xml::ostream::EndElem()
00074 {
00075   // Sanity check
00076   if ( !(IsState(ELEM_OPENA) || IsState(ELEM_OPENI) || IsState(ELEM_OPEN)) ) {
00077     SetStateError();
00078     throw Exception("EndElem: No currently open elements to end!");
00079   } 
00080   if (IsStateComment()) {
00081     SetStateError();
00082     throw Exception("EndElem: Within a comment!");
00083   }
00084   
00085   IndentDecr();
00086   if (IsState(ELEM_OPENA)) {
00087     EndAttr(); // state is updated 
00088   }
00089 
00090   if (IsState(ELEM_OPENI)) {
00091     (*this) << "/>\n";
00092   } 
00093   else { // ELEM_OPEN
00094     std::string& etag = elemstack.front();
00095     Indent();
00096     (*this) << "</" << etag << ">\n";
00097   }
00098   
00099   // Determine the appropriate state after an element has been closed
00100   elemstack.pop_front();
00101   if (elemstack.size() == 0) { 
00102     SetState(FINI);
00103   } 
00104   else {
00105     SetState(ELEM_OPEN);
00106   }
00107 }
00108 
00109 
00110 void
00111 xml::ostream::BegAttr(const char* attr)
00112 {
00113   // Sanity check
00114   if ( !(IsState(ELEM_OPENA) || IsState(ELEM_OPENI)) ) {
00115     SetStateError();
00116     throw Exception("BegAttr: No currently open element start tag!");
00117   }
00118   if (IsStateComment()) {
00119     SetStateError();
00120     throw Exception("BegAttr: Within a comment!");
00121   }
00122 
00123   if (IsState(ELEM_OPENA)) {
00124     EndAttr();
00125   }
00126   
00127   (*this) << ' ' << attr << "=\"";
00128   SetState(ELEM_OPENA);
00129 }
00130 
00131 void
00132 xml::ostream::EndAttr()
00133 {
00134   // Sanity check
00135   if (!(IsState(ELEM_OPENA))) {
00136     SetStateError();
00137     throw Exception("EndAttr: No currently open attribute!");
00138   }
00139   if (IsStateComment()) {
00140     SetStateError();
00141     throw Exception("EndAttr: Within a comment!");
00142   }
00143   
00144   (*this) << '"';
00145   SetState(ELEM_OPENI);
00146 }
00147 
00148 
00149 void
00150 xml::ostream::EndAttrs()
00151 {
00152   // Sanity check
00153   if ( !(IsState(ELEM_OPENA) || IsState(ELEM_OPENI)) ) {
00154     SetStateError();
00155     throw Exception("EndAttrs: No currently open element start tag!");
00156   }
00157   if (IsStateComment()) {
00158     SetStateError();
00159     throw Exception("EndAttrs: Within a comment!");
00160   }
00161   
00162   if (IsState(ELEM_OPENA)) {
00163     EndAttr();
00164   }
00165   (*this) << ">\n"; 
00166   SetState(ELEM_OPEN);
00167 }
00168 
00169 //****************************************************************************
00170 
00171 void
00172 xml::ostream::BegComment()
00173 {
00174   // Sanity check
00175   if (IsStateComment()) {
00176     SetStateError();
00177     throw Exception("BegComment: Already within a comment!");    
00178   }
00179   
00180   if (IsState(ELEM_OPENA) || IsState(ELEM_OPENI)) {
00181     EndAttrs(); // state is updated
00182   }
00183   Indent();
00184   (*this) << "<!-- ";
00185 
00186   SetStateComment();
00187 }
00188 
00189 void
00190 xml::ostream::EndComment()
00191 {
00192   // Sanity check
00193   if (!IsStateComment()) {
00194     SetStateError();
00195     throw Exception("EndComment: Not within a comment!");
00196   }
00197   
00198   (*this) << " -->\n";
00199 
00200   ResetStateComment();
00201 }
00202 
00203 void
00204 xml::ostream::Comment(const char* str)
00205 {
00206   // Sanity check -- rely on BegComment()
00207   
00208   BegComment();
00209   (*this) << str;
00210   EndComment();
00211 }
00212 
00213 //****************************************************************************
00214 
00215 void
00216 xml::ostream::Indent()
00217 {
00218   for (int i = 0; i < indentAmnt; ++i) {
00219     (*this) << ' ';
00220   }
00221 }
00222 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines