diff --git a/code/OpenGEXParser.cpp b/code/OpenGEXParser.cpp index 19fdcb990..efb1ff7b0 100644 --- a/code/OpenGEXParser.cpp +++ b/code/OpenGEXParser.cpp @@ -55,8 +55,7 @@ static const std::string Metric = "Metric"; static const std::string GeometryNode = "GeometryNode"; static const std::string GeometryObject = "GeometryObject"; static const std::string Material = "Material"; -static const size_t NumObjects = 4; - +static const size_t NumObjects = 4; static const std::string RootNodes[ NumObjects ] = { Metric, GeometryNode, @@ -64,9 +63,31 @@ static const std::string RootNodes[ NumObjects ] = { Material }; -static bool containsNode( const char *bufferPtr, size_t size, const std::string *nodes, size_t numNodes, - const std::string *tokenFound ) { - tokenFound = NULL; +static const size_t NumSeparator = 4; +static const std::string Separator[ NumSeparator ] = { + "(", ")", "{", "}" +}; + + +static const size_t NumToken = 8; +static const std::string Token[ NumToken ] = { + RootNodes[ 0 ], + RootNodes[ 1 ], + RootNodes[ 2 ], + RootNodes[ 3 ], + Separator[ 0 ], + Separator[ 1 ], + Separator[ 2 ], + Separator[ 3 ] +}; + +static bool isSeparator( char in ) { + return ( in == '(' || in == ')' || in == '{' || in == '}' ); +} + +static bool containsNode( const char *bufferPtr, size_t size, const std::string *nodes, + size_t numNodes, std::string &tokenFound ) { + tokenFound = ""; if( 0 == numNodes ) { return false; } @@ -74,7 +95,7 @@ static bool containsNode( const char *bufferPtr, size_t size, const std::string bool found( false ); for( size_t i = 0; i < numNodes; ++i ) { if( TokenMatch( bufferPtr, nodes[ i ].c_str(), nodes[ i ].size() ) ) { - tokenFound = &nodes[ i ]; + tokenFound = nodes[ i ]; found = true; break; } @@ -83,12 +104,27 @@ static bool containsNode( const char *bufferPtr, size_t size, const std::string return found; } +static OpenGEXParser::TokenType getTokenTypeByName( const char *in ) { + ai_assert( NULL != in ); + + OpenGEXParser::TokenType type( OpenGEXParser::None ); + for( size_t i = 0; i < NumToken; ++i ) { + if( TokenMatch( in, Token[ i ].c_str(), Token[ i ].size() ) ) { + type = static_cast( i+1 ); + break; + } + } + + return type; +} + //------------------------------------------------------------------------------------------------ OpenGEXParser::OpenGEXParser( const std::vector &buffer ) : m_buffer( buffer ) , m_index( 0 ) -, m_buffersize( buffer.size() ) { - +, m_buffersize( buffer.size() ) +, m_nodeTypeStack() { + // empty } //------------------------------------------------------------------------------------------------ @@ -107,10 +143,10 @@ void OpenGEXParser::parse() { std::string OpenGEXParser::getNextToken() { std::string token; while( m_index < m_buffersize && IsSpace( m_buffer[ m_index ] ) ) { - ++m_index; + m_index++; } - while( m_index < m_buffersize && !IsSpace( m_buffer[ m_index ] ) ) { + while( m_index < m_buffersize && !IsSpace( m_buffer[ m_index ] ) && !isSeparator( m_buffer[ m_index ] ) ) { token += m_buffer[ m_index ]; m_index++; } @@ -120,6 +156,13 @@ std::string OpenGEXParser::getNextToken() { token = getNextToken(); } + if( token.empty() ) { + if( isSeparator( m_buffer[ m_index ] ) ) { + token += m_buffer[ m_index ]; + m_index++; + } + } + return token; } @@ -140,7 +183,8 @@ bool OpenGEXParser::skipComments() { bool OpenGEXParser::parseNextNode() { std::string token( getNextToken() ); std::string rootNodeName; - if( containsNode( token.c_str(), token.size(), RootNodes, NumObjects, &rootNodeName ) ) { + if( containsNode( token.c_str(), token.size(), RootNodes, NumObjects, rootNodeName ) ) { + m_nodeTypeStack.push_back( getTokenTypeByName( rootNodeName.c_str() ) ); if( !getNodeHeader( rootNodeName ) ) { return false; } @@ -148,6 +192,8 @@ bool OpenGEXParser::parseNextNode() { if( !getNodeData() ) { return false; } + + m_nodeTypeStack.pop_back(); } return true; @@ -155,12 +201,15 @@ bool OpenGEXParser::parseNextNode() { //------------------------------------------------------------------------------------------------ bool OpenGEXParser::getNodeHeader( const std::string &name ) { - if( name == Metric ) { - std::string token( getNextToken() ); - + bool success( false ); + if( m_nodeTypeStack.back() == MetricNode ) { + std::string attribName, value; + if( getMetricAttributeKey( attribName, value ) ) { + success = true; + } } - return false; + return success; } //------------------------------------------------------------------------------------------------ @@ -226,33 +275,31 @@ bool OpenGEXParser::getFloatData( size_t num, float *data ) { //------------------------------------------------------------------------------------------------ bool OpenGEXParser::getNodeData() { - if( !getBracketOpen() ) { - return false; - } - - if( !onMetricNode() ) { - return false; - } - - if( !getBracketClose() ) { - return false; - } - return true; } //------------------------------------------------------------------------------------------------ -bool OpenGEXParser::getMetricAttribute( std::string &attribName ) { - return false; +bool OpenGEXParser::getMetricAttributeKey( std::string &attribName, std::string &value ) { + bool ok( false ); + attribName = ""; + std::string token( getNextToken() ); + if( token[ 0 ] == '(' ) { + // get attribute + attribName = getNextToken(); + std::string equal = getNextToken(); + value = getNextToken(); + + token = getNextToken(); + if( token[ 0 ] == ')' ) { + ok = true; + } + } + + return ok; } //------------------------------------------------------------------------------------------------ -bool OpenGEXParser::onMetricNode() { - std::string attribName; - if( !getMetricAttribute( attribName ) ) { - return false; - } - +bool OpenGEXParser::onMetricNode( const std::string &attribName ) { if( "distance" == attribName ) { float distance( 0.0f ); getFloatData( 1, &distance ); diff --git a/code/OpenGEXParser.h b/code/OpenGEXParser.h index 0bdb7909a..1733366f7 100644 --- a/code/OpenGEXParser.h +++ b/code/OpenGEXParser.h @@ -47,6 +47,19 @@ namespace Assimp { namespace OpenGEX { class OpenGEXParser { +public: + enum TokenType { + None = 0, + MetricNode, + GeometryNode, + GeometryObject, + Material, + BracketIn, + BracketOut, + CurlyBracketIn, + CurlyBracketOut, + }; + public: OpenGEXParser( const std::vector &buffer ); ~OpenGEXParser(); @@ -62,8 +75,8 @@ protected: bool getStringData( std::string &data ); bool getFloatData( size_t num, float *data ); bool getNodeData(); - bool getMetricAttribute( std::string &attribName ); - bool onMetricNode(); + bool getMetricAttributeKey( std::string &attribName, std::string &value ); + bool onMetricNode( const std::string &attribName ); private: OpenGEXParser( const OpenGEXParser & ); @@ -71,6 +84,7 @@ private: private: const std::vector &m_buffer; + std::vector m_nodeTypeStack; size_t m_index; size_t m_buffersize; };