diff options
Diffstat (limited to 'libs/assimp/contrib/openddlparser')
18 files changed, 4499 insertions, 0 deletions
diff --git a/libs/assimp/contrib/openddlparser/CMakeLists.txt b/libs/assimp/contrib/openddlparser/CMakeLists.txt new file mode 100644 index 0000000..407f084 --- /dev/null +++ b/libs/assimp/contrib/openddlparser/CMakeLists.txt @@ -0,0 +1,170 @@ +CMAKE_MINIMUM_REQUIRED( VERSION 3.10 ) +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 ${OPENDDL_PARSER_VERSION_MAJOR}.${OPENDDL_PARSER_VERSION_MINOR}.${OPENDDL_PARSER_VERSION_PATCH} ) +SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" ) + +option( DDL_DEBUG_OUTPUT "Set to ON to use output debug texts" OFF ) +option( DDL_STATIC_LIBRARY "Set to ON to build static libary of OpenDDL Parser." ON ) +option( COVERALLS "Generate coveralls data" OFF ) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) + find_package(Threads) +else() + add_definitions( -D_CRT_SECURE_NO_WARNINGS ) +endif() + +if ( DDL_STATIC_LIBRARY ) + add_definitions( -DOPENDDL_STATIC_LIBARY ) +endif() + +if (MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING") + add_definitions(-DGTEST_HAS_TR1_TUPLE=0) +endif() + +add_definitions( -DOPENDDLPARSER_BUILD ) +add_definitions( -D_VARIADIC_MAX=10 ) +add_definitions( -DGTEST_HAS_PTHREAD=0 ) +if ( DDL_DEBUG_OUTPUT ) + add_definitions( -DDDL_DEBUG_HEADER_NAME) +endif() + +INCLUDE_DIRECTORIES( + ./ + include/ + contrib/gtest-1.7.0/include + contrib/gtest-1.7.0/ +) + +link_directories( + ${CMAKE_HOME_DIRECTORY}/lib +) + +SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake ) +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 ${OPENDDL_CXXFLAGS}") +elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic ${OPENDDL_CXXFLAGS} -Wwrite-strings") +endif() + +if (COVERALLS) + include(Coveralls) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") +endif() + +# Include the doc component. +FIND_PACKAGE( doxygen ) +IF ( DOXYGEN_FOUND ) + CONFIGURE_FILE( doc/openddlparser_doc.in doc/doxygenfile @ONLY ) + ADD_CUSTOM_TARGET( doc ALL ${DOXYGEN_EXECUTABLE} doc/doxygenfile + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation with Doxygen" VERBATIM ) +ENDIF ( DOXYGEN_FOUND ) + +SET ( openddl_parser_src + code/OpenDDLCommon.cpp + code/OpenDDLExport.cpp + code/OpenDDLParser.cpp + code/OpenDDLStream.cpp + code/DDLNode.cpp + code/Value.cpp + include/openddlparser/OpenDDLCommon.h + include/openddlparser/OpenDDLExport.h + include/openddlparser/OpenDDLParser.h + include/openddlparser/OpenDDLParserUtils.h + include/openddlparser/OpenDDLStream.h + include/openddlparser/DDLNode.h + include/openddlparser/Value.h + include/openddlparser/TPoolAllocator.h + README.md +) + +SOURCE_GROUP( code FILES ${openddl_parser_src} ) + +if ( DDL_STATIC_LIBRARY ) + ADD_LIBRARY( openddl_parser STATIC + ${openddl_parser_src} + ) +else() + ADD_LIBRARY( openddl_parser SHARED + ${openddl_parser_src} + ) +endif() + +SET ( GTEST_PATH contrib/gtest-1.7.0 ) + +SET ( gtest_src + ${GTEST_PATH}/src/gtest-death-test.cc + ${GTEST_PATH}/src/gtest-filepath.cc + ${GTEST_PATH}/src/gtest-internal-inl.h + ${GTEST_PATH}/src/gtest-port.cc + ${GTEST_PATH}/src/gtest-printers.cc + ${GTEST_PATH}/src/gtest-test-part.cc + ${GTEST_PATH}/src/gtest-typed-test.cc + ${GTEST_PATH}/src/gtest.cc +) + +SET( openddl_parser_unittest_src + test/UnitTestCommon.h + test/DDLNodeTest.cpp + test/OpenDDLCommonTest.cpp + test/OpenDDLExportTest.cpp + test/OpenDDLParserTest.cpp + test/OpenDDLParserUtilsTest.cpp + test/OpenDDLStreamTest.cpp + test/OpenDDLIntegrationTest.cpp + test/ValueTest.cpp + test/OpenDDLDefectsTest.cpp + test/OssFuzzTest.cpp + test/main.cpp +) +add_definitions(-DOPENDDL_TEST_DATA="${CMAKE_CURRENT_LIST_DIR}/test/TestData") + +SOURCE_GROUP( code FILES ${openddl_parser_unittest_src} ) +SOURCE_GROUP( gtest FILES ${gtest_src} ) + +ADD_EXECUTABLE( openddl_parser_unittest + ${gtest_src} + ${openddl_parser_unittest_src} +) + +target_link_libraries( openddl_parser_unittest openddl_parser ${CMAKE_THREAD_LIBS_INIT} ) + +SET( openddl_parser_demo_src + demo/main.cpp +) + +if (COVERALLS) + set(COVERAGE_SRCS ${gtest_src} ${openddl_parser_unittest_src} ) + + # Create the coveralls target. + coveralls_setup( + "${COVERAGE_SRCS}" # The source files. + ON # If we should upload. + "${PROJECT_SOURCE_DIR}/cmake/") # (Optional) Alternate project cmake module path. +endif() + +ADD_EXECUTABLE( openddl_parser_demo + ${openddl_parser_demo_src} +) + +target_link_libraries( openddl_parser_demo openddl_parser ) diff --git a/libs/assimp/contrib/openddlparser/CREDITS b/libs/assimp/contrib/openddlparser/CREDITS new file mode 100644 index 0000000..d3936af --- /dev/null +++ b/libs/assimp/contrib/openddlparser/CREDITS @@ -0,0 +1,19 @@ +=============================================================== +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 + +- (wise86-android) +fix several mem-leaks + +- Paul Holland ( pkholland ): +Bugfixes. diff --git a/libs/assimp/contrib/openddlparser/LICENSE b/libs/assimp/contrib/openddlparser/LICENSE new file mode 100644 index 0000000..4c1476b --- /dev/null +++ b/libs/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/libs/assimp/contrib/openddlparser/README.md b/libs/assimp/contrib/openddlparser/README.md new file mode 100644 index 0000000..a48ea1b --- /dev/null +++ b/libs/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> +Current test coverage:[![Coverage Status](https://coveralls.io/repos/github/kimkulling/openddl-parser/badge.svg?branch=master)](https://coveralls.io/github/kimkulling/openddl-parser?branch=cpp_coveralls) +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 preferred build tool ( 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/libs/assimp/contrib/openddlparser/code/DDLNode.cpp b/libs/assimp/contrib/openddlparser/code/DDLNode.cpp new file mode 100644 index 0000000..724c5d6 --- /dev/null +++ b/libs/assimp/contrib/openddlparser/code/DDLNode.cpp @@ -0,0 +1,227 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2020 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 <openddlparser/OpenDDLStream.h> + +#include <algorithm> + +BEGIN_ODDLPARSER_NS + +DDLNode::DllNodeList DDLNode::s_allocatedNodes; + +template <class T> +inline static void releaseDataType(T *ptr) { + if (nullptr == ptr) { + return; + } + + T *current(nullptr); + while (ptr) { + current = ptr; + ptr = ptr->m_next; + delete current; + } +} + +static void releaseReferencedNames(Reference *ref) { + if (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(nullptr), + m_value(nullptr), + m_dtArrayList(nullptr), + m_references(nullptr), + m_idx(idx) { + if (m_parent) { + m_parent->m_children.push_back(this); + } +} + +DDLNode::~DDLNode() { + delete m_properties; + delete m_value; + releaseReferencedNames(m_references); + + delete m_dtArrayList; + m_dtArrayList = nullptr; + if (s_allocatedNodes[m_idx] == this) { + s_allocatedNodes[m_idx] = nullptr; + } + for (size_t i = 0; i < m_children.size(); i++) { + delete m_children[i]; + } +} + +void DDLNode::attachParent(DDLNode *parent) { + if (m_parent == parent) { + return; + } + + m_parent = parent; + if (nullptr != m_parent) { + m_parent->m_children.push_back(this); + } +} + +void DDLNode::detachParent() { + if (nullptr != m_parent) { + DDLNodeIt 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 = 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) { + if (m_properties != nullptr) + delete m_properties; + m_properties = prop; +} + +Property *DDLNode::getProperties() const { + return m_properties; +} + +bool DDLNode::hasProperty(const std::string &name) { + const Property *prop(findPropertyByName(name)); + return (nullptr != prop); +} + +bool DDLNode::hasProperties() const { + return (nullptr != m_properties); +} + +Property *DDLNode::findPropertyByName(const std::string &name) { + if (name.empty()) { + return nullptr; + } + + if (nullptr == m_properties) { + return nullptr; + } + + Property *current(m_properties); + while (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 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; +} + +void DDLNode::dump(IOStreamBase &stream) { + if (!stream.isOpen()) { + return; + } + + const std::string &type = this->getType(); + stream.write("type = " + type); + Value::Iterator it(getValue()); + while (it.hasNext()) { + Value *v = it.getNext(); + v->dump(stream); + } +} + +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 (DDLNodeIt it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++) { + if (*it) { + delete *it; + } + } + s_allocatedNodes.clear(); + } +} + +END_ODDLPARSER_NS diff --git a/libs/assimp/contrib/openddlparser/code/OpenDDLCommon.cpp b/libs/assimp/contrib/openddlparser/code/OpenDDLCommon.cpp new file mode 100644 index 0000000..d853efa --- /dev/null +++ b/libs/assimp/contrib/openddlparser/code/OpenDDLCommon.cpp @@ -0,0 +1,200 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2020 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/OpenDDLCommon.h> +#include <openddlparser/Value.h> + +BEGIN_ODDLPARSER_NS + +Text::Text(const char *buffer, size_t numChars) : + m_capacity(0), + m_len(0), + m_buffer(nullptr) { + set(buffer, numChars); +} + +Text::~Text() { + clear(); +} + +void Text::clear() { + delete[] m_buffer; + m_buffer = 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 = nullptr; +} + +Name::Name(const Name &name) { + m_type = name.m_type; + m_id = new Text(name.m_id->m_buffer, name.m_id->m_len); +} + +Reference::Reference() : + m_numRefs(0), m_referencedName(nullptr) { + // empty +} + +Reference::Reference(size_t numrefs, Name **names) : + m_numRefs(numrefs), m_referencedName(nullptr) { + if (numrefs > 0) { + m_referencedName = new Name *[numrefs]; + for (size_t i = 0; i < numrefs; i++) { + m_referencedName[i] = names[i]; + } + } +} +Reference::Reference(const Reference &ref) { + m_numRefs = ref.m_numRefs; + if (m_numRefs != 0) { + m_referencedName = new Name *[m_numRefs]; + for (size_t i = 0; i < m_numRefs; i++) { + m_referencedName[i] = new Name(*ref.m_referencedName[i]); + } + } +} + +Reference::~Reference() { + for (size_t i = 0; i < m_numRefs; i++) { + delete m_referencedName[i]; + } + m_numRefs = 0; + delete[] m_referencedName; + m_referencedName = 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 (nullptr != name) { + size += name->m_id->m_len; + } + } + + return size; +} + +Property::Property(Text *id) : + m_key(id), m_value(nullptr), m_ref(nullptr), m_next(nullptr) { + // empty +} + +Property::~Property() { + delete m_key; + if (m_value != nullptr) + delete m_value; + if (m_ref != nullptr) + delete (m_ref); + if (m_next != nullptr) + delete m_next; +} + +DataArrayList::DataArrayList() : + m_numItems(0), m_dataList(nullptr), m_next(nullptr), m_refs(nullptr), m_numRefs(0) { + // empty +} + +DataArrayList::~DataArrayList() { + delete m_dataList; + if (m_next != nullptr) + delete m_next; + if (m_refs != nullptr) + delete m_refs; +} + +size_t DataArrayList::size() { + size_t result(0); + if (nullptr == m_next) { + if (m_dataList != nullptr) { + result = 1; + } + return result; + } + + DataArrayList *n(m_next); + while (nullptr != n) { + result++; + n = n->m_next; + } + return result; +} + +Context::Context() : + m_root(nullptr) { + // empty +} + +Context::~Context() { + clear(); +} + +void Context::clear() { + delete m_root; + m_root = nullptr; +} + +END_ODDLPARSER_NS diff --git a/libs/assimp/contrib/openddlparser/code/OpenDDLExport.cpp b/libs/assimp/contrib/openddlparser/code/OpenDDLExport.cpp new file mode 100644 index 0000000..d235b55 --- /dev/null +++ b/libs/assimp/contrib/openddlparser/code/OpenDDLExport.cpp @@ -0,0 +1,361 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2020 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/OpenDDLExport.h> +#include <openddlparser/OpenDDLParser.h> +#include <openddlparser/Value.h> + +#include <sstream> + +BEGIN_ODDLPARSER_NS + +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 (nullptr == m_stream) { + m_stream = new IOStreamBase(); + } +} + +OpenDDLExport::~OpenDDLExport() { + if (nullptr != m_stream) { + m_stream->close(); + } + delete m_stream; +} + +bool OpenDDLExport::exportContext(Context *ctx, const std::string &filename) { + if (nullptr == ctx) { + return false; + } + + DDLNode *root(ctx->m_root); + if (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 (nullptr == node) { + return true; + } + + const DDLNode::DllNodeList &childs = node->getChildNodeList(); + if (childs.empty()) { + return true; + } + DDLNode *current(nullptr); + DDLNodeIterator it(childs); + std::string statement; + bool success(true); + while (it.getNext(¤t)) { + if (nullptr != current) { + success |= writeNode(current, statement); + if (!handleNode(current)) { + success = false; + } + } + } + + return success; +} + +bool OpenDDLExport::writeToStream(const std::string &statement) { + if (nullptr == m_stream) { + return false; + } + + if (!statement.empty()) { + m_stream->write(statement); + } + + return true; +} + +bool OpenDDLExport::writeNode(DDLNode *node, std::string &statement) { + writeNodeHeader(node, statement); + if (node->hasProperties()) { + writeProperties(node, statement); + } + writeLineEnd(statement); + + statement = "}"; + DataArrayList *al(node->getDataArrayList()); + if (nullptr != al) { + writeValueType(al->m_dataList->m_type, al->m_numItems, statement); + writeValueArray(al, statement); + } + Value *v(node->getValue()); + if (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 (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 (nullptr == node) { + return false; + } + + Property *prop(node->getProperties()); + // if no properties are there, return + if (nullptr == prop) { + return true; + } + + if (nullptr != prop) { + // for instance (attrib = "position", bla=2) + statement += "("; + bool first(true); + while (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::ValueType::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", static_cast<int>(numItems)); + statement += buffer; + statement += "]"; + } + + return true; +} + +bool OpenDDLExport::writeValue(Value *val, std::string &statement) { + if (nullptr == val) { + return false; + } + + switch (val->m_type) { + case Value::ValueType::ddl_bool: + if (true == val->getBool()) { + statement += "true"; + } else { + statement += "false"; + } + break; + case Value::ValueType::ddl_int8 : { + std::stringstream stream; + const int i = static_cast<int>(val->getInt8()); + stream << i; + statement += stream.str(); + } break; + case Value::ValueType::ddl_int16: { + std::stringstream stream; + char buffer[256]; + ::memset(buffer, '\0', 256 * sizeof(char)); + sprintf(buffer, "%d", val->getInt16()); + statement += buffer; + } break; + case Value::ValueType::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::ValueType::ddl_int64: { + std::stringstream stream; + const int i = static_cast<int>(val->getInt64()); + stream << i; + statement += stream.str(); + } break; + case Value::ValueType::ddl_unsigned_int8: { + std::stringstream stream; + const int i = static_cast<unsigned int>(val->getUnsignedInt8()); + stream << i; + statement += stream.str(); + } break; + case Value::ValueType::ddl_unsigned_int16: { + std::stringstream stream; + const int i = static_cast<unsigned int>(val->getUnsignedInt16()); + stream << i; + statement += stream.str(); + } break; + case Value::ValueType::ddl_unsigned_int32: { + std::stringstream stream; + const int i = static_cast<unsigned int>(val->getUnsignedInt32()); + stream << i; + statement += stream.str(); + } break; + case Value::ValueType::ddl_unsigned_int64: { + std::stringstream stream; + const int i = static_cast<unsigned int>(val->getUnsignedInt64()); + stream << i; + statement += stream.str(); + } break; + case Value::ValueType::ddl_half: + break; + case Value::ValueType::ddl_float: { + std::stringstream stream; + stream << val->getFloat(); + statement += stream.str(); + } break; + case Value::ValueType::ddl_double: { + std::stringstream stream; + stream << val->getDouble(); + statement += stream.str(); + } break; + case Value::ValueType::ddl_string: { + std::stringstream stream; + stream << val->getString(); + statement += "\""; + statement += stream.str(); + statement += "\""; + } break; + case Value::ValueType::ddl_ref: + break; + case Value::ValueType::ddl_none: + case Value::ValueType::ddl_types_max: + default: + break; + } + + return true; +} + +bool OpenDDLExport::writeValueArray(DataArrayList *al, std::string &statement) { + if (nullptr == al) { + return false; + } + + if (0 == al->m_numItems) { + return true; + } + + DataArrayList *nextDataArrayList = al; + Value *nextValue(nextDataArrayList->m_dataList); + while (nullptr != nextDataArrayList) { + if (nullptr != nextDataArrayList) { + statement += "{ "; + nextValue = nextDataArrayList->m_dataList; + size_t idx(0); + while (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/libs/assimp/contrib/openddlparser/code/OpenDDLParser.cpp b/libs/assimp/contrib/openddlparser/code/OpenDDLParser.cpp new file mode 100644 index 0000000..e2bef97 --- /dev/null +++ b/libs/assimp/contrib/openddlparser/code/OpenDDLParser.cpp @@ -0,0 +1,1035 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2020 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/OpenDDLParser.h> + +#include <math.h> +#include <algorithm> +#include <cassert> +#include <iostream> +#include <sstream> + +#ifdef _WIN32 +#include <windows.h> +#endif // _WIN32 + +BEGIN_ODDLPARSER_NS + +static const char *Version = "0.4.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[(size_t)Value::ValueType::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[(size_t)type]; +} + +static void logInvalidTokenError(char *in, const std::string &exp, OpenDDLParser::logCallback callback) { + if (callback) { + std::string full(in); + std::string part(full.substr(0, 50)); + std::stringstream stream; + stream << "Invalid token \"" << *in << "\" " + << "(expected \"" << exp << "\") " + << "in: \"" << part << "\""; + callback(ddl_error_msg, stream.str()); + } +} + +static bool isIntegerType(Value::ValueType integerType) { + if (integerType != Value::ValueType::ddl_int8 && integerType != Value::ValueType::ddl_int16 && + integerType != Value::ValueType::ddl_int32 && integerType != Value::ValueType::ddl_int64) { + return false; + } + + return true; +} + +static bool isUnsignedIntegerType(Value::ValueType integerType) { + if (integerType != Value::ValueType::ddl_unsigned_int8 && integerType != Value::ValueType::ddl_unsigned_int16 && + integerType != Value::ValueType::ddl_unsigned_int32 && integerType != Value::ValueType::ddl_unsigned_int64) { + return false; + } + + return true; +} + +static DDLNode *createDDLNode(Text *id, OpenDDLParser *parser) { + if (nullptr == id || nullptr == parser || id->m_buffer == nullptr) { + return nullptr; + } + + const std::string type(id->m_buffer); + DDLNode *parent(parser->top()); + DDLNode *node = DDLNode::create(type, "", parent); + + return node; +} + +OpenDDLParser::OpenDDLParser() : + m_logCallback(nullptr), + m_buffer(), + m_stack(), + m_context(nullptr) { + // empty +} + +OpenDDLParser::OpenDDLParser(const char *buffer, size_t len) : + m_logCallback(nullptr), m_buffer(), m_context(nullptr) { + if (0 != len) { + setBuffer(buffer, len); + } +} + +OpenDDLParser::~OpenDDLParser() { + clear(); +} + +void OpenDDLParser::logToStream(FILE *f, LogSeverity severity, const std::string &message) { + if (f) { + const char *tag = "none"; + switch (severity) { + case ddl_debug_msg: tag = "debug"; break; + case ddl_info_msg: tag = "info"; break; + case ddl_warn_msg: tag = "warn"; break; + case ddl_error_msg: tag = "error"; break; + } + fprintf(f, "OpenDDLParser: (%5s) %s\n", tag, message.c_str()); + } +} + +OpenDDLParser::logCallback OpenDDLParser::StdLogCallback (FILE *destination) { + using namespace std::placeholders; + return std::bind(logToStream, destination ? destination : stderr, _1, _2); +} + +void OpenDDLParser::setLogCallback(logCallback callback) { + // install user-specific log callback; null = no log callback + m_logCallback = callback; +} + +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 nullptr; + } + + return &m_buffer[0]; +} + +size_t OpenDDLParser::getBufferSize() const { + return m_buffer.size(); +} + +void OpenDDLParser::clear() { + m_buffer.resize(0); + delete m_context; + m_context = nullptr; +} + +bool OpenDDLParser::validate() { + if (m_buffer.empty()) { + return true; + } + + if (!isCharacter(m_buffer[0]) && !isNumeric(m_buffer[0])) { + return false; + } + + return true; +} + +bool OpenDDLParser::parse() { + if (m_buffer.empty()) { + return false; + } + + normalizeBuffer(m_buffer); + if (!validate()) { + return false; + } + + m_context = new Context; + m_context->m_root = DDLNode::create("root", "", 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 == nullptr) { + return false; + } + pos = current - &m_buffer[0]; + } + return true; +} + +bool OpenDDLParser::exportContext(Context *ctx, const std::string &filename) { + if (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 (nullptr != id) { + if (nullptr != id->m_text.m_buffer) { + std::cout << id->m_text.m_buffer << std::endl; + } + } +} +#endif + +char *OpenDDLParser::parseHeader(char *in, char *end) { + if (nullptr == in || in == end) { + return in; + } + + Text *id(nullptr); + in = OpenDDLParser::parseIdentifier(in, end, &id); + +#ifdef DEBUG_HEADER_NAME + dumpId(id); +#endif // DEBUG_HEADER_NAME + + in = lookForNextToken(in, end); + if (nullptr != id) { + // store the node + DDLNode *node(createDDLNode(id, this)); + if (nullptr != node) { + pushNode(node); + } else { + std::cerr << "nullptr returned by creating DDLNode." << std::endl; + } + delete id; + + Name *name(nullptr); + in = OpenDDLParser::parseName(in, end, &name); + if (nullptr != name && nullptr != node && nullptr != name->m_id->m_buffer) { + const std::string nodeName(name->m_id->m_buffer); + node->setName(nodeName); + delete name; + } + + Property *first(nullptr); + in = lookForNextToken(in, end); + if (in != end && *in == Grammar::OpenPropertyToken[0]) { + in++; + Property *prop(nullptr), *prev(nullptr); + while (in != end && *in != Grammar::ClosePropertyToken[0]) { + in = OpenDDLParser::parseProperty(in, end, &prop); + in = lookForNextToken(in, end); + if(in == end) { + break; + } + + if (*in != Grammar::CommaSeparator[0] && *in != Grammar::ClosePropertyToken[0]) { + logInvalidTokenError(in, Grammar::ClosePropertyToken, m_logCallback); + return nullptr; + } + + if (nullptr != prop && *in != Grammar::CommaSeparator[0]) { + if (nullptr == first) { + first = prop; + } + if (nullptr != prev) { + prev->m_next = prop; + } + prev = prop; + } + } + if(in != end) { + ++in; + } + } + + // set the properties + if (nullptr != first && nullptr != node) { + node->setProperties(first); + } + } + + return in; +} + +char *OpenDDLParser::parseStructure(char *in, char *end) { + if (nullptr == in || in == end) { + return in; + } + + bool error(false); + in = lookForNextToken(in, end); + if (*in == *Grammar::OpenBracketToken) { + // loop over all children ( data and nodes ) + do { + in = parseStructureBody(in, end, error); + if (in == nullptr) { + return nullptr; + } + } while (*in != *Grammar::CloseBracketToken); + ++in; + } else { + ++in; + logInvalidTokenError(in, std::string(Grammar::OpenBracketToken), m_logCallback); + error = true; + return 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 (nullptr != values) { + if (nullptr != currentNode) { + currentNode->setValue(values); + } + } +} + +static void setNodeReferences(DDLNode *currentNode, Reference *refs) { + if (nullptr != refs) { + if (nullptr != currentNode) { + currentNode->setReferences(refs); + } + } +} + +static void setNodeDataArrayList(DDLNode *currentNode, DataArrayList *dtArrayList) { + if (nullptr != dtArrayList) { + if (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::ValueType::ddl_none); + size_t arrayLen(0); + in = OpenDDLParser::parsePrimitiveDataType(in, end, type, arrayLen); + if (Value::ValueType::ddl_none != type) { + // parse a primitive data type + in = lookForNextToken(in, end); + if (*in == Grammar::OpenBracketToken[0]) { + Reference *refs(nullptr); + DataArrayList *dtArrayList(nullptr); + Value *values(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 nullptr; + } else { + //in++; + } + } else { + // parse a complex data type + in = parseNextNode(in, end); + } + + return in; +} + +void OpenDDLParser::pushNode(DDLNode *node) { + if (nullptr == node) { + return; + } + + m_stack.push_back(node); +} + +DDLNode *OpenDDLParser::popNode() { + if (m_stack.empty()) { + return nullptr; + } + + DDLNode *topNode(top()); + m_stack.pop_back(); + return topNode; +} + +DDLNode *OpenDDLParser::top() { + if (m_stack.empty()) { + return nullptr; + } + + DDLNode *top(m_stack.back()); + return top; +} + +DDLNode *OpenDDLParser::getRoot() const { + if (nullptr == m_context) { + return 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 (isCommentOpenTag(c, end)) { + ++readIdx; + while (readIdx < len && !isCommentCloseTag(&buffer[readIdx], end)) { + ++readIdx; + } + ++readIdx; + } else 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 (readIdx < len && !isEndofLine(buffer[readIdx])) { + ++readIdx; + } + } + } + } + buffer = newBuffer; +} + +char *OpenDDLParser::parseName(char *in, char *end, Name **name) { + *name = nullptr; + if (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(nullptr); + Text *id(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 = nullptr; + if (nullptr == in || in == end) { + return in; + } + + // ignore blanks + in = lookForNextToken(in, end); + if (in == end) { + return in; + } + + // 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 ((in != end) && !isSeparator(*in) && !isNewLine(*in) && + *in != Grammar::OpenPropertyToken[0] && + *in != Grammar::ClosePropertyToken[0] && + *in != '$') { + ++in; + ++idLen; + } + + const size_t len(idLen); + *id = new Text(start, len); + + return in; +} + +char *OpenDDLParser::parsePrimitiveDataType(char *in, char *end, Value::ValueType &type, size_t &len) { + type = Value::ValueType::ddl_none; + len = 0; + if (nullptr == in || in == end) { + return in; + } + + size_t prim_len(0); + for (size_t i = 0; i < (size_t) Value::ValueType::ddl_types_max; i++) { + prim_len = strlen(Grammar::PrimitiveTypeToken[i]); + if (0 == strncmp(in, Grammar::PrimitiveTypeToken[i], prim_len)) { + type = static_cast<Value::ValueType>(i); + break; + } + } + + if (Value::ValueType::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::ValueType::ddl_none; + } + + return in; +} + +char *OpenDDLParser::parseReference(char *in, char *end, std::vector<Name *> &names) { + if (nullptr == in || in == end) { + return in; + } + + Name *nextName(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 = nullptr; + if (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 = nullptr; + return in; + } + *boolean = ValueAllocator::allocPrimData(Value::ValueType::ddl_bool); + (*boolean)->setBool(false); + } else { + *boolean = ValueAllocator::allocPrimData(Value::ValueType::ddl_bool); + (*boolean)->setBool(true); + } + + return in; +} + +char *OpenDDLParser::parseIntegerLiteral(char *in, char *end, Value **integer, Value::ValueType integerType) { + *integer = nullptr; + if (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, nullptr, 10)); +#else + const int64 value(atoll(start)); + const uint64 uvalue(strtoull(start, nullptr, 10)); +#endif + *integer = ValueAllocator::allocPrimData(integerType); + switch (integerType) { + case Value::ValueType::ddl_int8: + (*integer)->setInt8((int8)value); + break; + case Value::ValueType::ddl_int16: + (*integer)->setInt16((int16)value); + break; + case Value::ValueType::ddl_int32: + (*integer)->setInt32((int32)value); + break; + case Value::ValueType::ddl_int64: + (*integer)->setInt64((int64)value); + break; + case Value::ValueType::ddl_unsigned_int8: + (*integer)->setUnsignedInt8((uint8)uvalue); + break; + case Value::ValueType::ddl_unsigned_int16: + (*integer)->setUnsignedInt16((uint16)uvalue); + break; + case Value::ValueType::ddl_unsigned_int32: + (*integer)->setUnsignedInt32((uint32)uvalue); + break; + case Value::ValueType::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 = nullptr; + if (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::ValueType::ddl_double) { + const double value(atof(start)); + *floating = ValueAllocator::allocPrimData(Value::ValueType::ddl_double); + (*floating)->setDouble(value); + } else { + const float value((float)atof(start)); + *floating = ValueAllocator::allocPrimData(Value::ValueType::ddl_float); + (*floating)->setFloat(value); + } + } + + return in; +} + +char *OpenDDLParser::parseStringLiteral(char *in, char *end, Value **stringData) { + *stringData = nullptr; + if (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::ValueType::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 (nullptr != primData) { + (*prop) = new Property(id); + (*prop)->m_value = primData; + } +} + +char *OpenDDLParser::parseHexaLiteral(char *in, char *end, Value **data) { + *data = nullptr; + if (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::ValueType::ddl_unsigned_int64); + if (nullptr != *data) { + (*data)->setUnsignedInt64(value); + } + + return in; +} + +char *OpenDDLParser::parseProperty(char *in, char *end, Property **prop) { + *prop = nullptr; + if (nullptr == in || in == end) { + return in; + } + + in = lookForNextToken(in, end); + Text *id = nullptr; + in = parseIdentifier(in, end, &id); + if (nullptr != id) { + in = lookForNextToken(in, end); + if (in != end && *in == '=') { + ++in; + in = getNextToken(in, end); + Value *primData(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; + } + } + } else { + delete id; + } + } + + return in; +} + +char *OpenDDLParser::parseDataList(char *in, char *end, Value::ValueType type, Value **data, + size_t &numValues, Reference **refs, size_t &numRefs) { + *data = nullptr; + numValues = numRefs = 0; + if (nullptr == in || in == end) { + return in; + } + + in = lookForNextToken(in, end); + if (*in == '{') { + ++in; + Value *current(nullptr), *prev(nullptr); + while ('}' != *in) { + current = nullptr; + in = lookForNextToken(in, end); + if (Value::ValueType::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::ValueType::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::ValueType::ddl_int8: + case Value::ValueType::ddl_int16: + case Value::ValueType::ddl_int32: + case Value::ValueType::ddl_int64: + case Value::ValueType::ddl_unsigned_int8: + case Value::ValueType::ddl_unsigned_int16: + case Value::ValueType::ddl_unsigned_int32: + case Value::ValueType::ddl_unsigned_int64: + in = parseIntegerLiteral(in, end, ¤t, type); + break; + case Value::ValueType::ddl_half: + case Value::ValueType::ddl_float: + case Value::ValueType::ddl_double: + in = parseFloatingLiteral(in, end, ¤t, type); + break; + case Value::ValueType::ddl_string: + in = parseStringLiteral(in, end, ¤t); + break; + default: + break; + } + } + + if (nullptr != current) { + if (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 (nullptr == dataArrayList) { + return in; + } + + *dataArrayList = nullptr; + if (nullptr == in || in == end) { + return in; + } + + in = lookForNextToken(in, end); + if (*in == Grammar::OpenBracketToken[0]) { + ++in; + Value *currentValue(nullptr); + Reference *refs(nullptr); + DataArrayList *prev(nullptr), *currentDataList(nullptr); + do { + size_t numRefs(0), numValues(0); + currentValue = nullptr; + + in = parseDataList(in, end, type, ¤tValue, numValues, &refs, numRefs); + if (nullptr != currentValue || 0 != numRefs) { + if (nullptr == prev) { + *dataArrayList = createDataArrayList(currentValue, numValues, refs, numRefs); + prev = *dataArrayList; + } else { + currentDataList = createDataArrayList(currentValue, numValues, refs, numRefs); + if (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/libs/assimp/contrib/openddlparser/code/OpenDDLStream.cpp b/libs/assimp/contrib/openddlparser/code/OpenDDLStream.cpp new file mode 100644 index 0000000..1a38dfa --- /dev/null +++ b/libs/assimp/contrib/openddlparser/code/OpenDDLStream.cpp @@ -0,0 +1,96 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2020 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/OpenDDLStream.h> + +BEGIN_ODDLPARSER_NS + +StreamFormatterBase::StreamFormatterBase() { + // empty +} + +StreamFormatterBase::~StreamFormatterBase() { + // empty +} + +std::string StreamFormatterBase::format(const std::string &statement) { + std::string tmp(statement); + return tmp; +} + +IOStreamBase::IOStreamBase(StreamFormatterBase *formatter) : + m_formatter(formatter), + m_file(nullptr) { + if (nullptr == m_formatter) { + m_formatter = new StreamFormatterBase; + } +} + +IOStreamBase::~IOStreamBase() { + delete m_formatter; + m_formatter = nullptr; +} + +bool IOStreamBase::open(const std::string &name) { + m_file = ::fopen(name.c_str(), "a"); + if (m_file == nullptr) { + return false; + } + + return true; +} + +bool IOStreamBase::close() { + if (nullptr == m_file) { + return false; + } + + ::fclose(m_file); + m_file = nullptr; + + return true; +} + +bool IOStreamBase::isOpen() const { + return (nullptr != m_file); +} + +size_t IOStreamBase::read(size_t sizeToRead, std::string &statement) { + if (nullptr == m_file) { + return 0; + } + + statement.resize(sizeToRead); + const size_t readBytes = ::fread(&statement[0], 1, sizeToRead, m_file); + + return readBytes; +} + +size_t IOStreamBase::write(const std::string &statement) { + if (nullptr == m_file) { + return 0; + } + std::string formatStatement = m_formatter->format(statement); + return ::fwrite(formatStatement.c_str(), sizeof(char), formatStatement.size(), m_file); +} + +END_ODDLPARSER_NS diff --git a/libs/assimp/contrib/openddlparser/code/Value.cpp b/libs/assimp/contrib/openddlparser/code/Value.cpp new file mode 100644 index 0000000..5a8aa39 --- /dev/null +++ b/libs/assimp/contrib/openddlparser/code/Value.cpp @@ -0,0 +1,438 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2020 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/OpenDDLStream.h> +#include <openddlparser/Value.h> + +#include <cassert> + +BEGIN_ODDLPARSER_NS + +static Value::Iterator end(nullptr); + +Value::Iterator::Iterator() : + m_start(nullptr), + m_current(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 (nullptr == m_current) { + return false; + } + return (nullptr != m_current->getNext()); +} + +Value *Value::Iterator::getNext() { + if (!hasNext()) { + return nullptr; + } + + Value *v(m_current->getNext()); + m_current = v; + + return v; +} + +const Value::Iterator Value::Iterator::operator++(int) { + if (nullptr == m_current) { + return end; + } + + m_current = m_current->getNext(); + Iterator inst(m_current); + + return inst; +} + +Value::Iterator &Value::Iterator::operator++() { + if (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 (nullptr == m_current) { + return nullptr; + } + return m_current; +} + +Value::Value(ValueType type) : + m_type(type), + m_size(0), + m_data(nullptr), + m_next(nullptr) { + // empty +} + +Value::~Value() { + if (m_data != nullptr) { + if (m_type == ValueType::ddl_ref) { + Reference *tmp = (Reference *)m_data; + if (tmp != nullptr) { + delete tmp; + } + } else { + delete[] m_data; + } + } + delete m_next; +} + +void Value::setBool(bool value) { + assert(ValueType::ddl_bool == m_type); + ::memcpy(m_data, &value, m_size); +} + +bool Value::getBool() { + assert(ValueType::ddl_bool == m_type); + return (*m_data == 1); +} + +void Value::setInt8(int8 value) { + assert(ValueType::ddl_int8 == m_type); + ::memcpy(m_data, &value, m_size); +} + +int8 Value::getInt8() { + assert(ValueType::ddl_int8 == m_type); + return (int8)(*m_data); +} + +void Value::setInt16(int16 value) { + assert(ValueType::ddl_int16 == m_type); + ::memcpy(m_data, &value, m_size); +} + +int16 Value::getInt16() { + assert(ValueType::ddl_int16 == m_type); + int16 i; + ::memcpy(&i, m_data, m_size); + return i; +} + +void Value::setInt32(int32 value) { + assert(ValueType::ddl_int32 == m_type); + ::memcpy(m_data, &value, m_size); +} + +int32 Value::getInt32() { + assert(ValueType::ddl_int32 == m_type); + int32 i; + ::memcpy(&i, m_data, m_size); + return i; +} + +void Value::setInt64(int64 value) { + assert(ValueType::ddl_int64 == m_type); + ::memcpy(m_data, &value, m_size); +} + +int64 Value::getInt64() { + assert(ValueType::ddl_int64 == m_type); + int64 i; + ::memcpy(&i, m_data, m_size); + return i; +} + +void Value::setUnsignedInt8(uint8 value) { + assert(ValueType::ddl_unsigned_int8 == m_type); + ::memcpy(m_data, &value, m_size); +} + +uint8 Value::getUnsignedInt8() const { + assert(ValueType::ddl_unsigned_int8 == m_type); + uint8 i; + ::memcpy(&i, m_data, m_size); + return i; +} + +void Value::setUnsignedInt16(uint16 value) { + assert(ValueType::ddl_unsigned_int16 == m_type); + ::memcpy(m_data, &value, m_size); +} + +uint16 Value::getUnsignedInt16() const { + assert(ValueType::ddl_unsigned_int16 == m_type); + uint16 i; + ::memcpy(&i, m_data, m_size); + return i; +} + +void Value::setUnsignedInt32(uint32 value) { + assert(ValueType::ddl_unsigned_int32 == m_type); + ::memcpy(m_data, &value, m_size); +} + +uint32 Value::getUnsignedInt32() const { + assert(ValueType::ddl_unsigned_int32 == m_type); + uint32 i; + ::memcpy(&i, m_data, m_size); + return i; +} + +void Value::setUnsignedInt64(uint64 value) { + assert(ValueType::ddl_unsigned_int64 == m_type); + ::memcpy(m_data, &value, m_size); +} + +uint64 Value::getUnsignedInt64() const { + assert(ValueType::ddl_unsigned_int64 == m_type); + uint64 i; + ::memcpy(&i, m_data, m_size); + return i; +} + +void Value::setFloat(float value) { + assert(ValueType::ddl_float == m_type); + ::memcpy(m_data, &value, m_size); +} + +float Value::getFloat() const { + if (m_type == ValueType::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(ValueType::ddl_double == m_type); + ::memcpy(m_data, &value, m_size); +} + +double Value::getDouble() const { + if (m_type == ValueType::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(ValueType::ddl_string == m_type); + ::memcpy(m_data, str.c_str(), str.size()); + m_data[str.size()] = '\0'; +} + +const char *Value::getString() const { + assert(ValueType::ddl_string == m_type); + return (const char *)m_data; +} + +void Value::setRef(Reference *ref) { + assert(ValueType::ddl_ref == m_type); + + if (nullptr != ref) { + const size_t sizeInBytes(ref->sizeInBytes()); + if (sizeInBytes > 0) { + if (nullptr != m_data) { + delete[] m_data; + } + + m_data = (unsigned char *)new Reference(*ref); + } + } +} + +Reference *Value::getRef() const { + assert(ValueType::ddl_ref == m_type); + + return (Reference *)m_data; +} + +void Value::dump(IOStreamBase &stream) { + switch (m_type) { + case ValueType::ddl_none: + stream.write("None\n"); + break; + case ValueType::ddl_bool: + stream.write(std::to_string(getBool()) + "\n"); + break; + case ValueType::ddl_int8: + stream.write(std::to_string(getInt8()) + "\n"); + break; + case ValueType::ddl_int16: + stream.write(std::to_string(getInt16()) + "\n"); + break; + case ValueType::ddl_int32: + stream.write(std::to_string(getInt32()) + "\n"); + break; + case ValueType::ddl_int64: + stream.write(std::to_string(getInt64()) + "\n"); + break; + case ValueType::ddl_unsigned_int8: + stream.write("Not supported\n"); + break; + case ValueType::ddl_unsigned_int16: + stream.write("Not supported\n"); + break; + case ValueType::ddl_unsigned_int32: + stream.write("Not supported\n"); + break; + case ValueType::ddl_unsigned_int64: + stream.write("Not supported\n"); + break; + case ValueType::ddl_half: + stream.write("Not supported\n"); + break; + case ValueType::ddl_float: + stream.write(std::to_string(getFloat()) + "\n"); + break; + case ValueType::ddl_double: + stream.write(std::to_string(getDouble()) + "\n"); + break; + case ValueType::ddl_string: + stream.write(std::string(getString()) + "\n"); + break; + case ValueType::ddl_ref: + stream.write("Not supported\n"); + break; + default: + break; + } +} + +void Value::setNext(Value *next) { + m_next = next; +} + +Value *Value::getNext() const { + return m_next; +} + +size_t Value::size() const { + size_t result = 1; + Value *n = m_next; + while (n != nullptr) { + result++; + n = n->m_next; + } + return result; +} + +Value *ValueAllocator::allocPrimData(Value::ValueType type, size_t len) { + if (type == Value::ValueType::ddl_none || Value::ValueType::ddl_types_max == type) { + return nullptr; + } + + Value *data = new Value(type); + switch (type) { + case Value::ValueType::ddl_bool: + data->m_size = sizeof(bool); + break; + case Value::ValueType::ddl_int8: + data->m_size = sizeof(int8); + break; + case Value::ValueType::ddl_int16: + data->m_size = sizeof(int16); + break; + case Value::ValueType::ddl_int32: + data->m_size = sizeof(int32); + break; + case Value::ValueType::ddl_int64: + data->m_size = sizeof(int64); + break; + case Value::ValueType::ddl_unsigned_int8: + data->m_size = sizeof(uint8); + break; + case Value::ValueType::ddl_unsigned_int16: + data->m_size = sizeof(uint16); + break; + case Value::ValueType::ddl_unsigned_int32: + data->m_size = sizeof(uint32); + break; + case Value::ValueType::ddl_unsigned_int64: + data->m_size = sizeof(uint64); + break; + case Value::ValueType::ddl_half: + data->m_size = sizeof(short); + break; + case Value::ValueType::ddl_float: + data->m_size = sizeof(float); + break; + case Value::ValueType::ddl_double: + data->m_size = sizeof(double); + break; + case Value::ValueType::ddl_string: + data->m_size = sizeof(char) * (len + 1); + break; + case Value::ValueType::ddl_ref: + data->m_size = 0; + break; + case Value::ValueType::ddl_none: + case Value::ValueType::ddl_types_max: + default: + break; + } + + if (data->m_size) { + data->m_data = new unsigned char[data->m_size]; + ::memset(data->m_data, 0, data->m_size); + } + + return data; +} + +void ValueAllocator::releasePrimData(Value **data) { + if (!data) { + return; + } + + delete *data; + *data = nullptr; +} + +END_ODDLPARSER_NS diff --git a/libs/assimp/contrib/openddlparser/include/openddlparser/DDLNode.h b/libs/assimp/contrib/openddlparser/include/openddlparser/DDLNode.h new file mode 100644 index 0000000..593a5f1 --- /dev/null +++ b/libs/assimp/contrib/openddlparser/include/openddlparser/DDLNode.h @@ -0,0 +1,173 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2020 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> +#include <vector> + +BEGIN_ODDLPARSER_NS + +// Forward declarations +class IOStreamBase; +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; + + /// @brief The child-node-list iterator. + typedef std::vector<DDLNode *>::iterator DDLNodeIt; + +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 name [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 dtArrayList [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 refs [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 Will dump the node into the stream. + /// @param stream [in] The stream to write to. + void dump(IOStreamBase &stream); + + /// @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 = nullptr); + +private: + DDLNode(const std::string &type, const std::string &name, size_t idx, DDLNode *parent = 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/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h new file mode 100644 index 0000000..6ccc83b --- /dev/null +++ b/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h @@ -0,0 +1,245 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2020 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 <string> +#include <vector> + +#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 nullptr nullptr +#define ddl_override override +#define ddl_final final +#define ddl_no_copy = delete +#else +// Fall-back for older compilers +#define 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 +using int8 = signed char; ///< Signed integer, 1 byte +using int16 = signed short; ///< Signed integer, 2 byte +using int32 = signed int; ///< Signed integer, 4 byte +using int64 = int64_impl; ///< Signed integer, 8 byte +using uint8 = unsigned char; ///< Unsigned integer, 1 byte +using uint16 = unsigned short ; ///< Unsigned integer, 2 byte +using uint32 = unsigned int; ///< Unsigned integer, 4 byte +using uint64 = uint64_impl ; ///< 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); + Name(const Name &name); + /// @brief The destructor. + ~Name(); + +private: + 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(); + Reference(const Reference &ref); + /// @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 &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/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLExport.h b/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLExport.h new file mode 100644 index 0000000..9452535 --- /dev/null +++ b/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLExport.h @@ -0,0 +1,80 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2020 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/OpenDDLStream.h> +#include <openddlparser/Value.h> + +BEGIN_ODDLPARSER_NS + +// Forward declarations +class IOStreamBase; + +//------------------------------------------------------------------------------------------------- +/// +/// @ingroup OpenDDLParser +/// @brief This class represents the OpenDDLExporter. +/// +//------------------------------------------------------------------------------------------------- +class DLL_ODDLPARSER_EXPORT OpenDDLExport { +public: + /// @brief The class constructor + OpenDDLExport(IOStreamBase *stream = 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/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParser.h b/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParser.h new file mode 100644 index 0000000..3fbb4b6 --- /dev/null +++ b/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParser.h @@ -0,0 +1,206 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2020 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/DDLNode.h> +#include <openddlparser/OpenDDLCommon.h> +#include <openddlparser/OpenDDLParserUtils.h> +#include <openddlparser/Value.h> + +#include <string> +#include <vector> +#include <functional> + +BEGIN_ODDLPARSER_NS + +class DDLNode; +class Value; + +struct Identifier; +struct Reference; +struct Property; + +template <class T> +inline bool isEmbeddedCommentOpenTag(T *in, T *end) { + if (in == '/' && in + 1 == '*') { + return true; + } + + return false; +} + +/// @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 ((in != end) && (isSpace(*in) || isNewLine(*in) || ',' == *in)) { + ++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. + typedef std::function<void (LogSeverity severity, const std::string &msg)> logCallback; + +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 A default log callback that writes to a FILE. + /// @param destination [in] Output stream. NULL will use stderr. + /// @return A callback that you can pass to setLogCallback. + static logCallback StdLogCallback(FILE *destination = nullptr); + + /// @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(); + + bool validate(); + + /// @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::ValueType::ddl_int32); + static char *parseFloatingLiteral(char *in, char *end, Value **floating, Value::ValueType floatType = Value::ValueType::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; + + /// @brief Callback for StdLogCallback(). Not meant to be called directly. + static void logToStream (FILE *, LogSeverity, const std::string &); +}; + +END_ODDLPARSER_NS diff --git a/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h b/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h new file mode 100644 index 0000000..42ad675 --- /dev/null +++ b/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h @@ -0,0 +1,503 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2020 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) { + size_t idx = static_cast<size_t>(in); + return idx < sizeof(chartype_table) && (chartype_table[idx] == 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; +} + +template <class T> +inline bool isCommentOpenTag(T *in, T *end) { + if (*in == '/') { + if (in + 1 != end) { + if (*(in + 1) == '*') { + return true; + } + } + } + + return false; +} + +template <class T> +inline bool isCommentCloseTag(T *in, T *end) { + if (*in == '*') { + if (in + 1 != end) { + if (*(in + 1) == '/') { + return true; + } + } + } + + return false; +} + +END_ODDLPARSER_NS diff --git a/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLStream.h b/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLStream.h new file mode 100644 index 0000000..93bde5f --- /dev/null +++ b/libs/assimp/contrib/openddlparser/include/openddlparser/OpenDDLStream.h @@ -0,0 +1,89 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2020 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 + +//------------------------------------------------------------------------------------------------- +/// @ingroup IOStreamBase +/// @brief This class represents the stream to write out. +//------------------------------------------------------------------------------------------------- +class DLL_ODDLPARSER_EXPORT StreamFormatterBase { +public: + /// @brief The class constructor. + StreamFormatterBase(); + + /// @brief The class destructor, virtual. + virtual ~StreamFormatterBase(); + + /// @brief Will format the string and return the new formatted result. + /// @param statement [in] The string to reformat. + /// @return The reformatted result. + 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: + /// @brief The class constructor with the formatter. + /// @param formatter [in] The formatter to use. + explicit IOStreamBase(StreamFormatterBase *formatter = nullptr); + + /// @brief The class destructor, virtual. + virtual ~IOStreamBase(); + + /// @brief Will open the stream. + /// @param name [in] The name for the stream. + /// @return true, if the stream was opened successfully, false if not. + virtual bool open(const std::string &name); + + /// @brief Will close the stream. + /// @return true, if the stream was closed successfully, false if not. + virtual bool close(); + + /// @brief Returns true, if the stream is open. + /// @return true, if the stream is open, false if not. + virtual bool isOpen() const; + + /// @brief Will read a string from the stream. + /// @param sizeToRead [in] The size to read in bytes. + /// @param statement [out] The read statements. + /// @return The bytes read from the stream. + virtual size_t read(size_t sizeToRead, std::string &statement); + + /// @brief Will write a string into the stream. + /// @param statement [in] The string to write. + /// @return The bytes written into the stream. + virtual size_t write(const std::string &statement); + +private: + StreamFormatterBase *m_formatter; + FILE *m_file; +}; + +END_ODDLPARSER_NS diff --git a/libs/assimp/contrib/openddlparser/include/openddlparser/TPoolAllocator.h b/libs/assimp/contrib/openddlparser/include/openddlparser/TPoolAllocator.h new file mode 100644 index 0000000..6076c73 --- /dev/null +++ b/libs/assimp/contrib/openddlparser/include/openddlparser/TPoolAllocator.h @@ -0,0 +1,226 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2019 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 + +//------------------------------------------------------------------------------------------------- +/// @class TPoolAllocator +/// @ingroup CPPCore +/// +/// @brief This class implements a simple pool-based allocation scheme. +/// Initially you have to define its size. Each allocation will be done from this initially created +/// pool. You have to release all pooled instances after the usage. +/// This allocation scheme is fast and does no call any new-calls during the lifetime of the +/// allocator. +//------------------------------------------------------------------------------------------------- +template <class T> +class TPoolAllocator { +public: + TPoolAllocator(); + TPoolAllocator(size_t numItems); + ~TPoolAllocator(); + T *alloc(); + void release(); + void reserve(size_t size); + void clear(); + size_t capacity() const; + size_t reservedMem() const; + size_t freeMem() const; + void dumpAllocations(std::string &allocs); + void resize(size_t growSize); + + CPPCORE_NONE_COPYING(TPoolAllocator) + +private: + struct Pool { + size_t m_poolsize; + T *m_pool; + size_t m_currentIdx; + Pool *m_next; + + Pool() : + m_poolsize(0u), m_pool(nullptr), m_currentIdx(0u), m_next(nullptr) { + // empty + } + + Pool(size_t numItems, Pool *prev) : + m_poolsize(numItems), m_pool(nullptr), m_currentIdx(0u), m_next(prev) { + m_pool = new T[m_poolsize]; + } + + ~Pool() { + delete[] m_pool; + m_pool = nullptr; + } + + CPPCORE_NONE_COPYING(Pool) + }; + + Pool *getFreePool() { + Pool *current(m_freeList); + if (nullptr != m_freeList) { + m_freeList = m_freeList->m_next; + } + return current; + } + + Pool *m_first; + Pool *m_current; + Pool *m_freeList; + size_t m_capacity; +}; + +template <class T> +inline TPoolAllocator<T>::TPoolAllocator() : + m_first(nullptr), m_current(nullptr), m_freeList(nullptr), m_capacity(0L) { + // empty +} + +template <class T> +inline TPoolAllocator<T>::TPoolAllocator(size_t numItems) : + m_first(nullptr), m_current(nullptr), m_freeList(nullptr), m_capacity(0L) { + m_first = new Pool(numItems); + m_capacity += numItems; + m_current = m_first; +} + +template <class T> +inline TPoolAllocator<T>::~TPoolAllocator() { + clear(); +} + +template <class T> +inline T *TPoolAllocator<T>::alloc() { + if (nullptr == m_current) { + return nullptr; + } + + if (m_current->m_currentIdx == m_current->m_poolsize) { + resize(m_current->m_poolsize); + } + + T *ptr(&m_current->m_pool[m_current->m_currentIdx]); + m_current->m_currentIdx++; + + return ptr; +} + +template <class T> +inline void TPoolAllocator<T>::release() { + if (nullptr == m_current) { + return; + } + + Pool *current(m_first); + while (nullptr != current) { + current->m_currentIdx = 0; + current = current->m_next; + } + m_freeList = m_first->m_next; + m_current = m_first; +} + +template <class T> +inline void TPoolAllocator<T>::reserve(size_t size) { + clear(); + + m_first = new Pool(size, nullptr); + m_current = m_first; + + m_current->m_pool = new T[size]; + m_current->m_poolsize = size; + + m_capacity = size; +} + +template <class T> +inline void TPoolAllocator<T>::clear() { + if (nullptr == m_current) { + return; + } + + Pool *next(m_first); + while (nullptr != next) { + Pool *current = next; + next = current->m_next; + delete current; + } + m_current = nullptr; + m_freeList = nullptr; +} + +template <class T> +inline size_t TPoolAllocator<T>::capacity() const { + return m_capacity; +} + +template <class T> +inline size_t TPoolAllocator<T>::reservedMem() const { + return m_capacity * sizeof(T); +} + +template <class T> +inline size_t TPoolAllocator<T>::freeMem() const { + if (nullptr == m_current) { + return 0L; + } + + return (m_current->m_poolsize - m_current->m_currentIdx); +} + +template <class T> +inline void TPoolAllocator<T>::dumpAllocations(std::string &allocs) { + allocs.clear(); + allocs += "Number allocations = "; + allocs += std::to_string(m_current->m_currentIdx); + allocs += "\n"; +} + +template <class T> +inline void TPoolAllocator<T>::resize(size_t growSize) { + if (nullptr != m_current) { + if (growSize < m_current->m_poolsize) { + return; + } + } + + if (nullptr == m_first) { + m_first = new Pool(growSize, nullptr); + m_current = m_first; + m_capacity += m_current->m_poolsize; + } else { + Pool *pool = getFreePool(); + if (nullptr == pool) { + pool = new Pool(growSize, nullptr); + m_capacity += growSize; + } + m_current->m_next = pool; + m_current = m_current->m_next; + } +} + +END_ODDLPARSER_NS
\ No newline at end of file diff --git a/libs/assimp/contrib/openddlparser/include/openddlparser/Value.h b/libs/assimp/contrib/openddlparser/include/openddlparser/Value.h new file mode 100644 index 0000000..75af781 --- /dev/null +++ b/libs/assimp/contrib/openddlparser/include/openddlparser/Value.h @@ -0,0 +1,273 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2020 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 + +// Forward declarations +struct ValueAllocator; + +class IOStreamBase; + +///------------------------------------------------------------------------------------------------ +/// @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 class 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 str [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. + /// @param stream [in] The stream to write in. + void dump( IOStreamBase &stream ); + + /// @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() const; + + 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 |