xmlostream.cxx

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

Generated on Fri Jul 24 04:29:08 2009 for OpenADFortTk (extended to Open64) by  doxygen 1.5.7.1