| |
libFAUDES
Sections
Index
|
tokenreader.cppGo to the documentation of this file.00001 /** @file 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 "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 mLineCount=mLevelLine[level]; 00262 firstgo=false; 00263 mHasPeekToken=false; 00264 continue; 00265 } 00266 // exception: did not find begin label 00267 if((mFilePos>=startpos) && (!firstgo)) { 00268 std::stringstream errstr; 00269 errstr << "Section \"" << rLabel << "\" expected at " << FileLine() << ", did not find begin lable"; 00270 throw Exception("TokenReader::ReadBegin Missed", errstr.str(), 51); 00271 } 00272 // skip this token 00273 Get(token); 00274 } 00275 } 00276 // catch my seek/tell errors 00277 catch (std::ios::failure&) { 00278 std::stringstream errstr; 00279 errstr << "Section \"" << rLabel << "\" expected at " << FileLine(); 00280 throw Exception("TokenReader::ReadBegin Rewind", errstr.str(), 1); 00281 } 00282 } 00283 00284 00285 // ReadEnd(label) 00286 void TokenReader::ReadEnd(const std::string& rLabel) { 00287 FD_DV("TokenReader::ReadEnd: " << rLabel << " at " << FileLine() ); 00288 // search for end at current level 00289 int level=mLevel; 00290 Token token; 00291 for (;;) { 00292 // exception: did not get a token at all 00293 if(!Get(token)) { 00294 std::stringstream errstr; 00295 errstr << "end of Section \"" << rLabel << "\" expected at " << FileLine(); 00296 throw Exception("TokenReader::ReadEnd", errstr.str(), 51); 00297 } 00298 // success: found end of current section 00299 if ((token.Type() == Token::End) && (token.StringValue() == rLabel) && (mLevel==level-1)) { 00300 break; 00301 } 00302 // exception: current section ends with unexpected label 00303 if(mLevel<level) { 00304 std::stringstream errstr; 00305 errstr << "end of Section \"" << rLabel << "\" expected at " << FileLine(); 00306 throw Exception("TokenReader::ReadEnd", errstr.str(), 51); 00307 } 00308 } 00309 } 00310 00311 // Eos(label) 00312 bool TokenReader::Eos(const std::string& rLabel) { 00313 // peek token and check for end of section 00314 Token token; 00315 Peek(token); 00316 if (token.Type() != Token::End) 00317 return false; 00318 if ((token.Type() == Token::End) && (token.StringValue() == rLabel)) 00319 return true; 00320 std::stringstream errstr; 00321 errstr << "Section End\"" << rLabel << "\" expected at " << FileLine(); 00322 throw Exception("TokenReader::Eos", errstr.str(), 51); 00323 return false; 00324 } 00325 00326 00327 // ReadInteger() 00328 long int TokenReader::ReadInteger(void) { 00329 Token token; 00330 Get(token); 00331 if((token.Type()!=Token::Integer) && (token.Type()!=Token::Integer16) ) { 00332 std::stringstream errstr; 00333 errstr << "Integer expected at " << FileLine(); 00334 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00335 } 00336 return token.IntegerValue(); 00337 } 00338 00339 // ReadFloat() 00340 double TokenReader::ReadFloat(void) { 00341 Token token; 00342 Get(token); 00343 if((token.Type()!=Token::Float) && (token.Type()!=Token::Integer)) { 00344 std::stringstream errstr; 00345 errstr << "Float expected at " << FileLine(); 00346 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00347 } 00348 return token.FloatValue(); 00349 } 00350 00351 // ReadString() 00352 const std::string& TokenReader::ReadString(void) { 00353 Token token; 00354 Get(token); 00355 if(token.Type()!=Token::String) { 00356 std::stringstream errstr; 00357 errstr << "Name expected at " << FileLine(); 00358 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00359 } 00360 mLastString=token.StringValue(); 00361 return(mLastString); 00362 } 00363 00364 00365 // ReadOption() 00366 const std::string& TokenReader::ReadOption(void) { 00367 Token token; 00368 Get(token); 00369 if(token.Type()!=Token::Option) { 00370 std::stringstream errstr; 00371 errstr << "Option expected at " << FileLine(); 00372 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00373 } 00374 mLastString=token.StringValue(); 00375 return(mLastString); 00376 } 00377 00378 // ReadBinary() 00379 const std::string& TokenReader::ReadBinary(void) { 00380 Token token; 00381 Get(token); 00382 if(token.Type()!=Token::Binary) { 00383 std::stringstream errstr; 00384 errstr << "Binary string expected at " << FileLine(); 00385 throw Exception("TokenReader::TokenReader", errstr.str(), 50); 00386 } 00387 mLastString=token.StringValue(); 00388 return(mLastString); 00389 } 00390 00391 00392 00393 00394 // Line() 00395 int TokenReader::Line(void) const { 00396 return mLineCount; 00397 } 00398 00399 // FileLine() 00400 std::string TokenReader::FileLine(void) const { 00401 if(mFileName!="") 00402 return "("+ mFileName + ":" + ToStringInteger(mLineCount) +")"; 00403 else 00404 return "(#" + ToStringInteger(mLineCount) +")"; 00405 } 00406 00407 } // namespace faudes |
libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6