21686c27af
To make it compiel with future gcc's we sppear to need the attached missing includes ..."
341 lines
8.3 KiB
C++
341 lines
8.3 KiB
C++
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 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>
|
|
#include <osgDB/FieldReader>
|
|
#include <stdio.h>
|
|
|
|
using namespace osgDB;
|
|
|
|
FieldReader::FieldReader()
|
|
{
|
|
_init();
|
|
}
|
|
|
|
|
|
FieldReader::FieldReader(const FieldReader& ic)
|
|
{
|
|
_copy(ic);
|
|
}
|
|
|
|
|
|
FieldReader::~FieldReader()
|
|
{
|
|
_free();
|
|
}
|
|
|
|
|
|
FieldReader& FieldReader::operator = (const FieldReader& ic)
|
|
{
|
|
if (this==&ic) return *this;
|
|
_free();
|
|
_copy(ic);
|
|
return *this;
|
|
}
|
|
|
|
|
|
void FieldReader::_free()
|
|
{
|
|
// free all data
|
|
|
|
_init();
|
|
|
|
}
|
|
|
|
|
|
void FieldReader::_init()
|
|
{
|
|
_fin = NULL;
|
|
_eof = true;
|
|
|
|
_noNestedBrackets = 0;
|
|
|
|
int i;
|
|
for(i=0;i<256;++i) _delimiterEatLookUp[i]=false;
|
|
_delimiterEatLookUp[int(' ')] = true;
|
|
_delimiterEatLookUp[int('\t')] = true;
|
|
_delimiterEatLookUp[int('\n')] = true;
|
|
_delimiterEatLookUp[int('\r')] = true;
|
|
|
|
for(i=0;i<256;++i) _delimiterKeepLookUp[i]=false;
|
|
_delimiterKeepLookUp[int('{')] = true;
|
|
_delimiterKeepLookUp[int('}')] = true;
|
|
_delimiterKeepLookUp[int('"')] = true;
|
|
_delimiterKeepLookUp[int('\'')] = true;
|
|
|
|
}
|
|
|
|
|
|
void FieldReader::_copy(const FieldReader& ic)
|
|
{
|
|
|
|
_fin = ic._fin;
|
|
_eof = ic._eof;
|
|
|
|
_noNestedBrackets = ic._noNestedBrackets;
|
|
|
|
int i;
|
|
for(i=0;i<256;++i) _delimiterEatLookUp[i]=ic._delimiterEatLookUp[i];
|
|
for(i=0;i<256;++i) _delimiterKeepLookUp[i]=ic._delimiterKeepLookUp[i];
|
|
}
|
|
|
|
|
|
void FieldReader::attach(std::istream* input)
|
|
{
|
|
_fin = input;
|
|
|
|
if (_fin)
|
|
{
|
|
_eof = _fin->eof()!=0;
|
|
}
|
|
else
|
|
{
|
|
_eof = true;
|
|
}
|
|
}
|
|
|
|
|
|
void FieldReader::detach()
|
|
{
|
|
_fin = NULL;
|
|
_eof = true;
|
|
}
|
|
|
|
|
|
bool FieldReader::eof() const
|
|
{
|
|
return _eof;
|
|
}
|
|
|
|
|
|
bool FieldReader::findStartOfNextField()
|
|
{
|
|
int ch = 0;
|
|
while (true)
|
|
{
|
|
ch = _fin->peek();
|
|
if (ch==EOF)
|
|
{
|
|
_eof = true;
|
|
return false;
|
|
}
|
|
else if (_delimiterEatLookUp[ch])
|
|
{
|
|
_fin->ignore(1);
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
bool FieldReader::readField(Field& fieldPtr)
|
|
{
|
|
return _readField(&fieldPtr);
|
|
}
|
|
|
|
|
|
void FieldReader::ignoreField()
|
|
{
|
|
_readField(NULL);
|
|
}
|
|
|
|
|
|
bool FieldReader::_readField(Field* fieldPtr)
|
|
{
|
|
if (fieldPtr) fieldPtr->reset();
|
|
|
|
if (!eof() && findStartOfNextField())
|
|
{
|
|
|
|
int ch = _fin->peek();
|
|
if (ch==EOF)
|
|
{
|
|
_eof = true;
|
|
if (fieldPtr) fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
|
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
|
}
|
|
else if (ch=='"')
|
|
{
|
|
if (fieldPtr)
|
|
{
|
|
fieldPtr->setWithinQuotes(true);
|
|
fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
|
}
|
|
_fin->ignore(1);
|
|
char c;
|
|
bool escape = false; // use the escape character sequence \" to allow " to included in strings.
|
|
while (true)
|
|
{
|
|
ch = _fin->peek();
|
|
if (ch==EOF)
|
|
{
|
|
_eof = true;
|
|
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
|
}
|
|
c = ch;
|
|
if (ch=='\\')
|
|
{
|
|
if (escape)
|
|
{
|
|
escape = false;
|
|
_fin->get(c);
|
|
if (fieldPtr) fieldPtr->addChar(c);
|
|
}
|
|
else
|
|
{
|
|
escape = true;
|
|
_fin->ignore(1);
|
|
}
|
|
}
|
|
else if (ch=='"')
|
|
{
|
|
if (escape)
|
|
{
|
|
escape = false;
|
|
_fin->get(c);
|
|
if (fieldPtr) fieldPtr->addChar(c);
|
|
}
|
|
else
|
|
{
|
|
_fin->ignore(1);
|
|
//return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
|
return fieldPtr!=NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (escape)
|
|
{
|
|
escape = false;
|
|
if (fieldPtr) fieldPtr->addChar('\\');
|
|
}
|
|
_fin->get(c);
|
|
if (fieldPtr) fieldPtr->addChar(c);
|
|
}
|
|
}
|
|
}
|
|
else if (ch=='\'')
|
|
{
|
|
if (fieldPtr)
|
|
{
|
|
fieldPtr->setWithinQuotes(true);
|
|
fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
|
}
|
|
_fin->ignore(1);
|
|
char c;
|
|
bool escape = false; // use the escape character sequence \' to allow ' to included in strings.
|
|
while (true)
|
|
{
|
|
ch = _fin->peek();
|
|
if (ch==EOF)
|
|
{
|
|
_eof = true;
|
|
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
|
}
|
|
c = ch;
|
|
if (ch=='\\' && !escape)
|
|
{
|
|
if (escape)
|
|
{
|
|
escape = false;
|
|
_fin->get(c);
|
|
if (fieldPtr) fieldPtr->addChar(c);
|
|
}
|
|
else
|
|
{
|
|
escape = true;
|
|
_fin->ignore(1);
|
|
}
|
|
}
|
|
else if (ch=='\'')
|
|
{
|
|
if (escape)
|
|
{
|
|
escape = false;
|
|
_fin->get(c);
|
|
if (fieldPtr) fieldPtr->addChar(c);
|
|
}
|
|
else
|
|
{
|
|
_fin->ignore(1);
|
|
//return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
|
return fieldPtr!=NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (escape)
|
|
{
|
|
escape = false;
|
|
if (fieldPtr) fieldPtr->addChar('\\');
|
|
}
|
|
_fin->get(c);
|
|
if (fieldPtr) fieldPtr->addChar(c);
|
|
}
|
|
}
|
|
}
|
|
else if (_delimiterKeepLookUp[ch])
|
|
{
|
|
char c;
|
|
_fin->get(c);
|
|
if (fieldPtr) fieldPtr->addChar(c);
|
|
if (c=='{') ++_noNestedBrackets;
|
|
else if (c=='}') --_noNestedBrackets;
|
|
if (fieldPtr) fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
|
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
|
}
|
|
else
|
|
{
|
|
if (fieldPtr) fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
|
char c;
|
|
while (true)
|
|
{
|
|
ch = _fin->peek();
|
|
if (ch==EOF)
|
|
{
|
|
_eof = true;
|
|
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
|
}
|
|
c = ch;
|
|
if (_delimiterEatLookUp[int(c)])
|
|
{
|
|
_fin->ignore(1);
|
|
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
|
}
|
|
if (_delimiterKeepLookUp[int(c)])
|
|
{
|
|
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
|
}
|
|
else
|
|
{
|
|
_fin->get(c);
|
|
if (fieldPtr) fieldPtr->addChar(c);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
int FieldReader::getNoNestedBrackets() const
|
|
{
|
|
return _noNestedBrackets;
|
|
}
|