libFAUDES

Sections

Index

tokenreader.cpp

Go 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