|
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 mLevel=0; 00100 mLevelPos.clear(); 00101 mLevelPos.push_back(0); 00102 mLevelLine.clear(); 00103 mLevelLine.push_back(1); 00104 mSeekLevel.clear(); 00105 mLineCount=1; 00106 mFilePos=0; 00107 } 00108 catch (std::ios::failure&) { 00109 std::stringstream errstr; 00110 errstr << "Exception opening/reading file in "<< FileLine(); 00111 throw Exception("TokenReader::Rewind", errstr.str(), 1); 00112 } 00113 } 00114 00115 00116 // FileName() 00117 std::string TokenReader::FileName(void) const { 00118 return mFileName; 00119 } 00120 00121 // Peek(token) 00122 bool TokenReader::Peek(Token& token) { 00123 if(mHasPeekToken) { 00124 token=mPeekToken; 00125 return true; 00126 } 00127 try{ 00128 mLineCount += token.Read(mpStream); 00129 } 00130 catch (std::ios::failure&) { 00131 std::stringstream errstr; 00132 errstr << "Exception opening/reading file in "<< FileLine(); 00133 throw Exception("TokenReader::Peek", errstr.str(), 1); 00134 } 00135 mPeekToken=token; 00136 if (mPeekToken.Type() == Token::None) { 00137 return false; 00138 } 00139 mHasPeekToken=true; 00140 return true; 00141 } 00142 00143 // Get(token) 00144 bool TokenReader::Get(Token& token) { 00145 bool res; 00146 // get token either from peek buffer or stream 00147 if(mHasPeekToken) { 00148 res=true; 00149 token=mPeekToken; 00150 mHasPeekToken=false; 00151 } else { 00152 res=Peek(token); 00153 mHasPeekToken=false; 00154 } 00155 // track state (level of nested sections, filepos etc) 00156 if(res) { 00157 mFilePos=mpStream->tellg(); 00158 if (token.Type() == Token::Begin) { 00159 mLevel++; 00160 mLevelPos.push_back(mFilePos); 00161 mLevelLine.push_back(mLineCount); 00162 } 00163 if (token.Type() == Token::End) { 00164 mLevel--; 00165 mLevelPos.pop_back(); 00166 mLevelLine.pop_back(); 00167 } 00168 } 00169 return res; 00170 } 00171 00172 // SeekBegin(label) 00173 void TokenReader::SeekBegin(const std::string& rLabel) { 00174 // search for begin at any descending level, no rewind 00175 // if successful, must be followed by SeekEnd 00176 FD_DV("TokenReader::SeekBegin: " << rLabel << " at " << FileLine() << " level " << mLevel); 00177 mSeekLevel.push_back(mLevel); 00178 int level=mLevel; 00179 long int startpos=mFilePos; 00180 int startline=mLineCount; 00181 Token token; 00182 for (;;) { 00183 // exception: did not get a token at all (incl. eof) 00184 if(!Peek(token)) { 00185 Rewind(); 00186 std::stringstream errstr; 00187 errstr << "Section \"" << rLabel << "\" expected at " << FileLine() << " no more tokens"; 00188 throw Exception("TokenReader::SeekBegin", errstr.str(), 51); 00189 } 00190 // exception: current section ends 00191 if ((token.Type() == Token::End) && (mLevel == level)) { 00192 mpStream->seekg(startpos); 00193 mLineCount=startline; 00194 mSeekLevel.pop_back(); 00195 mHasPeekToken=false; 00196 std::stringstream errstr; 00197 errstr << "Section \"" << rLabel << "\" expected at " << FileLine() 00198 << "current section ended unexpected. Found: " << token.StringValue() << " Type " << token.Type(); 00199 throw Exception("TokenReader::SeekBegin", errstr.str(), 51); 00200 } 00201 Get(token); 00202 // success: found begin section 00203 if ((token.Type() == Token::Begin) && (token.StringValue() == rLabel)) 00204 break; 00205 } 00206 } 00207 00208 // SeekEnd(label) 00209 void TokenReader::SeekEnd(const std::string& rLabel) { 00210 // search for end at current level ... 00211 ReadEnd(rLabel); // throws id 51 00212 // ... then climb up to undo recent seek 00213 if(mSeekLevel.size()==0) { 00214 std::stringstream errstr; 00215 errstr << "unmatched call"; 00216 throw Exception("TokenReader::SeekEnd", errstr.str(), 52); 00217 } 00218 int level=mSeekLevel.back(); 00219 mSeekLevel.pop_back(); 00220 FD_DV("TokenReader::SeekEnd: " << rLabel << " at " << FileLine() << " level " << mLevel << " for " << level); 00221 Token token; 00222 for (;;) { 00223 // success 00224 if(mLevel==level) { 00225 break; 00226 } 00227 // exception: did not get a token at all 00228 if(!Get(token)) { 00229 std::stringstream errstr; 00230 errstr << "could not find level " << level << " " << FileLine(); 00231 throw Exception("TokenReader::SeekEnd", errstr.str(), 52); 00232 } 00233 } 00234 } 00235 00236 // ReadBegin(label) 00237 void TokenReader::ReadBegin(const std::string& rLabel) { 00238 FD_DV("looking for Section \"" << rLabel << "\""); 00239 try { 00240 int level=mLevel; 00241 bool firstgo=true; 00242 long int startpos=mFilePos; 00243 FD_DV("section level " << level << " current pos " << startpos << " begin of section " << mLevelPos[level]); 00244 Token token; 00245 // search for begin at current level 00246 for (;;) { 00247 // exception: did not get a token at all (incl eof) 00248 if(!Peek(token)) { 00249 std::stringstream errstr; 00250 errstr << "Section \"" << rLabel << "\" expected at " << FileLine() << ", no token at all"; 00251 throw Exception("TokenReader::ReadBegin Peek", errstr.str(), 51); 00252 } 00253 // success: found begin section 00254 if ((token.Type() == Token::Begin) && (token.StringValue() == rLabel) && (mLevel==level)) { 00255 Get(token); 00256 break; 00257 } 00258 // rewind once when current section ends 00259 if ((token.Type() == Token::End) && (mLevel == level) && firstgo) { 00260 mpStream->seekg(mLevelPos[level]); 00261 mFilePos=mLevelPos[level]; 00262 mLineCount=mLevelLine[level]; 00263 firstgo=false; 00264 mHasPeekToken=false; 00265 continue; 00266 } 00267 // exception: did not find begin label 00268 if((mFilePos>=startpos) && (!firstgo)) { 00269 std::stringstream errstr; 00270 errstr << "Section \"" << rLabel << "\" expected at " << FileLine() << ", did not find begin lable"; 00271 throw Exception("TokenReader::ReadBegin Missed", errstr.str(), 51); 00272 } 00273 // skip this token 00274 Get(token); 00275 } 00276 } 00277 // catch my seek/tell errors 00278 catch (std::ios::failure&) { 00279 std::stringstream errstr; 00280 errstr << "Section \"" << rLabel << "\" expected at " << FileLine(); 00281 throw Exception("TokenReader::ReadBegin Rewind", errstr.str(), 1); 00282 } 00283 } 00284 00285 00286 // ExistsBegin(label) 00287 bool TokenReader::ExistsBegin(const std::string& rLabel) { 00288 FD_DV("TokenReader::ExistsBegin(): looking for Section \"" << rLabel << "\""); 00289 try { 00290 int level=mLevel; 00291 bool firstgo=true; 00292 long int startpos=mFilePos; 00293 FD_DV("section level " << level << " current pos " << startpos << " begin of section " << mLevelPos[level]); 00294 Token token; 00295 // search for begin at current level 00296 for(;;) { 00297 // fail: did not get a token at all (incl eof) 00298 if(!Peek(token)) { 00299 return false; 00300 } 00301 // success: found begin section 00302 if((token.Type() == Token::Begin) && (token.StringValue() == rLabel) && (mLevel==level)) { 00303 return true; 00304 } 00305 // rewind once when current section ends 00306 if((token.Type() == Token::End) && (mLevel == level) && firstgo) { 00307 mpStream->seekg(mLevelPos[level]); 00308 mFilePos=mLevelPos[level]; 00309 mLineCount=mLevelLine[level]; 00310 firstgo=false; 00311 mHasPeekToken=false; 00312 continue; 00313 } 00314 // fail: did not find begin label 00315 if((mFilePos>=startpos) && (!firstgo)) { 00316 return false; 00317 } 00318 // skip this token 00319 Get(token); 00320 } 00321 } 00322 // catch my seek/tell errors 00323 catch (std::ios::failure&) { 00324 std::stringstream errstr; 00325 errstr << "Section \"" << rLabel << "\" expected at " << FileLine(); 00326 throw Exception("TokenReader::ReadBegin Rewind", errstr.str(), 1); 00327 } 00328 return false; 00329 } 00330 00331 // ReadEnd(label) 00332 void TokenReader::ReadEnd(const std::string& rLabel) { 00333 FD_DV("TokenReader::ReadEnd: " << rLabel << " at " << FileLine() ); 00334 // search for end at current level 00335 int level=mLevel; 00336 Token token; 00337 for (;;) { 00338 // exception: did not get a token at all 00339 if(!Get(token)) { 00340 std::stringstream errstr; 00341 errstr << "end of Section \"" << rLabel << "\" expected at " << FileLine(); 00342 throw Exception("TokenReader::ReadEnd", errstr.str(), 51); 00343 } 00344 // success: found end of current section 00345 if ((token.Type() == Token::End) && (token.StringValue() == rLabel) && (mLevel==level-1)) { 00346 break; 00347 } 00348 // exception: current section ends with unexpected label 00349 if(mLevel<level) { 00350 std::stringstream errstr; 00351 errstr << "end of Section \"" << rLabel << "\" expected at " << FileLine(); 00352 throw Exception("TokenReader::ReadEnd", errstr.str(), 51); 00353 } 00354 } 00355 } 00356 00357 // Eos(label) 00358 bool TokenReader::Eos(const std::string& rLabel) { 00359 // peek token and check for end of section 00360 Token token; 00361 Peek(token); 00362 if (token.Type() != Token::End) 00363 return false; 00364 if ((token.Type() == Token::End) && (token.StringValue() == rLabel)) 00365 return true; 00366 std::stringstream errstr; 00367 errstr << "Section End\"" << rLabel << "\" expected at " << FileLine(); 00368 throw Exception("TokenReader::Eos", errstr.str(), 51); 00369 return false; 00370 } 00371 00372 00373 // ReadInteger() 00374 long int TokenReader::ReadInteger(void) { 00375 Token token; 00376 Get(token); 00377 if((token.Type()!=Token::Integer) && (token.Type()!=Token::Integer16) ) { 00378 std::stringstream errstr; 00379 errstr << "Integer expected at " << FileLine(); 00380 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00381 } 00382 return token.IntegerValue(); 00383 } 00384 00385 // ReadFloat() 00386 double TokenReader::ReadFloat(void) { 00387 Token token; 00388 Get(token); 00389 if((token.Type()!=Token::Float) && (token.Type()!=Token::Integer)) { 00390 std::stringstream errstr; 00391 errstr << "Float expected at " << FileLine(); 00392 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00393 } 00394 return token.FloatValue(); 00395 } 00396 00397 // ReadString() 00398 const std::string& TokenReader::ReadString(void) { 00399 Token token; 00400 Get(token); 00401 if(token.Type()!=Token::String) { 00402 std::stringstream errstr; 00403 errstr << "Name expected at " << FileLine(); 00404 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00405 } 00406 mLastString=token.StringValue(); 00407 return(mLastString); 00408 } 00409 00410 00411 // ReadOption() 00412 const std::string& TokenReader::ReadOption(void) { 00413 Token token; 00414 Get(token); 00415 if(token.Type()!=Token::Option) { 00416 std::stringstream errstr; 00417 errstr << "Option expected at " << FileLine(); 00418 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00419 } 00420 mLastString=token.StringValue(); 00421 return(mLastString); 00422 } 00423 00424 // ReadBinary() 00425 const std::string& TokenReader::ReadBinary(void) { 00426 Token token; 00427 Get(token); 00428 if(token.Type()!=Token::Binary) { 00429 std::stringstream errstr; 00430 errstr << "Binary string expected at " << FileLine(); 00431 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00432 } 00433 mLastString=token.StringValue(); 00434 return(mLastString); 00435 } 00436 00437 00438 00439 00440 // Line() 00441 int TokenReader::Line(void) const { 00442 return mLineCount; 00443 } 00444 00445 // FileLine() 00446 std::string TokenReader::FileLine(void) const { 00447 if(mFileName!="") 00448 return "("+ mFileName + ":" + ToStringInteger(mLineCount) +")"; 00449 else 00450 return "(#" + ToStringInteger(mLineCount) +")"; 00451 } 00452 00453 } // namespace faudes |
libFAUDES 2.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3