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
1.5.7.1