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, ...): " << rInString);
00038 mpSStream= new std::istringstream(rInString, std::istringstream::in | std::istringstream::binary);
00039 mpStream= mpSStream;
00040 Rewind();
00041 break;
00042 case File:
00043
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
00067 TokenReader::TokenReader(const std::string& rFilename)
00068 : mMode(File), mpStream(NULL), mFileName(rFilename)
00069 {
00070
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
00088 TokenReader::~TokenReader(void) {
00089 if(mMode==String) delete mpSStream;
00090 }
00091
00092
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
00117 std::string TokenReader::FileName(void) const {
00118 return mFileName;
00119 }
00120
00121
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
00144 bool TokenReader::Get(Token& token) {
00145 bool res;
00146
00147 if(mHasPeekToken) {
00148 res=true;
00149 token=mPeekToken;
00150 mHasPeekToken=false;
00151 } else {
00152 res=Peek(token);
00153 mHasPeekToken=false;
00154 }
00155
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
00173 void TokenReader::SeekBegin(const std::string& rLabel) {
00174
00175
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
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
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
00203 if ((token.Type() == Token::Begin) && (token.StringValue() == rLabel))
00204 break;
00205 }
00206 }
00207
00208
00209 void TokenReader::SeekEnd(const std::string& rLabel) {
00210
00211 ReadEnd(rLabel);
00212
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
00224 if(mLevel==level) {
00225 break;
00226 }
00227
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
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
00246 for (;;) {
00247
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
00254 if ((token.Type() == Token::Begin) && (token.StringValue() == rLabel) && (mLevel==level)) {
00255 Get(token);
00256 break;
00257 }
00258
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
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
00273 Get(token);
00274 }
00275 }
00276
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
00286 void TokenReader::ReadEnd(const std::string& rLabel) {
00287 FD_DV("TokenReader::ReadEnd: " << rLabel << " at " << FileLine() );
00288
00289 int level=mLevel;
00290 Token token;
00291 for (;;) {
00292
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
00299 if ((token.Type() == Token::End) && (token.StringValue() == rLabel) && (mLevel==level-1)) {
00300 break;
00301 }
00302
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
00312 bool TokenReader::Eos(const std::string& rLabel) {
00313
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
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
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
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
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
00379
00380
00381
00382 int TokenReader::Line(void) const {
00383 return mLineCount;
00384 }
00385
00386
00387 std::string TokenReader::FileLine(void) const {
00388 return " ("+ mFileName + ":" + ToStringInteger(mLineCount) +")";
00389 }
00390
00391 }