Files
OpenSceneGraph/src/osgDB/Field.cpp
Robert Osfield fced94fab3 Added support for decoration of the osgTerrain::DataSet generated databases
with a CoordinateSystemNode which reflect the coordinate system of the
database.

Added support for reading and writing CoordianteSystemNode into the .osg
and .ive formats.
2004-05-02 21:50:15 +00:00

473 lines
8.7 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <osgDB/Field>
using namespace osgDB;
using namespace std;
Field::Field()
{
_init();
}
Field::Field(const Field& ic)
{
_copy(ic);
}
Field::~Field()
{
_free();
}
Field& Field::operator = (const Field& ic)
{
if (this==&ic) return *this;
_free();
_copy(ic);
return *this;
}
void Field::_free()
{
// free all data
if (_fieldCache) delete [] _fieldCache;
_init();
}
void Field::_init()
{
_fieldCacheCapacity = 256;
_fieldCacheSize = 0;
_fieldCache = NULL;
_fieldType = UNINITIALISED;
_withinQuotes = false;
_noNestedBrackets = 0;
}
void Field::_copy(const Field& ic)
{
// copy string cache.
if (ic._fieldCache)
{
_fieldCacheCapacity = ic._fieldCacheCapacity;
_fieldCacheSize = ic._fieldCacheSize;
_fieldCache = new char [_fieldCacheCapacity];
strncpy(_fieldCache,ic._fieldCache,_fieldCacheCapacity);
}
else
{
_fieldCacheCapacity = 0;
_fieldCacheSize = 0;
_fieldCache = NULL;
}
_fieldType = ic._fieldType;
_withinQuotes = ic._withinQuotes;
_noNestedBrackets = ic._noNestedBrackets;
}
void Field::setWithinQuotes(bool withinQuotes)
{
_withinQuotes=withinQuotes;
_fieldType = UNINITIALISED;
}
bool Field::getWithinQuotes()
{
return _withinQuotes;
}
void Field::setNoNestedBrackets(int no)
{
_noNestedBrackets=no;
}
int Field::getNoNestedBrackets()
{
return _noNestedBrackets;
}
const char* Field::getStr() const
{
if (_fieldCacheSize!=0) return _fieldCache;
else return NULL;
}
char* Field::takeStr()
{
char* field = _fieldCache;
_fieldCache = NULL;
_fieldCacheSize = 0;
_fieldType = UNINITIALISED;
_withinQuotes = false;
return field;
}
void Field::reset()
{
_fieldCacheSize = 0;
if (_fieldCache)
{
_fieldCache[_fieldCacheSize] = 0;
}
_withinQuotes = false;
_noNestedBrackets = 0;
}
void Field::addChar(char c)
{
if (_fieldCache==NULL)
{
if (_fieldCacheCapacity<MIN_CACHE_SIZE) _fieldCacheCapacity=MIN_CACHE_SIZE;
_fieldCache = new char[_fieldCacheCapacity];
memset(_fieldCache,0,_fieldCacheCapacity);
_fieldCacheSize = 0;
}
else if (_fieldCacheSize>=_fieldCacheCapacity-1)
{
if (_fieldCacheCapacity<MIN_CACHE_SIZE) _fieldCacheCapacity=MIN_CACHE_SIZE;
while (_fieldCacheSize>=_fieldCacheCapacity-1) _fieldCacheCapacity *= 2;
char* tmp_str = _fieldCache;
_fieldCache = new char[_fieldCacheCapacity];
memset(_fieldCache,0,_fieldCacheCapacity);
strncpy(_fieldCache,tmp_str,_fieldCacheSize);
delete [] tmp_str;
}
_fieldCache[_fieldCacheSize++] = c;
_fieldCache[_fieldCacheSize] = 0;
_fieldType = UNINITIALISED;
}
Field::FieldType Field::getFieldType() const
{
if (_fieldType==UNINITIALISED && _fieldCache)
{
_fieldType = calculateFieldType(_fieldCache,_withinQuotes);
}
return _fieldType;
}
bool Field::isValid() const
{
if (_fieldCacheSize>0 && !_withinQuotes) return true;
else return false;
}
bool Field::isOpenBracket() const
{
if (_fieldCacheSize==1) return _fieldCache[0]=='{';
else return false;
}
bool Field::isCloseBracket() const
{
if (_fieldCacheSize==1) return _fieldCache[0]=='}';
else return false;
}
bool Field::isWord() const
{
getFieldType();
return (_fieldType==WORD);
}
bool Field::matchWord(const char* str) const
{
getFieldType();
return _fieldType==WORD && strcmp(_fieldCache,str)==0;
}
bool Field::matchWord(const char* str,int noCharacters) const
{
getFieldType();
return _fieldType==WORD && strncmp(_fieldCache,str,noCharacters)==0;
}
bool Field::isString() const
{
return getNoCharacters()!=0;
}
bool Field::matchString(const char* str) const
{
return strcmp(_fieldCache,str)==0;
}
bool Field::matchString(const char* str,int noCharacters) const
{
return strncmp(_fieldCache,str,noCharacters)==0;
}
bool Field::isQuotedString() const
{
return _withinQuotes;
}
bool Field::isInt() const
{
getFieldType();
return _fieldType==INTEGER;
}
bool Field::matchInt(int i) const
{
getFieldType();
if (_fieldType==INTEGER)
{
return strtol(_fieldCache,NULL,0)==i;
}
else
{
return false;
}
}
bool Field::getInt(int& i) const
{
getFieldType();
if (_fieldType==INTEGER)
{
i = strtol(_fieldCache,NULL,0);
return true;
}
else
{
return false;
}
}
bool Field::isUInt() const
{
getFieldType();
return _fieldType==INTEGER;
}
bool Field::matchUInt(unsigned int i) const
{
getFieldType();
if (_fieldType==INTEGER)
{
return (unsigned int) strtoul(_fieldCache,NULL,0)==i;
}
else
{
return false;
}
}
bool Field::getUInt(unsigned int& i) const
{
getFieldType();
if (_fieldType==INTEGER)
{
i = strtoul(_fieldCache,NULL,0);
return true;
}
else
{
return false;
}
}
bool Field::isFloat() const
{
getFieldType();
return _fieldType==REAL || _fieldType==INTEGER;
}
bool Field::matchFloat(float f) const
{
getFieldType();
if (_fieldType==REAL || _fieldType==INTEGER)
{
return (float)atof(_fieldCache)==f;
}
else
{
return false;
}
}
bool Field::getFloat(float& f) const
{
getFieldType();
if (_fieldType==REAL || _fieldType==INTEGER)
{
f = (float)atof(_fieldCache);
return true;
}
else
{
return false;
}
}
bool Field::getFloat(double& f) const
{
getFieldType();
if (_fieldType==REAL || _fieldType==INTEGER)
{
f = atof(_fieldCache);
return true;
}
else
{
return false;
}
}
Field::FieldType Field::calculateFieldType(const char* str,bool withinQuotes)
{
if (str==NULL) return BLANK;
if (*str==0) return BLANK;
if (withinQuotes) return STRING;
bool hadPlusMinus = false;
bool hadDecimalPlace = false;
bool hadExponent = false;
bool couldBeInt = true;
bool couldBeFloat = true;
int noZeroToNine = 0;
const char* ptr = str;
// check if could be a hex number.
if (strncmp(ptr,"0x",2)==0)
{
// skip over leading 0x, and then go through rest of string
// checking to make sure all values are 0...9 or a..f.
ptr+=2;
while (
*ptr!=0 &&
((*ptr>='0' && *ptr<='9') ||
(*ptr>='a' && *ptr<='f') ||
(*ptr>='A' && *ptr<='F'))
)
{
++ptr;
}
// got to end of string without failure, therefore must be a hex integer.
if (*ptr==0) return INTEGER;
}
ptr = str;
// check if a float or an int.
while (*ptr!=0 && couldBeFloat)
{
if (*ptr=='+' || *ptr=='-')
{
if (hadPlusMinus)
{
couldBeInt = false;
couldBeFloat = false;
} else hadPlusMinus = true;
}
else if (*ptr>='0' && *ptr<='9')
{
noZeroToNine++;
}
else if (*ptr=='.')
{
if (hadDecimalPlace)
{
couldBeInt = false;
couldBeFloat = false;
}
else
{
hadDecimalPlace = true;
couldBeInt = false;
}
}
else if (*ptr=='e' || *ptr=='E')
{
if (hadExponent || noZeroToNine==0)
{
couldBeInt = false;
couldBeFloat = false;
}
else
{
hadExponent = true;
couldBeInt = false;
hadDecimalPlace = false;
hadPlusMinus = false;
noZeroToNine=0;
}
}
else
{
couldBeInt = false;
couldBeFloat = false;
}
++ptr;
}
if (couldBeInt && noZeroToNine>0) return INTEGER;
if (couldBeFloat && noZeroToNine>0) return REAL;
if (str[0]=='{') return OPEN_BRACKET;
if (str[0]=='}') return CLOSE_BRACKET;
return WORD;
}