00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef TEXTPARSER_H
00011 #define TEXTPARSER_H
00012
00013 #include <wx/sstream.h>
00014 #include <string.h>
00015 #include "common.h"
00016 #include <math.h>
00017 #include "flexilog.h"
00018
00019 #ifdef __WINDOWS__
00020 #pragma warning (disable: 4748)
00021 #endif
00022
00023 namespace VRUT
00024 {
00026 class TextParser
00027 {
00028 private:
00030 wxInputStream * inputStream;
00032 char *buff;
00034 char *aPos;
00036 char *bEnd;
00038 size_t buffSize;
00040 size_t minSize;
00041
00042 public:
00046 TextParser(wxInputStream * _inputStream, size_t _buffSize, size_t _minSize) : inputStream(_inputStream), buffSize(_buffSize), minSize(_minSize)
00047 {
00048 if (buffSize==0)
00049 {
00050
00051 buffSize = inputStream->GetSize();
00052 if (buffSize==0)
00053 {
00054
00055
00056 char *buf = (char*)malloc(10000000);
00057 std::string temp;
00058 while (!inputStream->Eof())
00059 {
00060 inputStream->Read(buf, 9999999);
00061 buf[inputStream->LastRead()]=0;
00062 temp += buf;
00063 }
00064 buffSize = temp.size()+1;
00065 buff = (char*)malloc(buffSize);
00066 strcpy(buff, temp.c_str());
00067 free(buf);
00068 }
00069 else
00070 {
00071 buff = (char*)malloc(++buffSize);
00072 inputStream->Read(buff, buffSize-1);
00073 if (inputStream->LastRead()<buffSize-1)
00074 buffSize=inputStream->LastRead();
00075 buff[buffSize-1]=0;
00076 }
00077 minSize = 0;
00078 }
00079 else
00080 {
00081 if (minSize<10)
00082 minSize = 10;
00083 if (buffSize<10*minSize)
00084 buffSize=10*minSize;
00085 buff = (char*)malloc(buffSize);
00086 inputStream->Read(buff, buffSize-1);
00087 if (inputStream->LastRead()<buffSize-1)
00088 buffSize=inputStream->LastRead()+1;
00089 buff[buffSize-1]=0;
00090 }
00091 aPos = buff;
00092 bEnd = buff + buffSize-1;
00093 };
00094
00096 TextParser(const char * _input) : inputStream(NULL), minSize(0)
00097 {
00098 buffSize = strlen(_input)+1;
00099 buff = (char*)malloc(buffSize);
00100 strcpy(buff, _input);
00101 aPos = buff;
00102 bEnd = buff + buffSize - 1;
00103 }
00104
00106 TextParser(const wxString _input) : inputStream(NULL), minSize(0)
00107 {
00108 buffSize = _input.size()+1;
00109 buff = (char*)malloc(buffSize);
00110 strcpy(buff, _input.mb_str(wxConvISO8859_1));
00111 aPos = buff;
00112 bEnd = buff + buffSize - 1;
00113 }
00114
00116 ~TextParser()
00117 {
00118 free(buff);
00119 };
00120
00124 bool ReadToBuffer(bool force=false)
00125 {
00126 if (minSize)
00127 {
00128 if (aPos==buff)
00129 return false;
00130 size_t restLen = (size_t)(bEnd-aPos);
00131 if (((restLen<minSize)||(force))&&(!inputStream->Eof()))
00132 {
00133 strncpy(buff, aPos, restLen);
00134 inputStream->Read(buff+restLen, buffSize-restLen-1);
00135 if (inputStream->LastRead()<buffSize-restLen-1)
00136 {
00137 buffSize=inputStream->LastRead()+restLen;
00138 bEnd = buff + buffSize;
00139 }
00140 aPos=buff;
00141 return true;
00142 }
00143 }
00144 return false;
00145 }
00146
00148 inline void SkipChars(const char *chars)
00149 {
00150 while (true)
00151 {
00152 while ((aPos<bEnd)&&(strchr(chars, *aPos)!=NULL))
00153 aPos++;
00154 if (aPos==bEnd)
00155 {
00156 if (!ReadToBuffer())
00157 return;
00158 }
00159 else
00160 return;
00161 }
00162 };
00163
00166 inline char* FindFirstOf(const char *chars)
00167 {
00168 char* res=aPos;
00169 for (; res<bEnd; res++)
00170 {
00171 const char *pos=chars;
00172 while ((*pos) && (*pos!=*res))
00173 pos++;
00174 if (*pos)
00175 break;
00176 }
00177 return res;
00178 }
00179
00181 void SkipCharsAndComments(const char *chars)
00182 {
00183 while (true)
00184 {
00185
00186 SkipChars(chars);
00187 ReadToBuffer();
00188 if (*aPos=='#')
00189 {
00190 while (true)
00191 {
00192 aPos=FindFirstOf("\n\r");
00193 if (aPos==bEnd)
00194 {
00195 if (!ReadToBuffer())
00196 return;
00197 }
00198 else
00199 {
00200 ReadToBuffer();
00201 break;
00202 }
00203 }
00204 }
00205 else if ((*aPos=='/') && (*(aPos+1)=='*') && (aPos<bEnd-1))
00206 {
00207 aPos+=2;
00208 while (true)
00209 {
00210 while (!((*aPos=='*') && (*(aPos+1)=='/')) && (aPos<bEnd-1))
00211 aPos++;
00212 if (aPos==bEnd-1)
00213 {
00214 if (!ReadToBuffer())
00215 return;
00216 }
00217 else
00218 {
00219 aPos+=2;
00220 ReadToBuffer();
00221 break;
00222 }
00223 }
00224 }
00225 else
00226 return;
00227 }
00228 };
00229
00231 inline void ForceEmpty()
00232 {
00233 aPos = bEnd;
00234 }
00235
00237 inline bool IsEmpty(const char *separators = NULL, bool skip = true)
00238 {
00239 if (skip)
00240 {
00241 if (separators==NULL)
00242 {
00243 separators = " \t\n\r";
00244 }
00245 SkipCharsAndComments(separators);
00246 }
00247 return (aPos>=bEnd);
00248 };
00249
00251 bool NextKeywordIs(const char *keyword, const char *separators = NULL)
00252 {
00253 if (separators==NULL)
00254 {
00255 separators = " \t\n\r";
00256 }
00257 SkipCharsAndComments(separators);
00258 size_t keyLen = strlen(keyword);
00259 if (!_strnicmp(aPos, keyword, keyLen))
00260 {
00261 if (strchr(separators, *(aPos+keyLen))!=NULL)
00262 {
00263 aPos+=keyLen;
00264 return true;
00265 }
00266 }
00267 return false;
00268 };
00269
00275 int KeywordsSwitch(const char *keywords[], const char *whitechars = NULL, const char *separators = NULL)
00276 {
00277 if (whitechars==NULL)
00278 {
00279 whitechars = " \t\n\r";
00280 }
00281 if (separators==NULL)
00282 {
00283 separators = whitechars;
00284 }
00285 SkipCharsAndComments(whitechars);
00286 int i=0;
00287 while (**keywords)
00288 {
00289 size_t keyLen = strlen(*keywords);
00290 if (!_strnicmp(aPos, *keywords, keyLen))
00291 {
00292 if (strchr(separators, *(aPos+keyLen))!=NULL)
00293 {
00294 aPos+=keyLen;
00295 return i;
00296 }
00297 }
00298 i++;
00299 keywords++;
00300 }
00301 return -1;
00302 };
00303
00309 int CharsSwitch(const char *chars, const char *separators = NULL, bool skip = true)
00310 {
00311 if (skip)
00312 SkipCharsAndComments(separators);
00313 int charsNum = (int)strlen(chars);
00314 for (int i=0; i<charsNum; i++)
00315 {
00316 if (*aPos==*chars)
00317 {
00318 aPos++;
00319 return i;
00320 }
00321 chars++;
00322 }
00323 return -1;
00324 };
00325
00327 inline bool NextCharIs(const char chr, const char *separators = NULL, bool skip = true)
00328 {
00329 if (separators==NULL)
00330 {
00331 separators = " \t\n\r";
00332 }
00333 if (skip) SkipCharsAndComments(separators);
00334 return (*aPos==chr);
00335 };
00336
00338 inline char GetChar(const char *separators = NULL, bool skip = true)
00339 {
00340 if (skip)
00341 {
00342 if (separators==NULL)
00343 separators = " \t\n\r";
00344 SkipCharsAndComments(separators);
00345 }
00346 return *(aPos++);
00347 };
00348
00350 std::string GetString(const char *separators = NULL)
00351 {
00352 std::string res;
00353 if (separators==NULL)
00354 separators = " \t\n\r";
00355 SkipCharsAndComments(separators);
00356 if (*aPos=='\"')
00357 {
00358
00359 aPos++;
00360 while (true)
00361 {
00362 char *pos=FindFirstOf("\"");
00363 if (pos==bEnd)
00364 {
00365 res+=aPos;
00366 aPos=bEnd;
00367 if (!ReadToBuffer())
00368 return res;
00369 }
00370 else
00371 {
00372 char tmpChr = *pos;
00373 *pos=0;
00374 res += aPos;
00375 *pos = tmpChr;
00376 aPos=pos + 1;
00377 ReadToBuffer();
00378 return res;
00379 }
00380 }
00381 }
00382 else
00383 {
00384
00385 while (true)
00386 {
00387 char *pos=FindFirstOf(separators);
00388 if (pos==bEnd)
00389 {
00390 res+=aPos;
00391 aPos=bEnd;
00392 if (!ReadToBuffer())
00393 return res;
00394 }
00395 else
00396 {
00397 char tmpChr = *pos;
00398 *pos=0;
00399 res += aPos;
00400 *pos = tmpChr;
00401 aPos=pos;
00402 ReadToBuffer();
00403 return res;
00404 }
00405 }
00406 }
00407 };
00408
00410 wxString GetWxString(const char *separators = NULL)
00411 {
00412 return wxString::FromAscii(GetString(separators).c_str());
00413 };
00414
00416 wxString GetWxLine()
00417 {
00418 wxString res;
00419 while (true)
00420 {
00421 char *pos=FindFirstOf("\n\r");
00422 if (pos==bEnd)
00423 {
00424 res+=wxString::FromAscii(aPos);
00425 aPos=bEnd;
00426 if (!ReadToBuffer())
00427 return res;
00428 }
00429 else
00430 {
00431 char tmpChr = *pos;
00432 *pos=0;
00433 res+=wxString::FromAscii(aPos);
00434 *pos = tmpChr;
00435 aPos=pos + 1;
00436 ReadToBuffer();
00437 return res;
00438 }
00439 }
00440 };
00441
00447 bool ParseInt(int * target, const char *separators = NULL, bool skip = true)
00448 {
00449 if (skip)
00450 {
00451 if (separators==NULL)
00452 separators = " \t\n\r";
00453 SkipCharsAndComments(separators);
00454 }
00455
00456
00457 *target = 0;
00458 bool isOK=false;
00459 char *origPos = aPos;
00460 bool sign = false;
00461 if (*aPos=='-')
00462 {
00463 sign = true;
00464 aPos++;
00465 } else if (*aPos=='+')
00466 {
00467 aPos++;
00468 }
00469
00470 unsigned char n;
00471 while (*aPos && ((n=*aPos-'0')<10))
00472 {
00473 *target = *target*10 + n;
00474 aPos++;
00475 isOK = true;
00476 }
00477
00478 if (sign)
00479 *target=-*target;
00480 if (!isOK)
00481 aPos = origPos;
00482 return isOK;
00483 };
00484
00490 bool ParseLong(long * target, const char *separators = NULL, bool skip = true)
00491 {
00492 if (skip)
00493 {
00494 if (separators==NULL)
00495 separators = " \t\n\r";
00496 SkipCharsAndComments(separators);
00497 }
00498 *target = 0;
00499 bool isOK=false;
00500 char *origPos = aPos;
00501 bool sign = false;
00502 if (*aPos=='-')
00503 {
00504 sign = true;
00505 aPos++;
00506 } else if (*aPos=='+')
00507 {
00508 aPos++;
00509 }
00510
00511 unsigned char n;
00512 while (*aPos && ((n=*aPos-'0')<10))
00513 {
00514 *target = *target*10 + n;
00515 aPos++;
00516 isOK = true;
00517 }
00518
00519 if (sign)
00520 *target=-*target;
00521 if (!isOK)
00522 aPos = origPos;
00523 return isOK;
00524 };
00525
00527 bool myatof(float &target)
00528 {
00529 if (!*aPos)
00530 return false;
00531 target = 0;
00532 bool isOK=false;
00533 char *origPos = aPos;
00534
00535 bool sign = false;
00536 if (*aPos=='-')
00537 {
00538 sign = true;
00539 aPos++;
00540 } else if (*aPos=='+')
00541 {
00542 aPos++;
00543 }
00544
00545 while (*aPos && (*aPos>='0') &&(*aPos<='9'))
00546 {
00547 target = target*10 + (*aPos-'0');
00548 aPos++;
00549 isOK = true;
00550 }
00551
00552 if (*aPos=='.')
00553 {
00554 isOK = false;
00555 aPos++;
00556 if (*aPos=='#')
00557 {
00558 aPos++;
00559 if (!_strnicmp(aPos, "IND", 3))
00560 aPos+=3;
00561 while (*aPos && (*aPos>='0') && (*aPos<='9'))
00562 aPos++;
00563 target=log(0.0f);
00564 return true;
00565 }
00566 float ratio = 1;
00567 while (*aPos && (*aPos>='0') && (*aPos<='9'))
00568 {
00569 ratio/=10;
00570 target += ratio*(*aPos-'0');
00571 aPos++;
00572 isOK = true;
00573 }
00574 }
00575
00576 if ((*aPos=='e')||(*aPos=='E'))
00577 {
00578 aPos++;
00579
00580 bool esign = false;
00581 if (*aPos=='-')
00582 {
00583 esign = true;
00584 aPos++;
00585 } else if (*aPos=='+')
00586 {
00587 aPos++;
00588 }
00589 int exponent = 0;
00590 unsigned char n;
00591 while (*aPos && ((n=*aPos-'0')<10))
00592 {
00593 exponent = exponent*10 + n;
00594 aPos++;
00595 isOK = true;
00596 }
00597 if (esign)
00598 target/=pow((float)10,exponent);
00599 else
00600 target*=pow((float)10,exponent);
00601 }
00602
00603 if (sign)
00604 target=-target;
00605 if (!isOK)
00606 aPos = origPos;
00607 return isOK;
00608 }
00609
00614 bool ParseFloat(float * target, const char *separators = NULL)
00615 {
00616 if (separators==NULL)
00617 {
00618 separators = " \t\n\r";
00619 }
00620 SkipCharsAndComments(separators);
00621 return myatof(*target);
00622 };
00623
00631 size_t ParseVector(float * target, size_t dim, bool skipParenthesis = false, const char* separators = NULL, bool skip = true)
00632 {
00633 if (!skipParenthesis)
00634 {
00635 if (GetChar(separators, skip)!='(')
00636 {
00637 LOGERROR(wxT("EXPECTED (\t") + GetWxLine());
00638 return 0;
00639 }
00640 }
00641 size_t i=0;
00642 bool checkDim = dim > 0;
00643 for ( ; (i < dim) || !checkDim; i++)
00644 {
00645 if (NextCharIs(')', " ,\t\n\r"))
00646 break;
00647 if (!myatof(*target))
00648 break;
00649 target++;
00650 }
00651 if (!skipParenthesis)
00652 {
00653 if (GetChar()!=')')
00654 {
00655 LOGERROR(wxT("EXPECTED )\t"));
00656
00657 }
00658 }
00659 if (checkDim && (i != dim))
00660 LOGWARNING(wxT("VECTOR size not expected"));
00661 return i;
00662 }
00663 };
00664 };
00665
00666 #endif
00667