|
OpenADFortTk (basic)
|
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