libFAUDES

Sections

Index

cfl_tokenreader.cpp

Go 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