libFAUDES
Sections
Index
|
cfl_tokenwriter.cppGo to the documentation of this file.00001 /** @file cfl_tokenwriter.cpp @brief Class TokenWriter */ 00002 00003 /* FAU Discrete Event Systems Library (libfaudes) 00004 00005 Copyright (C) 2006 Bernd Opitz 00006 Copyright (C) 2006 Thomas Moor 00007 Exclusive copyright is granted to Klaus Schmidt 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public 00020 License along with this library; if not, write to the Free Software 00021 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00022 00023 00024 #include "cfl_tokenwriter.h" 00025 00026 namespace faudes { 00027 00028 // TokenWriter(rFilename, openmode) 00029 TokenWriter::TokenWriter(const std::string& rFilename, std::ios::openmode openmode) 00030 : mMode(File), pSStream(0), mHasOutBuffer(false), mFileName(rFilename), mColumns(80/FD_NAMELEN), mColCount(0) { 00031 // set up mFStream 00032 mFStream.exceptions(std::ios::badbit|std::ios::failbit); 00033 try{ 00034 mFStream.open(rFilename.c_str(), openmode); 00035 } 00036 catch (std::ios::failure&) { 00037 std::stringstream errstr; 00038 errstr << "Exception opening/writing file \""<< rFilename << "\""; 00039 throw Exception("TokenWriter::TokenWriter", errstr.str(), 2); 00040 } 00041 // use mFStream 00042 mpStream=&mFStream; 00043 mEndl=true; 00044 } 00045 00046 // TokenWriter(rFilename, doctype) 00047 TokenWriter::TokenWriter(const std::string& rFilename, const std::string& ftype) 00048 : mMode(XmlFile), pSStream(0), mHasOutBuffer(false), mFileName(rFilename), mColumns(80/FD_NAMELEN), mColCount(0) { 00049 // set up mFStream 00050 mFStream.exceptions(std::ios::badbit|std::ios::failbit); 00051 try{ 00052 mFStream.open(rFilename.c_str(), std::ios::out|std::ios::trunc); 00053 mFStream << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"no\"?>" << std::endl; 00054 if(ftype!="") 00055 if(ftype!="Void") { 00056 std::string dtdfile=ftype; 00057 std::transform(dtdfile.begin(), dtdfile.end(), dtdfile.begin(), tolower); 00058 dtdfile="http://www.faudes.org/dtd/1.0/"+dtdfile+".dtd"; 00059 mFStream << "<!DOCTYPE " << ftype << " SYSTEM \"" << dtdfile << "\">" << std::endl; 00060 } 00061 } 00062 catch (std::ios::failure&) { 00063 std::stringstream errstr; 00064 errstr << "Exception opening/writing xml file \""<< rFilename << "\""; 00065 throw Exception("TokenWriter::TokenWriter", errstr.str(), 2); 00066 } 00067 // use mFStream 00068 mpStream=&mFStream; 00069 mEndl=true; 00070 } 00071 00072 // TokenWriter(mode) 00073 TokenWriter::TokenWriter(Mode mode) 00074 : mMode(mode), pSStream(0), mHasOutBuffer(false), mFileName(""), mColumns(80/FD_NAMELEN), mColCount(0) { 00075 switch(mode) { 00076 case Stdout: 00077 // set up mFStream 00078 mFileName="stdout"; 00079 /* 00080 try { 00081 mFStream.copyfmt(std::cout); 00082 mFStream.clear(std::cout.rdstate()); 00083 typedef std::basic_ios<char> ___basic_ios_char_; // trick for vc++ 00084 mFStream.___basic_ios_char_::rdbuf(std::cout.rdbuf()); 00085 } 00086 catch (std::ios::failure&) { 00087 std::stringstream errstr; 00088 errstr << "Exception opening/writing file \""<< mFileName << "\""; 00089 throw Exception("TokenWriter::TokenWriter", errstr.str(), 2); 00090 } 00091 // use mFStream 00092 mpStream=&mFStream; 00093 */ 00094 // use std::cout 00095 mpStream= &std::cout; 00096 mEndl=true; 00097 break; 00098 case String: 00099 // use mSStream 00100 mFileName="string"; 00101 mpStream=&mSStream; 00102 mEndl=false; 00103 break; 00104 default: 00105 std::stringstream errstr; 00106 errstr << "Invalid Mode / Not Implemented"; 00107 throw Exception("TokenWriter::TokenWriter", errstr.str(), 2); 00108 } 00109 } 00110 00111 00112 // TokenWriter(stream) 00113 TokenWriter::TokenWriter(std::ostream& stream, const std::string& ftype) 00114 : mMode(Stream), pSStream(&stream), mHasOutBuffer(false), mFileName("stream"), mColumns(0), mColCount(0) { 00115 // xml if there is a doctype 00116 try { 00117 if(ftype!="") 00118 if(ftype!="Void") { 00119 std::string dtdfile=ftype; 00120 std::transform(dtdfile.begin(), dtdfile.end(), dtdfile.begin(), tolower); 00121 dtdfile="http://www.faudes.org/dtd/1.0/"+dtdfile+".dtd"; 00122 *pSStream << "<!DOCTYPE " << ftype << " SYSTEM \"" << dtdfile << "\">" << std::endl; 00123 mMode=XmlStream; 00124 } 00125 } catch (std::ios::failure&) { 00126 std::stringstream errstr; 00127 errstr << "Exception opening/writing xml stream"; 00128 throw Exception("TokenWriter::TokenWriter", errstr.str(), 2); 00129 } 00130 // use provided stream 00131 mpStream=pSStream; 00132 mEndl=true; 00133 } 00134 00135 // destructor 00136 TokenWriter::~TokenWriter(void) { 00137 Flush(); 00138 if(mMode==File) mFStream.close(); 00139 } 00140 00141 // Flush buffers 00142 void TokenWriter::Flush(void) { 00143 DoFlush(); 00144 mpStream->flush(); 00145 } 00146 00147 // Str() 00148 std::string TokenWriter::Str(void) { 00149 if(mMode!=String) { 00150 std::stringstream errstr; 00151 errstr << "Not in String Mode"; 00152 throw Exception("TokenWriter::Str()", errstr.str(), 2); 00153 } 00154 Flush(); 00155 return mSStream.str(); 00156 } 00157 00158 // Stream() 00159 std::ostream* TokenWriter::Streamp(void) { 00160 Flush(); 00161 return mpStream; 00162 } 00163 00164 00165 00166 // Columns() 00167 int TokenWriter::Columns(void) const { 00168 return mColumns; 00169 } 00170 00171 // Columns() 00172 void TokenWriter::Columns(int columns) { 00173 mColumns = columns; 00174 } 00175 00176 // Endl() 00177 void TokenWriter::Endl(void) { 00178 DoFlush(); 00179 try{ 00180 if(mEndl) *mpStream << std::endl; 00181 else *mpStream << " "; 00182 } 00183 catch (std::ios::failure&) { 00184 std::stringstream errstr; 00185 errstr << "Exception opening/writing file \"" << mFileName << "\""; 00186 throw Exception("Generator::write", errstr.str(), 2); 00187 } 00188 } 00189 00190 // Endl(bool) 00191 void TokenWriter::Endl(bool on) { 00192 mEndl=on; 00193 } 00194 00195 // DoFlush: write buffered token 00196 // Note: dont call Endl() since this calles DoFlush 00197 void TokenWriter::DoFlush(void) { 00198 if(!mHasOutBuffer) return; 00199 FD_DV("TokenWriter::DoFlush()"); 00200 try{ 00201 // markup starts a new line: pre linefeed 00202 if(mOutBuffer.IsBegin() || mOutBuffer.IsEnd()) 00203 if(mColCount !=0 && (mColumns>0) && mEndl) { 00204 mOutBuffer.mPreceedingNewline=true; 00205 mOutBuffer.mPreceedingSpace=false; 00206 } 00207 // columncount starts a new line 00208 if(mColCount >= mColumns && (mColumns>0) && mEndl) { 00209 mOutBuffer.mPreceedingNewline=true; 00210 mOutBuffer.mPreceedingSpace=false; 00211 } 00212 // if we just started a new column, we dont need any seps 00213 if(mColCount==0) { 00214 mOutBuffer.mPreceedingNewline=false; 00215 mOutBuffer.mPreceedingSpace=false; 00216 } 00217 // do the write 00218 mOutBuffer.Write(mpStream); 00219 mColCount++; 00220 // count my columns 00221 if(mOutBuffer.mPreceedingNewline) mColCount =1; 00222 // markup starts a new line: post line feed 00223 if(mOutBuffer.IsBegin() || mOutBuffer.IsEnd()) 00224 if(mColumns>0 && mEndl) { 00225 *mpStream << std::endl; 00226 mColCount=0; 00227 } 00228 } 00229 catch (std::ios::failure&) { 00230 std::stringstream errstr; 00231 errstr << "Exception opening/writing file \"" << mFileName << "\""; 00232 throw Exception("TokenWriter::Write(token)", errstr.str(), 2); 00233 } 00234 mHasOutBuffer=false; 00235 } 00236 00237 // Write(rToken) 00238 void TokenWriter::Write(const Token& rToken) { 00239 FD_DV("TokenWriter::Write(token)"); 00240 // figure wether we can merge to an empty section: 00241 // 1. buffer begin must match the current token end tag 00242 if(rToken.IsEnd() && !rToken.IsBegin()) 00243 if(mHasOutBuffer) 00244 if(mOutBuffer.IsBegin() && !mOutBuffer.IsEnd()) 00245 if(mOutBuffer.StringValue()==rToken.StringValue()) 00246 // 2. dont do it on HTML tags since it irritates bowsers 00247 if(mOutBuffer.StringValue()!="b") 00248 if(mOutBuffer.StringValue()!="i") 00249 if(mOutBuffer.StringValue()!="tt") 00250 if(mOutBuffer.StringValue()!="p") 00251 if(mOutBuffer.StringValue()!="h1") 00252 if(mOutBuffer.StringValue()!="h2") 00253 if(mOutBuffer.StringValue()!="h3") 00254 if(mOutBuffer.StringValue()!="h4") 00255 if(mOutBuffer.StringValue()!="font") 00256 if(mOutBuffer.StringValue()!="strong") 00257 { 00258 mOutBuffer.mType |= Token::End; 00259 DoFlush(); 00260 return; 00261 } 00262 // figure wether we need a preceeding space 00263 bool needsep=true; 00264 if(mHasOutBuffer) { 00265 if(mOutBuffer.IsBegin()) needsep=false; 00266 if(mOutBuffer.IsEnd()) needsep=false; 00267 } 00268 if(rToken.IsBegin()) needsep=false; 00269 if(rToken.IsEnd()) needsep=false; 00270 // write buffer if any 00271 DoFlush(); 00272 // record to buffer 00273 mOutBuffer=rToken; 00274 mOutBuffer.mPreceedingSpace = mOutBuffer.mPreceedingSpace || needsep; 00275 mHasOutBuffer=true; 00276 } 00277 00278 00279 // WriteString(rName) 00280 void TokenWriter::WriteString(const std::string& rName) { 00281 if((rName == "\n") || (rName == "\r\n")) { 00282 Endl(); 00283 mColCount = 0; 00284 return; 00285 } 00286 Token token; 00287 token.SetString(rName); 00288 Write(token); 00289 } 00290 00291 00292 // WriteText(rText) 00293 void TokenWriter::WriteText(const std::string& rText) { 00294 try { 00295 DoFlush(); 00296 Token::WriteEscapedString(mpStream,rText); 00297 } 00298 catch (std::ios::failure&) { 00299 std::stringstream errstr; 00300 errstr << "Exception opening/writing file \"" << mFileName << "\""; 00301 throw Exception("TokenWriter::WriteText(text)", errstr.str(), 2); 00302 } 00303 } 00304 00305 // WriteText(rBegin,rText) 00306 void TokenWriter::WriteText(const Token& rBeginTag, const std::string& rText) { 00307 if(!rBeginTag.IsBegin() || rBeginTag.IsEnd()) { 00308 std::stringstream errstr; 00309 errstr << "Invalid begin token while writing file \"" << mFileName << "\""; 00310 throw Exception("TokenWriter::WriteText(label,text)", errstr.str(), 2); 00311 } 00312 try { 00313 Write(rBeginTag); 00314 DoFlush(); 00315 Token::WriteEscapedString(mpStream,rText); 00316 Endl(); 00317 WriteEnd(rBeginTag.StringValue()); 00318 } 00319 catch (std::ios::failure&) { 00320 std::stringstream errstr; 00321 errstr << "Exception writing file \"" << mFileName << "\""; 00322 throw Exception("TokenWriter::WriteText(label,text)", errstr.str(), 2); 00323 } 00324 } 00325 00326 00327 // WriteText(rLabel,rText) 00328 void TokenWriter::WriteText(const std::string& rLabel, const std::string& rText) { 00329 Token btag; 00330 btag.SetBegin(rLabel); 00331 WriteText(btag,rText); 00332 } 00333 00334 00335 // WriteCharacterData(rCData) 00336 void TokenWriter::WriteCharacterData(const std::string& rCharacterData) { 00337 try { 00338 DoFlush(); 00339 *mpStream << rCharacterData; 00340 } 00341 catch (std::ios::failure&) { 00342 std::stringstream errstr; 00343 errstr << "Exception opening/writing file \"" << mFileName << "\""; 00344 throw Exception("TokenWriter::WriteCharacterData(text)", errstr.str(), 2); 00345 } 00346 } 00347 00348 // WriteVerbatim(rData) 00349 void TokenWriter::WriteVerbatim(const std::string& rData) { 00350 FD_DV("TokenWriter::Write(token)"); 00351 // if(mMode==Stdout) mpStream = &std::cout; // fix 00352 DoFlush(); 00353 try{ 00354 if(mColCount !=0) Endl(); 00355 Token::WriteVerbatim(mpStream,rData); 00356 mColCount = 0; 00357 } 00358 catch (std::ios::failure&) { 00359 std::stringstream errstr; 00360 errstr << "Exception opening/writing file \"" << mFileName << "\""; 00361 throw Exception("TokenWriter::WriteVerbatim()", errstr.str(), 2); 00362 } 00363 } 00364 00365 // WriteInteger(index) 00366 void TokenWriter::WriteInteger(Idx index) { 00367 Token token; 00368 token.SetInteger(index); 00369 Write(token); 00370 } 00371 00372 // WriteInteger(index) 00373 void TokenWriter::WriteInteger16(long int val) { 00374 Token token; 00375 token.SetInteger16(val); 00376 Write(token); 00377 } 00378 00379 // WriteFloat(float) 00380 void TokenWriter::WriteFloat(const double& val) { 00381 Token token; 00382 token.SetFloat(val); 00383 Write(token); 00384 } 00385 00386 00387 // WriteOption(rOpt) 00388 void TokenWriter::WriteOption(const std::string& rOpt) { 00389 Token token; 00390 token.SetOption(rOpt); 00391 Write(token); 00392 } 00393 00394 00395 // WriteBegin(rLabel) 00396 void TokenWriter::WriteBegin(const std::string& rLabel) { 00397 Token token; 00398 token.SetBegin(rLabel); 00399 Write(token); 00400 } 00401 00402 // WriteEnd(rLabel) 00403 void TokenWriter::WriteEnd(const std::string& rLabel) { 00404 Token token; 00405 token.SetEnd(rLabel); 00406 Write(token); 00407 } 00408 00409 // WriteBegin(rLabel) 00410 void TokenWriter::WriteEmpty(const std::string& rLabel) { 00411 Token token; 00412 token.SetEmpty(rLabel); 00413 Write(token); 00414 } 00415 00416 // WriteComment(comment) 00417 void TokenWriter::WriteComment(const std::string& comment){ 00418 DoFlush(); 00419 // auto xml 00420 if(mMode==XmlFile || mMode==XmlStream) { WriteXmlComment(comment); return; } 00421 // no endl ... no comment 00422 if(!mEndl) return; 00423 try{ 00424 if(mColCount!=0) Endl(); 00425 // fix comment indicator 00426 if(comment.length()==0) 00427 *mpStream << "% "; 00428 if(comment.length()>0) 00429 if(comment.at(0)!='%') 00430 *mpStream << "% "; 00431 // xml/endl escape 00432 std::string::const_iterator cit=comment.begin(); 00433 for(;cit!=comment.end(); cit++) { 00434 if(*cit=='<') 00435 { *mpStream << "<"; continue;} 00436 if(*cit=='>') 00437 { *mpStream << ">"; continue;} 00438 if(*cit=='&') 00439 { *mpStream << "&"; continue;} 00440 if(*cit=='\n') 00441 { *mpStream << " "; continue;} 00442 if(*cit=='\r') 00443 { ; continue;} 00444 *mpStream << *cit; 00445 } 00446 // done 00447 Endl(); 00448 mColCount = 0; 00449 } 00450 catch (std::ios::failure&) { 00451 std::stringstream errstr; 00452 errstr << "Exception opening/writing file \"" << mFileName << "\""; 00453 throw Exception("TokenWriter::Comment", errstr.str(), 2); 00454 } 00455 } 00456 00457 // WriteXmlComment(comment) 00458 void TokenWriter::WriteXmlComment(const std::string& comment){ 00459 if(!mEndl) return; // no endl implies no comments 00460 DoFlush(); 00461 try{ 00462 if(mColCount!=0) Endl(); 00463 // begin tag 00464 *mpStream << "<!-- "; 00465 // test for multiline 00466 static const std::string newline="\n\r"; 00467 if(comment.find_first_of(newline)!=std::string::npos) 00468 Endl(); 00469 // xml/endl escape 00470 std::string::const_iterator cit=comment.begin(); 00471 for(;cit!=comment.end(); cit++) { 00472 if(*cit=='>') 00473 { *mpStream << ">"; continue;} 00474 *mpStream << *cit; 00475 } 00476 // end tag 00477 *mpStream << " -->"; 00478 // done 00479 Endl(); 00480 mColCount = 0; 00481 } 00482 catch (std::ios::failure&) { 00483 std::stringstream errstr; 00484 errstr << "Exception opening/writing file \"" << mFileName << "\""; 00485 throw Exception("TokenWriter::Comment", errstr.str(), 2); 00486 } 00487 } 00488 00489 // write base64 00490 void TokenWriter::WriteBinary(const char* pData, long int len) { 00491 DoFlush(); 00492 Token::WriteBinary(mpStream,pData,len); 00493 } 00494 00495 // FileName() 00496 std::string TokenWriter::FileName(void) const { 00497 return mFileName; 00498 } 00499 00500 00501 00502 00503 } // namespace faudes |
libFAUDES 2.20d --- 2011.04.26 --- c++ source docu by doxygen