| /* |
| --------------------------------------------------------------------------- |
| Open Asset Import Library (assimp) |
| --------------------------------------------------------------------------- |
| |
| Copyright (c) 2006-2017, assimp team |
| |
| |
| All rights reserved. |
| |
| Redistribution and use of this software in source and binary forms, |
| with or without modification, are permitted provided that the following |
| conditions are met: |
| |
| * Redistributions of source code must retain the above |
| copyright notice, this list of conditions and the |
| following disclaimer. |
| |
| * Redistributions in binary form must reproduce the above |
| copyright notice, this list of conditions and the |
| following disclaimer in the documentation and/or other |
| materials provided with the distribution. |
| |
| * Neither the name of the assimp team, nor the names of its |
| contributors may be used to endorse or promote products |
| derived from this software without specific prior |
| written permission of the assimp team. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| --------------------------------------------------------------------------- |
| */ |
| |
| /** @file metadata.h |
| * @brief Defines the data structures for holding node meta information. |
| */ |
| #pragma once |
| #ifndef AI_METADATA_H_INC |
| #define AI_METADATA_H_INC |
| |
| #if defined(_MSC_VER) && (_MSC_VER <= 1500) |
| # include "Compiler/pstdint.h" |
| #else |
| # include <stdint.h> |
| #endif |
| |
| // ------------------------------------------------------------------------------- |
| /** |
| * Enum used to distinguish data types |
| */ |
| // ------------------------------------------------------------------------------- |
| typedef enum aiMetadataType { |
| AI_BOOL = 0, |
| AI_INT32 = 1, |
| AI_UINT64 = 2, |
| AI_FLOAT = 3, |
| AI_DOUBLE = 4, |
| AI_AISTRING = 5, |
| AI_AIVECTOR3D = 6, |
| |
| #ifndef SWIG |
| FORCE_32BIT = INT_MAX |
| #endif |
| } aiMetadataType; |
| |
| // ------------------------------------------------------------------------------- |
| /** |
| * Metadata entry |
| * |
| * The type field uniquely identifies the underlying type of the data field |
| */ |
| // ------------------------------------------------------------------------------- |
| struct aiMetadataEntry { |
| aiMetadataType mType; |
| void* mData; |
| }; |
| |
| #ifdef __cplusplus |
| |
| #include <string> |
| |
| // ------------------------------------------------------------------------------- |
| /** |
| * Helper functions to get the aiType enum entry for a type |
| */ |
| // ------------------------------------------------------------------------------- |
| |
| inline aiMetadataType GetAiType( bool ) { return AI_BOOL; } |
| inline aiMetadataType GetAiType( int32_t ) { return AI_INT32; } |
| inline aiMetadataType GetAiType( uint64_t ) { return AI_UINT64; } |
| inline aiMetadataType GetAiType( float ) { return AI_FLOAT; } |
| inline aiMetadataType GetAiType( double ) { return AI_DOUBLE; } |
| inline aiMetadataType GetAiType( const aiString & ) { return AI_AISTRING; } |
| inline aiMetadataType GetAiType( const aiVector3D & ) { return AI_AIVECTOR3D; } |
| |
| #endif // __cplusplus |
| |
| // ------------------------------------------------------------------------------- |
| /** |
| * Container for holding metadata. |
| * |
| * Metadata is a key-value store using string keys and values. |
| */ |
| // ------------------------------------------------------------------------------- |
| struct aiMetadata { |
| /** Length of the mKeys and mValues arrays, respectively */ |
| unsigned int mNumProperties; |
| |
| /** Arrays of keys, may not be NULL. Entries in this array may not be NULL as well. */ |
| C_STRUCT aiString* mKeys; |
| |
| /** Arrays of values, may not be NULL. Entries in this array may be NULL if the |
| * corresponding property key has no assigned value. */ |
| C_STRUCT aiMetadataEntry* mValues; |
| |
| #ifdef __cplusplus |
| |
| /** |
| * @brief The default constructor, set all members to zero by default. |
| */ |
| aiMetadata() |
| : mNumProperties(0) |
| , mKeys(NULL) |
| , mValues(NULL) { |
| // empty |
| } |
| |
| /** |
| * @brief The destructor. |
| */ |
| ~aiMetadata() { |
| delete [] mKeys; |
| mKeys = NULL; |
| if (mValues) { |
| // Delete each metadata entry |
| for (unsigned i=0; i<mNumProperties; ++i) { |
| void* data = mValues[i].mData; |
| switch (mValues[i].mType) { |
| case AI_BOOL: |
| delete static_cast<bool*>(data); |
| break; |
| case AI_INT32: |
| delete static_cast<int32_t*>(data); |
| break; |
| case AI_UINT64: |
| delete static_cast<uint64_t*>(data); |
| break; |
| case AI_FLOAT: |
| delete static_cast<float*>(data); |
| break; |
| case AI_DOUBLE: |
| delete static_cast<double*>(data); |
| break; |
| case AI_AISTRING: |
| delete static_cast<aiString*>(data); |
| break; |
| case AI_AIVECTOR3D: |
| delete static_cast<aiVector3D*>(data); |
| break; |
| #ifndef SWIG |
| case FORCE_32BIT: |
| #endif |
| default: |
| break; |
| } |
| } |
| |
| // Delete the metadata array |
| delete [] mValues; |
| mValues = NULL; |
| } |
| } |
| |
| /** |
| * @brief Allocates property fields + keys. |
| * @param numProperties Number of requested properties. |
| */ |
| static inline |
| aiMetadata *Alloc( unsigned int numProperties ) { |
| if ( 0 == numProperties ) { |
| return nullptr; |
| } |
| |
| aiMetadata *data = new aiMetadata; |
| data->mNumProperties = numProperties; |
| data->mKeys = new aiString[ data->mNumProperties ](); |
| data->mValues = new aiMetadataEntry[ data->mNumProperties ](); |
| |
| return data; |
| } |
| |
| /** |
| * @brief Deallocates property fields + keys. |
| */ |
| static inline |
| void Dealloc( aiMetadata *metadata ) { |
| delete metadata; |
| } |
| |
| template<typename T> |
| inline void Add(const std::string& key, const T& value) |
| { |
| aiString* new_keys = new aiString[mNumProperties + 1]; |
| aiMetadataEntry* new_values = new aiMetadataEntry[mNumProperties + 1]; |
| |
| for(unsigned int i = 0; i < mNumProperties; ++i) |
| { |
| new_keys[i] = mKeys[i]; |
| new_values[i] = mValues[i]; |
| } |
| |
| delete mKeys; |
| delete mValues; |
| |
| mKeys = new_keys; |
| mValues = new_values; |
| |
| mNumProperties++; |
| |
| Set(mNumProperties - 1, key, value); |
| } |
| |
| template<typename T> |
| inline |
| bool Set( unsigned index, const std::string& key, const T& value ) { |
| // In range assertion |
| if ( index >= mNumProperties ) { |
| return false; |
| } |
| |
| // Ensure that we have a valid key. |
| if ( key.empty() ) { |
| return false; |
| } |
| |
| // Set metadata key |
| mKeys[index] = key; |
| |
| // Set metadata type |
| mValues[index].mType = GetAiType(value); |
| // Copy the given value to the dynamic storage |
| mValues[index].mData = new T(value); |
| |
| return true; |
| } |
| |
| template<typename T> |
| inline |
| bool Get( unsigned index, T& value ) { |
| // In range assertion |
| if ( index >= mNumProperties ) { |
| return false; |
| } |
| |
| // Return false if the output data type does |
| // not match the found value's data type |
| if ( GetAiType( value ) != mValues[ index ].mType ) { |
| return false; |
| } |
| |
| // Otherwise, output the found value and |
| // return true |
| value = *static_cast<T*>(mValues[index].mData); |
| |
| return true; |
| } |
| |
| template<typename T> |
| inline |
| bool Get( const aiString& key, T& value ) { |
| // Search for the given key |
| for ( unsigned int i = 0; i < mNumProperties; ++i ) { |
| if ( mKeys[ i ] == key ) { |
| return Get( i, value ); |
| } |
| } |
| return false; |
| } |
| |
| template<typename T> |
| inline bool Get( const std::string& key, T& value ) { |
| return Get(aiString(key), value); |
| } |
| |
| /// Return metadata entry for analyzing it by user. |
| /// \param [in] pIndex - index of the entry. |
| /// \param [out] pKey - pointer to the key value. |
| /// \param [out] pEntry - pointer to the entry: type and value. |
| /// \return false - if pIndex is out of range, else - true. |
| inline bool Get(size_t index, const aiString*& key, const aiMetadataEntry*& entry) { |
| if ( index >= mNumProperties ) { |
| return false; |
| } |
| |
| key = &mKeys[index]; |
| entry = &mValues[index]; |
| |
| return true; |
| } |
| |
| #endif // __cplusplus |
| |
| }; |
| |
| #endif // AI_METADATA_H_INC |