diff options
Diffstat (limited to 'src/3rdparty/assimp/contrib/openddlparser')
15 files changed, 3745 insertions, 0 deletions
diff --git a/src/3rdparty/assimp/contrib/openddlparser/CMakeLists.txt b/src/3rdparty/assimp/contrib/openddlparser/CMakeLists.txt new file mode 100644 index 000000000..a39d0219f --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/CMakeLists.txt @@ -0,0 +1,64 @@ +CMAKE_MINIMUM_REQUIRED( VERSION 2.6 ) +PROJECT( OpenDDL-Parser ) +SET ( OPENDDL_PARSER_VERSION_MAJOR 0 ) +SET ( OPENDDL_PARSER_VERSION_MINOR 1 ) +SET ( OPENDDL_PARSER_VERSION_PATCH 0 ) +SET ( OPENDDL_PARSER_VERSION ${CPPCORE_VERSION_MAJOR}.${CPPCORE_VERSION_MINOR}.${CPPCORE_VERSION_PATCH} ) +SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" ) + +if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) + find_package(Threads) +else() + add_definitions( -D_CRT_SECURE_NO_WARNINGS ) +endif() + +add_definitions( -DOPENDDLPARSER_BUILD ) +add_definitions( -DOPENDDL_NO_USE_CPP11 ) +add_definitions( -D_VARIADIC_MAX=10 ) + +INCLUDE_DIRECTORIES( + ./ + include/ + contrib/gtest-1.7.0/include + contrib/gtest-1.7.0/ +) + +link_directories( + ./ +) + +SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) +SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) +SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin ) + +if( WIN32 AND NOT CYGWIN ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc" ) # Force to always compile with W4 + if( CMAKE_CXX_FLAGS MATCHES "/W[0-4]" ) + string( REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" ) + else() + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4" ) + endif() +elseif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) + # Update if necessary + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++0x") +elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++11") +endif() + +SET ( openddl_parser_src + code/OpenDDLParser.cpp + code/DDLNode.cpp + code/Value.cpp + include/openddlparser/OpenDDLParser.h + include/openddlparser/OpenDDLParserUtils.h + include/openddlparser/OpenDDLCommon.h + include/openddlparser/DDLNode.h + include/openddlparser/Value.h + README.md +) + +SOURCE_GROUP( code FILES ${openddl_parser_src} ) + +ADD_LIBRARY( openddl_parser SHARED + ${openddl_parser_src} +) diff --git a/src/3rdparty/assimp/contrib/openddlparser/CREDITS b/src/3rdparty/assimp/contrib/openddlparser/CREDITS new file mode 100644 index 000000000..a2b01eb13 --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/CREDITS @@ -0,0 +1,16 @@ +=============================================================== +OpenDDL-Parser +Developers and Contributors +=============================================================== + +- Kim Kulling ( kimmi ): +Founder + +- Fredrik Hansson ( FredrikHson ): +Improvements value interface, serveral bugfixes. + +- Henry Read ( henrya2 ): +Static build option, Interface improvements + +- Paul Holland ( pkholland ): +Bugfixes. diff --git a/src/3rdparty/assimp/contrib/openddlparser/LICENSE b/src/3rdparty/assimp/contrib/openddlparser/LICENSE new file mode 100644 index 000000000..4c1476bc4 --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 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. + diff --git a/src/3rdparty/assimp/contrib/openddlparser/README.md b/src/3rdparty/assimp/contrib/openddlparser/README.md new file mode 100644 index 000000000..619747d23 --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/README.md @@ -0,0 +1,136 @@ +The OpenDDL-Parser +================== + +The OpenDDL-Parser is a small and easy to use library for OpenDDL-file-format-parsing. OpenDDL is the shortcut for Open Data Description Language, a data-declaration language introduced by Eric Lengyel. Please check http://openddl.org/ if you want to learn more about it. + +Build status +============ +Linux build status: [![Build Status](https://travis-ci.org/kimkulling/openddl-parser.png)](https://travis-ci.org/kimkulling/openddl-parser) +Current coverity check status: +<a href="https://scan.coverity.com/projects/5606"> + <img alt="Coverity Scan Build Status" + src="https://scan.coverity.com/projects/5606/badge.svg"/> +</a> + +Get the source code +=================== +You can get the code from our git repository, which is located at GitHub. You can clone the repository with the following command: + +> git clone https://github.com/kimkulling/openddl-parser.git + +Building the source from the GitHub-Repo +======================================== +To build the library you need to install cmake first ( see http://www.cmake.org/ for more information ). Make also sure that a compiler tool-chain is installed on your machine. +After installing it you can open a console and enter: + +> cmake CMakeLists.txt + +This command will generate a build environment for your installed build enrironment ( for Visual-Studio-users the project files will be generated, for gcc-users the makefiles will be generated ). +When using an IDE open the IDE and run the build. When using GNU-make type in your console: + +> make + +and that's all. + +When using Visual Studio CMake will generate you a solution for ythe library. Just build it there. + +Use the library +=============== +To use the OpenDDL-parser you need to build the lib first. Now add the +> <Repo-folder>/include + +to your include-path and the + +> <Repo-folder>/lib + +to your lib-folder. Link the openddl.lib to your application. + +Here is a small example how to use the lib: + +```cpp + +#include <iostream> +#include <cassert> +#include <openddlparser/OpenDDLParser.h> + +USE_ODDLPARSER_NS; + +int main( int argc, char *argv[] ) { + if( argc < 3 ) { + return 1; + } + + char *filename( nullptr ); + if( 0 == strncmp( FileOption, argv[ 1 ], strlen( FileOption ) ) ) { + filename = argv[ 2 ]; + } + std::cout << "file to import: " << filename << std::endl; + if( nullptr == filename ) { + std::cerr << "Invalid filename." << std::endl; + return Error; + } + + FILE *fileStream = fopen( filename, "r+" ); + if( NULL == filename ) { + std::cerr << "Cannot open file " << filename << std::endl; + return 1; + } + + // obtain file size: + fseek( fileStream, 0, SEEK_END ); + const size_t size( ftell( fileStream ) ); + rewind( fileStream ); + if( size > 0 ) { + char *buffer = new char[ size ]; + const size_t readSize( fread( buffer, sizeof( char ), size, fileStream ) ); + assert( readSize == size ); + OpenDDLParser theParser; + theParser.setBuffer( buffer, size ); + const bool result( theParser.parse() ); + if( !result ) { + std::cerr << "Error while parsing file " << filename << "." << std::endl; + } + } + return 0; +} + +``` + +How to access the imported data +=============================== +The data is organized as a tree. You can get the root-node of the tree with the following code: + +```cpp +OpenDDLParser theParser; +theParser.setBuffer( buffer, size ); +const bool result( theParser.parse() ); +if ( result ) { + DDLNode *root = theParser.getRoot(); + DDLNode::DllNodeList childs = root->getChildNodeList(); + for ( size_t i=0; i<childs.size(); i++ ) { + DDLNode *child = childs[ i ]; + Property *prop = child->getProperty(); // to get properties + std::string type = child->getType(); // to get the node type + Value *values = child->getValue(); // to get the data; + + // to loop through all values + while ( values != ddl_nullptr ) { + int current = values->getInt32(); + values = value->getNext(); + } + } +} + +``` + +The node instance called root contains the data. + +All data lists are organized as linked lists. + +Reference documentation +======================= +Please check http://kimkulling.github.io/openddl-parser/doxygen_html/index.html. + +Projects using OpenDDL-Parser +============================= +- Asset Importer Lib: https://github.com/assimp/assimp . diff --git a/src/3rdparty/assimp/contrib/openddlparser/code/DDLNode.cpp b/src/3rdparty/assimp/contrib/openddlparser/code/DDLNode.cpp new file mode 100644 index 000000000..0cc95bdfc --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/code/DDLNode.cpp @@ -0,0 +1,209 @@ +/*----------------------------------------------------------------------------------------------- +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/DDLNode.h> +#include <openddlparser/OpenDDLParser.h> + +#include <algorithm> + +BEGIN_ODDLPARSER_NS + +DDLNode::DllNodeList DDLNode::s_allocatedNodes; + +template<class T> +inline +static void releaseDataType( T *ptr ) { + if( ddl_nullptr == ptr ) { + return; + } + + T *current( ddl_nullptr ); + while( ptr ) { + current = ptr; + ptr = ptr->m_next; + delete current; + } +} + +static void releaseReferencedNames( Reference *ref ) { + if( ddl_nullptr == ref ) { + return; + } + + delete ref; +} + +DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent ) +: m_type( type ) +, m_name( name ) +, m_parent( parent ) +, m_children() +, m_properties( ddl_nullptr ) +, m_value( ddl_nullptr ) +, m_dtArrayList( ddl_nullptr ) +, m_references( ddl_nullptr ) +, m_idx( idx ) { + if( m_parent ) { + m_parent->m_children.push_back( this ); + } +} + +DDLNode::~DDLNode() { + releaseDataType<Property>( m_properties ); + releaseDataType<Value>( m_value ); + releaseReferencedNames( m_references ); + + delete m_dtArrayList; + m_dtArrayList = ddl_nullptr; + if( s_allocatedNodes[ m_idx ] == this ) { + s_allocatedNodes[ m_idx ] = ddl_nullptr; + } +} + +void DDLNode::attachParent( DDLNode *parent ) { + if( m_parent == parent ) { + return; + } + + m_parent = parent; + if( ddl_nullptr != m_parent ) { + m_parent->m_children.push_back( this ); + } +} + +void DDLNode::detachParent() { + if( m_parent ) { + std::vector<DDLNode*>::iterator it; + it = std::find( m_parent->m_children.begin(), m_parent->m_children.end(), this ); + if( m_parent->m_children.end() != it ) { + m_parent->m_children.erase( it ); + } + m_parent = ddl_nullptr; + } +} + +DDLNode *DDLNode::getParent() const { + return m_parent; +} + +const DDLNode::DllNodeList &DDLNode::getChildNodeList() const { + return m_children; +} + +void DDLNode::setType( const std::string &type ) { + m_type = type; +} + +const std::string &DDLNode::getType() const { + return m_type; +} + +void DDLNode::setName( const std::string &name ) { + m_name = name; +} + +const std::string &DDLNode::getName() const { + return m_name; +} + +void DDLNode::setProperties( Property *prop ) { + m_properties = prop; +} + +Property *DDLNode::getProperties() const { + return m_properties; +} + +bool DDLNode::hasProperty( const std::string &name ) { + const Property *prop( findPropertyByName( name ) ); + return ( ddl_nullptr != prop ); +} + +bool DDLNode::hasProperties() const { + return( ddl_nullptr != m_properties ); +} + +Property *DDLNode::findPropertyByName( const std::string &name ) { + if( name.empty() ) { + return ddl_nullptr; + } + + if( ddl_nullptr == m_properties ) { + return ddl_nullptr; + } + + Property *current( m_properties ); + while( ddl_nullptr != current ) { + int res = strncmp( current->m_key->m_buffer, name.c_str(), name.size() ); + if( 0 == res ) { + return current; + } + current = current->m_next; + } + + return ddl_nullptr; +} + +void DDLNode::setValue( Value *val ) { + m_value = val; +} + +Value *DDLNode::getValue() const { + return m_value; +} + +void DDLNode::setDataArrayList( DataArrayList *dtArrayList ) { + m_dtArrayList = dtArrayList; +} + +DataArrayList *DDLNode::getDataArrayList() const { + return m_dtArrayList; +} + +void DDLNode::setReferences( Reference *refs ) { + m_references = refs; +} + +Reference *DDLNode::getReferences() const { + return m_references; +} + +DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) { + const size_t idx( s_allocatedNodes.size() ); + DDLNode *node = new DDLNode( type, name, idx, parent ); + s_allocatedNodes.push_back( node ); + + return node; +} + +void DDLNode::releaseNodes() { + if( s_allocatedNodes.size() > 0 ) { + for( DllNodeList::iterator it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) { + if( *it ) { + delete *it; + } + } + s_allocatedNodes.clear(); + } +} + +END_ODDLPARSER_NS diff --git a/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLCommon.cpp b/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLCommon.cpp new file mode 100644 index 000000000..13a96f7a8 --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLCommon.cpp @@ -0,0 +1,186 @@ +/*----------------------------------------------------------------------------------------------- +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/OpenDDLCommon.h> +#include <openddlparser/DDLNode.h> + +BEGIN_ODDLPARSER_NS + +Text::Text( const char *buffer, size_t numChars ) +: m_capacity( 0 ) +, m_len( 0 ) +, m_buffer( ddl_nullptr ) { + set( buffer, numChars ); +} + +Text::~Text() { + clear(); +} + +void Text::clear() { + delete[] m_buffer; + m_buffer = ddl_nullptr; + m_capacity = 0; + m_len = 0; +} + +void Text::set( const char *buffer, size_t numChars ) { + clear(); + if( numChars > 0 ) { + m_len = numChars; + m_capacity = m_len + 1; + m_buffer = new char[ m_capacity ]; + strncpy( m_buffer, buffer, numChars ); + m_buffer[ numChars ] = '\0'; + } +} + +bool Text::operator == ( const std::string &name ) const { + if( m_len != name.size() ) { + return false; + } + const int res( strncmp( m_buffer, name.c_str(), name.size() ) ); + + return ( 0 == res ); +} + +bool Text::operator == ( const Text &rhs ) const { + if( m_len != rhs.m_len ) { + return false; + } + + const int res( strncmp( m_buffer, rhs.m_buffer, m_len ) ); + + return ( 0 == res ); +} + +Name::Name( NameType type, Text *id ) +: m_type( type ) +, m_id( id ) { + // empty +} + +Name::~Name() { + delete m_id; + m_id = ddl_nullptr; +} + +Reference::Reference() +: m_numRefs( 0 ) +, m_referencedName( ddl_nullptr ) { + // empty +} + +Reference::Reference( size_t numrefs, Name **names ) +: m_numRefs( numrefs ) +, m_referencedName( ddl_nullptr ) { + if ( numrefs > 0 ) { + m_referencedName = new Name *[ numrefs ]; + for ( size_t i = 0; i < numrefs; i++ ) { + Name *name = new Name( names[ i ]->m_type, names[ i ]->m_id ); + m_referencedName[ i ] = name; + } + } +} + +Reference::~Reference() { + for( size_t i = 0; i < m_numRefs; i++ ) { + delete m_referencedName[ i ]; + } + m_numRefs = 0; + m_referencedName = ddl_nullptr; +} + +size_t Reference::sizeInBytes() { + if ( 0 == m_numRefs ) { + return 0; + } + + size_t size( 0 ); + for ( size_t i = 0; i < m_numRefs; i++ ) { + Name *name( m_referencedName[ i ] ); + if ( ddl_nullptr != name ) { + size += name->m_id->m_len; + } + } + + return size; +} + +Property::Property( Text *id ) +: m_key( id ) +, m_value( ddl_nullptr ) +, m_ref( ddl_nullptr ) +, m_next( ddl_nullptr ) { + // empty +} + +Property::~Property() { + m_key = ddl_nullptr; + m_value = ddl_nullptr; + m_ref = ddl_nullptr;; + m_next = ddl_nullptr;; +} + +DataArrayList::DataArrayList() +: m_numItems( 0 ) +, m_dataList( ddl_nullptr ) +, m_next( ddl_nullptr ) { + // empty +} + +DataArrayList::~DataArrayList() { + // empty +} + +size_t DataArrayList::size() { + size_t result( 0 ); + if ( ddl_nullptr == m_next ) { + if ( m_dataList != ddl_nullptr ) { + result = 1; + } + return result; + } + + DataArrayList *n( m_next ); + while( ddl_nullptr != n ) { + result++; + n = n->m_next; + } + return result; +} + +Context::Context() +: m_root( ddl_nullptr ) { + // empty +} + +Context::~Context() { + clear(); +} + +void Context::clear() { + delete m_root; + m_root = ddl_nullptr; +} + +END_ODDLPARSER_NS diff --git a/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLExport.cpp b/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLExport.cpp new file mode 100644 index 000000000..2e73ea470 --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLExport.cpp @@ -0,0 +1,439 @@ +/*----------------------------------------------------------------------------------------------- +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/OpenDDLExport.h> +#include <openddlparser/DDLNode.h> +#include <openddlparser/Value.h> +#include <openddlparser/OpenDDLParser.h> + +#include <sstream> + +BEGIN_ODDLPARSER_NS + +StreamFormatterBase::StreamFormatterBase() { + +} + +StreamFormatterBase::~StreamFormatterBase() { + +} + +std::string StreamFormatterBase::format( const std::string &statement ) { + std::string tmp( statement ); + return tmp; +} + +IOStreamBase::IOStreamBase( StreamFormatterBase *formatter ) +: m_formatter( formatter ) +, m_file( ddl_nullptr ) { + if (ddl_nullptr == m_formatter) { + m_formatter = new StreamFormatterBase; + } +} + +IOStreamBase::~IOStreamBase() { + delete m_formatter; + m_formatter = ddl_nullptr; +} + +bool IOStreamBase::open( const std::string &name ) { + m_file = ::fopen( name.c_str(), "a" ); + if (m_file == ddl_nullptr) { + return false; + } + + return true; +} + +bool IOStreamBase::close() { + if (ddl_nullptr == m_file) { + return false; + } + + ::fclose( m_file ); + m_file = ddl_nullptr; + + return true; +} + +size_t IOStreamBase::write( const std::string &statement ) { + if (ddl_nullptr == m_file) { + return 0; + } + std::string formatStatement = m_formatter->format( statement ); + return ::fwrite( formatStatement.c_str(), sizeof( char ), formatStatement.size(), m_file ); +} + +struct DDLNodeIterator { + const DDLNode::DllNodeList &m_childs; + size_t m_idx; + + DDLNodeIterator( const DDLNode::DllNodeList &childs ) + : m_childs( childs ) + , m_idx( 0 ) { + // empty + } + + ~DDLNodeIterator() { + // empty + } + + bool getNext( DDLNode **node ) { + if( m_childs.size() > (m_idx+1) ) { + m_idx++; + *node = m_childs[ m_idx ]; + return true; + } + + return false; + } + +private: + DDLNodeIterator() ddl_no_copy; + DDLNodeIterator &operator = ( const DDLNodeIterator & ) ddl_no_copy; +}; + +static void writeLineEnd( std::string &statement ) { + statement += "\n"; +} + +OpenDDLExport::OpenDDLExport( IOStreamBase *stream ) +: m_stream( stream ) { + if (ddl_nullptr == m_stream) { + m_stream = new IOStreamBase(); + } +} + +OpenDDLExport::~OpenDDLExport() { + if (ddl_nullptr != m_stream) { + m_stream->close(); + } + delete m_stream; +} + +bool OpenDDLExport::exportContext( Context *ctx, const std::string &filename ) { + if( ddl_nullptr == ctx ) { + return false; + } + + DDLNode *root( ctx->m_root ); + if ( ddl_nullptr == root ) { + return true; + } + + if (!filename.empty()) { + if (!m_stream->open( filename )) { + return false; + } + } + + const bool retValue( handleNode( root ) ); + + return retValue; +} + +bool OpenDDLExport::handleNode( DDLNode *node ) { + if( ddl_nullptr == node ) { + return true; + } + + const DDLNode::DllNodeList &childs = node->getChildNodeList(); + if( childs.empty() ) { + return true; + } + DDLNode *current( ddl_nullptr ); + DDLNodeIterator it( childs ); + std::string statement; + bool success( true ); + while( it.getNext( ¤t ) ) { + if( ddl_nullptr != current ) { + success |= writeNode( current, statement ); + if( !handleNode( current ) ) { + success = false; + } + } + } + + return success; +} + +bool OpenDDLExport::writeToStream( const std::string &statement ) { + if (ddl_nullptr == m_stream ) { + return false; + } + + if ( !statement.empty()) { + m_stream->write( statement ); + } + + return true; +} + +bool OpenDDLExport::writeNode( DDLNode *node, std::string &statement ) { + bool success( true ); + writeNodeHeader( node, statement ); + if (node->hasProperties()) { + success |= writeProperties( node, statement ); + } + writeLineEnd( statement ); + + statement = "}"; + DataArrayList *al( node->getDataArrayList() ); + if ( ddl_nullptr != al ) { + writeValueType( al->m_dataList->m_type, al->m_numItems, statement ); + writeValueArray( al, statement ); + } + Value *v( node->getValue() ); + if (ddl_nullptr != v ) { + writeValueType( v->m_type, 1, statement ); + statement = "{"; + writeLineEnd( statement ); + writeValue( v, statement ); + statement = "}"; + writeLineEnd( statement ); + } + statement = "}"; + writeLineEnd( statement ); + + writeToStream( statement ); + + return true; +} + +bool OpenDDLExport::writeNodeHeader( DDLNode *node, std::string &statement ) { + if (ddl_nullptr == node) { + return false; + } + + statement += node->getType(); + const std::string &name( node->getName() ); + if ( !name.empty() ) { + statement += " "; + statement += "$"; + statement += name; + } + + return true; +} + +bool OpenDDLExport::writeProperties( DDLNode *node, std::string &statement ) { + if ( ddl_nullptr == node ) { + return false; + } + + Property *prop( node->getProperties() ); + // if no properties are there, return + if ( ddl_nullptr == prop ) { + return true; + } + + if ( ddl_nullptr != prop ) { + // for instance (attrib = "position", bla=2) + statement += "("; + bool first( true ); + while ( ddl_nullptr != prop ) { + if (!first) { + statement += ", "; + } else { + first = false; + } + statement += std::string( prop->m_key->m_buffer ); + statement += " = "; + writeValue( prop->m_value, statement ); + prop = prop->m_next; + } + + statement += ")"; + } + + return true; +} + +bool OpenDDLExport::writeValueType( Value::ValueType type, size_t numItems, std::string &statement ) { + if ( Value::ddl_types_max == type) { + return false; + } + + const std::string typeStr( getTypeToken( type ) ); + statement += typeStr; + // if we have an array to write + if ( numItems > 1 ) { + statement += "["; + char buffer[ 256 ]; + ::memset( buffer, '\0', 256 * sizeof( char ) ); + sprintf( buffer, "%d", int(numItems) ); + statement += buffer; + statement += "]"; + } + + return true; +} + +bool OpenDDLExport::writeValue( Value *val, std::string &statement ) { + if (ddl_nullptr == val) { + return false; + } + + switch ( val->m_type ) { + case Value::ddl_bool: + if ( true == val->getBool() ) { + statement += "true"; + } else { + statement += "false"; + } + break; + case Value::ddl_int8: + { + std::stringstream stream; + const int i = static_cast<int>( val->getInt8() ); + stream << i; + statement += stream.str(); + } + break; + case Value::ddl_int16: + { + std::stringstream stream; + char buffer[ 256 ]; + ::memset( buffer, '\0', 256 * sizeof( char ) ); + sprintf( buffer, "%d", val->getInt16() ); + statement += buffer; + } + break; + case Value::ddl_int32: + { + std::stringstream stream; + char buffer[ 256 ]; + ::memset( buffer, '\0', 256 * sizeof( char ) ); + const int i = static_cast< int >( val->getInt32() ); + sprintf( buffer, "%d", i ); + statement += buffer; + } + break; + case Value::ddl_int64: + { + std::stringstream stream; + const int i = static_cast< int >( val->getInt64() ); + stream << i; + statement += stream.str(); + } + break; + case Value::ddl_unsigned_int8: + { + std::stringstream stream; + const int i = static_cast< unsigned int >( val->getUnsignedInt8() ); + stream << i; + statement += stream.str(); + } + break; + case Value::ddl_unsigned_int16: + { + std::stringstream stream; + const int i = static_cast< unsigned int >( val->getUnsignedInt16() ); + stream << i; + statement += stream.str(); + } + break; + case Value::ddl_unsigned_int32: + { + std::stringstream stream; + const int i = static_cast< unsigned int >( val->getUnsignedInt32() ); + stream << i; + statement += stream.str(); + } + break; + case Value::ddl_unsigned_int64: + { + std::stringstream stream; + const int i = static_cast< unsigned int >( val->getUnsignedInt64() ); + stream << i; + statement += stream.str(); + } + break; + case Value::ddl_half: + break; + case Value::ddl_float: + { + std::stringstream stream; + stream << val->getFloat(); + statement += stream.str(); + } + break; + case Value::ddl_double: + { + std::stringstream stream; + stream << val->getDouble(); + statement += stream.str(); + } + break; + case Value::ddl_string: + { + std::stringstream stream; + stream << val->getString(); + statement += "\""; + statement += stream.str(); + statement += "\""; + } + break; + case Value::ddl_ref: + break; + case Value::ddl_none: + case Value::ddl_types_max: + default: + break; + } + + return true; +} + +bool OpenDDLExport::writeValueArray( DataArrayList *al, std::string &statement ) { + if (ddl_nullptr == al) { + return false; + } + + if (0 == al->m_numItems) { + return true; + } + + DataArrayList *nextDataArrayList = al ; + Value *nextValue( nextDataArrayList->m_dataList ); + while (ddl_nullptr != nextDataArrayList) { + if (ddl_nullptr != nextDataArrayList) { + statement += "{ "; + nextValue = nextDataArrayList->m_dataList; + size_t idx( 0 ); + while (ddl_nullptr != nextValue) { + if (idx > 0) { + statement += ", "; + } + writeValue( nextValue, statement ); + nextValue = nextValue->m_next; + idx++; + } + statement += " }"; + } + nextDataArrayList = nextDataArrayList->m_next; + } + + return true; +} + +END_ODDLPARSER_NS diff --git a/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLParser.cpp b/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLParser.cpp new file mode 100644 index 000000000..6f471be36 --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLParser.cpp @@ -0,0 +1,1008 @@ +/*----------------------------------------------------------------------------------------------- +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, + Reference *refs, size_t numRefs ) { + DataArrayList *dataList( new DataArrayList ); + dataList->m_dataList = currentValue; + dataList->m_numItems = numValues; + dataList->m_refs = refs; + dataList->m_numRefs = numRefs; + + return dataList; +} + +char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType type, + DataArrayList **dataArrayList ) { + if ( ddl_nullptr == dataArrayList ) { + return in; + } + + *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, refs, numRefs ); + prev = *dataArrayList; + } else { + currentDataList = createDataArrayList( currentValue, numValues, refs, numRefs ); + 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 diff --git a/src/3rdparty/assimp/contrib/openddlparser/code/Value.cpp b/src/3rdparty/assimp/contrib/openddlparser/code/Value.cpp new file mode 100644 index 000000000..3e251c508 --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/code/Value.cpp @@ -0,0 +1,440 @@ +/*----------------------------------------------------------------------------------------------- +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/Value.h> + +#include <iostream> +#include <cassert> + +BEGIN_ODDLPARSER_NS + +static Value::Iterator end( ddl_nullptr ); + +Value::Iterator::Iterator() +: m_start( ddl_nullptr ) +, m_current( ddl_nullptr ) { + // empty +} + +Value::Iterator::Iterator( Value *start ) +: m_start( start ) +, m_current( start ) { + // empty +} + +Value::Iterator::Iterator( const Iterator &rhs ) +: m_start( rhs.m_start ) +, m_current( rhs.m_current ) { + // empty +} + +Value::Iterator::~Iterator() { + // empty +} + +bool Value::Iterator::hasNext() const { + if( ddl_nullptr == m_current ) { + return false; + } + return ( ddl_nullptr != m_current->getNext() ); +} + +Value *Value::Iterator::getNext() { + if( !hasNext() ) { + return ddl_nullptr; + } + + Value *v( m_current->getNext() ); + m_current = v; + + return v; +} + +const Value::Iterator Value::Iterator::operator++( int ) { + if( ddl_nullptr == m_current ) { + return end; + } + + m_current = m_current->getNext(); + Iterator inst( m_current ); + + return inst; +} + +Value::Iterator &Value::Iterator::operator++( ) { + if( ddl_nullptr == m_current ) { + return end; + } + + m_current = m_current->getNext(); + + return *this; +} + +bool Value::Iterator::operator == ( const Iterator &rhs ) const { + return ( m_current == rhs.m_current ); +} + +Value *Value::Iterator::operator->( ) const { + if(ddl_nullptr == m_current ) { + return ddl_nullptr; + } + return m_current; +} + +Value::Value( ValueType type ) +: m_type( type ) +, m_size( 0 ) +, m_data( ddl_nullptr ) +, m_next( ddl_nullptr ) { + // empty +} + +Value::~Value() { + // empty +} + +void Value::setBool( bool value ) { + assert( ddl_bool == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +bool Value::getBool() { + assert( ddl_bool == m_type ); + return ( *m_data == 1 ); +} + +void Value::setInt8( int8 value ) { + assert( ddl_int8 == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +int8 Value::getInt8() { + assert( ddl_int8 == m_type ); + return ( int8 ) ( *m_data ); +} + +void Value::setInt16( int16 value ) { + assert( ddl_int16 == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +int16 Value::getInt16() { + assert( ddl_int16 == m_type ); + int16 i; + ::memcpy( &i, m_data, m_size ); + return i; +} + +void Value::setInt32( int32 value ) { + assert( ddl_int32 == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +int32 Value::getInt32() { + assert( ddl_int32 == m_type ); + int32 i; + ::memcpy( &i, m_data, m_size ); + return i; +} + +void Value::setInt64( int64 value ) { + assert( ddl_int64 == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +int64 Value::getInt64() { + assert( ddl_int64 == m_type ); + int64 i; + ::memcpy( &i, m_data, m_size ); + return i; +} + +void Value::setUnsignedInt8( uint8 value ) { + assert( ddl_unsigned_int8 == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +uint8 Value::getUnsignedInt8() const { + assert( ddl_unsigned_int8 == m_type ); + uint8 i; + ::memcpy( &i, m_data, m_size ); + return i; +} + +void Value::setUnsignedInt16( uint16 value ) { + assert( ddl_unsigned_int16 == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +uint16 Value::getUnsignedInt16() const { + assert( ddl_unsigned_int16 == m_type ); + uint16 i; + ::memcpy( &i, m_data, m_size ); + return i; +} + +void Value::setUnsignedInt32( uint32 value ) { + assert( ddl_unsigned_int32 == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +uint32 Value::getUnsignedInt32() const { + assert( ddl_unsigned_int32 == m_type ); + uint32 i; + ::memcpy( &i, m_data, m_size ); + return i; +} + +void Value::setUnsignedInt64( uint64 value ) { + assert( ddl_unsigned_int64 == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +uint64 Value::getUnsignedInt64() const { + assert( ddl_unsigned_int64 == m_type ); + uint64 i; + ::memcpy( &i, m_data, m_size ); + return i; +} + +void Value::setFloat( float value ) { + assert( ddl_float == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +float Value::getFloat() const { + if( m_type == ddl_float ) { + float v; + ::memcpy( &v, m_data, m_size ); + return ( float ) v; + } else { + float tmp; + ::memcpy( &tmp, m_data, 4 ); + return ( float ) tmp; + } +} + +void Value::setDouble( double value ) { + assert( ddl_double == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +double Value::getDouble() const { + if ( m_type == ddl_double ) { + double v; + ::memcpy( &v, m_data, m_size ); + return ( float ) v; + } + else { + double tmp; + ::memcpy( &tmp, m_data, 4 ); + return ( double ) tmp; + } +} + +void Value::setString( const std::string &str ) { + assert( ddl_string == m_type ); + ::memcpy( m_data, str.c_str(), str.size() ); + m_data[ str.size() ] = '\0'; +} + +const char *Value::getString() const { + assert( ddl_string == m_type ); + return (const char*) m_data; +} + +void Value::setRef( Reference *ref ) { + assert( ddl_ref == m_type ); + + if ( ddl_nullptr != ref ) { + const size_t sizeInBytes( ref->sizeInBytes() ); + if ( sizeInBytes > 0 ) { + if ( ddl_nullptr != m_data ) { + delete [] m_data; + } + + m_data = new unsigned char[ sizeof( Reference ) ]; + Reference *myRef = ( Reference * ) m_data; + myRef->m_numRefs = ref->m_numRefs; + myRef->m_referencedName = new Name *[ myRef->m_numRefs ]; + for ( size_t i = 0; i < myRef->m_numRefs; i++ ) { + myRef->m_referencedName[ i ] = new Name( ref->m_referencedName[ i ]->m_type, ref->m_referencedName[ i ]->m_id ); + } + } + } +} + +Reference *Value::getRef() const { + assert( ddl_ref == m_type ); + + return (Reference*) m_data; +} + +void Value::dump() { + switch( m_type ) { + case ddl_none: + std::cout << "None" << std::endl; + break; + case ddl_bool: + std::cout << getBool() << std::endl; + break; + case ddl_int8: + std::cout << getInt8() << std::endl; + break; + case ddl_int16: + std::cout << getInt16() << std::endl; + break; + case ddl_int32: + std::cout << getInt32() << std::endl; + break; + case ddl_int64: + std::cout << getInt64() << std::endl; + break; + case ddl_unsigned_int8: + std::cout << "Not supported" << std::endl; + break; + case ddl_unsigned_int16: + std::cout << "Not supported" << std::endl; + break; + case ddl_unsigned_int32: + std::cout << "Not supported" << std::endl; + break; + case ddl_unsigned_int64: + std::cout << "Not supported" << std::endl; + break; + case ddl_half: + std::cout << "Not supported" << std::endl; + break; + case ddl_float: + std::cout << getFloat() << std::endl; + break; + case ddl_double: + std::cout << getDouble() << std::endl; + break; + case ddl_string: + std::cout << getString() << std::endl; + break; + case ddl_ref: + std::cout << "Not supported" << std::endl; + break; + default: + break; + } +} + +void Value::setNext( Value *next ) { + m_next = next; +} + +Value *Value::getNext() const { + return m_next; +} + +size_t Value::size(){ + size_t result=1; + Value *n=m_next; + while( n!=ddl_nullptr) { + result++; + n=n->m_next; + } + return result; +} + +Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) { + if( type == Value::ddl_none || Value::ddl_types_max == type ) { + return ddl_nullptr; + } + + Value *data = new Value( type ); + data->m_type = type; + switch( type ) { + case Value::ddl_bool: + data->m_size = sizeof( bool ); + break; + case Value::ddl_int8: + data->m_size = sizeof( int8 ); + break; + case Value::ddl_int16: + data->m_size = sizeof( int16 ); + break; + case Value::ddl_int32: + data->m_size = sizeof( int32 ); + break; + case Value::ddl_int64: + data->m_size = sizeof( int64 ); + break; + case Value::ddl_unsigned_int8: + data->m_size = sizeof( uint8 ); + break; + case Value::ddl_unsigned_int16: + data->m_size = sizeof( uint16 ); + break; + case Value::ddl_unsigned_int32: + data->m_size = sizeof( uint32 ); + break; + case Value::ddl_unsigned_int64: + data->m_size = sizeof( uint64 ); + break; + case Value::ddl_half: + data->m_size = sizeof( short ); + break; + case Value::ddl_float: + data->m_size = sizeof( float ); + break; + case Value::ddl_double: + data->m_size = sizeof( double ); + break; + case Value::ddl_string: + data->m_size = sizeof( char ); + break; + case Value::ddl_ref: + data->m_size = sizeof( char ); + break; + case Value::ddl_none: + case Value::ddl_types_max: + default: + break; + } + + if( data->m_size ) { + size_t len1( len ); + if( Value::ddl_string == type ) { + len1++; + } + data->m_size *= len1; + data->m_data = new unsigned char[ data->m_size ]; + } + + return data; +} + +void ValueAllocator::releasePrimData( Value **data ) { + if( !data ) { + return; + } + + delete *data; + *data = ddl_nullptr; +} + +END_ODDLPARSER_NS diff --git a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/DDLNode.h b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/DDLNode.h new file mode 100644 index 000000000..137135604 --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/DDLNode.h @@ -0,0 +1,164 @@ +/*----------------------------------------------------------------------------------------------- +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. +-----------------------------------------------------------------------------------------------*/ +#pragma once + +#include <openddlparser/OpenDDLCommon.h> + +#include <vector> +#include <string> + +BEGIN_ODDLPARSER_NS + +class Value; +class OpenDDLParser; + +struct Identifier; +struct Reference; +struct Property; +struct DataArrayList; + +/// +/// @ingroup OpenDDLParser +/// @brief This class represents one single instance in the object tree of the parsed OpenDDL-file. +/// +/// A DDLNode represents one leaf in the OpenDDL-node tree. It can have one parent node and multiple children. +/// You can assign special properties to a single DDLNode instance. +/// A node instance can store values via a linked list. You can get the first value from the DDLNode. +/// A node can store data-array-lists and references as well. +/// +class DLL_ODDLPARSER_EXPORT DDLNode { +public: + friend class OpenDDLParser; + + /// @brief The child-node-list type. + typedef std::vector<DDLNode*> DllNodeList; + +public: + /// @brief The class destructor. + ~DDLNode(); + + /// @brief Will attach a parent node instance, an older one will be released. + /// @param parent [in] The parent node instance. + void attachParent( DDLNode *parent ); + + /// @brief Will try to detach a parent node instance, if there is any. + void detachParent(); + + /// @brief Returns the assigned parent node instance, will return ddl_nullptr id no parent is assigned. + /// @return The parent node instance. + DDLNode *getParent() const; + + /// @brief Returns the child node list. + /// @return The list of child nodes. + const DllNodeList &getChildNodeList() const; + + /// Set the type of the DDLNode instance. + /// @param type [in] The type. + void setType( const std::string &type ); + + /// @brief Returns the type of the DDLNode instance. + /// @return The type of the DDLNode instance. + const std::string &getType() const; + + /// Set the name of the DDLNode instance. + /// @param type [in] The name. + void setName( const std::string &name ); + + /// @brief Returns the name of the DDLNode instance. + /// @return The name of the DDLNode instance. + const std::string &getName() const; + + /// @brief Set a new property set. + /// @param prop [in] The first element of the property set. + void setProperties( Property *prop ); + + /// @brief Returns the first element of the assigned property set. + /// @return The first property of the assigned property set. + Property *getProperties() const; + + /// @brief Looks for a given property. + /// @param name [in] The name for the property to look for. + /// @return true, if a corresponding property is assigned to the node, false if not. + bool hasProperty( const std::string &name ); + + /// @brief Will return true, if any properties are assigned to the node instance. + /// @return True, if properties are assigned. + bool hasProperties() const; + + /// @brief Search for a given property and returns it. Will return ddl_nullptr if no property was found. + /// @param name [in] The name for the property to look for. + /// @return The property or ddl_nullptr if no property was found. + Property *findPropertyByName( const std::string &name ); + + /// @brief Set a new value set. + /// @param val [in] The first value instance of the value set. + void setValue( Value *val ); + + /// @brief Returns the first element of the assigned value set. + /// @return The first property of the assigned value set. + Value *getValue() const; + + /// @brief Set a new DataArrayList. + /// @param val [in] The DataArrayList instance. + void setDataArrayList( DataArrayList *dtArrayList ); + + /// @brief Returns the DataArrayList. + /// @return The DataArrayList. + DataArrayList *getDataArrayList() const; + + /// @brief Set a new Reference set. + /// @param val [in] The first value instance of the Reference set. + void setReferences( Reference *refs ); + + /// @brief Returns the first element of the assigned Reference set. + /// @return The first property of the assigned Reference set. + Reference *getReferences() const; + + /// @brief The creation method. + /// @param type [in] The DDLNode type. + /// @param name [in] The name for the new DDLNode instance. + /// @param parent [in] The parent node instance or ddl_nullptr if no parent node is there. + /// @return The new created node instance. + static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr ); + +private: + DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent = ddl_nullptr ); + DDLNode(); + DDLNode( const DDLNode & ) ddl_no_copy; + DDLNode &operator = ( const DDLNode & ) ddl_no_copy; + static void releaseNodes(); + +private: + std::string m_type; + std::string m_name; + DDLNode *m_parent; + std::vector<DDLNode*> m_children; + Property *m_properties; + Value *m_value; + DataArrayList *m_dtArrayList; + Reference *m_references; + size_t m_idx; + static DllNodeList s_allocatedNodes; +}; + +END_ODDLPARSER_NS diff --git a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h new file mode 100644 index 000000000..d3e0fb458 --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h @@ -0,0 +1,247 @@ +/*----------------------------------------------------------------------------------------------- +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. +-----------------------------------------------------------------------------------------------*/ +#pragma once + +#include <cstddef> +#include <vector> +#include <string> + +#include <stdio.h> +#include <string.h> +#ifndef _WIN32 +# include <inttypes.h> +#endif + +#if defined(_MSC_VER) && !defined( OPENDDL_STATIC_LIBARY ) + +# define TAG_DLL_EXPORT __declspec(dllexport) +# define TAG_DLL_IMPORT __declspec(dllimport ) +# ifdef OPENDDLPARSER_BUILD +# define DLL_ODDLPARSER_EXPORT TAG_DLL_EXPORT +# else +# define DLL_ODDLPARSER_EXPORT TAG_DLL_IMPORT +# endif // OPENDDLPARSER_BUILD +# pragma warning( disable : 4251 ) +#else +# define DLL_ODDLPARSER_EXPORT +#endif // _WIN32 + +// Namespace declarations, override this to avoid any conflicts +#define BEGIN_ODDLPARSER_NS namespace ODDLParser { +#define END_ODDLPARSER_NS } // namespace ODDLParser +#define USE_ODDLPARSER_NS using namespace ODDLParser; + +BEGIN_ODDLPARSER_NS + +// We will use C++11 optional +#ifndef OPENDDL_NO_USE_CPP11 + // All C++11 constructs +# define ddl_nullptr nullptr +# define ddl_override override +# define ddl_final final +# define ddl_no_copy = delete +#else + // Fall-back for older compilers +# define ddl_nullptr NULL +# define ddl_override +# define ddl_final +# define ddl_no_copy +#endif // OPENDDL_NO_USE_CPP11 + +// Forward declarations +class DDLNode; +class Value; + +struct Name; +struct Identifier; +struct Reference; +struct Property; +struct DataArrayList; + +// Platform-specific typedefs +#ifdef _WIN32 +typedef signed __int64 int64_impl; +typedef unsigned __int64 uint64_impl; +#else +typedef int64_t int64_impl; +typedef uint64_t uint64_impl; +#endif + +// OpenDDL-specific data typedefs +typedef signed char int8; ///< Signed integer, 1 byte +typedef signed short int16; ///< Signed integer, 2 byte +typedef signed int int32; ///< Signed integer, 4 byte +typedef int64_impl int64; ///< Signed integer, 8 byte +typedef unsigned char uint8; ///< Unsigned integer, 1 byte +typedef unsigned short uint16; ///< Unsigned integer, 2 byte +typedef unsigned int uint32; ///< Unsigned integer, 4 byte +typedef uint64_impl uint64; ///< Unsigned integer, 8 byte + +/// @brief Stores a text. +/// +/// A text is stored in a simple character buffer. Texts buffer can be +/// greater than the number of stored characters in them. +struct DLL_ODDLPARSER_EXPORT Text { + size_t m_capacity; ///< The capacity of the text. + size_t m_len; ///< The length of the text. + char *m_buffer; ///< The buffer with the text. + + /// @brief The constructor with a given text buffer. + /// @param buffer [in] The buffer. + /// @param numChars [in] The number of characters in the buffer. + Text( const char *buffer, size_t numChars ); + + /// @brief The destructor. + ~Text(); + + /// @brief Clears the text. + void clear(); + + /// @brief Set a new text. + /// @param buffer [in] The buffer. + /// @param numChars [in] The number of characters in the buffer. + void set( const char *buffer, size_t numChars ); + + /// @brief The compare operator for std::strings. + bool operator == ( const std::string &name ) const; + + /// @brief The compare operator for Texts. + bool operator == ( const Text &rhs ) const; + +private: + Text( const Text & ) ddl_no_copy; + Text &operator = ( const Text & ) ddl_no_copy; +}; + +/// @brief Description of the type of a name. +enum NameType { + GlobalName, ///< Name is global. + LocalName ///< Name is local. +}; + +/// @brief Stores an OpenDDL-specific name +struct DLL_ODDLPARSER_EXPORT Name { + NameType m_type; ///< The type of the name ( @see NameType ). + Text *m_id; ///< The id. + + /// @brief The constructor with the type and the id. + /// @param type [in] The name type. + /// @param id [in] The id. + Name( NameType type, Text *id ); + + /// @brief The destructor. + ~Name(); + +private: + Name( const Name & ) ddl_no_copy; + Name &operator = ( const Name& ) ddl_no_copy; +}; + +/// @brief Stores a bundle of references. +struct DLL_ODDLPARSER_EXPORT Reference { + size_t m_numRefs; ///< The number of stored references. + Name **m_referencedName; ///< The reference names. + + /// @brief The default constructor. + Reference(); + + /// @brief The constructor with an array of ref names. + /// @param numrefs [in] The number of ref names. + /// @param names [in] The ref names. + Reference( size_t numrefs, Name **names ); + + /// @brief The destructor. + ~Reference(); + + /// @brief Returns the size in bytes to store one deep reference copy. + /// @return The size on bytes. + size_t sizeInBytes(); + +private: + Reference( const Reference & ) ddl_no_copy; + Reference &operator = ( const Reference & ) ddl_no_copy; +}; + +/// @brief Stores a property list. +struct DLL_ODDLPARSER_EXPORT Property { + Text *m_key; ///< The identifier / key of the property. + Value *m_value; ///< The value assigned to its key / id ( ddl_nullptr if none ). + Reference *m_ref; ///< References assigned to its key / id ( ddl_nullptr if none ). + Property *m_next; ///< The next property ( ddl_nullptr if none ). + + /// @brief The default constructor. + Property(); + + /// @brief The constructor for initialization. + /// @param id [in] The identifier + Property( Text *id ); + + /// @brief The destructor. + ~Property(); + +private: + Property( const Property & ) ddl_no_copy; + Property &operator = ( const Property & ) ddl_no_copy; +}; + +/// @brief Stores a data array list. +struct DLL_ODDLPARSER_EXPORT DataArrayList { + size_t m_numItems; ///< The number of items in the list. + Value *m_dataList; ///< The data list ( a Value ). + DataArrayList *m_next; ///< The next data array list ( ddl_nullptr if last ). + Reference *m_refs; + size_t m_numRefs; + + /// @brief The default constructor for initialization. + DataArrayList(); + + /// @brief The destructor. + ~DataArrayList(); + + /// @brief Gets the length of the array + size_t size(); + +private: + DataArrayList( const DataArrayList & ) ddl_no_copy; + DataArrayList &operator = ( const DataArrayList & ) ddl_no_copy; +}; + +/// @brief Stores the context of a parsed OpenDDL declaration. +struct DLL_ODDLPARSER_EXPORT Context { + DDLNode *m_root; ///< The root node of the OpenDDL node tree. + + /// @brief Constructor for initialization. + Context(); + + /// @brief Destructor. + ~Context(); + + /// @brief Clears the whole node tree. + void clear(); + +private: + Context( const Context & ) ddl_no_copy; + Context &operator = ( const Context & ) ddl_no_copy; +}; + +END_ODDLPARSER_NS diff --git a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLExport.h b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLExport.h new file mode 100644 index 000000000..8ede537d9 --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLExport.h @@ -0,0 +1,104 @@ +/*----------------------------------------------------------------------------------------------- +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. +-----------------------------------------------------------------------------------------------*/ +#pragma once + +#include <openddlparser/OpenDDLCommon.h> +#include <openddlparser/Value.h> + +BEGIN_ODDLPARSER_NS + +//------------------------------------------------------------------------------------------------- +/// @ingroup IOStreamBase +/// @brief This class represents the stream to write out. +//------------------------------------------------------------------------------------------------- +class DLL_ODDLPARSER_EXPORT StreamFormatterBase { +public: + StreamFormatterBase(); + virtual ~StreamFormatterBase(); + virtual std::string format( const std::string &statement ); +}; + +//------------------------------------------------------------------------------------------------- +/// @ingroup IOStreamBase +/// @brief This class represents the stream to write out. +//------------------------------------------------------------------------------------------------- +class DLL_ODDLPARSER_EXPORT IOStreamBase { +public: + IOStreamBase( StreamFormatterBase *formatter = ddl_nullptr ); + virtual ~IOStreamBase(); + virtual bool open( const std::string &anme ); + virtual bool close(); + virtual size_t write( const std::string &statement ); + +private: + StreamFormatterBase *m_formatter; + FILE *m_file; +}; + +//------------------------------------------------------------------------------------------------- +/// +/// @ingroup OpenDDLParser +/// @brief This class represents the OpenDDLExporter. +/// +//------------------------------------------------------------------------------------------------- +class DLL_ODDLPARSER_EXPORT OpenDDLExport { +public: + /// @brief The class constructor + OpenDDLExport( IOStreamBase *stream = ddl_nullptr ); + + /// @brief The class destructor. + ~OpenDDLExport(); + + /// @brief Export the data of a parser context. + /// @param ctx [in] Pointer to the context. + /// @param filename [in] The filename for the export. + /// @return True in case of success, false in case of an error. + bool exportContext( Context *ctx, const std::string &filename ); + + /// @brief Handles a node export. + /// @param node [in] The node to handle with. + /// @return True in case of success, false in case of an error. + bool handleNode( DDLNode *node ); + + /// @brief Writes the statement to the stream. + /// @param statement [in] The content to write. + /// @return True in case of success, false in case of an error. + bool writeToStream( const std::string &statement ); + +protected: + bool writeNode( DDLNode *node, std::string &statement ); + bool writeNodeHeader( DDLNode *node, std::string &statement ); + bool writeProperties( DDLNode *node, std::string &statement ); + bool writeValueType( Value::ValueType type, size_t numItems, std::string &statement ); + bool writeValue( Value *val, std::string &statement ); + bool writeValueArray( DataArrayList *al, std::string &statement ); + +private: + OpenDDLExport( const OpenDDLExport & ) ddl_no_copy; + OpenDDLExport &operator = ( const OpenDDLExport & ) ddl_no_copy; + +private: + IOStreamBase *m_stream; +}; + +END_ODDLPARSER_NS diff --git a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParser.h b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParser.h new file mode 100644 index 000000000..efeab6026 --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParser.h @@ -0,0 +1,187 @@ +/*----------------------------------------------------------------------------------------------- +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. +-----------------------------------------------------------------------------------------------*/ +#pragma once + +#include <openddlparser/OpenDDLCommon.h> +#include <openddlparser/DDLNode.h> +#include <openddlparser/OpenDDLParserUtils.h> +#include <openddlparser/Value.h> + +#include <vector> +#include <string> + +BEGIN_ODDLPARSER_NS + +class DDLNode; +class Value; + +struct Identifier; +struct Reference; +struct Property; + +/// @brief Utility function to search for the next token or the end of the buffer. +/// @param in [in] The start position in the buffer. +/// @param end [in] The end position in the buffer. +/// @return Pointer showing to the next token or the end of the buffer. +/// @detail Will not increase buffer when already a valid buffer was found. +template<class T> +inline +T *lookForNextToken( T *in, T *end ) { + while( ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) && ( in != end ) ) { + in++; + } + return in; +} + +/// @brief Utility function to go for the next token or the end of the buffer. +/// @param in [in] The start position in the buffer. +/// @param end [in] The end position in the buffer. +/// @return Pointer showing to the next token or the end of the buffer. +/// @detail Will increase buffer by a minimum of one. +template<class T> +inline +T *getNextToken( T *in, T *end ) { + T *tmp( in ); + in = lookForNextToken( in, end ); + if( tmp == in ) { + in++; + } + return in; +} + +/// @brief Defines the log severity. +enum LogSeverity { + ddl_debug_msg = 0, ///< Debug message, for debugging + ddl_info_msg, ///< Info messages, normal mode + ddl_warn_msg, ///< Parser warnings + ddl_error_msg ///< Parser errors +}; + +DLL_ODDLPARSER_EXPORT const char *getTypeToken( Value::ValueType type ); + +//------------------------------------------------------------------------------------------------- +/// @class OpenDDLParser +/// @ingroup OpenDDLParser + +/// +/// @brief This is the main API for the OpenDDL-parser. +/// +/// Use instances of this class to manage the parsing and handling of your parser contexts. +//------------------------------------------------------------------------------------------------- +class DLL_ODDLPARSER_EXPORT OpenDDLParser { +public: + /// @brief The log callback function pointer. + typedef void( *logCallback )( LogSeverity severity, const std::string &msg ); + +public: + /// @brief The default class constructor. + OpenDDLParser(); + + /// @brief The class constructor. + /// @param buffer [in] The buffer + /// @param len [in] Size of the buffer + OpenDDLParser( const char *buffer, size_t len ); + + /// @brief The class destructor. + ~OpenDDLParser(); + + /// @brief Setter for an own log callback function. + /// @param callback [in] The own callback. + void setLogCallback( logCallback callback ); + + /// @brief Getter for the log callback. + /// @return The current log callback. + logCallback getLogCallback() const; + + /// @brief Assigns a new buffer to parse. + /// @param buffer [in] The buffer + /// @param len [in] Size of the buffer + void setBuffer( const char *buffer, size_t len ); + + /// @brief Assigns a new buffer to parse. + /// @param buffer [in] The buffer as a std::vector. + void setBuffer( const std::vector<char> &buffer ); + + /// @brief Returns the buffer pointer. + /// @return The buffer pointer. + const char *getBuffer() const; + + /// @brief Returns the size of the buffer. + /// @return The buffer size. + size_t getBufferSize() const; + + /// @brief Clears all parser data, including buffer and active context. + void clear(); + + /// @brief Starts the parsing of the OpenDDL-file. + /// @return True in case of success, false in case of an error. + /// @remark In case of errors check log. + bool parse(); + + bool exportContext( Context *ctx, const std::string &filename ); + + /// @brief Returns the root node. + /// @return The root node. + DDLNode *getRoot() const; + + /// @brief Returns the parser context, only available in case of a succeeded parsing. + /// @return Pointer to the active context or ddl_nullptr. + Context *getContext() const; + +public: // parser helpers + char *parseNextNode( char *current, char *end ); + char *parseHeader( char *in, char *end ); + char *parseStructure( char *in, char *end ); + char *parseStructureBody( char *in, char *end, bool &error ); + void pushNode( DDLNode *node ); + DDLNode *popNode(); + DDLNode *top(); + static void normalizeBuffer( std::vector<char> &buffer ); + static char *parseName( char *in, char *end, Name **name ); + static char *parseIdentifier( char *in, char *end, Text **id ); + static char *parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len ); + static char *parseReference( char *in, char *end, std::vector<Name*> &names ); + static char *parseBooleanLiteral( char *in, char *end, Value **boolean ); + static char *parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType = Value::ddl_int32 ); + static char *parseFloatingLiteral( char *in, char *end, Value **floating, Value::ValueType floatType= Value::ddl_float ); + static char *parseStringLiteral( char *in, char *end, Value **stringData ); + static char *parseHexaLiteral( char *in, char *end, Value **data ); + static char *parseProperty( char *in, char *end, Property **prop ); + static char *parseDataList( char *in, char *end, Value::ValueType type, Value **data, size_t &numValues, Reference **refs, size_t &numRefs ); + static char *parseDataArrayList( char *in, char *end, Value::ValueType type, DataArrayList **dataList ); + static const char *getVersion(); + +private: + OpenDDLParser( const OpenDDLParser & ) ddl_no_copy; + OpenDDLParser &operator = ( const OpenDDLParser & ) ddl_no_copy; + +private: + logCallback m_logCallback; + std::vector<char> m_buffer; + + typedef std::vector<DDLNode*> DDLNodeStack; + DDLNodeStack m_stack; + Context *m_context; +}; + +END_ODDLPARSER_NS diff --git a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h new file mode 100644 index 000000000..778a1b46e --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h @@ -0,0 +1,254 @@ +/*----------------------------------------------------------------------------------------------- +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. +-----------------------------------------------------------------------------------------------*/ +#pragma once + +#include <openddlparser/OpenDDLCommon.h> + +BEGIN_ODDLPARSER_NS + +template<class T> +inline +bool isUpperCase( T in ) { + return ( in >= 'A' && in <= 'Z' ); +} + +template<class T> +inline +bool isLowerCase( T in ) { + return ( in >= 'a' && in <= 'z' ); +} + +template<class T> +inline +bool isSpace( const T in ) { + return ( ' ' == in || '\t' == in ); +} + +template<class T> +inline +bool isNewLine( const T in ) { + return ( '\n' == in || ( '\r' == in ) ); +} + +template<class T> +inline +bool isSeparator( T in ) { + if( isSpace( in ) || ',' == in || '{' == in || '}' == in || '[' == in || '(' == in || ')' == in ) { + return true; + } + return false; +} + +static const unsigned char chartype_table[ 256 ] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32-47 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // 48-63 + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 64-79 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-95 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 96-111 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 112-127 + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // > 127 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +template<class T> +inline +bool isNumeric( const T in ) { + return ( chartype_table[ static_cast<int>( in ) ] == 1 ); +} + +template<class T> +inline +bool isNotEndOfToken( T *in, T *end ) { + return ( '}' != *in && ',' != *in && !isSpace( *in ) && ')' != *in && in != end ); +} + +template<class T> +inline +bool isInteger( T *in, T *end ) { + if( in != end ) { + if( *in == '-' ) { + in++; + } + } + + bool result( false ); + while( isNotEndOfToken( in, end ) ) { + result = isNumeric( *in ); + if( !result ) { + break; + } + in++; + } + + return result; +} + +template<class T> +inline +bool isFloat( T *in, T *end ) { + if( in != end ) { + if( *in == '-' ) { + in++; + } + } + + // check for <1>.0f + bool result( false ); + while( isNotEndOfToken( in, end ) ) { + if( *in == '.' ) { + result = true; + break; + } + result = isNumeric( *in ); + if( !result ) { + return false; + } + in++; + } + + // check for 1<.>0f + if( *in == '.' ) { + in++; + } else { + return false; + } + + // check for 1.<0>f + while( isNotEndOfToken( in, end ) ) { + result = isNumeric( *in ); + if( !result ) { + return false; + } + in++; + } + + return result; +} + +template<class T> +inline +bool isCharacter( const T in ) { + return ( ( in >= 'a' && in <= 'z' ) || ( in >= 'A' && in <= 'Z' ) ); +} + +template<class T> +inline +bool isStringLiteral( const T in ) { + return ( in == '\"' ); +} + +template<class T> +inline +bool isHexLiteral( T *in, T *end ) { + if( *in == '0' ) { + if( in + 1 != end ) { + if( *( in + 1 ) == 'x' || *( in + 1 ) == 'X' ) { + return true; + } + } + } + + return false; +} + +template<class T> +inline +bool isReference( T *in, T *end ) { + if( *in == 'r' ) { + if( *(in+1) == 'e' ) { + if( *(in+2) == 'f' ) { + if( ( in + 2 ) != end ) { + return true; + } + } + } + } + + return false; +} + +template<class T> +inline +bool isEndofLine( const T in ) { + return ( '\n' == in ); +} + +template<class T> +inline +static T *getNextSeparator( T *in, T *end ) { + while( !isSeparator( *in ) || in == end ) { + in++; + } + return in; +} + +static const int ErrorHex2Decimal = 9999999; + +inline +int hex2Decimal( char in ) { + if( isNumeric( in ) ) { + return ( in - 48 ); + } + + char hexCodeLower( 'a' ), hexCodeUpper( 'A' ); + for( int i = 0; i<16; i++ ) { + if( in == hexCodeLower + i || in == hexCodeUpper + i ) { + return ( i+10 ); + } + } + + return ErrorHex2Decimal; +} + +template<class T> +inline +bool isComment( T *in, T *end ) { + if ( *in=='/' ) { + if ( in+1!=end ) { + if ( *( in+1 )=='/' ) { + char *drive( ( in+2 ) ); + if ( (isUpperCase<T>( *drive )||isLowerCase<T>( *drive ))&&*( drive+1 )=='/' ) { + return false; + } else { + return true; + } + } + } + } + + return false; +} + +END_ODDLPARSER_NS + diff --git a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/Value.h b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/Value.h new file mode 100644 index 000000000..242ec8781 --- /dev/null +++ b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/Value.h @@ -0,0 +1,269 @@ +/*----------------------------------------------------------------------------------------------- +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. +-----------------------------------------------------------------------------------------------*/ +#pragma once + +#include <openddlparser/OpenDDLCommon.h> + +#include <string> + +BEGIN_ODDLPARSER_NS + +struct ValueAllocator; + +///------------------------------------------------------------------------------------------------ +/// @brief This class implements a value. +/// +/// Values are used to store data types like boolean, integer, floats, double and many mode. To get +/// an overview please check the enum VylueType ( @see Value::ValueType ). +/// Values can be single items or lists of items. They are implemented as linked lists. +///------------------------------------------------------------------------------------------------ +class DLL_ODDLPARSER_EXPORT Value { + friend struct ValueAllocator; + +public: + /// @brief This class implements an iterator through a Value list. + /// + /// When getting a new value you need to know how to iterate through it. The Value::Iterator + /// will help you here: + /// @code + /// Value *val = node->getValue(); + /// Value::Iterator it( val ); + /// while( it.hasNext() ) { + /// Value v( it.getNext ); + /// } + /// @endcode + class DLL_ODDLPARSER_EXPORT Iterator { + public: + /// @brief The default class constructor. + Iterator(); + + /// @brief The class constructor with the start value. + /// @param start [in] The first value for iteration, + Iterator( Value *start ); + + Iterator( const Iterator &rhs ); + + /// @brief The class destructor. + ~Iterator(); + + /// @brief Will return true, if another value is in the list. + /// @return true if another value is there. + bool hasNext() const; + + /// @brief Returns the next item and moves the iterator to it. + /// @return The next value, is ddl_nullptr in case of being the last item. + Value *getNext(); + + /// @brief The post-increment operator. + const Iterator operator++( int ); + + /// @brief The pre-increment operator. + Iterator &operator++( ); + + /// @brief The compare operator. + /// @param rhs [in] The instance to compare. + /// @return true if equal. + bool operator == ( const Iterator &rhs ) const; + + /// @brief The * operator. + /// @return The instance or ddl_nullptr if end of list is reached. + Value *operator->( ) const; + + private: + Value *m_start; + Value *m_current; + + private: + Iterator &operator = ( const Iterator & ); + }; + + /// @brief This enum describes the data type stored in the value. + enum ValueType { + ddl_none = -1, ///< Nothing specified + ddl_bool = 0, ///< A boolean type + ddl_int8, ///< Integer type, 8 bytes + ddl_int16, ///< Integer type, 16 bytes + ddl_int32, ///< Integer type, 32 bytes + ddl_int64, ///< Integer type, 64 bytes + ddl_unsigned_int8, ///< Unsigned integer type, 8 bytes + ddl_unsigned_int16, ///< Unsigned integer type, 16 bytes + ddl_unsigned_int32, ///< Unsigned integer type, 32 bytes + ddl_unsigned_int64, ///< Unsigned integer type, 64 bytes + ddl_half, ///< Half data type. + ddl_float, ///< float data type + ddl_double, ///< Double data type. + ddl_string, ///< String data type. + ddl_ref, ///< Reference, used to define references to other data definitions. + ddl_types_max ///< Upper limit. + }; + + /// @brief The class constructor. + /// @param type [in] The value type. + Value( ValueType type ); + + /// @brief The class destructor. + ~Value(); + + /// @brief Assigns a boolean to the value. + /// @param value [in9 The value. + void setBool( bool value ); + + /// @brief Returns the boolean value. + /// @return The boolean value. + bool getBool(); + + /// @brief Assigns a int8 to the value. + /// @param value [in] The value. + void setInt8( int8 value ); + + /// @brief Returns the int8 value. + /// @return The int8 value. + int8 getInt8(); + + /// @brief Assigns a int16 to the value. + /// @param value [in] The value. + void setInt16( int16 value ); + + /// @brief Returns the int16 value. + /// @return The int16 value. + int16 getInt16(); + + /// @brief Assigns a int32 to the value. + /// @param value [in] The value. + void setInt32( int32 value ); + + /// @brief Returns the int16 value. + /// @return The int32 value. + int32 getInt32(); + + /// @brief Assigns a int64 to the value. + /// @param value [in] The value. + void setInt64( int64 value ); + + /// @brief Returns the int16 value. + /// @return The int64 value. + int64 getInt64(); + + /// @brief Assigns a unsigned int8 to the value. + /// @param value [in] The value. + void setUnsignedInt8( uint8 value ); + + /// @brief Returns the unsigned int8 value. + /// @return The unsigned int8 value. + uint8 getUnsignedInt8() const; + + /// @brief Assigns a unsigned int16 to the value. + /// @param value [in] The value. + void setUnsignedInt16( uint16 value ); + + /// @brief Returns the unsigned int16 value. + /// @return The unsigned int16 value. + uint16 getUnsignedInt16() const; + + /// @brief Assigns a unsigned int32 to the value. + /// @param value [in] The value. + void setUnsignedInt32( uint32 value ); + + /// @brief Returns the unsigned int8 value. + /// @return The unsigned int32 value. + uint32 getUnsignedInt32() const; + + /// @brief Assigns a unsigned int64 to the value. + /// @param value [in] The value. + void setUnsignedInt64( uint64 value ); + + /// @brief Returns the unsigned int64 value. + /// @return The unsigned int64 value. + uint64 getUnsignedInt64() const; + + /// @brief Assigns a float to the value. + /// @param value [in] The value. + void setFloat( float value ); + + /// @brief Returns the float value. + /// @return The float value. + float getFloat() const; + + /// @brief Assigns a double to the value. + /// @param value [in] The value. + void setDouble( double value ); + + /// @brief Returns the double value. + /// @return The double value. + double getDouble() const; + + /// @brief Assigns a std::string to the value. + /// @param value [in] The value. + void setString( const std::string &str ); + + /// @brief Returns the std::string value. + /// @return The std::string value. + const char *getString() const; + + /// @brief Set the reference. + /// @param ref [in] Pointer showing to the reference. + void setRef( Reference *ref ); + + /// @brief Returns the pointer showing to the reference. + /// @return Pointer showing to the reference. + Reference *getRef() const; + + /// @brief Dumps the value. + void dump(); + + /// @brief Assigns the next value. + /// @param next [n] The next value. + void setNext( Value *next ); + + /// @brief Returns the next value. + /// @return The next value.s + Value *getNext() const; + + /// @brief Gets the length of the array. + /// @return The number of items in the array. + size_t size(); + + ValueType m_type; + size_t m_size; + unsigned char *m_data; + Value *m_next; + +private: + Value &operator =( const Value & ) ddl_no_copy; + Value( const Value & ) ddl_no_copy; +}; + +///------------------------------------------------------------------------------------------------ +/// @brief This class implements the value allocator. +///------------------------------------------------------------------------------------------------ +struct DLL_ODDLPARSER_EXPORT ValueAllocator { + static Value *allocPrimData( Value::ValueType type, size_t len = 1 ); + static void releasePrimData( Value **data ); + +private: + ValueAllocator() ddl_no_copy; + ValueAllocator( const ValueAllocator & ) ddl_no_copy; + ValueAllocator &operator = ( const ValueAllocator & ) ddl_no_copy; +}; + +END_ODDLPARSER_NS |