Changeset 8630

Show
Ignore:
Timestamp:
07/18/08 13:39:06
Author:
robert
Message:

Introduce a custom atof function that always assumes data comes in form 10.10 with
the full stop used as a decimal place.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • OpenSceneGraph/trunk/src/osgDB/Field.cpp

    r7747 r8630  
    1212*/ 
    1313#include <string.h> 
     14#include <math.h> 
     15#include <osg/Notify> 
    1416#include <osgDB/Field> 
    1517 
     
    1719using namespace std; 
    1820 
    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 
     22double osg_atof(const char* str) 
     23
    39324    const char* ptr = str; 
    394      
     25 
    39526    // check if could be a hex number. 
    39627    if (strncmp(ptr,"0x",2)==0) 
    39728    { 
     29 
     30        double value = 0.0; 
     31 
    39832        // skip over leading 0x, and then go through rest of string 
    39933        // checking to make sure all values are 0...9 or a..f. 
     
    40640              ) 
    40741        { 
     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 
     119Field::Field() 
     120{ 
     121    _init(); 
     122} 
     123 
     124 
     125Field::Field(const Field& ic) 
     126{ 
     127    _copy(ic); 
     128} 
     129 
     130 
     131Field::~Field() 
     132{ 
     133    _free(); 
     134} 
     135 
     136 
     137Field& Field::operator = (const Field& ic) 
     138{ 
     139    if (this==&ic) return *this; 
     140    _free(); 
     141    _copy(ic); 
     142    return *this; 
     143} 
     144 
     145 
     146void Field::_free() 
     147{ 
     148    // free all data 
     149    if (_fieldCache) delete [] _fieldCache; 
     150 
     151    _init(); 
     152 
     153} 
     154 
     155 
     156void 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 
     172void 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 
     198void Field::setWithinQuotes(bool withinQuotes) 
     199{ 
     200    _withinQuotes=withinQuotes; 
     201    _fieldType = UNINITIALISED; 
     202} 
     203 
     204 
     205bool Field::getWithinQuotes() 
     206{ 
     207    return _withinQuotes; 
     208} 
     209 
     210 
     211void Field::setNoNestedBrackets(int no) 
     212{ 
     213    _noNestedBrackets=no; 
     214} 
     215 
     216 
     217int Field::getNoNestedBrackets() 
     218{ 
     219    return _noNestedBrackets; 
     220} 
     221 
     222 
     223const char* Field::getStr() const 
     224{ 
     225    if (_fieldCacheSize!=0) return _fieldCache; 
     226    else return NULL; 
     227} 
     228 
     229 
     230char* 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 
     244void 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 
     257void 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 
     283Field::FieldType Field::getFieldType() const 
     284{ 
     285    if (_fieldType==UNINITIALISED && _fieldCache) 
     286    { 
     287        _fieldType = calculateFieldType(_fieldCache,_withinQuotes); 
     288    } 
     289    return _fieldType; 
     290} 
     291 
     292 
     293bool Field::isValid() const 
     294{ 
     295    if (_fieldCacheSize>0  && !_withinQuotes) return true; 
     296    else return false; 
     297} 
     298 
     299 
     300bool Field::isOpenBracket() const 
     301{ 
     302    if (_fieldCacheSize==1) return _fieldCache[0]=='{'; 
     303    else return false; 
     304} 
     305 
     306 
     307bool Field::isCloseBracket() const 
     308{ 
     309    if (_fieldCacheSize==1) return _fieldCache[0]=='}'; 
     310    else return false; 
     311} 
     312 
     313 
     314bool Field::isWord() const 
     315{ 
     316    getFieldType(); 
     317    return (_fieldType==WORD); 
     318} 
     319 
     320 
     321bool Field::matchWord(const char* str) const 
     322{ 
     323    getFieldType(); 
     324    return _fieldType==WORD && strcmp(_fieldCache,str)==0; 
     325} 
     326 
     327 
     328bool Field::matchWord(const char* str,int noCharacters) const 
     329{ 
     330    getFieldType(); 
     331    return _fieldType==WORD && strncmp(_fieldCache,str,noCharacters)==0; 
     332} 
     333 
     334 
     335bool Field::isString() const 
     336{ 
     337    return getNoCharacters()!=0; 
     338} 
     339 
     340 
     341bool Field::matchString(const char* str) const 
     342{ 
     343    return strcmp(_fieldCache,str)==0; 
     344} 
     345 
     346 
     347bool Field::matchString(const char* str,int noCharacters) const 
     348{ 
     349    return strncmp(_fieldCache,str,noCharacters)==0; 
     350} 
     351 
     352 
     353bool Field::isQuotedString() const 
     354{ 
     355    return _withinQuotes; 
     356} 
     357 
     358 
     359bool Field::isInt() const 
     360{ 
     361    getFieldType(); 
     362    return _fieldType==INTEGER; 
     363} 
     364 
     365 
     366bool 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 
     380bool 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 
     394bool Field::isUInt() const 
     395{ 
     396    getFieldType(); 
     397    return _fieldType==INTEGER; 
     398} 
     399 
     400 
     401bool 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 
     415bool 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 
     429bool Field::isFloat() const 
     430{ 
     431    getFieldType(); 
     432    return _fieldType==REAL || _fieldType==INTEGER; 
     433} 
     434 
     435 
     436bool 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 
     450bool 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 
     464bool 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 
     479Field::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        { 
    408508            ++ptr; 
    409509        }