|
libFAUDES
Sections
Index
|
cfl_tokenreader.cppGo to the documentation of this file.00001 /** @file cfl_tokenreader.cpp @brief Class TokenReader */ 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 00025 00026 #include "cfl_tokenreader.h" 00027 00028 namespace faudes { 00029 00030 // TokenReader(mode,instring) 00031 TokenReader::TokenReader(Mode mode, const std::string& rInString) 00032 : mMode(mode), mpStream(NULL), mFileName("") 00033 { 00034 switch(mode) { 00035 case String: 00036 // use mSStream 00037 FD_DV("TokenReader::Tokenreader(String, ...): " << rInString); 00038 mpSStream= new std::istringstream(rInString, std::istringstream::in | std::istringstream::binary); 00039 mpStream= mpSStream; 00040 Rewind(); 00041 break; 00042 case File: 00043 // set up mFStream 00044 FD_DV("TokenReader::Tokenreader(File, \"" << rInString <<"\")"); 00045 mFStream.exceptions(std::ios::badbit|std::ios::failbit); 00046 try{ 00047 mFStream.open(rInString.c_str(), std::ios::in | std::ios::binary); 00048 } 00049 catch (std::ios::failure&) { 00050 std::stringstream errstr; 00051 errstr << "Exception opening/reading file \""<< rInString << "\""; 00052 throw Exception("TokenReader::TokenReader", errstr.str(), 1); 00053 } 00054 mFileName=rInString; 00055 mpStream=&mFStream; 00056 Rewind(); 00057 break; 00058 default: 00059 std::stringstream errstr; 00060 errstr << "Invalid Mode / Not implemented"; 00061 throw Exception("TokenReader::TokenReader(mode,instring)", errstr.str(), 1); 00062 } 00063 } 00064 00065 00066 // TokenReader(rFilename) 00067 TokenReader::TokenReader(const std::string& rFilename) 00068 : mMode(File), mpStream(NULL), mFileName(rFilename) 00069 { 00070 // set up mFStream 00071 FD_DV("TokenReader::Tokenreader(File, \"" << rFilename <<"\")"); 00072 mFStream.exceptions(std::ios::badbit|std::ios::failbit); 00073 try{ 00074 mFStream.open(rFilename.c_str(), std::ios::in | std::ios::binary); 00075 } 00076 catch (std::ios::failure&) { 00077 std::stringstream errstr; 00078 errstr << "Exception opening/reading file \""<< rFilename << "\""; 00079 throw Exception("TokenReader::TokenReader", errstr.str(), 1); 00080 } 00081 mFileName=rFilename; 00082 mpStream=&mFStream; 00083 Rewind(); 00084 } 00085 00086 00087 // destruct 00088 TokenReader::~TokenReader(void) { 00089 if(mMode==String) delete mpSStream; 00090 } 00091 00092 // Rewind() 00093 void TokenReader::Rewind(void) { 00094 FD_DV("TokenReader::Rewind: \"" << mFileName <<"\""); 00095 try { 00096 mpStream->clear(); 00097 mpStream->seekg(0); 00098 mHasPeekToken=false; 00099 mPeekToken.SetNone(); 00100 mLevel=0; 00101 mLevelPos.clear(); 00102 mLevelPos.push_back(0); 00103 mLevelLine.clear(); 00104 mLevelLine.push_back(1); 00105 mSeekLevel.clear(); 00106 mLineCount=1; 00107 mFilePos=0; 00108 } 00109 catch (std::ios::failure&) { 00110 std::stringstream errstr; 00111 errstr << "Exception opening/reading file in "<< FileLine(); 00112 throw Exception("TokenReader::Rewind", errstr.str(), 1); 00113 } 00114 } 00115 00116 00117 // FileName() 00118 std::string TokenReader::FileName(void) const { 00119 return mFileName; 00120 } 00121 00122 // Peek(token) 00123 bool TokenReader::Peek(Token& token) { 00124 // fake end token for empty section 00125 if(!mHasPeekToken && mPeekToken.IsBegin() && mPeekToken.IsEnd()) { 00126 FD_DV("TokenReader: fake from : " << mPeekToken.Str()); 00127 mPeekToken.SetEnd(std::string(mPeekToken.StringValue())); 00128 mHasPeekToken=true; 00129 } 00130 // get from peek buffer 00131 if(mHasPeekToken) { 00132 token=mPeekToken; 00133 FD_DV("TokenReader: Peek: " << token.Str()); 00134 return true; 00135 } 00136 // get new token 00137 try{ 00138 mLineCount += token.Read(mpStream); 00139 } 00140 catch (std::ios::failure&) { 00141 std::stringstream errstr; 00142 errstr << "Exception opening/reading file in "<< FileLine(); 00143 throw Exception("TokenReader::Peek", errstr.str(), 1); 00144 } 00145 mPeekToken=token; 00146 FD_DV("TokenReader: Peek: " << token.Str()); 00147 if(mPeekToken.IsNone()) { 00148 return false; 00149 } 00150 mHasPeekToken=true; 00151 return true; 00152 } 00153 00154 // Get(token) 00155 bool TokenReader::Get(Token& token) { 00156 bool res; 00157 // get token from peek buffer and invalidate 00158 res=Peek(token); 00159 mHasPeekToken=false; 00160 // track state (level of nested sections, filepos etc) 00161 if(res) { 00162 mFilePos=mpStream->tellg(); 00163 if(token.IsBegin()) { 00164 mLevel++; 00165 mLevelPos.push_back(mFilePos); 00166 mLevelLine.push_back(mLineCount); 00167 } 00168 if(token.IsEnd() && !token.IsBegin()) { 00169 mLevel--; 00170 if(mLevelPos.size()<=0 || mLevelLine.size()<=0) { 00171 #ifdef FAUDES_CHECKED 00172 FD_WARN("TokenReader::Get(): Unbalanced end of section at " << FileLine()); 00173 #endif 00174 token.SetNone(); 00175 return false; 00176 } 00177 mLevelPos.pop_back(); 00178 mLevelLine.pop_back(); 00179 } 00180 } 00181 FD_DV("TokenReader:Get(): " << token.Str()); 00182 return res; 00183 } 00184 00185 // SeekBegin(label) 00186 void TokenReader::SeekBegin(const std::string& rLabel) { 00187 Token token; 00188 SeekBegin(rLabel,token); 00189 } 00190 00191 // SeekBegin(label) 00192 void TokenReader::SeekBegin(const std::string& rLabel, Token& rToken) { 00193 // search for begin at any descending level, no rewind 00194 FD_DV("TokenReader::SeekBegin: " << rLabel << " at " << FileLine() << " level " << mLevel); 00195 int level=mLevel; 00196 long int startpos=mFilePos; 00197 int startline=mLineCount; 00198 for (;;) { 00199 // exception: did not get a token at all (incl. eof) 00200 if(!Peek(rToken)) { 00201 Rewind(); 00202 std::stringstream errstr; 00203 errstr << "Section \"" << rLabel << "\" expected at " << FileLine() << " no more tokens"; 00204 throw Exception("TokenReader::SeekBegin", errstr.str(), 51); 00205 } 00206 // exception: current section ends 00207 if((rToken.Type() == Token::End) && (mLevel == level)) { 00208 mpStream->seekg(startpos); 00209 mLineCount=startline; 00210 mHasPeekToken=false; 00211 mPeekToken.SetNone(); 00212 std::stringstream errstr; 00213 errstr << "Section \"" << rLabel << "\" expected at " << FileLine() 00214 << "current section ended unexpected. Found: " << rToken.StringValue() << " Type " << rToken.Type(); 00215 throw Exception("TokenReader::SeekBegin", errstr.str(), 51); 00216 } 00217 // success: found begin section 00218 if ((rToken.IsBegin()) && (rToken.StringValue() == rLabel)) 00219 break; 00220 // go on seeking 00221 Get(rToken); 00222 } 00223 } 00224 00225 // ReadBegin(label) 00226 void TokenReader::ReadBegin(const std::string& rLabel) { 00227 Token token; 00228 ReadBegin(rLabel,token); 00229 } 00230 00231 // ReadBegin(label,token) 00232 void TokenReader::ReadBegin(const std::string& rLabel, Token& rToken) { 00233 FD_DV("Looking for Section \"" << rLabel << "\""); 00234 try { 00235 int level=mLevel; 00236 bool firstgo=true; 00237 long int startpos=mFilePos; 00238 FD_DV("section level " << level << " current pos " << startpos << " begin of section " << mLevelPos[level]); 00239 // search for begin at current level 00240 for (;;) { 00241 // exception: did not get a token at all (incl eof) 00242 if(!Peek(rToken)) { 00243 std::stringstream errstr; 00244 errstr << "Section \"" << rLabel << "\" expected at " << FileLine() << ", no token at all"; 00245 throw Exception("TokenReader::ReadBegin Peek", errstr.str(), 51); 00246 } 00247 // success: found begin section 00248 if((rToken.IsBegin()) && (rToken.StringValue() == rLabel) && (mLevel==level)) { 00249 Get(rToken); 00250 break; 00251 } 00252 // rewind once when current section ends 00253 if(rToken.IsEnd() && !rToken.IsBegin() && (mLevel == level) && firstgo) { 00254 mpStream->seekg(mLevelPos[level]); 00255 mFilePos=mLevelPos[level]; 00256 mLineCount=mLevelLine[level]; 00257 firstgo=false; 00258 mHasPeekToken=false; 00259 mPeekToken.SetNone(); 00260 continue; 00261 } 00262 // exception: did not find begin label 00263 if((mFilePos>=startpos) && (!firstgo)) { 00264 std::stringstream errstr; 00265 errstr << "Section \"" << rLabel << "\" expected at " << FileLine() << ", did not find begin label"; 00266 throw Exception("TokenReader::ReadBegin Missed", errstr.str(), 51); 00267 } 00268 // skip this token 00269 Get(rToken); 00270 } 00271 } 00272 // catch my seek/tell errors 00273 catch (std::ios::failure&) { 00274 std::stringstream errstr; 00275 errstr << "Section \"" << rLabel << "\" expected at " << FileLine(); 00276 throw Exception("TokenReader::ReadBegin Rewind", errstr.str(), 1); 00277 } 00278 } 00279 00280 00281 // ExistsBegin(label) 00282 bool TokenReader::ExistsBegin(const std::string& rLabel) { 00283 FD_DV("TokenReader::ExistsBegin(): looking for Section \"" << rLabel << "\""); 00284 try { 00285 int level=mLevel; 00286 bool firstgo=true; 00287 long int startpos=mFilePos; 00288 FD_DV("section level " << level << " current pos " << startpos << " begin of section " << mLevelPos[level]); 00289 Token token; 00290 // search for begin at current level 00291 for(;;) { 00292 // fail: did not get a token at all (incl eof) 00293 if(!Peek(token)) { 00294 return false; 00295 } 00296 // success: found begin section 00297 if((token.IsBegin()) && (token.StringValue() == rLabel) && (mLevel==level)) { 00298 return true; 00299 } 00300 // rewind once when current section ends 00301 if((token.IsEnd() && !token.IsBegin()) && (mLevel == level) && firstgo) { 00302 mpStream->seekg(mLevelPos[level]); 00303 mFilePos=mLevelPos[level]; 00304 mLineCount=mLevelLine[level]; 00305 firstgo=false; 00306 mHasPeekToken=false; 00307 mPeekToken.SetNone(); 00308 continue; 00309 } 00310 // fail: did not find begin label 00311 if((mFilePos>=startpos) && (!firstgo)) { 00312 return false; 00313 } 00314 // skip this token 00315 Get(token); 00316 } 00317 } 00318 // catch my seek/tell errors 00319 catch (std::ios::failure&) { 00320 std::stringstream errstr; 00321 errstr << "Section \"" << rLabel << "\" expected at " << FileLine(); 00322 throw Exception("TokenReader::ReadBegin Rewind", errstr.str(), 1); 00323 } 00324 return false; 00325 } 00326 00327 // ReadEnd(label) 00328 void TokenReader::ReadEnd(const std::string& rLabel) { 00329 FD_DV("TokenReader::ReadEnd: " << rLabel << " at " << FileLine() ); 00330 // search for end at current level 00331 int level=mLevel; 00332 Token token; 00333 for (;;) { 00334 // exception: did not get a token at all 00335 if(!Get(token)) { 00336 std::stringstream errstr; 00337 errstr << "end of Section \"" << rLabel << "\" expected at " << FileLine(); 00338 throw Exception("TokenReader::ReadEnd", errstr.str(), 51); 00339 } 00340 // success: found end of current section 00341 if(token.IsEnd() && !token.IsBegin() && (token.StringValue() == rLabel) && (mLevel==level-1)) { 00342 break; 00343 } 00344 // exception: current section ends with unexpected label 00345 if(mLevel<level) { 00346 std::stringstream errstr; 00347 errstr << "end of Section \"" << rLabel << "\" expected at " << FileLine(); 00348 throw Exception("TokenReader::ReadEnd", errstr.str(), 51); 00349 } 00350 } 00351 } 00352 00353 // Recover() 00354 bool TokenReader::Recover(int level) { 00355 // trivial cases 00356 if(level>mLevel) return false; 00357 if(level==mLevel) return true; 00358 // loop until match 00359 Token token; 00360 while(Get(token)) 00361 if(mLevel<=level) break; 00362 // done 00363 return level==mLevel; 00364 } 00365 00366 // Eos(label) 00367 bool TokenReader::Eos(const std::string& rLabel) { 00368 // peek token and check for end of section 00369 Token token; 00370 Peek(token); 00371 if(! (token.IsEnd() && !token.IsBegin())) 00372 return false; 00373 if((token.IsEnd() && !token.IsBegin()) && (token.StringValue() == rLabel)) 00374 return true; 00375 std::stringstream errstr; 00376 errstr << "Section End\"" << rLabel << "\" expected at " << FileLine(); 00377 throw Exception("TokenReader::Eos", errstr.str(), 51); 00378 return false; 00379 } 00380 00381 00382 // ReadInteger() 00383 long int TokenReader::ReadInteger(void) { 00384 Token token; 00385 Get(token); 00386 if(!token.IsInteger()) { 00387 std::stringstream errstr; 00388 errstr << "Integer expected at " << FileLine(); 00389 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00390 } 00391 return token.IntegerValue(); 00392 } 00393 00394 // ReadFloat() 00395 double TokenReader::ReadFloat(void) { 00396 Token token; 00397 Get(token); 00398 if((!token.IsFloat()) && (!token.IsInteger())) { 00399 std::stringstream errstr; 00400 errstr << "Float expected at " << FileLine(); 00401 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00402 } 00403 return token.FloatValue(); 00404 } 00405 00406 // ReadString() 00407 const std::string& TokenReader::ReadString(void) { 00408 Token token; 00409 Get(token); 00410 if(!token.IsString()) { 00411 std::stringstream errstr; 00412 errstr << "Name expected at " << FileLine(); 00413 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00414 } 00415 mLastString=token.StringValue(); 00416 return(mLastString); 00417 } 00418 00419 00420 // ReadOption() 00421 const std::string& TokenReader::ReadOption(void) { 00422 Token token; 00423 Get(token); 00424 if(!token.IsOption()) { 00425 std::stringstream errstr; 00426 errstr << "Option expected at " << FileLine(); 00427 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00428 } 00429 mLastString=token.OptionValue(); 00430 return(mLastString); 00431 } 00432 00433 // ReadBinary() 00434 const std::string& TokenReader::ReadBinary(void) { 00435 Token token; 00436 Get(token); 00437 if(!token.IsBinary()) { 00438 std::stringstream errstr; 00439 errstr << "Binary string expected at " << FileLine(); 00440 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00441 } 00442 mLastString=token.StringValue(); 00443 return(mLastString); 00444 } 00445 00446 00447 // ReadText() 00448 const std::string& TokenReader::ReadText(void) { 00449 // do my own reading 00450 int ll=Token::ReadEscapedString(mpStream,'<',mLastString); 00451 if(ll<0) { 00452 std::stringstream errstr; 00453 errstr << "Text expected at " << FileLine(); 00454 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00455 } 00456 // strip leading/tailing space 00457 static const std::string white=" \n\t\r\v\f"; 00458 unsigned int pos1=mLastString.find_first_not_of(white); 00459 if(pos1!=std::string::npos) 00460 mLastString=mLastString.substr(pos1); 00461 else 00462 mLastString.clear(); 00463 unsigned int pos2=mLastString.find_last_not_of(white); 00464 if(pos2!=std::string::npos) 00465 mLastString.erase(pos2+1); 00466 // clear peak buffer 00467 mHasPeekToken=false; 00468 mPeekToken.SetNone(); 00469 // do linecount 00470 mLineCount+=ll; 00471 return mLastString; 00472 } 00473 00474 00475 00476 // Line() 00477 int TokenReader::Line(void) const { 00478 return mLineCount; 00479 } 00480 00481 // FileLine() 00482 std::string TokenReader::FileLine(void) const { 00483 if(mFileName!="") 00484 return "("+ mFileName + ":" + ToStringInteger(mLineCount) +")"; 00485 else 00486 return "(#" + ToStringInteger(mLineCount) +")"; 00487 } 00488 00489 } // namespace faudes |
libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3