tokenreader.cpp

Go to the documentation of this file.
00001 
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, ...)");
00038     mpSStream= new std::istringstream(rInString, std::istringstream::in | std::istringstream::binary);
00039     mpStream= mpSStream;
00040     break;
00041   case File: 
00042     // set up mFStream
00043     FD_DV("TokenReader::Tokenreader(File, \"" << rInString <<"\")");
00044     mFStream.exceptions(std::ios::badbit|std::ios::failbit);
00045     try{
00046       mFStream.open(rInString.c_str(), std::ios::in | std::ios::binary); 
00047     } 
00048     catch (std::ios::failure&) {
00049       std::stringstream errstr;
00050       errstr << "Exception opening/reading file \""<< rInString << "\"";
00051       throw Exception("TokenReader::TokenReader", errstr.str(), 1);
00052     }
00053     mFileName=rInString;
00054     mpStream=&mFStream;
00055     Rewind();
00056     break;
00057   default:
00058     std::stringstream errstr;
00059     errstr << "Invalid Mode / Not implemented";
00060     throw Exception("TokenReader::TokenReader(mode,instring)", errstr.str(), 1);
00061   }
00062 }
00063 
00064 
00065 // TokenReader(rFilename)
00066 TokenReader::TokenReader(const std::string& rFilename) 
00067   : mMode(File), mpStream(NULL), mFileName(rFilename) 
00068 {
00069   // set up mFStream
00070   FD_DV("TokenReader::Tokenreader(File, \"" << rFilename <<"\")");
00071   mFStream.exceptions(std::ios::badbit|std::ios::failbit);
00072   try{
00073     mFStream.open(rFilename.c_str(), std::ios::in | std::ios::binary); 
00074   } 
00075   catch (std::ios::failure&) {
00076     std::stringstream errstr;
00077     errstr << "Exception opening/reading file \""<< rFilename << "\"";
00078     throw Exception("TokenReader::TokenReader", errstr.str(), 1);
00079   }
00080   mFileName=rFilename;
00081   mpStream=&mFStream;
00082   Rewind();
00083 }
00084 
00085 
00086 //  destruct
00087 TokenReader::~TokenReader(void) {
00088   if(mMode==String) delete mpSStream;
00089 }
00090 
00091 // Rewind()
00092 void TokenReader::Rewind(void) {
00093   FD_DV("TokenReader::Rewind: \"" << mFileName <<"\"");
00094   try {
00095     mpStream->clear();
00096     mpStream->seekg(0);
00097     mHasPeekToken=false;
00098     mLevel=0;
00099     mLevelPos.clear();
00100     mLevelPos.push_back(0);
00101     mLevelLine.clear();
00102     mLevelLine.push_back(1);
00103     mSeekLevel.clear();
00104     mLineCount=1;
00105     mFilePos=0;
00106   }
00107   catch (std::ios::failure&) {
00108     std::stringstream errstr;
00109     errstr << "Exception opening/reading file in \""<< FileLine() << "\"";
00110     throw Exception("TokenReader::Rewind", errstr.str(), 1);
00111   }
00112 }
00113 
00114 
00115 // FileName()
00116 std::string TokenReader::FileName(void) const {
00117   return mFileName;
00118 }
00119 
00120 // Peek(token)
00121 bool TokenReader::Peek(Token& token) {
00122   if(mHasPeekToken) { 
00123     token=mPeekToken;
00124     return true;
00125   }
00126   try{
00127     mLineCount += token.Read(mpStream);
00128   } 
00129   catch (std::ios::failure&) {
00130     std::stringstream errstr;
00131     errstr << "Exception opening/reading file in \""<< FileLine() << "\"";
00132     throw Exception("TokenReader::Peek", errstr.str(), 1);
00133   }
00134   mPeekToken=token;
00135   if (mPeekToken.Type() == Token::None) {
00136     return false;
00137   } 
00138   mHasPeekToken=true;
00139   return true;
00140 }
00141 
00142 // Get(token)
00143 bool TokenReader::Get(Token& token) {
00144   bool res;
00145   // get token either from peek buffer or stream
00146   if(mHasPeekToken) {   
00147     res=true;
00148     token=mPeekToken;
00149     mHasPeekToken=false;
00150   } else {
00151     res=Peek(token);
00152     mHasPeekToken=false;
00153   }    
00154   // track state (level of nested sections, filepos etc)
00155   if(res) {
00156     mFilePos=mpStream->tellg();
00157     if (token.Type() == Token::Begin) {
00158       mLevel++;
00159       mLevelPos.push_back(mFilePos);
00160       mLevelLine.push_back(mLineCount);
00161     }
00162     if (token.Type() == Token::End) {
00163       mLevel--;
00164       mLevelPos.pop_back();
00165       mLevelLine.pop_back();
00166     }
00167   }
00168   return res;
00169 }
00170 
00171 // SeekBegin(label)
00172 void TokenReader::SeekBegin(const std::string& rLabel) {
00173   // search for begin at any descending level, no rewind
00174   // if successful, must be followed by SeekEnd
00175   FD_DV("TokenReader::SeekBegin: " << rLabel << " at " << FileLine() << " level " << mLevel);
00176   mSeekLevel.push_back(mLevel);
00177   int level=mLevel;
00178   long int startpos=mFilePos;
00179   int startline=mLineCount;
00180   Token token;
00181   for (;;) {
00182     // exception: did not get a token at all (incl. eof)
00183     if(!Peek(token)) {
00184       Rewind();
00185       std::stringstream errstr;
00186       errstr << "Section \"" << rLabel << "\" expected at " << FileLine() << " no more tokens";
00187       throw Exception("TokenReader::SeekBegin", errstr.str(), 51);
00188     }
00189     // exception: current section ends
00190     if ((token.Type() == Token::End) && (mLevel == level)) {
00191       mpStream->seekg(startpos);
00192       mLineCount=startline;
00193       mSeekLevel.pop_back();
00194       mHasPeekToken=false;
00195       std::stringstream errstr;
00196       errstr << "Section \"" << rLabel << "\" expected at " << FileLine() 
00197        << "current section ended unexpected. Found: " << token.StringValue() << " Type " << token.Type();
00198       throw Exception("TokenReader::SeekBegin", errstr.str(), 51);
00199     }
00200     Get(token);
00201     // success: found begin section
00202     if ((token.Type() == Token::Begin) && (token.StringValue() == rLabel))
00203       break;
00204   }
00205 }
00206  
00207 // SeekEnd(label)
00208 void TokenReader::SeekEnd(const std::string& rLabel) {
00209   // search for end at current level ...
00210   ReadEnd(rLabel); // throws id 51
00211   // ... then climb up to undo recent seek
00212   if(mSeekLevel.size()==0) {
00213     std::stringstream errstr;
00214     errstr << "unmatched call";
00215     throw Exception("TokenReader::SeekEnd", errstr.str(), 52);
00216   }
00217   int level=mSeekLevel.back();
00218   mSeekLevel.pop_back();
00219   FD_DV("TokenReader::SeekEnd: " << rLabel << " at " << FileLine() << " level " << mLevel << " for " << level);
00220   Token token;
00221   for (;;) {
00222     // success 
00223     if(mLevel==level) {
00224       break;
00225     }
00226     // exception: did not get a token at all
00227     if(!Get(token)) {
00228       std::stringstream errstr;
00229       errstr << "could not find level " << level << " " << FileLine();
00230       throw Exception("TokenReader::SeekEnd", errstr.str(), 52);
00231     }
00232   }
00233 }
00234 
00235 // ReadBegin(label)
00236 void TokenReader::ReadBegin(const std::string& rLabel) {
00237   FD_DV("looking for Section \"" << rLabel << "\"");
00238   try {
00239     int level=mLevel;
00240     bool firstgo=true;
00241     long int startpos=mFilePos;
00242     FD_DV("section level " << level << " current pos " << startpos << " begin of section " << mLevelPos[level]);
00243     Token token;
00244     // search for begin at current level
00245     for (;;) {
00246       // exception: did not get a token at all (incl eof)
00247       if(!Peek(token)) {
00248   std::stringstream errstr;
00249   errstr << "Section \"" << rLabel << "\" expected at " << FileLine() << ", no token at all";
00250   throw Exception("TokenReader::ReadBegin Peek", errstr.str(), 51);
00251       }
00252       // success: found begin section
00253       if ((token.Type() == Token::Begin) && (token.StringValue() == rLabel) && (mLevel==level)) {
00254   Get(token);
00255   break;
00256       }
00257       // rewind once when current section ends
00258       if ((token.Type() == Token::End) && (mLevel == level) && firstgo) {
00259   mpStream->seekg(mLevelPos[level]);
00260   mLineCount=mLevelLine[level];                       
00261   firstgo=false;
00262   mHasPeekToken=false;
00263   continue;
00264       }
00265       // exception: did not find begin label
00266       if((mFilePos>=startpos) && (!firstgo)) {
00267   std::stringstream errstr;
00268   errstr << "Section \"" << rLabel << "\" expected at " << FileLine() << ", did not find begin lable";
00269   throw Exception("TokenReader::ReadBegin Missed", errstr.str(), 51);
00270       }
00271       // skip this token
00272       Get(token);
00273     }
00274   }
00275   // catch my seek/tell errors
00276   catch (std::ios::failure&) {
00277     std::stringstream errstr;
00278     errstr << "Section \"" << rLabel << "\" expected at " << FileLine();
00279     throw Exception("TokenReader::ReadBegin Rewind", errstr.str(), 1);
00280   }
00281 }
00282  
00283 
00284 // ReadEnd(label)
00285 void TokenReader::ReadEnd(const std::string& rLabel) {
00286   FD_DV("TokenReader::ReadEnd: " << rLabel << " at " << FileLine() );
00287   // search for end at current level
00288   int level=mLevel;
00289   Token token;
00290   for (;;) {
00291     // exception: did not get a token at all
00292     if(!Get(token)) {
00293       std::stringstream errstr;
00294       errstr << "end of Section \"" << rLabel << "\" expected at " << FileLine();
00295       throw Exception("TokenReader::ReadEnd", errstr.str(), 51);
00296     }
00297     // success: found end of current section
00298     if ((token.Type() == Token::End) && (token.StringValue() == rLabel) && (mLevel==level-1)) {
00299       break;
00300     }
00301     // exception: current section ends with unexpected label
00302     if(mLevel<level) {
00303       std::stringstream errstr;
00304       errstr << "end of Section \"" << rLabel << "\" expected at " << FileLine();
00305       throw Exception("TokenReader::ReadEnd", errstr.str(), 51);
00306     }
00307   }
00308 }
00309 
00310 // Eos(label)
00311 bool TokenReader::Eos(const std::string& rLabel) {
00312   // peek token and check for end of section
00313   Token token;
00314   Peek(token);
00315   if (token.Type() != Token::End) 
00316     return false;
00317   if ((token.Type() == Token::End) && (token.StringValue() == rLabel))
00318     return true; 
00319   std::stringstream errstr;
00320   errstr << "Section End\"" << rLabel << "\" expected at " << FileLine();
00321   throw Exception("TokenReader::Eos", errstr.str(), 51);
00322   return false;
00323 }
00324   
00325 
00326 // ReadInteger()
00327 long int TokenReader::ReadInteger(void) {
00328   Token token;      
00329   Get(token);
00330   if((token.Type()!=Token::Integer) && (token.Type()!=Token::Integer16)  ) {
00331     std::stringstream errstr;
00332     errstr << "Integer expected at " << FileLine();
00333     throw Exception("TokenReader::TokenReader", errstr.str(), 50);
00334   }
00335   return token.IntegerValue();
00336 }
00337 
00338 // ReadFloat()
00339 double TokenReader::ReadFloat(void) {
00340   Token token;      
00341   Get(token);
00342   if((token.Type()!=Token::Float) && (token.Type()!=Token::Integer)) {
00343     std::stringstream errstr;
00344     errstr << "Float expected at " << FileLine();
00345     throw Exception("TokenReader::TokenReader", errstr.str(), 50);
00346   }
00347   return token.FloatValue();
00348 }
00349 
00350 // ReadString()
00351 const std::string& TokenReader::ReadString(void) {
00352   Token token;      
00353   Get(token);
00354   if(token.Type()!=Token::String) {
00355     std::stringstream errstr;
00356     errstr << "Name expected at " << FileLine();
00357     throw Exception("TokenReader::TokenReader", errstr.str(), 50);
00358   }
00359   mLastString=token.StringValue();
00360   return(mLastString);
00361 }
00362 
00363  
00364 // ReadOption()
00365 const std::string& TokenReader::ReadOption(void) {
00366   Token token;      
00367   Get(token);
00368   if(token.Type()!=Token::Option) {
00369     std::stringstream errstr;
00370     errstr << "Option expected at " << FileLine();
00371     throw Exception("TokenReader::TokenReader", errstr.str(), 50);
00372   }
00373   mLastString=token.StringValue();
00374   return(mLastString);
00375 }
00376 
00377 
00378  
00379 
00380 // Line()
00381 int TokenReader::Line(void) const {
00382   return mLineCount;
00383 }
00384 
00385 // FileLine()
00386 std::string TokenReader::FileLine(void) const {
00387   return " ("+ mFileName + ":" + ToStringInteger(mLineCount) +")";
00388 }
00389 
00390 } // namespace faudes

Generated on Fri May 9 11:26:47 2008 for libFAUDES 2.09b by  doxygen 1.4.4