| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000 |
- /*-----------------------------------------------------------------------------------------------
- The MIT License (MIT)
- Copyright (c) 2014-2015 Kim Kulling
- Permission is hereby granted, free of charge, to any person obtaining a copy of
- this software and associated documentation files (the "Software"), to deal in
- the Software without restriction, including without limitation the rights to
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- the Software, and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- -----------------------------------------------------------------------------------------------*/
- #include <openddlparser/OpenDDLParser.h>
- #include <openddlparser/OpenDDLExport.h>
- #include <cassert>
- #include <iostream>
- #include <sstream>
- #include <algorithm>
- #include <math.h>
- #ifdef _WIN32
- # include <windows.h>
- #endif // _WIN32
- BEGIN_ODDLPARSER_NS
- static const char *Version = "0.3.0";
- namespace Grammar {
- static const char *OpenBracketToken = "{";
- static const char *CloseBracketToken = "}";
- static const char *OpenPropertyToken = "(";
- static const char *ClosePropertyToken = ")";
- static const char *OpenArrayToken = "[";
- static const char *CloseArrayToken = "]";
- static const char *BoolTrue = "true";
- static const char *BoolFalse = "false";
- static const char *CommaSeparator = ",";
- static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = {
- "bool",
- "int8",
- "int16",
- "int32",
- "int64",
- "unsigned_int8",
- "unsigned_int16",
- "unsigned_int32",
- "unsigned_int64",
- "half",
- "float",
- "double",
- "string",
- "ref"
- };
- } // Namespace Grammar
- const char *getTypeToken( Value::ValueType type ) {
- return Grammar::PrimitiveTypeToken[ type ];
- }
- static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParser::logCallback callback ) {
- std::stringstream stream;
- stream << "Invalid token \"" << *in << "\"" << " expected \"" << exp << "\"" << std::endl;
- std::string full(in);
- std::string part(full.substr(0,50));
- stream << part;
- callback( ddl_error_msg, stream.str() );
- }
- static bool isIntegerType( Value::ValueType integerType ) {
- if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 &&
- integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) {
- return false;
- }
- return true;
- }
- static bool isUnsignedIntegerType( Value::ValueType integerType ) {
- if( integerType != Value::ddl_unsigned_int8 && integerType != Value::ddl_unsigned_int16 &&
- integerType != Value::ddl_unsigned_int32 && integerType != Value::ddl_unsigned_int64 ) {
- return false;
- }
- return true;
- }
- static DDLNode *createDDLNode( Text *id, OpenDDLParser *parser ) {
- if( ddl_nullptr == id || ddl_nullptr == parser ) {
- return ddl_nullptr;
- }
- const std::string type( id->m_buffer );
- DDLNode *parent( parser->top() );
- DDLNode *node = DDLNode::create( type, "", parent );
- return node;
- }
- static void logMessage( LogSeverity severity, const std::string &msg ) {
- std::string log;
- if( ddl_debug_msg == severity ) {
- log += "Debug:";
- } else if( ddl_info_msg == severity ) {
- log += "Info :";
- } else if( ddl_warn_msg == severity ) {
- log += "Warn :";
- } else if( ddl_error_msg == severity ) {
- log += "Error:";
- } else {
- log += "None :";
- }
- log += msg;
- std::cout << log;
- }
- OpenDDLParser::OpenDDLParser()
- : m_logCallback( logMessage )
- , m_buffer()
- , m_stack()
- , m_context( ddl_nullptr ) {
- // empty
- }
- OpenDDLParser::OpenDDLParser( const char *buffer, size_t len )
- : m_logCallback( &logMessage )
- , m_buffer()
- , m_context( ddl_nullptr ) {
- if( 0 != len ) {
- setBuffer( buffer, len );
- }
- }
- OpenDDLParser::~OpenDDLParser() {
- clear();
- }
- void OpenDDLParser::setLogCallback( logCallback callback ) {
- if( ddl_nullptr != callback ) {
- // install user-specific log callback
- m_logCallback = callback;
- } else {
- // install default log callback
- m_logCallback = &logMessage;
- }
- }
- OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const {
- return m_logCallback;
- }
- void OpenDDLParser::setBuffer( const char *buffer, size_t len ) {
- clear();
- if( 0 == len ) {
- return;
- }
- m_buffer.resize( len );
- ::memcpy(&m_buffer[ 0 ], buffer, len );
- }
- void OpenDDLParser::setBuffer( const std::vector<char> &buffer ) {
- clear();
- m_buffer.resize( buffer.size() );
- std::copy( buffer.begin(), buffer.end(), m_buffer.begin() );
- }
- const char *OpenDDLParser::getBuffer() const {
- if( m_buffer.empty() ) {
- return ddl_nullptr;
- }
- return &m_buffer[ 0 ];
- }
- size_t OpenDDLParser::getBufferSize() const {
- return m_buffer.size();
- }
- void OpenDDLParser::clear() {
- m_buffer.resize( 0 );
- if( ddl_nullptr != m_context ) {
- m_context->m_root = ddl_nullptr;
- }
- DDLNode::releaseNodes();
- }
- bool OpenDDLParser::parse() {
- if( m_buffer.empty() ) {
- return false;
- }
- normalizeBuffer( m_buffer );
- m_context = new Context;
- m_context->m_root = DDLNode::create( "root", "", ddl_nullptr );
- pushNode( m_context->m_root );
- // do the main parsing
- char *current( &m_buffer[ 0 ] );
- char *end( &m_buffer[ m_buffer.size() - 1 ] + 1 );
- size_t pos( current - &m_buffer[ 0 ] );
- while( pos < m_buffer.size() ) {
- current = parseNextNode( current, end );
- if(current==ddl_nullptr) {
- return false;
- }
- pos = current - &m_buffer[ 0 ];
- }
- return true;
- }
- bool OpenDDLParser::exportContext( Context *ctx, const std::string &filename ) {
- if( ddl_nullptr == ctx ) {
- return false;
- }
- OpenDDLExport myExporter;
- return myExporter.exportContext( ctx, filename );
- }
- char *OpenDDLParser::parseNextNode( char *in, char *end ) {
- in = parseHeader( in, end );
- in = parseStructure( in, end );
- return in;
- }
- #ifdef DEBUG_HEADER_NAME
- static void dumpId( Identifier *id ) {
- if( ddl_nullptr != id ) {
- if ( ddl_nullptr != id->m_text.m_buffer ) {
- std::cout << id->m_text.m_buffer << std::endl;
- }
- }
- }
- #endif
- char *OpenDDLParser::parseHeader( char *in, char *end ) {
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- Text *id( ddl_nullptr );
- in = OpenDDLParser::parseIdentifier( in, end, &id );
- #ifdef DEBUG_HEADER_NAME
- dumpId( id );
- #endif // DEBUG_HEADER_NAME
- in = lookForNextToken( in, end );
- if( ddl_nullptr != id ) {
- // store the node
- DDLNode *node( createDDLNode( id, this ) );
- if( ddl_nullptr != node ) {
- pushNode( node );
- } else {
- std::cerr << "nullptr returned by creating DDLNode." << std::endl;
- }
- Name *name(ddl_nullptr);
- in = OpenDDLParser::parseName(in, end, &name);
- if( ddl_nullptr != name && ddl_nullptr != node ) {
- const std::string nodeName( name->m_id->m_buffer );
- node->setName( nodeName );
- }
- Property *first(ddl_nullptr);
- in = lookForNextToken(in, end);
- if (*in == Grammar::OpenPropertyToken[0]) {
- in++;
- Property *prop(ddl_nullptr), *prev(ddl_nullptr);
- while (*in != Grammar::ClosePropertyToken[0] && in != end) {
- in = OpenDDLParser::parseProperty(in, end, &prop);
- in = lookForNextToken(in, end);
- if (*in != Grammar::CommaSeparator[0] && *in != Grammar::ClosePropertyToken[0]) {
- logInvalidTokenError(in, Grammar::ClosePropertyToken, m_logCallback);
- return ddl_nullptr;
- }
- if (ddl_nullptr != prop && *in != Grammar::CommaSeparator[0]) {
- if (ddl_nullptr == first) {
- first = prop;
- }
- if (ddl_nullptr != prev) {
- prev->m_next = prop;
- }
- prev = prop;
- }
- }
- in++;
- }
- // set the properties
- if (ddl_nullptr != first && ddl_nullptr != node) {
- node->setProperties(first);
- }
- }
- return in;
- }
- char *OpenDDLParser::parseStructure( char *in, char *end ) {
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- bool error( false );
- in = lookForNextToken( in, end );
- if( *in == '{' ) {
- // loop over all children ( data and nodes )
- do {
- in = parseStructureBody( in, end, error );
- if(in == ddl_nullptr){
- return ddl_nullptr;
- }
- } while ( *in != '}' );
- in++;
- } else {
- in++;
- logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
- error = true;
- return ddl_nullptr;
- }
- in = lookForNextToken( in, end );
- // pop node from stack after successful parsing
- if( !error ) {
- popNode();
- }
- return in;
- }
- static void setNodeValues( DDLNode *currentNode, Value *values ) {
- if( ddl_nullptr != values ){
- if( ddl_nullptr != currentNode ) {
- currentNode->setValue( values );
- }
- }
- }
- static void setNodeReferences( DDLNode *currentNode, Reference *refs ) {
- if( ddl_nullptr != refs ) {
- if( ddl_nullptr != currentNode ) {
- currentNode->setReferences( refs );
- }
- }
- }
- static void setNodeDataArrayList( DDLNode *currentNode, DataArrayList *dtArrayList ) {
- if( ddl_nullptr != dtArrayList ) {
- if( ddl_nullptr != currentNode ) {
- currentNode->setDataArrayList( dtArrayList );
- }
- }
- }
- char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
- if( !isNumeric( *in ) && !isCharacter( *in ) ) {
- in++;
- }
- in = lookForNextToken( in, end );
- Value::ValueType type( Value::ddl_none );
- size_t arrayLen( 0 );
- in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen );
- if( Value::ddl_none != type ) {
- // parse a primitive data type
- in = lookForNextToken( in, end );
- if( *in == Grammar::OpenBracketToken[ 0 ] ) {
- Reference *refs( ddl_nullptr );
- DataArrayList *dtArrayList( ddl_nullptr );
- Value *values( ddl_nullptr );
- if( 1 == arrayLen ) {
- size_t numRefs( 0 ), numValues( 0 );
- in = parseDataList( in, end, type, &values, numValues, &refs, numRefs );
- setNodeValues( top(), values );
- setNodeReferences( top(), refs );
- } else if( arrayLen > 1 ) {
- in = parseDataArrayList( in, end, type, &dtArrayList );
- setNodeDataArrayList( top(), dtArrayList );
- } else {
- std::cerr << "0 for array is invalid." << std::endl;
- error = true;
- }
- }
- in = lookForNextToken( in, end );
- if( *in != '}' ) {
- logInvalidTokenError( in, std::string( Grammar::CloseBracketToken ), m_logCallback );
- return ddl_nullptr;
- } else {
- //in++;
- }
- } else {
- // parse a complex data type
- in = parseNextNode( in, end );
- }
- return in;
- }
- void OpenDDLParser::pushNode( DDLNode *node ) {
- if( ddl_nullptr == node ) {
- return;
- }
- m_stack.push_back( node );
- }
- DDLNode *OpenDDLParser::popNode() {
- if( m_stack.empty() ) {
- return ddl_nullptr;
- }
- DDLNode *topNode( top() );
- m_stack.pop_back();
- return topNode;
- }
- DDLNode *OpenDDLParser::top() {
- if( m_stack.empty() ) {
- return ddl_nullptr;
- }
- DDLNode *top( m_stack.back() );
- return top;
- }
- DDLNode *OpenDDLParser::getRoot() const {
- if( ddl_nullptr == m_context ) {
- return ddl_nullptr;
- }
- return m_context->m_root;
- }
- Context *OpenDDLParser::getContext() const {
- return m_context;
- }
- void OpenDDLParser::normalizeBuffer( std::vector<char> &buffer) {
- if( buffer.empty() ) {
- return;
- }
- std::vector<char> newBuffer;
- const size_t len( buffer.size() );
- char *end( &buffer[ len-1 ] + 1 );
- for( size_t readIdx = 0; readIdx<len; ++readIdx ) {
- char *c( &buffer[readIdx] );
- // check for a comment
- if( !isComment<char>( c, end ) && !isNewLine( *c ) ) {
- newBuffer.push_back( buffer[ readIdx ] );
- } else {
- if( isComment<char>( c, end ) ) {
- ++readIdx;
- // skip the comment and the rest of the line
- while( !isEndofLine( buffer[ readIdx ] ) ) {
- ++readIdx;
- }
- }
- }
- }
- buffer = newBuffer;
- }
- char *OpenDDLParser::parseName( char *in, char *end, Name **name ) {
- *name = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- // ignore blanks
- in = lookForNextToken( in, end );
- if( *in != '$' && *in != '%' ) {
- return in;
- }
- NameType ntype( GlobalName );
- if( *in == '%' ) {
- ntype = LocalName;
- }
- in++;
- Name *currentName( ddl_nullptr );
- Text *id( ddl_nullptr );
- in = parseIdentifier( in, end, &id );
- if( id ) {
- currentName = new Name( ntype, id );
- if( currentName ) {
- *name = currentName;
- }
- }
- return in;
- }
- char *OpenDDLParser::parseIdentifier( char *in, char *end, Text **id ) {
- *id = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- // ignore blanks
- in = lookForNextToken( in, end );
- // staring with a number is forbidden
- if( isNumeric<const char>( *in ) ) {
- return in;
- }
- // get size of id
- size_t idLen( 0 );
- char *start( in );
- while( !isSeparator( *in ) && !isNewLine( *in ) && ( in != end ) && *in != Grammar::OpenPropertyToken[ 0 ] && *in != Grammar::ClosePropertyToken[ 0 ] && *in != '$' ) {
- ++in;
- ++idLen;
- }
- const size_t len( idLen );
- Text *newId = new Text( start, len );
- *id = newId;
- return in;
- }
- char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len ) {
- type = Value::ddl_none;
- len = 0;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- size_t prim_len( 0 );
- for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) {
- prim_len = strlen( Grammar::PrimitiveTypeToken[ i ] );
- if( 0 == strncmp( in, Grammar::PrimitiveTypeToken[ i ], prim_len ) ) {
- type = ( Value::ValueType ) i;
- break;
- }
- }
- if( Value::ddl_none == type ) {
- in = lookForNextToken( in, end );
- return in;
- } else {
- in += prim_len;
- }
- bool ok( true );
- if( *in == Grammar::OpenArrayToken[ 0 ] ) {
- ok = false;
- in++;
- char *start( in );
- while ( in != end ) {
- in++;
- if( *in == Grammar::CloseArrayToken[ 0 ] ) {
- len = ::atoi( start );
- ok = true;
- in++;
- break;
- }
- }
- } else {
- len = 1;
- }
- if( !ok ) {
- type = Value::ddl_none;
- }
- return in;
- }
- char *OpenDDLParser::parseReference( char *in, char *end, std::vector<Name*> &names ) {
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- Name *nextName( ddl_nullptr );
- in = parseName( in, end, &nextName );
- if( nextName ) {
- names.push_back( nextName );
- }
- while( Grammar::CommaSeparator[ 0 ] == *in ) {
- in = getNextSeparator( in, end );
- if( Grammar::CommaSeparator[ 0 ] == *in ) {
- in = parseName( in, end, &nextName );
- if( nextName ) {
- names.push_back( nextName );
- }
- } else {
- break;
- }
- }
- return in;
- }
- char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) {
- *boolean = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- in = lookForNextToken( in, end );
- char *start( in );
- size_t len( 0 );
- while( !isSeparator( *in ) && in != end ) {
- in++;
- len++;
- }
- len++;
- int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) );
- if( 0 != res ) {
- res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) );
- if( 0 != res ) {
- *boolean = ddl_nullptr;
- return in;
- }
- *boolean = ValueAllocator::allocPrimData( Value::ddl_bool );
- (*boolean)->setBool( false );
- } else {
- *boolean = ValueAllocator::allocPrimData( Value::ddl_bool );
- (*boolean)->setBool( true );
- }
- return in;
- }
- char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType ) {
- *integer = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- if( !(isIntegerType( integerType ) || isUnsignedIntegerType(integerType)) ) {
- return in;
- }
- in = lookForNextToken( in, end );
- char *start( in );
- while( !isSeparator( *in ) && in != end ) {
- in++;
- }
- if( isNumeric( *start ) ) {
- #ifdef OPENDDL_NO_USE_CPP11
- const int64 value( atol( start ) ); // maybe not really 64bit as atoll is but exists without c++11
- const uint64 uvalue( strtoul( start,ddl_nullptr,10 ) );
- #else
- const int64 value( atoll( start ) );
- const uint64 uvalue( strtoull( start,ddl_nullptr,10 ) );
- #endif
- *integer = ValueAllocator::allocPrimData( integerType );
- switch( integerType ) {
- case Value::ddl_int8:
- ( *integer )->setInt8( (int8) value );
- break;
- case Value::ddl_int16:
- ( *integer )->setInt16( ( int16 ) value );
- break;
- case Value::ddl_int32:
- ( *integer )->setInt32( ( int32 ) value );
- break;
- case Value::ddl_int64:
- ( *integer )->setInt64( ( int64 ) value );
- break;
- case Value::ddl_unsigned_int8:
- ( *integer )->setUnsignedInt8( (uint8) uvalue );
- break;
- case Value::ddl_unsigned_int16:
- ( *integer )->setUnsignedInt16( ( uint16 ) uvalue );
- break;
- case Value::ddl_unsigned_int32:
- ( *integer )->setUnsignedInt32( ( uint32 ) uvalue );
- break;
- case Value::ddl_unsigned_int64:
- ( *integer )->setUnsignedInt64( ( uint64 ) uvalue );
- break;
- default:
- break;
- }
- }
- return in;
- }
- char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating, Value::ValueType floatType) {
- *floating = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- in = lookForNextToken( in, end );
- char *start( in );
- while( !isSeparator( *in ) && in != end ) {
- in++;
- }
- // parse the float value
- bool ok( false );
- if ( isHexLiteral( start, end ) ) {
- parseHexaLiteral( start, end, floating );
- return in;
- }
- if( isNumeric( *start ) ) {
- ok = true;
- } else {
- if( *start == '-' ) {
- if( isNumeric( *(start+1) ) ) {
- ok = true;
- }
- }
- }
- if( ok ) {
- if(floatType == Value::ddl_double)
- {
- const double value( atof( start ) );
- *floating = ValueAllocator::allocPrimData( Value::ddl_double );
- ( *floating )->setDouble( value );
- } else {
- const float value( ( float ) atof( start ) );
- *floating = ValueAllocator::allocPrimData( Value::ddl_float );
- ( *floating )->setFloat( value );
- }
- }
- return in;
- }
- char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData ) {
- *stringData = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- in = lookForNextToken( in, end );
- size_t len( 0 );
- char *start( in );
- if( *start == '\"' ) {
- start++;
- in++;
- while( *in != '\"' && in != end ) {
- in++;
- len++;
- }
- *stringData = ValueAllocator::allocPrimData( Value::ddl_string, len );
- ::strncpy( ( char* ) ( *stringData )->m_data, start, len );
- ( *stringData )->m_data[len] = '\0';
- in++;
- }
- return in;
- }
- static void createPropertyWithData( Text *id, Value *primData, Property **prop ) {
- if( ddl_nullptr != primData ) {
- ( *prop ) = new Property( id );
- ( *prop )->m_value = primData;
- }
- }
- char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
- *data = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- in = lookForNextToken( in, end );
- if( *in != '0' ) {
- return in;
- }
- in++;
- if( *in != 'x' && *in != 'X' ) {
- return in;
- }
- in++;
- bool ok( true );
- char *start( in );
- int pos( 0 );
- while( !isSeparator( *in ) && in != end ) {
- if( ( *in < '0' && *in > '9' ) || ( *in < 'a' && *in > 'f' ) || ( *in < 'A' && *in > 'F' ) ) {
- ok = false;
- break;
- }
- pos++;
- in++;
- }
- if( !ok ) {
- return in;
- }
- int value( 0 );
- while( pos > 0 ) {
- int v = hex2Decimal( *start );
- pos--;
- value = ( value << 4 ) | v;
- start++;
- }
- *data = ValueAllocator::allocPrimData( Value::ddl_unsigned_int64 );
- if( ddl_nullptr != *data ) {
- ( *data )->setUnsignedInt64( value );
- }
- return in;
- }
- char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
- *prop = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- in = lookForNextToken( in, end );
- Text *id( ddl_nullptr );
- in = parseIdentifier( in, end, &id );
- if( ddl_nullptr != id ) {
- in = lookForNextToken( in, end );
- if( *in == '=' ) {
- in++;
- in = getNextToken( in, end );
- Value *primData( ddl_nullptr );
- if( isInteger( in, end ) ) {
- in = parseIntegerLiteral( in, end, &primData );
- createPropertyWithData( id, primData, prop );
- } else if( isFloat( in, end ) ) {
- in = parseFloatingLiteral( in, end, &primData );
- createPropertyWithData( id, primData, prop );
- } else if( isStringLiteral( *in ) ) { // string data
- in = parseStringLiteral( in, end, &primData );
- createPropertyWithData( id, primData, prop );
- } else { // reference data
- std::vector<Name*> names;
- in = parseReference( in, end, names );
- if( !names.empty() ) {
- Reference *ref = new Reference( names.size(), &names[ 0 ] );
- ( *prop ) = new Property( id );
- ( *prop )->m_ref = ref;
- }
- }
- }
- }
- return in;
- }
- char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type, Value **data,
- size_t &numValues, Reference **refs, size_t &numRefs ) {
- *data = ddl_nullptr;
- numValues = numRefs = 0;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- in = lookForNextToken( in, end );
- if( *in == '{' ) {
- in++;
- Value *current( ddl_nullptr ), *prev( ddl_nullptr );
- while( '}' != *in ) {
- current = ddl_nullptr;
- in = lookForNextToken( in, end );
- if ( Value::ddl_ref == type ) {
- std::vector<Name*> names;
- in = parseReference( in, end, names );
- if ( !names.empty() ) {
- Reference *ref = new Reference( names.size(), &names[ 0 ] );
- *refs = ref;
- numRefs = names.size();
- }
- } else if ( Value::ddl_none == type ) {
- if (isInteger( in, end )) {
- in = parseIntegerLiteral( in, end, ¤t );
- } else if (isFloat( in, end )) {
- in = parseFloatingLiteral( in, end, ¤t );
- } else if (isStringLiteral( *in )) {
- in = parseStringLiteral( in, end, ¤t );
- } else if (isHexLiteral( in, end )) {
- in = parseHexaLiteral( in, end, ¤t );
- }
- } else {
- switch(type){
- case Value::ddl_int8:
- case Value::ddl_int16:
- case Value::ddl_int32:
- case Value::ddl_int64:
- case Value::ddl_unsigned_int8:
- case Value::ddl_unsigned_int16:
- case Value::ddl_unsigned_int32:
- case Value::ddl_unsigned_int64:
- in = parseIntegerLiteral( in, end, ¤t, type);
- break;
- case Value::ddl_half:
- case Value::ddl_float:
- case Value::ddl_double:
- in = parseFloatingLiteral( in, end, ¤t, type);
- break;
- case Value::ddl_string:
- in = parseStringLiteral( in, end, ¤t );
- break;
- default:
- break;
- }
- }
- if( ddl_nullptr != current ) {
- if( ddl_nullptr == *data ) {
- *data = current;
- prev = current;
- } else {
- prev->setNext( current );
- prev = current;
- }
- numValues++;
- }
- in = getNextSeparator( in, end );
- if( ',' != *in && Grammar::CloseBracketToken[ 0 ] != *in && !isSpace( *in ) ) {
- break;
- }
- }
- in++;
- }
- return in;
- }
- static DataArrayList *createDataArrayList( Value *currentValue, size_t numValues ) {
- DataArrayList *dataList = new DataArrayList;
- dataList->m_dataList = currentValue;
- dataList->m_numItems = numValues;
- return dataList;
- }
- char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType type, DataArrayList **dataArrayList ) {
- *dataArrayList = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
- in = lookForNextToken( in, end );
- if( *in == Grammar::OpenBracketToken[ 0 ] ) {
- in++;
- Value *currentValue( ddl_nullptr );
- Reference *refs( ddl_nullptr );
- DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr );
- do {
- size_t numRefs( 0 ), numValues( 0 );
- currentValue = ddl_nullptr;
- in = parseDataList( in, end, type, ¤tValue, numValues, &refs, numRefs );
- if( ddl_nullptr != currentValue || 0 != numRefs ) {
- if( ddl_nullptr == prev ) {
- *dataArrayList = createDataArrayList( currentValue, numValues );
- prev = *dataArrayList;
- } else {
- currentDataList = createDataArrayList( currentValue, numValues );
- if( ddl_nullptr != prev ) {
- prev->m_next = currentDataList;
- prev = currentDataList;
- }
- }
- }
- } while( Grammar::CommaSeparator[ 0 ] == *in && in != end );
- in = lookForNextToken( in, end );
- in++;
- }
- return in;
- }
- const char *OpenDDLParser::getVersion() {
- return Version;
- }
- END_ODDLPARSER_NS
|