#include <textparser.h>
Public Member Functions | |
TextParser (wxInputStream *_inputStream, size_t _buffSize, size_t _minSize) | |
TextParser (const char *_input) | |
Class constructor. | |
TextParser (const wxString _input) | |
Class constructor. | |
~TextParser () | |
Class destructor. | |
bool | ReadToBuffer (bool force=false) |
void | SkipChars (const char *chars) |
Skip any of given characters. | |
char * | FindFirstOf (const char *chars) |
void | SkipCharsAndComments (const char *chars) |
Skip any of given characters and comments. | |
void | ForceEmpty () |
Set parser as if it has reached end of buffer. | |
bool | IsEmpty (const char *separators=NULL, bool skip=true) |
Is there anything left to read? | |
bool | NextKeywordIs (const char *keyword, const char *separators=NULL) |
Check keyword and read it, useful only when only one keyword can occur. | |
int | KeywordsSwitch (const char *keywords[], const char *whitechars=NULL, const char *separators=NULL) |
int | CharsSwitch (const char *chars, const char *separators=NULL, bool skip=true) |
bool | NextCharIs (const char chr, const char *separators=NULL, bool skip=true) |
Test next character, but do not read it. | |
char | GetChar (const char *separators=NULL, bool skip=true) |
Read next character. | |
std::string | GetString (const char *separators=NULL) |
Read quoted of not quoted string up to next separator. | |
wxString | GetWxString (const char *separators=NULL) |
Read quoted of not quoted string up to next separator, wxString version. | |
wxString | GetWxLine () |
Read up to end of line, it should be used only for error messages. | |
bool | ParseInt (int *target, const char *separators=NULL, bool skip=true) |
bool | ParseLong (long *target, const char *separators=NULL, bool skip=true) |
bool | myatof (float &target) |
Convert string to float, it is workaround for extremely slow windows implementation of atof (that uses locales). | |
bool | ParseFloat (float *target, const char *separators=NULL) |
size_t | ParseVector (float *target, size_t dim, bool skipParenthesis=false, const char *separators=NULL, bool skip=true) |
Private Attributes | |
wxInputStream * | inputStream |
Input text stream with data. | |
char * | buff |
Read buffer. | |
char * | aPos |
Current position. | |
char * | bEnd |
End of buffer. | |
size_t | buffSize |
Position in read buffer. | |
size_t | minSize |
Minimal buffer size. |
Definition at line 26 of file textparser.h.
VRUT::TextParser::TextParser | ( | wxInputStream * | _inputStream, | |
size_t | _buffSize, | |||
size_t | _minSize | |||
) | [inline] |
Class constructor minSize must be at least max(maxKeywordLen+1, maxNumberLen+1) in buffered mode, i.e. buffSize>0 minSize must be 0 in "load whole scene" mode, i.e. buffSize=0
Definition at line 46 of file textparser.h.
00046 : inputStream(_inputStream), buffSize(_buffSize), minSize(_minSize) 00047 { 00048 if (buffSize==0) 00049 { 00050 //load whole scene 00051 buffSize = inputStream->GetSize(); 00052 if (buffSize==0) 00053 { 00054 //it is not possible to read size of stream 00055 //really wrong hack, please use real buffered mode instead of "read all at once" 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 };
VRUT::TextParser::TextParser | ( | const char * | _input | ) | [inline] |
VRUT::TextParser::TextParser | ( | const wxString | _input | ) | [inline] |
VRUT::TextParser::~TextParser | ( | ) | [inline] |
bool VRUT::TextParser::ReadToBuffer | ( | bool | force = false |
) | [inline] |
Read chars to buffer
[in] | force | If true Try to read chars even if not "needed" |
false
if no chars are read Definition at line 124 of file textparser.h.
00125 { 00126 if (minSize) 00127 { 00128 if (aPos==buff) 00129 return false;//buffer is full 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 }
void VRUT::TextParser::SkipChars | ( | const char * | chars | ) | [inline] |
Skip any of given characters.
Definition at line 148 of file textparser.h.
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 };
char* VRUT::TextParser::FindFirstOf | ( | const char * | chars | ) | [inline] |
Find first occurance of any character from chars
or return bEnd
and the caller must fill buffer and call again
Definition at line 166 of file textparser.h.
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 }
void VRUT::TextParser::SkipCharsAndComments | ( | const char * | chars | ) | [inline] |
Skip any of given characters and comments.
Definition at line 181 of file textparser.h.
00182 { 00183 while (true) 00184 { 00185 //skip useless chars and comments 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;//comment up to end of file 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;//comment up to end of file 00216 } 00217 else 00218 { 00219 aPos+=2; 00220 ReadToBuffer(); 00221 break; 00222 } 00223 } 00224 } 00225 else 00226 return; 00227 } 00228 };
void VRUT::TextParser::ForceEmpty | ( | ) | [inline] |
bool VRUT::TextParser::IsEmpty | ( | const char * | separators = NULL , |
|
bool | skip = true | |||
) | [inline] |
Is there anything left to read?
Definition at line 237 of file textparser.h.
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 };
bool VRUT::TextParser::NextKeywordIs | ( | const char * | keyword, | |
const char * | separators = NULL | |||
) | [inline] |
Check keyword and read it, useful only when only one keyword can occur.
Definition at line 251 of file textparser.h.
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 };
int VRUT::TextParser::KeywordsSwitch | ( | const char * | keywords[], | |
const char * | whitechars = NULL , |
|||
const char * | separators = NULL | |||
) | [inline] |
Check for more keywords at once, it can be used for example in switches (the last keyword must be empty)
[in] | keywords | Array with keywords to look for |
[in] | whitechars | Characters to be skipped |
[in] | separators | Characters used for check of keyword end |
Definition at line 275 of file textparser.h.
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 };
int VRUT::TextParser::CharsSwitch | ( | const char * | chars, | |
const char * | separators = NULL , |
|||
bool | skip = true | |||
) | [inline] |
Check for more keywords at once, it can be used for example in switches
[in] | chars | Array with characters to look for |
[in] | separators | Characters to be skipped |
[in] | skip | If true skip characters in separators and comments |
Definition at line 309 of file textparser.h.
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 };
bool VRUT::TextParser::NextCharIs | ( | const char | chr, | |
const char * | separators = NULL , |
|||
bool | skip = true | |||
) | [inline] |
Test next character, but do not read it.
Definition at line 327 of file textparser.h.
00328 { 00329 if (separators==NULL) 00330 { 00331 separators = " \t\n\r"; 00332 } 00333 if (skip) SkipCharsAndComments(separators); 00334 return (*aPos==chr); 00335 };
char VRUT::TextParser::GetChar | ( | const char * | separators = NULL , |
|
bool | skip = true | |||
) | [inline] |
Read next character.
Definition at line 338 of file textparser.h.
00339 { 00340 if (skip) 00341 { 00342 if (separators==NULL) 00343 separators = " \t\n\r"; 00344 SkipCharsAndComments(separators); 00345 } 00346 return *(aPos++); 00347 };
std::string VRUT::TextParser::GetString | ( | const char * | separators = NULL |
) | [inline] |
Read quoted of not quoted string up to next separator.
Definition at line 350 of file textparser.h.
00351 { 00352 std::string res; 00353 if (separators==NULL) 00354 separators = " \t\n\r"; 00355 SkipCharsAndComments(separators); 00356 if (*aPos=='\"') 00357 { 00358 //read quoted string 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;//string up to end of file 00369 } 00370 else 00371 { 00372 char tmpChr = *pos;//TODO useless to repair buffer? 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 //read not quoted string 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;//string up to end of file 00394 } 00395 else 00396 { 00397 char tmpChr = *pos;//TODO useless to repair buffer? 00398 *pos=0; 00399 res += aPos; 00400 *pos = tmpChr; 00401 aPos=pos; 00402 ReadToBuffer(); 00403 return res; 00404 } 00405 } 00406 } 00407 };
wxString VRUT::TextParser::GetWxString | ( | const char * | separators = NULL |
) | [inline] |
Read quoted of not quoted string up to next separator, wxString version.
Definition at line 410 of file textparser.h.
00411 { 00412 return wxString::FromAscii(GetString(separators).c_str()); 00413 };
wxString VRUT::TextParser::GetWxLine | ( | ) | [inline] |
Read up to end of line, it should be used only for error messages.
Definition at line 416 of file textparser.h.
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;//line up to end of file 00428 } 00429 else 00430 { 00431 char tmpChr = *pos;//TODO useless to repair buffer? 00432 *pos=0; 00433 res+=wxString::FromAscii(aPos); 00434 *pos = tmpChr; 00435 aPos=pos + 1; 00436 ReadToBuffer(); 00437 return res; 00438 } 00439 } 00440 };
bool VRUT::TextParser::ParseInt | ( | int * | target, | |
const char * | separators = NULL , |
|||
bool | skip = true | |||
) | [inline] |
Parse integer
[out] | target | Will be set to parsed value |
[in] | separators | Characters to be skipped |
[in] | skip | If true skip characters in separators and comments |
true
if successfull Definition at line 447 of file textparser.h.
00448 { 00449 if (skip) 00450 { 00451 if (separators==NULL) 00452 separators = " \t\n\r"; 00453 SkipCharsAndComments(separators); 00454 } 00455 /* *target = atoi(aPos); 00456 aPos = FindFirstOf(separators);*/ 00457 *target = 0; 00458 bool isOK=false; 00459 char *origPos = aPos; 00460 bool sign = false;//false = positive number 00461 if (*aPos=='-') 00462 { 00463 sign = true; 00464 aPos++; 00465 } else if (*aPos=='+') 00466 { 00467 aPos++; 00468 } 00469 //read integral part of number 00470 unsigned char n; 00471 while (*aPos && ((n=*aPos-'0')<10)) 00472 { 00473 *target = *target*10 + n; 00474 aPos++; 00475 isOK = true; 00476 } 00477 //apply sign 00478 if (sign) 00479 *target=-*target; 00480 if (!isOK) 00481 aPos = origPos; 00482 return isOK; 00483 };
bool VRUT::TextParser::ParseLong | ( | long * | target, | |
const char * | separators = NULL , |
|||
bool | skip = true | |||
) | [inline] |
Parse long integer
[out] | target | Will be set to parsed value |
[in] | separators | Characters to be skipped |
[in] | skip | If true skip characters in separators and comments |
true
if successfull Definition at line 490 of file textparser.h.
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;//false = positive number 00502 if (*aPos=='-') 00503 { 00504 sign = true; 00505 aPos++; 00506 } else if (*aPos=='+') 00507 { 00508 aPos++; 00509 } 00510 //read integral part of number 00511 unsigned char n; 00512 while (*aPos && ((n=*aPos-'0')<10)) 00513 { 00514 *target = *target*10 + n; 00515 aPos++; 00516 isOK = true; 00517 } 00518 //apply sign 00519 if (sign) 00520 *target=-*target; 00521 if (!isOK) 00522 aPos = origPos; 00523 return isOK; 00524 };
bool VRUT::TextParser::myatof | ( | float & | target | ) | [inline] |
Convert string to float, it is workaround for extremely slow windows implementation of atof (that uses locales).
Definition at line 527 of file textparser.h.
00528 { 00529 if (!*aPos) 00530 return false; 00531 target = 0; 00532 bool isOK=false; 00533 char *origPos = aPos; 00534 //test the sign 00535 bool sign = false;//false = positive number 00536 if (*aPos=='-') 00537 { 00538 sign = true; 00539 aPos++; 00540 } else if (*aPos=='+') 00541 { 00542 aPos++; 00543 } 00544 //read integral part of number 00545 while (*aPos && (*aPos>='0') &&(*aPos<='9')) 00546 { 00547 target = target*10 + (*aPos-'0'); 00548 aPos++; 00549 isOK = true; 00550 } 00551 //read decimals 00552 if (*aPos=='.') 00553 { 00554 isOK = false; 00555 aPos++; 00556 if (*aPos=='#') //NaN 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 //read exponent 00576 if ((*aPos=='e')||(*aPos=='E')) 00577 { 00578 aPos++; 00579 //test exponent sign 00580 bool esign = false;//false = positive number 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 //apply sign 00603 if (sign) 00604 target=-target; 00605 if (!isOK) 00606 aPos = origPos; 00607 return isOK; 00608 }
bool VRUT::TextParser::ParseFloat | ( | float * | target, | |
const char * | separators = NULL | |||
) | [inline] |
Parse float
[out] | target | Will be set to parsed value |
[in] | separators | Characters to be skipped |
true
if successfull Definition at line 614 of file textparser.h.
00615 { 00616 if (separators==NULL) 00617 { 00618 separators = " \t\n\r"; 00619 } 00620 SkipCharsAndComments(separators); 00621 return myatof(*target); 00622 };
size_t VRUT::TextParser::ParseVector | ( | float * | target, | |
size_t | dim, | |||
bool | skipParenthesis = false , |
|||
const char * | separators = NULL , |
|||
bool | skip = true | |||
) | [inline] |
Parse vector separated by () brackets
[out] | target | Array to be filled with values |
[in] | dim | Number of values to be read, if 0 read till delimiter |
[in] | skipParenthesis | Parse also parenthesis if true |
[in] | separators | Set of separators used on begin of vector |
[in] | skip | Early skip - do not repeat SkipChars redundantly true |
Definition at line 631 of file textparser.h.
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")/* + GetWxLine()*/); 00656 //return 0; 00657 } 00658 } 00659 if (checkDim && (i != dim)) 00660 LOGWARNING(wxT("VECTOR size not expected")); 00661 return i; 00662 }
wxInputStream* VRUT::TextParser::inputStream [private] |
char* VRUT::TextParser::buff [private] |
char* VRUT::TextParser::aPos [private] |
char* VRUT::TextParser::bEnd [private] |
size_t VRUT::TextParser::buffSize [private] |
size_t VRUT::TextParser::minSize [private] |