00001
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <string.h>
00015 #include <fstream.h>
00016
00017 #include "CTB.hxx"
00018 #include "CTB_Trace.hxx"
00019 #include "CTBosFill.hxx"
00020 #include "CTBprintf.hxx"
00021 #include "CTBxmlOStream.hxx"
00022
00028
00030
00031 CTBxmlOStream::CTBxmlOStream()
00032 : mp_os(0),
00033 mb_attached(false),
00034 mb_autonewline(true),
00035 mb_autoindent(true),
00036 mb_bad(false),
00037 mb_fail(false),
00038 mi_lasttag(starttag)
00039 {
00040 CTB_Trace("CTBxmlOStream()");
00041 }
00042
00043
00045
00046 CTBxmlOStream::CTBxmlOStream(ostream* p_os)
00047 : mp_os(p_os),
00048 mb_attached(p_os),
00049 mb_autonewline(true),
00050 mb_autoindent(true),
00051 mb_bad(false),
00052 mb_fail(false),
00053 mi_lasttag(starttag)
00054 {
00055 CTB_Trace("CTBxmlOStream(ostream*)");
00056 }
00057
00058
00060
00061 CTBxmlOStream::CTBxmlOStream(const char* c_filename, int i_mode, int i_prot)
00062 : mp_os(0),
00063 mb_attached(false),
00064 mb_autonewline(true),
00065 mb_autoindent(true),
00066 mb_bad(false),
00067 mb_fail(false),
00068 mi_lasttag(starttag)
00069 {
00070 CTB_Trace("CTBxmlOStream(const char*, int, int)");
00071 Open(c_filename,i_mode,i_prot);
00072 }
00073
00074
00076
00077 CTBxmlOStream::~CTBxmlOStream()
00078 {
00079 CTB_Trace("~CTBxmlOStream()");
00080 Close();
00081 }
00082
00083
00085
00086 void CTBxmlOStream::Attach(ostream* p_os)
00087 {
00088 CTB_Trace("CTBxmlOStream::Attach(ostream*)");
00089 Close();
00090 mp_os = p_os;
00091 mb_attached = p_os;
00092 mi_lasttag = starttag;
00093
00094 if(mp_os) (*mp_os) << "<?xml version='1.0' standalone='yes'?>";
00095
00096 return;
00097 }
00098
00099
00101
00102 void CTBxmlOStream::Open(const char* c_filename, int i_mode, int i_prot)
00103 {
00104 CTB_Trace("CTBxmlOStream::Open(const char*, int, int)");
00105 if (c_filename[0] == '-' && c_filename[1] == 0) {
00106 Attach(&cout);
00107
00108 } else {
00109 Close();
00110 mp_os = new ofstream(c_filename,i_mode,i_prot);
00111 if (mp_os->bad()) {
00112 delete mp_os;
00113 mp_os = 0;
00114 mb_fail = true;
00115 mb_bad = true;
00116 }
00117 if(mp_os) (*mp_os) << "<?xml version='1.0' standalone='yes'?>";
00118 }
00119
00120 return;
00121 }
00122
00123
00125
00126 void CTBxmlOStream::Close()
00127 {
00128 CTB_Trace("CTBxmlOStream::Close()");
00129 if (mp_os) {
00130 if (m_tagstack) {
00131 while (m_tagstack) PutEndTag();
00132 }
00133 *mp_os << endl;
00134
00135 if (!mb_attached) delete mp_os;
00136 mp_os = 0;
00137 mb_attached = false;
00138 mb_fail = false;
00139 mb_bad = false;
00140 mi_lasttag = starttag;
00141 }
00142 return;
00143 }
00144
00145
00147
00148 bool CTBxmlOStream::Good() const
00149 {
00150 CTB_Trace("CTBxmlOStream::Good()");
00151 return mb_fail ? false : (mp_os ? mp_os->good() : true);
00152 }
00153
00154
00156
00157 bool CTBxmlOStream::Bad() const
00158 {
00159 CTB_Trace("CTBxmlOStream::Bad()");
00160 return mb_bad ? true : (mp_os ? mp_os->bad() : false);
00161 }
00162
00164
00165 bool CTBxmlOStream::Fail() const
00166 {
00167 CTB_Trace("CTBxmlOStream::Fail()");
00168 return mb_fail ? true : (mp_os ? mp_os->fail() : false);
00169 }
00170
00171
00173
00174 bool CTBxmlOStream::Eof() const
00175 {
00176 CTB_Trace("CTBxmlOStream::Eof()");
00177 return mb_bad ? false : (mp_os ? mp_os->eof() : false);
00178 }
00179
00180
00182
00183 void CTBxmlOStream::PutStartTag(const char* c_name)
00184 {
00185 CTB_Trace("CTBxmlOStream::PutStartTag(const char*)");
00186 if (mp_os) {
00187 if (mb_autonewline) {
00188 *mp_os << "\n";
00189 if (mb_autoindent) *mp_os << CTBosFill(m_tagstack.Size());
00190 }
00191 m_tagstack << CTBstring(c_name);
00192 *mp_os << "<" << c_name << ">";
00193 mi_lasttag = starttag;
00194 } else {
00195 SetBad();
00196 }
00197 return;
00198 }
00199
00200
00202
00203 void CTBxmlOStream::PutEmptyTag(const char* c_name)
00204 {
00205 CTB_Trace("CTBxmlOStream::PutEmptyTag(const char*)");
00206 if (mp_os) {
00207 if (mb_autonewline) {
00208 *mp_os << "\n";
00209 if (mb_autoindent) *mp_os << CTBosFill(m_tagstack.Size());
00210 }
00211 *mp_os << "<" << c_name << "/>";
00212 mi_lasttag = emptytag;
00213 } else {
00214 SetBad();
00215 }
00216 return;
00217 }
00218
00219
00221
00222 void CTBxmlOStream::PutEndTag()
00223 {
00224 CTB_Trace("CTBxmlOStream::PutEndTag()");
00225 if (mp_os) {
00226 if (m_tagstack) {
00227 CTBstring tagname;
00228 m_tagstack >> tagname;
00229 if (mb_autonewline && mi_lasttag != starttag) {
00230 *mp_os << "\n";
00231 if (mb_autoindent) *mp_os << CTBosFill(m_tagstack.Size());
00232 }
00233 *mp_os << "</" << tagname << ">";
00234 mi_lasttag = endtag;
00235 } else {
00236 SetFail();
00237 }
00238 } else {
00239 SetBad();
00240 }
00241 return;
00242 }
00243
00244
00246
00247 void CTBxmlOStream::PutTaggedValue(const char* c_name, int i_value,
00248 const char* c_format, int i_width)
00249 {
00250 CTB_Trace("CTBxmlOStream::PutTaggedValue(const char*,int,const char*,int)");
00251 if (mp_os) {
00252 PutStartTag(c_name);
00253 (*mp_os) << CTBprintf(i_value,c_format,i_width);
00254 PutEndTag();
00255 } else {
00256 SetBad();
00257 }
00258 return;
00259 }
00260
00261
00263
00264 void CTBxmlOStream::PutTaggedValue(const char* c_name, unsigned int i_value,
00265 const char* c_format, int i_width)
00266 {
00267 CTB_Trace("CTBxmlOStream::PutTaggedValue(const char*,unsigned int,"
00268 "const char*, int)");
00269 if (mp_os) {
00270 PutStartTag(c_name);
00271 (*mp_os) << CTBprintf(i_value,c_format,i_width);
00272 PutEndTag();
00273 } else {
00274 SetBad();
00275 }
00276 return;
00277 }
00278
00279
00281
00282 void CTBxmlOStream::PutTaggedValue(const char* c_name, long i_value,
00283 const char* c_format, int i_width)
00284 {
00285 CTB_Trace("CTBxmlOStream::PutTaggedValue(const char*,long,const char*,int)");
00286 if (mp_os) {
00287 PutStartTag(c_name);
00288 (*mp_os) << CTBprintf(i_value,c_format,i_width);
00289 PutEndTag();
00290 } else {
00291 SetBad();
00292 }
00293 return;
00294 }
00295
00296
00298
00299 void CTBxmlOStream::PutTaggedValue(const char* c_name, unsigned long i_value,
00300 const char* c_format, int i_width)
00301 {
00302 CTB_Trace("CTBxmlOStream::PutTaggedValue(const char*,unsigned long,"
00303 "const char*, int)");
00304 if (mp_os) {
00305 PutStartTag(c_name);
00306 (*mp_os) << CTBprintf(i_value,c_format,i_width);
00307 PutEndTag();
00308 } else {
00309 SetBad();
00310 }
00311 return;
00312 }
00313
00314
00316
00317 void CTBxmlOStream::PutTaggedValue(const char* c_name, double d_value,
00318 const char* c_format, int i_width,
00319 int i_precision)
00320 {
00321 CTB_Trace("CTBxmlOStream::PutTaggedValue(const char*,double,const char*,"
00322 "int,int)");
00323 if (mp_os) {
00324 PutStartTag(c_name);
00325 (*mp_os) << CTBprintf(d_value,c_format,i_width,i_precision);
00326 PutEndTag();
00327 } else {
00328 SetBad();
00329 }
00330 return;
00331 }
00332
00333
00335
00336 void CTBxmlOStream::PutTaggedValue(const char* c_name, const char* c_value,
00337 bool b_dropempty)
00338 {
00339 CTB_Trace("CTBxmlOStream::PutTaggedValue(const char*, const char*, bool)");
00340 if (mp_os) {
00341 if (!b_dropempty || (c_value && *c_value)) {
00342 PutStartTag(c_name);
00343 PutEscapedString(c_value);
00344 PutEndTag();
00345 }
00346 } else {
00347 SetBad();
00348 }
00349 return;
00350 }
00351
00352
00354
00355 void CTBxmlOStream::PutTaggedValue(const char* c_name, const CTBstring& value,
00356 bool b_dropempty)
00357 {
00358 CTB_Trace("CTBxmlOStream::PutTaggedValue(const char*,const CTBstring&,bool)");
00359 if (mp_os) {
00360 if (!b_dropempty || value.Length() > 0) {
00361 PutStartTag(c_name);
00362 PutEscapedString(value);
00363 PutEndTag();
00364 }
00365 } else {
00366 SetBad();
00367 }
00368 return;
00369 }
00370
00371
00373
00374 void CTBxmlOStream::PutTaggedValue(const char* c_name, const CTBtime& value,
00375 bool b_dropempty)
00376 {
00377 CTB_Trace("CTBxmlOStream::PutTaggedValue(const char*,const CTBtime&,bool)");
00378 if (mp_os) {
00379 if (!b_dropempty || value.Valid()) {
00380 PutStartTag(c_name);
00381 (*mp_os) << value;
00382 PutEndTag();
00383 }
00384 } else {
00385 SetBad();
00386 }
00387 return;
00388 }
00389
00390
00392
00393 void CTBxmlOStream::Dump(int i_indent, ostream& os, const char* p_text) const
00394 {
00395 CTBosFill bl(i_indent);
00396
00397 os << bl << "--CTBxmlOStream ";
00398 if (p_text) os << p_text;
00399 os << " @ " << this << endl;
00400
00401 os << bl << " mp_os: " << mp_os << endl;
00402 os << bl << " mb_attached: " << mb_attached << endl;
00403 os << bl << " mb_autonewline: " << mb_autonewline << endl;
00404 os << bl << " mb_autoindent: " << mb_autoindent << endl;
00405 os << bl << " mb_fail: " << mb_fail << endl;
00406 os << bl << " mb_bad: " << mb_bad << endl;
00407 m_tagstack.Dump(i_indent+2,os,"m_tagstack");
00408
00409 return;
00410 }
00411
00412
00414
00415 CTBxmlOStream& CTBxmlOStream::operator<<(const char* c_text)
00416 {
00417 CTB_Trace("CTBxmlOStream::operator<<(const char*)");
00418 if (mp_os) PutEscapedString(c_text);
00419 else SetBad();
00420 return *this;
00421 }
00422
00423
00425
00426 void CTBxmlOStream::PutEscapedString(const char* c_text, CTBint i_length)
00427 {
00428 CTB_Trace("CTBxmlOStream::PutEscapedString(const char*,CTBint)");
00429 if (!mp_os) return;
00430 if (!c_text) return;
00431
00432 if (i_length < 0) i_length = strlen(c_text);
00433
00434 for (CTBint i = 0; i < i_length; i++) {
00435 char c = c_text[i];
00436 if (c == '<') *mp_os << "<";
00437 else if (c == '>') *mp_os << ">";
00438 else if (c == '&') *mp_os << "&";
00439 else *mp_os << c;
00440 }
00441 return;
00442 }
00443
00444
00446
00447 void CTBxmlOStream::PutEscapedString(const CTBstring& string)
00448 {
00449 CTB_Trace("CTBxmlOStream::PutEscapedString(const CTBstring&)");
00450 CTBint i_length = string.Length();
00451
00452 if (i_length == 0) return;
00453 PutEscapedString(string.Data(),i_length);
00454 return;
00455 }
00456
00457
00458