| 19 | | Field::Field() |
|---|
| 20 | | { |
|---|
| 21 | | _init(); |
|---|
| 22 | | } |
|---|
| 23 | | |
|---|
| 24 | | |
|---|
| 25 | | Field::Field(const Field& ic) |
|---|
| 26 | | { |
|---|
| 27 | | _copy(ic); |
|---|
| 28 | | } |
|---|
| 29 | | |
|---|
| 30 | | |
|---|
| 31 | | Field::~Field() |
|---|
| 32 | | { |
|---|
| 33 | | _free(); |
|---|
| 34 | | } |
|---|
| 35 | | |
|---|
| 36 | | |
|---|
| 37 | | Field& Field::operator = (const Field& ic) |
|---|
| 38 | | { |
|---|
| 39 | | if (this==&ic) return *this; |
|---|
| 40 | | _free(); |
|---|
| 41 | | _copy(ic); |
|---|
| 42 | | return *this; |
|---|
| 43 | | } |
|---|
| 44 | | |
|---|
| 45 | | |
|---|
| 46 | | void Field::_free() |
|---|
| 47 | | { |
|---|
| 48 | | // free all data |
|---|
| 49 | | if (_fieldCache) delete [] _fieldCache; |
|---|
| 50 | | |
|---|
| 51 | | _init(); |
|---|
| 52 | | |
|---|
| 53 | | } |
|---|
| 54 | | |
|---|
| 55 | | |
|---|
| 56 | | void Field::_init() |
|---|
| 57 | | { |
|---|
| 58 | | |
|---|
| 59 | | _fieldCacheCapacity = 256; |
|---|
| 60 | | _fieldCacheSize = 0; |
|---|
| 61 | | _fieldCache = NULL; |
|---|
| 62 | | |
|---|
| 63 | | _fieldType = UNINITIALISED; |
|---|
| 64 | | |
|---|
| 65 | | _withinQuotes = false; |
|---|
| 66 | | |
|---|
| 67 | | _noNestedBrackets = 0; |
|---|
| 68 | | |
|---|
| 69 | | } |
|---|
| 70 | | |
|---|
| 71 | | |
|---|
| 72 | | void Field::_copy(const Field& ic) |
|---|
| 73 | | { |
|---|
| 74 | | |
|---|
| 75 | | // copy string cache. |
|---|
| 76 | | if (ic._fieldCache) |
|---|
| 77 | | { |
|---|
| 78 | | _fieldCacheCapacity = ic._fieldCacheCapacity; |
|---|
| 79 | | _fieldCacheSize = ic._fieldCacheSize; |
|---|
| 80 | | _fieldCache = new char [_fieldCacheCapacity]; |
|---|
| 81 | | strncpy(_fieldCache,ic._fieldCache,_fieldCacheCapacity); |
|---|
| 82 | | } |
|---|
| 83 | | else |
|---|
| 84 | | { |
|---|
| 85 | | _fieldCacheCapacity = 0; |
|---|
| 86 | | _fieldCacheSize = 0; |
|---|
| 87 | | _fieldCache = NULL; |
|---|
| 88 | | } |
|---|
| 89 | | |
|---|
| 90 | | _fieldType = ic._fieldType; |
|---|
| 91 | | |
|---|
| 92 | | _withinQuotes = ic._withinQuotes; |
|---|
| 93 | | |
|---|
| 94 | | _noNestedBrackets = ic._noNestedBrackets; |
|---|
| 95 | | } |
|---|
| 96 | | |
|---|
| 97 | | |
|---|
| 98 | | void Field::setWithinQuotes(bool withinQuotes) |
|---|
| 99 | | { |
|---|
| 100 | | _withinQuotes=withinQuotes; |
|---|
| 101 | | _fieldType = UNINITIALISED; |
|---|
| 102 | | } |
|---|
| 103 | | |
|---|
| 104 | | |
|---|
| 105 | | bool Field::getWithinQuotes() |
|---|
| 106 | | { |
|---|
| 107 | | return _withinQuotes; |
|---|
| 108 | | } |
|---|
| 109 | | |
|---|
| 110 | | |
|---|
| 111 | | void Field::setNoNestedBrackets(int no) |
|---|
| 112 | | { |
|---|
| 113 | | _noNestedBrackets=no; |
|---|
| 114 | | } |
|---|
| 115 | | |
|---|
| 116 | | |
|---|
| 117 | | int Field::getNoNestedBrackets() |
|---|
| 118 | | { |
|---|
| 119 | | return _noNestedBrackets; |
|---|
| 120 | | } |
|---|
| 121 | | |
|---|
| 122 | | |
|---|
| 123 | | const char* Field::getStr() const |
|---|
| 124 | | { |
|---|
| 125 | | if (_fieldCacheSize!=0) return _fieldCache; |
|---|
| 126 | | else return NULL; |
|---|
| 127 | | } |
|---|
| 128 | | |
|---|
| 129 | | |
|---|
| 130 | | char* Field::takeStr() |
|---|
| 131 | | { |
|---|
| 132 | | char* field = _fieldCache; |
|---|
| 133 | | |
|---|
| 134 | | _fieldCache = NULL; |
|---|
| 135 | | _fieldCacheSize = 0; |
|---|
| 136 | | |
|---|
| 137 | | _fieldType = UNINITIALISED; |
|---|
| 138 | | _withinQuotes = false; |
|---|
| 139 | | |
|---|
| 140 | | return field; |
|---|
| 141 | | } |
|---|
| 142 | | |
|---|
| 143 | | |
|---|
| 144 | | void Field::reset() |
|---|
| 145 | | { |
|---|
| 146 | | _fieldCacheSize = 0; |
|---|
| 147 | | if (_fieldCache) |
|---|
| 148 | | { |
|---|
| 149 | | _fieldCache[_fieldCacheSize] = 0; |
|---|
| 150 | | } |
|---|
| 151 | | |
|---|
| 152 | | _withinQuotes = false; |
|---|
| 153 | | _noNestedBrackets = 0; |
|---|
| 154 | | } |
|---|
| 155 | | |
|---|
| 156 | | |
|---|
| 157 | | void Field::addChar(char c) |
|---|
| 158 | | { |
|---|
| 159 | | if (_fieldCache==NULL) |
|---|
| 160 | | { |
|---|
| 161 | | if (_fieldCacheCapacity<MIN_CACHE_SIZE) _fieldCacheCapacity=MIN_CACHE_SIZE; |
|---|
| 162 | | _fieldCache = new char[_fieldCacheCapacity]; |
|---|
| 163 | | memset(_fieldCache,0,_fieldCacheCapacity); |
|---|
| 164 | | _fieldCacheSize = 0; |
|---|
| 165 | | } |
|---|
| 166 | | else if (_fieldCacheSize>=_fieldCacheCapacity-1) |
|---|
| 167 | | { |
|---|
| 168 | | if (_fieldCacheCapacity<MIN_CACHE_SIZE) _fieldCacheCapacity=MIN_CACHE_SIZE; |
|---|
| 169 | | while (_fieldCacheSize>=_fieldCacheCapacity-1) _fieldCacheCapacity *= 2; |
|---|
| 170 | | char* tmp_str = _fieldCache; |
|---|
| 171 | | _fieldCache = new char[_fieldCacheCapacity]; |
|---|
| 172 | | memset(_fieldCache,0,_fieldCacheCapacity); |
|---|
| 173 | | strncpy(_fieldCache,tmp_str,_fieldCacheSize); |
|---|
| 174 | | delete [] tmp_str; |
|---|
| 175 | | |
|---|
| 176 | | } |
|---|
| 177 | | _fieldCache[_fieldCacheSize++] = c; |
|---|
| 178 | | _fieldCache[_fieldCacheSize] = 0; |
|---|
| 179 | | _fieldType = UNINITIALISED; |
|---|
| 180 | | } |
|---|
| 181 | | |
|---|
| 182 | | |
|---|
| 183 | | Field::FieldType Field::getFieldType() const |
|---|
| 184 | | { |
|---|
| 185 | | if (_fieldType==UNINITIALISED && _fieldCache) |
|---|
| 186 | | { |
|---|
| 187 | | _fieldType = calculateFieldType(_fieldCache,_withinQuotes); |
|---|
| 188 | | } |
|---|
| 189 | | return _fieldType; |
|---|
| 190 | | } |
|---|
| 191 | | |
|---|
| 192 | | |
|---|
| 193 | | bool Field::isValid() const |
|---|
| 194 | | { |
|---|
| 195 | | if (_fieldCacheSize>0 && !_withinQuotes) return true; |
|---|
| 196 | | else return false; |
|---|
| 197 | | } |
|---|
| 198 | | |
|---|
| 199 | | |
|---|
| 200 | | bool Field::isOpenBracket() const |
|---|
| 201 | | { |
|---|
| 202 | | if (_fieldCacheSize==1) return _fieldCache[0]=='{'; |
|---|
| 203 | | else return false; |
|---|
| 204 | | } |
|---|
| 205 | | |
|---|
| 206 | | |
|---|
| 207 | | bool Field::isCloseBracket() const |
|---|
| 208 | | { |
|---|
| 209 | | if (_fieldCacheSize==1) return _fieldCache[0]=='}'; |
|---|
| 210 | | else return false; |
|---|
| 211 | | } |
|---|
| 212 | | |
|---|
| 213 | | |
|---|
| 214 | | bool Field::isWord() const |
|---|
| 215 | | { |
|---|
| 216 | | getFieldType(); |
|---|
| 217 | | return (_fieldType==WORD); |
|---|
| 218 | | } |
|---|
| 219 | | |
|---|
| 220 | | |
|---|
| 221 | | bool Field::matchWord(const char* str) const |
|---|
| 222 | | { |
|---|
| 223 | | getFieldType(); |
|---|
| 224 | | return _fieldType==WORD && strcmp(_fieldCache,str)==0; |
|---|
| 225 | | } |
|---|
| 226 | | |
|---|
| 227 | | |
|---|
| 228 | | bool Field::matchWord(const char* str,int noCharacters) const |
|---|
| 229 | | { |
|---|
| 230 | | getFieldType(); |
|---|
| 231 | | return _fieldType==WORD && strncmp(_fieldCache,str,noCharacters)==0; |
|---|
| 232 | | } |
|---|
| 233 | | |
|---|
| 234 | | |
|---|
| 235 | | bool Field::isString() const |
|---|
| 236 | | { |
|---|
| 237 | | return getNoCharacters()!=0; |
|---|
| 238 | | } |
|---|
| 239 | | |
|---|
| 240 | | |
|---|
| 241 | | bool Field::matchString(const char* str) const |
|---|
| 242 | | { |
|---|
| 243 | | return strcmp(_fieldCache,str)==0; |
|---|
| 244 | | } |
|---|
| 245 | | |
|---|
| 246 | | |
|---|
| 247 | | bool Field::matchString(const char* str,int noCharacters) const |
|---|
| 248 | | { |
|---|
| 249 | | return strncmp(_fieldCache,str,noCharacters)==0; |
|---|
| 250 | | } |
|---|
| 251 | | |
|---|
| 252 | | |
|---|
| 253 | | bool Field::isQuotedString() const |
|---|
| 254 | | { |
|---|
| 255 | | return _withinQuotes; |
|---|
| 256 | | } |
|---|
| 257 | | |
|---|
| 258 | | |
|---|
| 259 | | bool Field::isInt() const |
|---|
| 260 | | { |
|---|
| 261 | | getFieldType(); |
|---|
| 262 | | return _fieldType==INTEGER; |
|---|
| 263 | | } |
|---|
| 264 | | |
|---|
| 265 | | |
|---|
| 266 | | bool Field::matchInt(int i) const |
|---|
| 267 | | { |
|---|
| 268 | | getFieldType(); |
|---|
| 269 | | if (_fieldType==INTEGER) |
|---|
| 270 | | { |
|---|
| 271 | | return strtol(_fieldCache,NULL,0)==i; |
|---|
| 272 | | } |
|---|
| 273 | | else |
|---|
| 274 | | { |
|---|
| 275 | | return false; |
|---|
| 276 | | } |
|---|
| 277 | | } |
|---|
| 278 | | |
|---|
| 279 | | |
|---|
| 280 | | bool Field::getInt(int& i) const |
|---|
| 281 | | { |
|---|
| 282 | | getFieldType(); |
|---|
| 283 | | if (_fieldType==INTEGER) |
|---|
| 284 | | { |
|---|
| 285 | | i = strtol(_fieldCache,NULL,0); |
|---|
| 286 | | return true; |
|---|
| 287 | | } |
|---|
| 288 | | else |
|---|
| 289 | | { |
|---|
| 290 | | return false; |
|---|
| 291 | | } |
|---|
| 292 | | } |
|---|
| 293 | | |
|---|
| 294 | | bool Field::isUInt() const |
|---|
| 295 | | { |
|---|
| 296 | | getFieldType(); |
|---|
| 297 | | return _fieldType==INTEGER; |
|---|
| 298 | | } |
|---|
| 299 | | |
|---|
| 300 | | |
|---|
| 301 | | bool Field::matchUInt(unsigned int i) const |
|---|
| 302 | | { |
|---|
| 303 | | getFieldType(); |
|---|
| 304 | | if (_fieldType==INTEGER) |
|---|
| 305 | | { |
|---|
| 306 | | return (unsigned int) strtoul(_fieldCache,NULL,0)==i; |
|---|
| 307 | | } |
|---|
| 308 | | else |
|---|
| 309 | | { |
|---|
| 310 | | return false; |
|---|
| 311 | | } |
|---|
| 312 | | } |
|---|
| 313 | | |
|---|
| 314 | | |
|---|
| 315 | | bool Field::getUInt(unsigned int& i) const |
|---|
| 316 | | { |
|---|
| 317 | | getFieldType(); |
|---|
| 318 | | if (_fieldType==INTEGER) |
|---|
| 319 | | { |
|---|
| 320 | | i = strtoul(_fieldCache,NULL,0); |
|---|
| 321 | | return true; |
|---|
| 322 | | } |
|---|
| 323 | | else |
|---|
| 324 | | { |
|---|
| 325 | | return false; |
|---|
| 326 | | } |
|---|
| 327 | | } |
|---|
| 328 | | |
|---|
| 329 | | bool Field::isFloat() const |
|---|
| 330 | | { |
|---|
| 331 | | getFieldType(); |
|---|
| 332 | | return _fieldType==REAL || _fieldType==INTEGER; |
|---|
| 333 | | } |
|---|
| 334 | | |
|---|
| 335 | | |
|---|
| 336 | | bool Field::matchFloat(float f) const |
|---|
| 337 | | { |
|---|
| 338 | | getFieldType(); |
|---|
| 339 | | if (_fieldType==REAL || _fieldType==INTEGER) |
|---|
| 340 | | { |
|---|
| 341 | | return (float)atof(_fieldCache)==f; |
|---|
| 342 | | } |
|---|
| 343 | | else |
|---|
| 344 | | { |
|---|
| 345 | | return false; |
|---|
| 346 | | } |
|---|
| 347 | | } |
|---|
| 348 | | |
|---|
| 349 | | |
|---|
| 350 | | bool Field::getFloat(float& f) const |
|---|
| 351 | | { |
|---|
| 352 | | getFieldType(); |
|---|
| 353 | | if (_fieldType==REAL || _fieldType==INTEGER) |
|---|
| 354 | | { |
|---|
| 355 | | f = (float)atof(_fieldCache); |
|---|
| 356 | | return true; |
|---|
| 357 | | } |
|---|
| 358 | | else |
|---|
| 359 | | { |
|---|
| 360 | | return false; |
|---|
| 361 | | } |
|---|
| 362 | | } |
|---|
| 363 | | |
|---|
| 364 | | bool Field::getFloat(double& f) const |
|---|
| 365 | | { |
|---|
| 366 | | getFieldType(); |
|---|
| 367 | | if (_fieldType==REAL || _fieldType==INTEGER) |
|---|
| 368 | | { |
|---|
| 369 | | f = atof(_fieldCache); |
|---|
| 370 | | return true; |
|---|
| 371 | | } |
|---|
| 372 | | else |
|---|
| 373 | | { |
|---|
| 374 | | return false; |
|---|
| 375 | | } |
|---|
| 376 | | } |
|---|
| 377 | | |
|---|
| 378 | | |
|---|
| 379 | | Field::FieldType Field::calculateFieldType(const char* str,bool withinQuotes) |
|---|
| 380 | | { |
|---|
| 381 | | if (str==NULL) return BLANK; |
|---|
| 382 | | if (*str==0) return BLANK; |
|---|
| 383 | | |
|---|
| 384 | | if (withinQuotes) return STRING; |
|---|
| 385 | | |
|---|
| 386 | | bool hadPlusMinus = false; |
|---|
| 387 | | bool hadDecimalPlace = false; |
|---|
| 388 | | bool hadExponent = false; |
|---|
| 389 | | bool couldBeInt = true; |
|---|
| 390 | | bool couldBeFloat = true; |
|---|
| 391 | | int noZeroToNine = 0; |
|---|
| 392 | | |
|---|
| | 21 | |
|---|
| | 22 | double osg_atof(const char* str) |
|---|
| | 23 | { |
|---|
| | 42 | if (*ptr>='0' && *ptr<='9') value = value*16.0 + double(*ptr-'0'); |
|---|
| | 43 | else if (*ptr>='a' && *ptr<='f') value = value*16.0 + double(*ptr-'a'+10); |
|---|
| | 44 | else if (*ptr>='A' && *ptr<='F') value = value*16.0 + double(*ptr-'A'+10); |
|---|
| | 45 | ++ptr; |
|---|
| | 46 | } |
|---|
| | 47 | |
|---|
| | 48 | // osg::notify(osg::NOTICE)<<"Read "<<str<<" result = "<<value<<std::endl; |
|---|
| | 49 | return value; |
|---|
| | 50 | } |
|---|
| | 51 | |
|---|
| | 52 | ptr = str; |
|---|
| | 53 | |
|---|
| | 54 | bool hadDecimal[2]; |
|---|
| | 55 | double value[2]; |
|---|
| | 56 | double sign[2]; |
|---|
| | 57 | double decimalMultiplier[2]; |
|---|
| | 58 | |
|---|
| | 59 | hadDecimal[0] = hadDecimal[1] = false; |
|---|
| | 60 | sign[0] = sign[1] = 1.0; |
|---|
| | 61 | value[0] = value[1] = 0.0; |
|---|
| | 62 | decimalMultiplier[0] = decimalMultiplier[1] = 0.1; |
|---|
| | 63 | int pos = 0; |
|---|
| | 64 | |
|---|
| | 65 | // compute mantissa and exponent parts |
|---|
| | 66 | while (*ptr!=0 && pos<2) |
|---|
| | 67 | { |
|---|
| | 68 | if (*ptr=='+') |
|---|
| | 69 | { |
|---|
| | 70 | sign[pos] = 1.0; |
|---|
| | 71 | } |
|---|
| | 72 | else if (*ptr=='-') |
|---|
| | 73 | { |
|---|
| | 74 | sign[pos] = -1.0; |
|---|
| | 75 | } |
|---|
| | 76 | else if (*ptr>='0' && *ptr<='9') |
|---|
| | 77 | { |
|---|
| | 78 | if (!hadDecimal[pos]) |
|---|
| | 79 | { |
|---|
| | 80 | value[pos] = value[pos]*10.0 + double(*ptr-'0'); |
|---|
| | 81 | } |
|---|
| | 82 | else |
|---|
| | 83 | { |
|---|
| | 84 | value[pos] = value[pos] + decimalMultiplier[pos] * double(*ptr-'0'); |
|---|
| | 85 | decimalMultiplier[pos] *= 0.1; |
|---|
| | 86 | } |
|---|
| | 87 | } |
|---|
| | 88 | else if (*ptr=='.') |
|---|
| | 89 | { |
|---|
| | 90 | hadDecimal[pos] = true; |
|---|
| | 91 | } |
|---|
| | 92 | else if (*ptr=='e' || *ptr=='E') |
|---|
| | 93 | { |
|---|
| | 94 | if (pos==1) break; |
|---|
| | 95 | |
|---|
| | 96 | pos = 1; |
|---|
| | 97 | } |
|---|
| | 98 | else |
|---|
| | 99 | { |
|---|
| | 100 | break; |
|---|
| | 101 | } |
|---|
| | 102 | ++ptr; |
|---|
| | 103 | } |
|---|
| | 104 | |
|---|
| | 105 | if (pos==0) |
|---|
| | 106 | { |
|---|
| | 107 | // osg::notify(osg::NOTICE)<<"Read "<<str<<" result = "<<value[0]*sign[0]<<std::endl; |
|---|
| | 108 | return value[0]*sign[0]; |
|---|
| | 109 | } |
|---|
| | 110 | else |
|---|
| | 111 | { |
|---|
| | 112 | double mantissa = value[0]*sign[0]; |
|---|
| | 113 | double exponent = value[1]*sign[1]; |
|---|
| | 114 | //osg::notify(osg::NOTICE)<<"Read "<<str<<" mantissa = "<<mantissa<<" exponent="<<exponent<<" result = "<<mantissa*pow(10.0,exponent)<<std::endl; |
|---|
| | 115 | return mantissa*pow(10.0,exponent); |
|---|
| | 116 | } |
|---|
| | 117 | } |
|---|
| | 118 | |
|---|
| | 119 | Field::Field() |
|---|
| | 120 | { |
|---|
| | 121 | _init(); |
|---|
| | 122 | } |
|---|
| | 123 | |
|---|
| | 124 | |
|---|
| | 125 | Field::Field(const Field& ic) |
|---|
| | 126 | { |
|---|
| | 127 | _copy(ic); |
|---|
| | 128 | } |
|---|
| | 129 | |
|---|
| | 130 | |
|---|
| | 131 | Field::~Field() |
|---|
| | 132 | { |
|---|
| | 133 | _free(); |
|---|
| | 134 | } |
|---|
| | 135 | |
|---|
| | 136 | |
|---|
| | 137 | Field& Field::operator = (const Field& ic) |
|---|
| | 138 | { |
|---|
| | 139 | if (this==&ic) return *this; |
|---|
| | 140 | _free(); |
|---|
| | 141 | _copy(ic); |
|---|
| | 142 | return *this; |
|---|
| | 143 | } |
|---|
| | 144 | |
|---|
| | 145 | |
|---|
| | 146 | void Field::_free() |
|---|
| | 147 | { |
|---|
| | 148 | // free all data |
|---|
| | 149 | if (_fieldCache) delete [] _fieldCache; |
|---|
| | 150 | |
|---|
| | 151 | _init(); |
|---|
| | 152 | |
|---|
| | 153 | } |
|---|
| | 154 | |
|---|
| | 155 | |
|---|
| | 156 | void Field::_init() |
|---|
| | 157 | { |
|---|
| | 158 | |
|---|
| | 159 | _fieldCacheCapacity = 256; |
|---|
| | 160 | _fieldCacheSize = 0; |
|---|
| | 161 | _fieldCache = NULL; |
|---|
| | 162 | |
|---|
| | 163 | _fieldType = UNINITIALISED; |
|---|
| | 164 | |
|---|
| | 165 | _withinQuotes = false; |
|---|
| | 166 | |
|---|
| | 167 | _noNestedBrackets = 0; |
|---|
| | 168 | |
|---|
| | 169 | } |
|---|
| | 170 | |
|---|
| | 171 | |
|---|
| | 172 | void Field::_copy(const Field& ic) |
|---|
| | 173 | { |
|---|
| | 174 | |
|---|
| | 175 | // copy string cache. |
|---|
| | 176 | if (ic._fieldCache) |
|---|
| | 177 | { |
|---|
| | 178 | _fieldCacheCapacity = ic._fieldCacheCapacity; |
|---|
| | 179 | _fieldCacheSize = ic._fieldCacheSize; |
|---|
| | 180 | _fieldCache = new char [_fieldCacheCapacity]; |
|---|
| | 181 | strncpy(_fieldCache,ic._fieldCache,_fieldCacheCapacity); |
|---|
| | 182 | } |
|---|
| | 183 | else |
|---|
| | 184 | { |
|---|
| | 185 | _fieldCacheCapacity = 0; |
|---|
| | 186 | _fieldCacheSize = 0; |
|---|
| | 187 | _fieldCache = NULL; |
|---|
| | 188 | } |
|---|
| | 189 | |
|---|
| | 190 | _fieldType = ic._fieldType; |
|---|
| | 191 | |
|---|
| | 192 | _withinQuotes = ic._withinQuotes; |
|---|
| | 193 | |
|---|
| | 194 | _noNestedBrackets = ic._noNestedBrackets; |
|---|
| | 195 | } |
|---|
| | 196 | |
|---|
| | 197 | |
|---|
| | 198 | void Field::setWithinQuotes(bool withinQuotes) |
|---|
| | 199 | { |
|---|
| | 200 | _withinQuotes=withinQuotes; |
|---|
| | 201 | _fieldType = UNINITIALISED; |
|---|
| | 202 | } |
|---|
| | 203 | |
|---|
| | 204 | |
|---|
| | 205 | bool Field::getWithinQuotes() |
|---|
| | 206 | { |
|---|
| | 207 | return _withinQuotes; |
|---|
| | 208 | } |
|---|
| | 209 | |
|---|
| | 210 | |
|---|
| | 211 | void Field::setNoNestedBrackets(int no) |
|---|
| | 212 | { |
|---|
| | 213 | _noNestedBrackets=no; |
|---|
| | 214 | } |
|---|
| | 215 | |
|---|
| | 216 | |
|---|
| | 217 | int Field::getNoNestedBrackets() |
|---|
| | 218 | { |
|---|
| | 219 | return _noNestedBrackets; |
|---|
| | 220 | } |
|---|
| | 221 | |
|---|
| | 222 | |
|---|
| | 223 | const char* Field::getStr() const |
|---|
| | 224 | { |
|---|
| | 225 | if (_fieldCacheSize!=0) return _fieldCache; |
|---|
| | 226 | else return NULL; |
|---|
| | 227 | } |
|---|
| | 228 | |
|---|
| | 229 | |
|---|
| | 230 | char* Field::takeStr() |
|---|
| | 231 | { |
|---|
| | 232 | char* field = _fieldCache; |
|---|
| | 233 | |
|---|
| | 234 | _fieldCache = NULL; |
|---|
| | 235 | _fieldCacheSize = 0; |
|---|
| | 236 | |
|---|
| | 237 | _fieldType = UNINITIALISED; |
|---|
| | 238 | _withinQuotes = false; |
|---|
| | 239 | |
|---|
| | 240 | return field; |
|---|
| | 241 | } |
|---|
| | 242 | |
|---|
| | 243 | |
|---|
| | 244 | void Field::reset() |
|---|
| | 245 | { |
|---|
| | 246 | _fieldCacheSize = 0; |
|---|
| | 247 | if (_fieldCache) |
|---|
| | 248 | { |
|---|
| | 249 | _fieldCache[_fieldCacheSize] = 0; |
|---|
| | 250 | } |
|---|
| | 251 | |
|---|
| | 252 | _withinQuotes = false; |
|---|
| | 253 | _noNestedBrackets = 0; |
|---|
| | 254 | } |
|---|
| | 255 | |
|---|
| | 256 | |
|---|
| | 257 | void Field::addChar(char c) |
|---|
| | 258 | { |
|---|
| | 259 | if (_fieldCache==NULL) |
|---|
| | 260 | { |
|---|
| | 261 | if (_fieldCacheCapacity<MIN_CACHE_SIZE) _fieldCacheCapacity=MIN_CACHE_SIZE; |
|---|
| | 262 | _fieldCache = new char[_fieldCacheCapacity]; |
|---|
| | 263 | memset(_fieldCache,0,_fieldCacheCapacity); |
|---|
| | 264 | _fieldCacheSize = 0; |
|---|
| | 265 | } |
|---|
| | 266 | else if (_fieldCacheSize>=_fieldCacheCapacity-1) |
|---|
| | 267 | { |
|---|
| | 268 | if (_fieldCacheCapacity<MIN_CACHE_SIZE) _fieldCacheCapacity=MIN_CACHE_SIZE; |
|---|
| | 269 | while (_fieldCacheSize>=_fieldCacheCapacity-1) _fieldCacheCapacity *= 2; |
|---|
| | 270 | char* tmp_str = _fieldCache; |
|---|
| | 271 | _fieldCache = new char[_fieldCacheCapacity]; |
|---|
| | 272 | memset(_fieldCache,0,_fieldCacheCapacity); |
|---|
| | 273 | strncpy(_fieldCache,tmp_str,_fieldCacheSize); |
|---|
| | 274 | delete [] tmp_str; |
|---|
| | 275 | |
|---|
| | 276 | } |
|---|
| | 277 | _fieldCache[_fieldCacheSize++] = c; |
|---|
| | 278 | _fieldCache[_fieldCacheSize] = 0; |
|---|
| | 279 | _fieldType = UNINITIALISED; |
|---|
| | 280 | } |
|---|
| | 281 | |
|---|
| | 282 | |
|---|
| | 283 | Field::FieldType Field::getFieldType() const |
|---|
| | 284 | { |
|---|
| | 285 | if (_fieldType==UNINITIALISED && _fieldCache) |
|---|
| | 286 | { |
|---|
| | 287 | _fieldType = calculateFieldType(_fieldCache,_withinQuotes); |
|---|
| | 288 | } |
|---|
| | 289 | return _fieldType; |
|---|
| | 290 | } |
|---|
| | 291 | |
|---|
| | 292 | |
|---|
| | 293 | bool Field::isValid() const |
|---|
| | 294 | { |
|---|
| | 295 | if (_fieldCacheSize>0 && !_withinQuotes) return true; |
|---|
| | 296 | else return false; |
|---|
| | 297 | } |
|---|
| | 298 | |
|---|
| | 299 | |
|---|
| | 300 | bool Field::isOpenBracket() const |
|---|
| | 301 | { |
|---|
| | 302 | if (_fieldCacheSize==1) return _fieldCache[0]=='{'; |
|---|
| | 303 | else return false; |
|---|
| | 304 | } |
|---|
| | 305 | |
|---|
| | 306 | |
|---|
| | 307 | bool Field::isCloseBracket() const |
|---|
| | 308 | { |
|---|
| | 309 | if (_fieldCacheSize==1) return _fieldCache[0]=='}'; |
|---|
| | 310 | else return false; |
|---|
| | 311 | } |
|---|
| | 312 | |
|---|
| | 313 | |
|---|
| | 314 | bool Field::isWord() const |
|---|
| | 315 | { |
|---|
| | 316 | getFieldType(); |
|---|
| | 317 | return (_fieldType==WORD); |
|---|
| | 318 | } |
|---|
| | 319 | |
|---|
| | 320 | |
|---|
| | 321 | bool Field::matchWord(const char* str) const |
|---|
| | 322 | { |
|---|
| | 323 | getFieldType(); |
|---|
| | 324 | return _fieldType==WORD && strcmp(_fieldCache,str)==0; |
|---|
| | 325 | } |
|---|
| | 326 | |
|---|
| | 327 | |
|---|
| | 328 | bool Field::matchWord(const char* str,int noCharacters) const |
|---|
| | 329 | { |
|---|
| | 330 | getFieldType(); |
|---|
| | 331 | return _fieldType==WORD && strncmp(_fieldCache,str,noCharacters)==0; |
|---|
| | 332 | } |
|---|
| | 333 | |
|---|
| | 334 | |
|---|
| | 335 | bool Field::isString() const |
|---|
| | 336 | { |
|---|
| | 337 | return getNoCharacters()!=0; |
|---|
| | 338 | } |
|---|
| | 339 | |
|---|
| | 340 | |
|---|
| | 341 | bool Field::matchString(const char* str) const |
|---|
| | 342 | { |
|---|
| | 343 | return strcmp(_fieldCache,str)==0; |
|---|
| | 344 | } |
|---|
| | 345 | |
|---|
| | 346 | |
|---|
| | 347 | bool Field::matchString(const char* str,int noCharacters) const |
|---|
| | 348 | { |
|---|
| | 349 | return strncmp(_fieldCache,str,noCharacters)==0; |
|---|
| | 350 | } |
|---|
| | 351 | |
|---|
| | 352 | |
|---|
| | 353 | bool Field::isQuotedString() const |
|---|
| | 354 | { |
|---|
| | 355 | return _withinQuotes; |
|---|
| | 356 | } |
|---|
| | 357 | |
|---|
| | 358 | |
|---|
| | 359 | bool Field::isInt() const |
|---|
| | 360 | { |
|---|
| | 361 | getFieldType(); |
|---|
| | 362 | return _fieldType==INTEGER; |
|---|
| | 363 | } |
|---|
| | 364 | |
|---|
| | 365 | |
|---|
| | 366 | bool Field::matchInt(int i) const |
|---|
| | 367 | { |
|---|
| | 368 | getFieldType(); |
|---|
| | 369 | if (_fieldType==INTEGER) |
|---|
| | 370 | { |
|---|
| | 371 | return strtol(_fieldCache,NULL,0)==i; |
|---|
| | 372 | } |
|---|
| | 373 | else |
|---|
| | 374 | { |
|---|
| | 375 | return false; |
|---|
| | 376 | } |
|---|
| | 377 | } |
|---|
| | 378 | |
|---|
| | 379 | |
|---|
| | 380 | bool Field::getInt(int& i) const |
|---|
| | 381 | { |
|---|
| | 382 | getFieldType(); |
|---|
| | 383 | if (_fieldType==INTEGER) |
|---|
| | 384 | { |
|---|
| | 385 | i = strtol(_fieldCache,NULL,0); |
|---|
| | 386 | return true; |
|---|
| | 387 | } |
|---|
| | 388 | else |
|---|
| | 389 | { |
|---|
| | 390 | return false; |
|---|
| | 391 | } |
|---|
| | 392 | } |
|---|
| | 393 | |
|---|
| | 394 | bool Field::isUInt() const |
|---|
| | 395 | { |
|---|
| | 396 | getFieldType(); |
|---|
| | 397 | return _fieldType==INTEGER; |
|---|
| | 398 | } |
|---|
| | 399 | |
|---|
| | 400 | |
|---|
| | 401 | bool Field::matchUInt(unsigned int i) const |
|---|
| | 402 | { |
|---|
| | 403 | getFieldType(); |
|---|
| | 404 | if (_fieldType==INTEGER) |
|---|
| | 405 | { |
|---|
| | 406 | return (unsigned int) strtoul(_fieldCache,NULL,0)==i; |
|---|
| | 407 | } |
|---|
| | 408 | else |
|---|
| | 409 | { |
|---|
| | 410 | return false; |
|---|
| | 411 | } |
|---|
| | 412 | } |
|---|
| | 413 | |
|---|
| | 414 | |
|---|
| | 415 | bool Field::getUInt(unsigned int& i) const |
|---|
| | 416 | { |
|---|
| | 417 | getFieldType(); |
|---|
| | 418 | if (_fieldType==INTEGER) |
|---|
| | 419 | { |
|---|
| | 420 | i = strtoul(_fieldCache,NULL,0); |
|---|
| | 421 | return true; |
|---|
| | 422 | } |
|---|
| | 423 | else |
|---|
| | 424 | { |
|---|
| | 425 | return false; |
|---|
| | 426 | } |
|---|
| | 427 | } |
|---|
| | 428 | |
|---|
| | 429 | bool Field::isFloat() const |
|---|
| | 430 | { |
|---|
| | 431 | getFieldType(); |
|---|
| | 432 | return _fieldType==REAL || _fieldType==INTEGER; |
|---|
| | 433 | } |
|---|
| | 434 | |
|---|
| | 435 | |
|---|
| | 436 | bool Field::matchFloat(float f) const |
|---|
| | 437 | { |
|---|
| | 438 | getFieldType(); |
|---|
| | 439 | if (_fieldType==REAL || _fieldType==INTEGER) |
|---|
| | 440 | { |
|---|
| | 441 | return (float)osg_atof(_fieldCache)==f; |
|---|
| | 442 | } |
|---|
| | 443 | else |
|---|
| | 444 | { |
|---|
| | 445 | return false; |
|---|
| | 446 | } |
|---|
| | 447 | } |
|---|
| | 448 | |
|---|
| | 449 | |
|---|
| | 450 | bool Field::getFloat(float& f) const |
|---|
| | 451 | { |
|---|
| | 452 | getFieldType(); |
|---|
| | 453 | if (_fieldType==REAL || _fieldType==INTEGER) |
|---|
| | 454 | { |
|---|
| | 455 | f = (float)osg_atof(_fieldCache); |
|---|
| | 456 | return true; |
|---|
| | 457 | } |
|---|
| | 458 | else |
|---|
| | 459 | { |
|---|
| | 460 | return false; |
|---|
| | 461 | } |
|---|
| | 462 | } |
|---|
| | 463 | |
|---|
| | 464 | bool Field::getFloat(double& f) const |
|---|
| | 465 | { |
|---|
| | 466 | getFieldType(); |
|---|
| | 467 | if (_fieldType==REAL || _fieldType==INTEGER) |
|---|
| | 468 | { |
|---|
| | 469 | f = osg_atof(_fieldCache); |
|---|
| | 470 | return true; |
|---|
| | 471 | } |
|---|
| | 472 | else |
|---|
| | 473 | { |
|---|
| | 474 | return false; |
|---|
| | 475 | } |
|---|
| | 476 | } |
|---|
| | 477 | |
|---|
| | 478 | |
|---|
| | 479 | Field::FieldType Field::calculateFieldType(const char* str,bool withinQuotes) |
|---|
| | 480 | { |
|---|
| | 481 | if (str==NULL) return BLANK; |
|---|
| | 482 | if (*str==0) return BLANK; |
|---|
| | 483 | |
|---|
| | 484 | if (withinQuotes) return STRING; |
|---|
| | 485 | |
|---|
| | 486 | bool hadPlusMinus = false; |
|---|
| | 487 | bool hadDecimalPlace = false; |
|---|
| | 488 | bool hadExponent = false; |
|---|
| | 489 | bool couldBeInt = true; |
|---|
| | 490 | bool couldBeFloat = true; |
|---|
| | 491 | int noZeroToNine = 0; |
|---|
| | 492 | |
|---|
| | 493 | const char* ptr = str; |
|---|
| | 494 | |
|---|
| | 495 | // check if could be a hex number. |
|---|
| | 496 | if (strncmp(ptr,"0x",2)==0) |
|---|
| | 497 | { |
|---|
| | 498 | // skip over leading 0x, and then go through rest of string |
|---|
| | 499 | // checking to make sure all values are 0...9 or a..f. |
|---|
| | 500 | ptr+=2; |
|---|
| | 501 | while ( |
|---|
| | 502 | *ptr!=0 && |
|---|
| | 503 | ((*ptr>='0' && *ptr<='9') || |
|---|
| | 504 | (*ptr>='a' && *ptr<='f') || |
|---|
| | 505 | (*ptr>='A' && *ptr<='F')) |
|---|
| | 506 | ) |
|---|
| | 507 | { |
|---|