00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "tokenreader.h"
00027
00028 namespace faudes {
00029
00030
00031 TokenReader::TokenReader(Mode mode, const std::string& rInString)
00032 : mMode(mode), mpStream(NULL), mFileName("")
00033 {
00034 switch(mode) {
00035 case String:
00036
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
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
00066 TokenReader::TokenReader(const std::string& rFilename)
00067 : mMode(File), mpStream(NULL), mFileName(rFilename)
00068 {
00069
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
00087 TokenReader::~TokenReader(void) {
00088 if(mMode==String) delete mpSStream;
00089 }
00090
00091
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
00116 std::string TokenReader::FileName(void) const {
00117 return mFileName;
00118 }
00119
00120
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
00143 bool TokenReader::Get(Token& token) {
00144 bool res;
00145
00146 if(mHasPeekToken) {
00147 res=true;
00148 token=mPeekToken;
00149 mHasPeekToken=false;
00150 } else {
00151 res=Peek(token);
00152 mHasPeekToken=false;
00153 }
00154
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
00172 void TokenReader::SeekBegin(const std::string& rLabel) {
00173
00174
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
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
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
00202 if ((token.Type() == Token::Begin) && (token.StringValue() == rLabel))
00203 break;
00204 }
00205 }
00206
00207
00208 void TokenReader::SeekEnd(const std::string& rLabel) {
00209
00210 ReadEnd(rLabel);
00211
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
00223 if(mLevel==level) {
00224 break;
00225 }
00226
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
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
00245 for (;;) {
00246
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
00253 if ((token.Type() == Token::Begin) && (token.StringValue() == rLabel) && (mLevel==level)) {
00254 Get(token);
00255 break;
00256 }
00257
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
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
00272 Get(token);
00273 }
00274 }
00275
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
00285 void TokenReader::ReadEnd(const std::string& rLabel) {
00286 FD_DV("TokenReader::ReadEnd: " << rLabel << " at " << FileLine() );
00287
00288 int level=mLevel;
00289 Token token;
00290 for (;;) {
00291
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
00298 if ((token.Type() == Token::End) && (token.StringValue() == rLabel) && (mLevel==level-1)) {
00299 break;
00300 }
00301
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
00311 bool TokenReader::Eos(const std::string& rLabel) {
00312
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
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
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
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
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
00381 int TokenReader::Line(void) const {
00382 return mLineCount;
00383 }
00384
00385
00386 std::string TokenReader::FileLine(void) const {
00387 return " ("+ mFileName + ":" + ToStringInteger(mLineCount) +")";
00388 }
00389
00390 }